xref: /aosp_15_r20/external/minigbm/rockchip.c (revision d95af8df99a05bcb8679a54dc3ab8e5cd312b38e)
1*d95af8dfSAndroid Build Coastguard Worker /*
2*d95af8dfSAndroid Build Coastguard Worker  * Copyright 2014 The Chromium OS Authors. All rights reserved.
3*d95af8dfSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
4*d95af8dfSAndroid Build Coastguard Worker  * found in the LICENSE file.
5*d95af8dfSAndroid Build Coastguard Worker  */
6*d95af8dfSAndroid Build Coastguard Worker 
7*d95af8dfSAndroid Build Coastguard Worker #ifdef DRV_ROCKCHIP
8*d95af8dfSAndroid Build Coastguard Worker 
9*d95af8dfSAndroid Build Coastguard Worker #include <drm_fourcc.h>
10*d95af8dfSAndroid Build Coastguard Worker #include <errno.h>
11*d95af8dfSAndroid Build Coastguard Worker #include <inttypes.h>
12*d95af8dfSAndroid Build Coastguard Worker #include <rockchip_drm.h>
13*d95af8dfSAndroid Build Coastguard Worker #include <stdio.h>
14*d95af8dfSAndroid Build Coastguard Worker #include <string.h>
15*d95af8dfSAndroid Build Coastguard Worker #include <sys/mman.h>
16*d95af8dfSAndroid Build Coastguard Worker #include <xf86drm.h>
17*d95af8dfSAndroid Build Coastguard Worker 
18*d95af8dfSAndroid Build Coastguard Worker #include "drv_helpers.h"
19*d95af8dfSAndroid Build Coastguard Worker #include "drv_priv.h"
20*d95af8dfSAndroid Build Coastguard Worker #include "util.h"
21*d95af8dfSAndroid Build Coastguard Worker 
22*d95af8dfSAndroid Build Coastguard Worker #define DRM_FORMAT_MOD_ROCKCHIP_AFBC                                                               \
23*d95af8dfSAndroid Build Coastguard Worker 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE |        \
24*d95af8dfSAndroid Build Coastguard Worker 				AFBC_FORMAT_MOD_YTR)
25*d95af8dfSAndroid Build Coastguard Worker 
26*d95af8dfSAndroid Build Coastguard Worker struct rockchip_private_map_data {
27*d95af8dfSAndroid Build Coastguard Worker 	void *cached_addr;
28*d95af8dfSAndroid Build Coastguard Worker 	void *gem_addr;
29*d95af8dfSAndroid Build Coastguard Worker };
30*d95af8dfSAndroid Build Coastguard Worker 
31*d95af8dfSAndroid Build Coastguard Worker static const uint32_t scanout_render_formats[] = { DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB8888,
32*d95af8dfSAndroid Build Coastguard Worker 						   DRM_FORMAT_BGR888,	DRM_FORMAT_RGB565,
33*d95af8dfSAndroid Build Coastguard Worker 						   DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888 };
34*d95af8dfSAndroid Build Coastguard Worker 
35*d95af8dfSAndroid Build Coastguard Worker static const uint32_t texture_only_formats[] = { DRM_FORMAT_NV12, DRM_FORMAT_YVU420,
36*d95af8dfSAndroid Build Coastguard Worker 						 DRM_FORMAT_YVU420_ANDROID };
37*d95af8dfSAndroid Build Coastguard Worker 
afbc_bo_from_format(struct bo * bo,uint32_t width,uint32_t height,uint32_t format,uint64_t modifier)38*d95af8dfSAndroid Build Coastguard Worker static int afbc_bo_from_format(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
39*d95af8dfSAndroid Build Coastguard Worker 			       uint64_t modifier)
40*d95af8dfSAndroid Build Coastguard Worker {
41*d95af8dfSAndroid Build Coastguard Worker 	/* We've restricted ourselves to four bytes per pixel. */
42*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t pixel_size = 4;
43*d95af8dfSAndroid Build Coastguard Worker 
44*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t clump_width = 4;
45*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t clump_height = 4;
46*d95af8dfSAndroid Build Coastguard Worker 
47*d95af8dfSAndroid Build Coastguard Worker #define AFBC_NARROW 1
48*d95af8dfSAndroid Build Coastguard Worker #if AFBC_NARROW == 1
49*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t block_width = 4 * clump_width;
50*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t block_height = 4 * clump_height;
51*d95af8dfSAndroid Build Coastguard Worker #else
52*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t block_width = 8 * clump_width;
53*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t block_height = 2 * clump_height;
54*d95af8dfSAndroid Build Coastguard Worker #endif
55*d95af8dfSAndroid Build Coastguard Worker 
56*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t header_block_size = 16;
57*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t body_block_size = block_width * block_height * pixel_size;
58*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t width_in_blocks = DIV_ROUND_UP(width, block_width);
59*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t height_in_blocks = DIV_ROUND_UP(height, block_height);
60*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t total_blocks = width_in_blocks * height_in_blocks;
61*d95af8dfSAndroid Build Coastguard Worker 
62*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t header_plane_size = total_blocks * header_block_size;
63*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t body_plane_size = total_blocks * body_block_size;
64*d95af8dfSAndroid Build Coastguard Worker 
65*d95af8dfSAndroid Build Coastguard Worker 	/* GPU requires 64 bytes, but EGL import code expects 1024 byte
66*d95af8dfSAndroid Build Coastguard Worker 	 * alignement for the body plane. */
67*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t body_plane_alignment = 1024;
68*d95af8dfSAndroid Build Coastguard Worker 
69*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t body_plane_offset = ALIGN(header_plane_size, body_plane_alignment);
70*d95af8dfSAndroid Build Coastguard Worker 	const uint32_t total_size = body_plane_offset + body_plane_size;
71*d95af8dfSAndroid Build Coastguard Worker 
72*d95af8dfSAndroid Build Coastguard Worker 	bo->meta.strides[0] = width_in_blocks * block_width * pixel_size;
73*d95af8dfSAndroid Build Coastguard Worker 	bo->meta.sizes[0] = total_size;
74*d95af8dfSAndroid Build Coastguard Worker 	bo->meta.offsets[0] = 0;
75*d95af8dfSAndroid Build Coastguard Worker 
76*d95af8dfSAndroid Build Coastguard Worker 	bo->meta.total_size = total_size;
77*d95af8dfSAndroid Build Coastguard Worker 
78*d95af8dfSAndroid Build Coastguard Worker 	bo->meta.format_modifier = modifier;
79*d95af8dfSAndroid Build Coastguard Worker 
80*d95af8dfSAndroid Build Coastguard Worker 	return 0;
81*d95af8dfSAndroid Build Coastguard Worker }
82*d95af8dfSAndroid Build Coastguard Worker 
rockchip_init(struct driver * drv)83*d95af8dfSAndroid Build Coastguard Worker static int rockchip_init(struct driver *drv)
84*d95af8dfSAndroid Build Coastguard Worker {
85*d95af8dfSAndroid Build Coastguard Worker 	struct format_metadata metadata;
86*d95af8dfSAndroid Build Coastguard Worker 
87*d95af8dfSAndroid Build Coastguard Worker 	metadata.tiling = 0;
88*d95af8dfSAndroid Build Coastguard Worker 	metadata.priority = 1;
89*d95af8dfSAndroid Build Coastguard Worker 	metadata.modifier = DRM_FORMAT_MOD_LINEAR;
90*d95af8dfSAndroid Build Coastguard Worker 
91*d95af8dfSAndroid Build Coastguard Worker 	drv_add_combinations(drv, scanout_render_formats, ARRAY_SIZE(scanout_render_formats),
92*d95af8dfSAndroid Build Coastguard Worker 			     &metadata, BO_USE_RENDER_MASK | BO_USE_SCANOUT);
93*d95af8dfSAndroid Build Coastguard Worker 
94*d95af8dfSAndroid Build Coastguard Worker 	drv_add_combinations(drv, texture_only_formats, ARRAY_SIZE(texture_only_formats), &metadata,
95*d95af8dfSAndroid Build Coastguard Worker 			     BO_USE_TEXTURE_MASK);
96*d95af8dfSAndroid Build Coastguard Worker 
97*d95af8dfSAndroid Build Coastguard Worker 	/* NV12 format for camera, display, decoding and encoding. */
98*d95af8dfSAndroid Build Coastguard Worker 	/* Camera ISP supports only NV12 output. */
99*d95af8dfSAndroid Build Coastguard Worker 	drv_modify_combination(drv, DRM_FORMAT_NV12, &metadata,
100*d95af8dfSAndroid Build Coastguard Worker 			       BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SCANOUT |
101*d95af8dfSAndroid Build Coastguard Worker 				   BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER);
102*d95af8dfSAndroid Build Coastguard Worker 
103*d95af8dfSAndroid Build Coastguard Worker 	drv_modify_linear_combinations(drv);
104*d95af8dfSAndroid Build Coastguard Worker 	/*
105*d95af8dfSAndroid Build Coastguard Worker 	 * R8 format is used for Android's HAL_PIXEL_FORMAT_BLOB and is used for JPEG snapshots
106*d95af8dfSAndroid Build Coastguard Worker 	 * from camera and input/output from hardware decoder/encoder.
107*d95af8dfSAndroid Build Coastguard Worker 	 */
108*d95af8dfSAndroid Build Coastguard Worker 	drv_add_combination(drv, DRM_FORMAT_R8, &metadata,
109*d95af8dfSAndroid Build Coastguard Worker 			    BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_SW_MASK |
110*d95af8dfSAndroid Build Coastguard Worker 				BO_USE_LINEAR | BO_USE_HW_VIDEO_DECODER | BO_USE_HW_VIDEO_ENCODER |
111*d95af8dfSAndroid Build Coastguard Worker 				BO_USE_GPU_DATA_BUFFER | BO_USE_SENSOR_DIRECT_DATA);
112*d95af8dfSAndroid Build Coastguard Worker 
113*d95af8dfSAndroid Build Coastguard Worker 	return 0;
114*d95af8dfSAndroid Build Coastguard Worker }
115*d95af8dfSAndroid Build Coastguard Worker 
rockchip_bo_create_with_modifiers(struct bo * bo,uint32_t width,uint32_t height,uint32_t format,const uint64_t * modifiers,uint32_t count)116*d95af8dfSAndroid Build Coastguard Worker static int rockchip_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height,
117*d95af8dfSAndroid Build Coastguard Worker 					     uint32_t format, const uint64_t *modifiers,
118*d95af8dfSAndroid Build Coastguard Worker 					     uint32_t count)
119*d95af8dfSAndroid Build Coastguard Worker {
120*d95af8dfSAndroid Build Coastguard Worker 	int ret;
121*d95af8dfSAndroid Build Coastguard Worker 	struct drm_rockchip_gem_create gem_create = { 0 };
122*d95af8dfSAndroid Build Coastguard Worker 	uint64_t afbc_modifier;
123*d95af8dfSAndroid Build Coastguard Worker 
124*d95af8dfSAndroid Build Coastguard Worker 	if (drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_ROCKCHIP_AFBC))
125*d95af8dfSAndroid Build Coastguard Worker 		afbc_modifier = DRM_FORMAT_MOD_ROCKCHIP_AFBC;
126*d95af8dfSAndroid Build Coastguard Worker 	else if (drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC))
127*d95af8dfSAndroid Build Coastguard Worker 		afbc_modifier = DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC;
128*d95af8dfSAndroid Build Coastguard Worker 	else
129*d95af8dfSAndroid Build Coastguard Worker 		afbc_modifier = 0;
130*d95af8dfSAndroid Build Coastguard Worker 
131*d95af8dfSAndroid Build Coastguard Worker 	if (format == DRM_FORMAT_NV12) {
132*d95af8dfSAndroid Build Coastguard Worker 		uint32_t w_mbs = DIV_ROUND_UP(width, 16);
133*d95af8dfSAndroid Build Coastguard Worker 		uint32_t h_mbs = DIV_ROUND_UP(height, 16);
134*d95af8dfSAndroid Build Coastguard Worker 
135*d95af8dfSAndroid Build Coastguard Worker 		uint32_t aligned_width = w_mbs * 16;
136*d95af8dfSAndroid Build Coastguard Worker 		uint32_t aligned_height = h_mbs * 16;
137*d95af8dfSAndroid Build Coastguard Worker 
138*d95af8dfSAndroid Build Coastguard Worker 		drv_bo_from_format(bo, aligned_width, 1, aligned_height, format);
139*d95af8dfSAndroid Build Coastguard Worker 		/*
140*d95af8dfSAndroid Build Coastguard Worker 		 * drv_bo_from_format updates total_size. Add an extra data space for rockchip video
141*d95af8dfSAndroid Build Coastguard Worker 		 * driver to store motion vectors.
142*d95af8dfSAndroid Build Coastguard Worker 		 */
143*d95af8dfSAndroid Build Coastguard Worker 		bo->meta.total_size += w_mbs * h_mbs * 128;
144*d95af8dfSAndroid Build Coastguard Worker 	} else if (width <= 2560 && afbc_modifier && bo->drv->compression) {
145*d95af8dfSAndroid Build Coastguard Worker 		/* If the caller has decided they can use AFBC, always
146*d95af8dfSAndroid Build Coastguard Worker 		 * pick that */
147*d95af8dfSAndroid Build Coastguard Worker 		afbc_bo_from_format(bo, width, height, format, afbc_modifier);
148*d95af8dfSAndroid Build Coastguard Worker 	} else {
149*d95af8dfSAndroid Build Coastguard Worker 		if (!drv_has_modifier(modifiers, count, DRM_FORMAT_MOD_LINEAR)) {
150*d95af8dfSAndroid Build Coastguard Worker 			errno = EINVAL;
151*d95af8dfSAndroid Build Coastguard Worker 			drv_loge("no usable modifier found\n");
152*d95af8dfSAndroid Build Coastguard Worker 			return -errno;
153*d95af8dfSAndroid Build Coastguard Worker 		}
154*d95af8dfSAndroid Build Coastguard Worker 
155*d95af8dfSAndroid Build Coastguard Worker 		uint32_t stride;
156*d95af8dfSAndroid Build Coastguard Worker 		/*
157*d95af8dfSAndroid Build Coastguard Worker 		 * Since the ARM L1 cache line size is 64 bytes, align to that
158*d95af8dfSAndroid Build Coastguard Worker 		 * as a performance optimization. For YV12, the Mali cmem allocator
159*d95af8dfSAndroid Build Coastguard Worker 		 * requires that chroma planes are aligned to 64-bytes, so align the
160*d95af8dfSAndroid Build Coastguard Worker 		 * luma plane to 128 bytes.
161*d95af8dfSAndroid Build Coastguard Worker 		 */
162*d95af8dfSAndroid Build Coastguard Worker 		stride = drv_stride_from_format(format, width, 0);
163*d95af8dfSAndroid Build Coastguard Worker 		if (format == DRM_FORMAT_YVU420 || format == DRM_FORMAT_YVU420_ANDROID)
164*d95af8dfSAndroid Build Coastguard Worker 			stride = ALIGN(stride, 128);
165*d95af8dfSAndroid Build Coastguard Worker 		else
166*d95af8dfSAndroid Build Coastguard Worker 			stride = ALIGN(stride, 64);
167*d95af8dfSAndroid Build Coastguard Worker 
168*d95af8dfSAndroid Build Coastguard Worker 		drv_bo_from_format(bo, stride, 1, height, format);
169*d95af8dfSAndroid Build Coastguard Worker 	}
170*d95af8dfSAndroid Build Coastguard Worker 
171*d95af8dfSAndroid Build Coastguard Worker 	gem_create.size = bo->meta.total_size;
172*d95af8dfSAndroid Build Coastguard Worker 	ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &gem_create);
173*d95af8dfSAndroid Build Coastguard Worker 
174*d95af8dfSAndroid Build Coastguard Worker 	if (ret) {
175*d95af8dfSAndroid Build Coastguard Worker 		drv_loge("DRM_IOCTL_ROCKCHIP_GEM_CREATE failed (size=%" PRIu64 ")\n",
176*d95af8dfSAndroid Build Coastguard Worker 			 gem_create.size);
177*d95af8dfSAndroid Build Coastguard Worker 		return -errno;
178*d95af8dfSAndroid Build Coastguard Worker 	}
179*d95af8dfSAndroid Build Coastguard Worker 
180*d95af8dfSAndroid Build Coastguard Worker 	bo->handle.u32 = gem_create.handle;
181*d95af8dfSAndroid Build Coastguard Worker 
182*d95af8dfSAndroid Build Coastguard Worker 	return 0;
183*d95af8dfSAndroid Build Coastguard Worker }
184*d95af8dfSAndroid Build Coastguard Worker 
rockchip_bo_create(struct bo * bo,uint32_t width,uint32_t height,uint32_t format,uint64_t use_flags)185*d95af8dfSAndroid Build Coastguard Worker static int rockchip_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format,
186*d95af8dfSAndroid Build Coastguard Worker 			      uint64_t use_flags)
187*d95af8dfSAndroid Build Coastguard Worker {
188*d95af8dfSAndroid Build Coastguard Worker 	uint64_t modifiers[] = { DRM_FORMAT_MOD_LINEAR };
189*d95af8dfSAndroid Build Coastguard Worker 	return rockchip_bo_create_with_modifiers(bo, width, height, format, modifiers,
190*d95af8dfSAndroid Build Coastguard Worker 						 ARRAY_SIZE(modifiers));
191*d95af8dfSAndroid Build Coastguard Worker }
192*d95af8dfSAndroid Build Coastguard Worker 
rockchip_bo_map(struct bo * bo,struct vma * vma,uint32_t map_flags)193*d95af8dfSAndroid Build Coastguard Worker static void *rockchip_bo_map(struct bo *bo, struct vma *vma, uint32_t map_flags)
194*d95af8dfSAndroid Build Coastguard Worker {
195*d95af8dfSAndroid Build Coastguard Worker 	int ret;
196*d95af8dfSAndroid Build Coastguard Worker 	struct rockchip_private_map_data *priv;
197*d95af8dfSAndroid Build Coastguard Worker 	struct drm_rockchip_gem_map_off gem_map = { 0 };
198*d95af8dfSAndroid Build Coastguard Worker 	void *addr = NULL;
199*d95af8dfSAndroid Build Coastguard Worker 
200*d95af8dfSAndroid Build Coastguard Worker 	/* We can only map buffers created with SW access flags, which should
201*d95af8dfSAndroid Build Coastguard Worker 	 * have no modifiers (ie, not AFBC). */
202*d95af8dfSAndroid Build Coastguard Worker 	if (bo->meta.format_modifier == DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC ||
203*d95af8dfSAndroid Build Coastguard Worker 	    bo->meta.format_modifier == DRM_FORMAT_MOD_ROCKCHIP_AFBC)
204*d95af8dfSAndroid Build Coastguard Worker 		return MAP_FAILED;
205*d95af8dfSAndroid Build Coastguard Worker 
206*d95af8dfSAndroid Build Coastguard Worker 	gem_map.handle = bo->handle.u32;
207*d95af8dfSAndroid Build Coastguard Worker 	ret = drmIoctl(bo->drv->fd, DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET, &gem_map);
208*d95af8dfSAndroid Build Coastguard Worker 	if (ret) {
209*d95af8dfSAndroid Build Coastguard Worker 		drv_loge("DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET failed\n");
210*d95af8dfSAndroid Build Coastguard Worker 		return MAP_FAILED;
211*d95af8dfSAndroid Build Coastguard Worker 	}
212*d95af8dfSAndroid Build Coastguard Worker 
213*d95af8dfSAndroid Build Coastguard Worker 	addr = mmap(0, bo->meta.total_size, drv_get_prot(map_flags), MAP_SHARED, bo->drv->fd,
214*d95af8dfSAndroid Build Coastguard Worker 		    gem_map.offset);
215*d95af8dfSAndroid Build Coastguard Worker 	if (addr == MAP_FAILED)
216*d95af8dfSAndroid Build Coastguard Worker 		return MAP_FAILED;
217*d95af8dfSAndroid Build Coastguard Worker 
218*d95af8dfSAndroid Build Coastguard Worker 	vma->length = bo->meta.total_size;
219*d95af8dfSAndroid Build Coastguard Worker 
220*d95af8dfSAndroid Build Coastguard Worker 	if (bo->meta.use_flags & BO_USE_RENDERSCRIPT) {
221*d95af8dfSAndroid Build Coastguard Worker 		priv = calloc(1, sizeof(*priv));
222*d95af8dfSAndroid Build Coastguard Worker 		if (!priv)
223*d95af8dfSAndroid Build Coastguard Worker 			goto out_unmap_addr;
224*d95af8dfSAndroid Build Coastguard Worker 
225*d95af8dfSAndroid Build Coastguard Worker 		priv->cached_addr = calloc(1, bo->meta.total_size);
226*d95af8dfSAndroid Build Coastguard Worker 		if (!priv->cached_addr)
227*d95af8dfSAndroid Build Coastguard Worker 			goto out_free_priv;
228*d95af8dfSAndroid Build Coastguard Worker 
229*d95af8dfSAndroid Build Coastguard Worker 		priv->gem_addr = addr;
230*d95af8dfSAndroid Build Coastguard Worker 		vma->priv = priv;
231*d95af8dfSAndroid Build Coastguard Worker 		addr = priv->cached_addr;
232*d95af8dfSAndroid Build Coastguard Worker 	}
233*d95af8dfSAndroid Build Coastguard Worker 
234*d95af8dfSAndroid Build Coastguard Worker 	return addr;
235*d95af8dfSAndroid Build Coastguard Worker 
236*d95af8dfSAndroid Build Coastguard Worker out_free_priv:
237*d95af8dfSAndroid Build Coastguard Worker 	free(priv);
238*d95af8dfSAndroid Build Coastguard Worker out_unmap_addr:
239*d95af8dfSAndroid Build Coastguard Worker 	munmap(addr, bo->meta.total_size);
240*d95af8dfSAndroid Build Coastguard Worker 	return MAP_FAILED;
241*d95af8dfSAndroid Build Coastguard Worker }
242*d95af8dfSAndroid Build Coastguard Worker 
rockchip_bo_unmap(struct bo * bo,struct vma * vma)243*d95af8dfSAndroid Build Coastguard Worker static int rockchip_bo_unmap(struct bo *bo, struct vma *vma)
244*d95af8dfSAndroid Build Coastguard Worker {
245*d95af8dfSAndroid Build Coastguard Worker 	if (vma->priv) {
246*d95af8dfSAndroid Build Coastguard Worker 		struct rockchip_private_map_data *priv = vma->priv;
247*d95af8dfSAndroid Build Coastguard Worker 		vma->addr = priv->gem_addr;
248*d95af8dfSAndroid Build Coastguard Worker 		free(priv->cached_addr);
249*d95af8dfSAndroid Build Coastguard Worker 		free(priv);
250*d95af8dfSAndroid Build Coastguard Worker 		vma->priv = NULL;
251*d95af8dfSAndroid Build Coastguard Worker 	}
252*d95af8dfSAndroid Build Coastguard Worker 
253*d95af8dfSAndroid Build Coastguard Worker 	return munmap(vma->addr, vma->length);
254*d95af8dfSAndroid Build Coastguard Worker }
255*d95af8dfSAndroid Build Coastguard Worker 
rockchip_bo_invalidate(struct bo * bo,struct mapping * mapping)256*d95af8dfSAndroid Build Coastguard Worker static int rockchip_bo_invalidate(struct bo *bo, struct mapping *mapping)
257*d95af8dfSAndroid Build Coastguard Worker {
258*d95af8dfSAndroid Build Coastguard Worker 	if (mapping->vma->priv) {
259*d95af8dfSAndroid Build Coastguard Worker 		struct rockchip_private_map_data *priv = mapping->vma->priv;
260*d95af8dfSAndroid Build Coastguard Worker 		memcpy(priv->cached_addr, priv->gem_addr, bo->meta.total_size);
261*d95af8dfSAndroid Build Coastguard Worker 	}
262*d95af8dfSAndroid Build Coastguard Worker 
263*d95af8dfSAndroid Build Coastguard Worker 	return 0;
264*d95af8dfSAndroid Build Coastguard Worker }
265*d95af8dfSAndroid Build Coastguard Worker 
rockchip_bo_flush(struct bo * bo,struct mapping * mapping)266*d95af8dfSAndroid Build Coastguard Worker static int rockchip_bo_flush(struct bo *bo, struct mapping *mapping)
267*d95af8dfSAndroid Build Coastguard Worker {
268*d95af8dfSAndroid Build Coastguard Worker 	struct rockchip_private_map_data *priv = mapping->vma->priv;
269*d95af8dfSAndroid Build Coastguard Worker 	if (priv && (mapping->vma->map_flags & BO_MAP_WRITE))
270*d95af8dfSAndroid Build Coastguard Worker 		memcpy(priv->gem_addr, priv->cached_addr, bo->meta.total_size);
271*d95af8dfSAndroid Build Coastguard Worker 
272*d95af8dfSAndroid Build Coastguard Worker 	return 0;
273*d95af8dfSAndroid Build Coastguard Worker }
274*d95af8dfSAndroid Build Coastguard Worker 
275*d95af8dfSAndroid Build Coastguard Worker const struct backend backend_rockchip = {
276*d95af8dfSAndroid Build Coastguard Worker 	.name = "rockchip",
277*d95af8dfSAndroid Build Coastguard Worker 	.init = rockchip_init,
278*d95af8dfSAndroid Build Coastguard Worker 	.bo_create = rockchip_bo_create,
279*d95af8dfSAndroid Build Coastguard Worker 	.bo_create_with_modifiers = rockchip_bo_create_with_modifiers,
280*d95af8dfSAndroid Build Coastguard Worker 	.bo_destroy = drv_gem_bo_destroy,
281*d95af8dfSAndroid Build Coastguard Worker 	.bo_import = drv_prime_bo_import,
282*d95af8dfSAndroid Build Coastguard Worker 	.bo_map = rockchip_bo_map,
283*d95af8dfSAndroid Build Coastguard Worker 	.bo_unmap = rockchip_bo_unmap,
284*d95af8dfSAndroid Build Coastguard Worker 	.bo_invalidate = rockchip_bo_invalidate,
285*d95af8dfSAndroid Build Coastguard Worker 	.bo_flush = rockchip_bo_flush,
286*d95af8dfSAndroid Build Coastguard Worker 	.resolve_format_and_use_flags = drv_resolve_format_and_use_flags_helper,
287*d95af8dfSAndroid Build Coastguard Worker };
288*d95af8dfSAndroid Build Coastguard Worker 
289*d95af8dfSAndroid Build Coastguard Worker #endif
290