1*7688df22SAndroid Build Coastguard Worker /*
2*7688df22SAndroid Build Coastguard Worker * Copyright (C) 2013 Samsung Electronics Co.Ltd
3*7688df22SAndroid Build Coastguard Worker * Authors:
4*7688df22SAndroid Build Coastguard Worker * Inki Dae <[email protected]>
5*7688df22SAndroid Build Coastguard Worker *
6*7688df22SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
7*7688df22SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
8*7688df22SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
9*7688df22SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*7688df22SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
11*7688df22SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
12*7688df22SAndroid Build Coastguard Worker *
13*7688df22SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
14*7688df22SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
15*7688df22SAndroid Build Coastguard Worker * Software.
16*7688df22SAndroid Build Coastguard Worker *
17*7688df22SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*7688df22SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*7688df22SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*7688df22SAndroid Build Coastguard Worker * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21*7688df22SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22*7688df22SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23*7688df22SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
24*7688df22SAndroid Build Coastguard Worker */
25*7688df22SAndroid Build Coastguard Worker
26*7688df22SAndroid Build Coastguard Worker #include <stdlib.h>
27*7688df22SAndroid Build Coastguard Worker #include <stdio.h>
28*7688df22SAndroid Build Coastguard Worker #include <string.h>
29*7688df22SAndroid Build Coastguard Worker #include <errno.h>
30*7688df22SAndroid Build Coastguard Worker #include <time.h>
31*7688df22SAndroid Build Coastguard Worker #include <unistd.h>
32*7688df22SAndroid Build Coastguard Worker
33*7688df22SAndroid Build Coastguard Worker #include <sys/mman.h>
34*7688df22SAndroid Build Coastguard Worker
35*7688df22SAndroid Build Coastguard Worker #include <xf86drm.h>
36*7688df22SAndroid Build Coastguard Worker #include <xf86drmMode.h>
37*7688df22SAndroid Build Coastguard Worker #include <libkms.h>
38*7688df22SAndroid Build Coastguard Worker #include <drm_fourcc.h>
39*7688df22SAndroid Build Coastguard Worker
40*7688df22SAndroid Build Coastguard Worker #include "exynos_drm.h"
41*7688df22SAndroid Build Coastguard Worker #include "exynos_drmif.h"
42*7688df22SAndroid Build Coastguard Worker #include "exynos_fimg2d.h"
43*7688df22SAndroid Build Coastguard Worker
44*7688df22SAndroid Build Coastguard Worker #define DRM_MODULE_NAME "exynos"
45*7688df22SAndroid Build Coastguard Worker
46*7688df22SAndroid Build Coastguard Worker static unsigned int screen_width, screen_height;
47*7688df22SAndroid Build Coastguard Worker
48*7688df22SAndroid Build Coastguard Worker struct connector {
49*7688df22SAndroid Build Coastguard Worker uint32_t id;
50*7688df22SAndroid Build Coastguard Worker char mode_str[64];
51*7688df22SAndroid Build Coastguard Worker drmModeModeInfo *mode;
52*7688df22SAndroid Build Coastguard Worker drmModeEncoder *encoder;
53*7688df22SAndroid Build Coastguard Worker int crtc;
54*7688df22SAndroid Build Coastguard Worker };
55*7688df22SAndroid Build Coastguard Worker
connector_find_mode(int fd,struct connector * c,drmModeRes * resources)56*7688df22SAndroid Build Coastguard Worker static void connector_find_mode(int fd, struct connector *c,
57*7688df22SAndroid Build Coastguard Worker drmModeRes *resources)
58*7688df22SAndroid Build Coastguard Worker {
59*7688df22SAndroid Build Coastguard Worker drmModeConnector *connector;
60*7688df22SAndroid Build Coastguard Worker int i, j;
61*7688df22SAndroid Build Coastguard Worker
62*7688df22SAndroid Build Coastguard Worker /* First, find the connector & mode */
63*7688df22SAndroid Build Coastguard Worker c->mode = NULL;
64*7688df22SAndroid Build Coastguard Worker for (i = 0; i < resources->count_connectors; i++) {
65*7688df22SAndroid Build Coastguard Worker connector = drmModeGetConnector(fd, resources->connectors[i]);
66*7688df22SAndroid Build Coastguard Worker
67*7688df22SAndroid Build Coastguard Worker if (!connector) {
68*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "could not get connector %i: %s\n",
69*7688df22SAndroid Build Coastguard Worker resources->connectors[i], strerror(errno));
70*7688df22SAndroid Build Coastguard Worker continue;
71*7688df22SAndroid Build Coastguard Worker }
72*7688df22SAndroid Build Coastguard Worker
73*7688df22SAndroid Build Coastguard Worker if (!connector->count_modes) {
74*7688df22SAndroid Build Coastguard Worker drmModeFreeConnector(connector);
75*7688df22SAndroid Build Coastguard Worker continue;
76*7688df22SAndroid Build Coastguard Worker }
77*7688df22SAndroid Build Coastguard Worker
78*7688df22SAndroid Build Coastguard Worker if (connector->connector_id != c->id) {
79*7688df22SAndroid Build Coastguard Worker drmModeFreeConnector(connector);
80*7688df22SAndroid Build Coastguard Worker continue;
81*7688df22SAndroid Build Coastguard Worker }
82*7688df22SAndroid Build Coastguard Worker
83*7688df22SAndroid Build Coastguard Worker for (j = 0; j < connector->count_modes; j++) {
84*7688df22SAndroid Build Coastguard Worker c->mode = &connector->modes[j];
85*7688df22SAndroid Build Coastguard Worker if (!strcmp(c->mode->name, c->mode_str))
86*7688df22SAndroid Build Coastguard Worker break;
87*7688df22SAndroid Build Coastguard Worker }
88*7688df22SAndroid Build Coastguard Worker
89*7688df22SAndroid Build Coastguard Worker /* Found it, break out */
90*7688df22SAndroid Build Coastguard Worker if (c->mode)
91*7688df22SAndroid Build Coastguard Worker break;
92*7688df22SAndroid Build Coastguard Worker
93*7688df22SAndroid Build Coastguard Worker drmModeFreeConnector(connector);
94*7688df22SAndroid Build Coastguard Worker }
95*7688df22SAndroid Build Coastguard Worker
96*7688df22SAndroid Build Coastguard Worker if (!c->mode) {
97*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str);
98*7688df22SAndroid Build Coastguard Worker return;
99*7688df22SAndroid Build Coastguard Worker }
100*7688df22SAndroid Build Coastguard Worker
101*7688df22SAndroid Build Coastguard Worker /* Now get the encoder */
102*7688df22SAndroid Build Coastguard Worker for (i = 0; i < resources->count_encoders; i++) {
103*7688df22SAndroid Build Coastguard Worker c->encoder = drmModeGetEncoder(fd, resources->encoders[i]);
104*7688df22SAndroid Build Coastguard Worker
105*7688df22SAndroid Build Coastguard Worker if (!c->encoder) {
106*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "could not get encoder %i: %s\n",
107*7688df22SAndroid Build Coastguard Worker resources->encoders[i], strerror(errno));
108*7688df22SAndroid Build Coastguard Worker continue;
109*7688df22SAndroid Build Coastguard Worker }
110*7688df22SAndroid Build Coastguard Worker
111*7688df22SAndroid Build Coastguard Worker if (c->encoder->encoder_id == connector->encoder_id)
112*7688df22SAndroid Build Coastguard Worker break;
113*7688df22SAndroid Build Coastguard Worker
114*7688df22SAndroid Build Coastguard Worker drmModeFreeEncoder(c->encoder);
115*7688df22SAndroid Build Coastguard Worker }
116*7688df22SAndroid Build Coastguard Worker
117*7688df22SAndroid Build Coastguard Worker if (c->crtc == -1)
118*7688df22SAndroid Build Coastguard Worker c->crtc = c->encoder->crtc_id;
119*7688df22SAndroid Build Coastguard Worker }
120*7688df22SAndroid Build Coastguard Worker
drm_set_crtc(struct exynos_device * dev,struct connector * c,unsigned int fb_id)121*7688df22SAndroid Build Coastguard Worker static int drm_set_crtc(struct exynos_device *dev, struct connector *c,
122*7688df22SAndroid Build Coastguard Worker unsigned int fb_id)
123*7688df22SAndroid Build Coastguard Worker {
124*7688df22SAndroid Build Coastguard Worker int ret;
125*7688df22SAndroid Build Coastguard Worker
126*7688df22SAndroid Build Coastguard Worker ret = drmModeSetCrtc(dev->fd, c->crtc,
127*7688df22SAndroid Build Coastguard Worker fb_id, 0, 0, &c->id, 1, c->mode);
128*7688df22SAndroid Build Coastguard Worker if (ret)
129*7688df22SAndroid Build Coastguard Worker drmMsg("failed to set mode: %s\n", strerror(errno));
130*7688df22SAndroid Build Coastguard Worker
131*7688df22SAndroid Build Coastguard Worker return ret;
132*7688df22SAndroid Build Coastguard Worker }
133*7688df22SAndroid Build Coastguard Worker
exynos_create_buffer(struct exynos_device * dev,unsigned long size,unsigned int flags)134*7688df22SAndroid Build Coastguard Worker static struct exynos_bo *exynos_create_buffer(struct exynos_device *dev,
135*7688df22SAndroid Build Coastguard Worker unsigned long size,
136*7688df22SAndroid Build Coastguard Worker unsigned int flags)
137*7688df22SAndroid Build Coastguard Worker {
138*7688df22SAndroid Build Coastguard Worker struct exynos_bo *bo;
139*7688df22SAndroid Build Coastguard Worker
140*7688df22SAndroid Build Coastguard Worker bo = exynos_bo_create(dev, size, flags);
141*7688df22SAndroid Build Coastguard Worker if (!bo)
142*7688df22SAndroid Build Coastguard Worker return bo;
143*7688df22SAndroid Build Coastguard Worker
144*7688df22SAndroid Build Coastguard Worker if (!exynos_bo_map(bo)) {
145*7688df22SAndroid Build Coastguard Worker exynos_bo_destroy(bo);
146*7688df22SAndroid Build Coastguard Worker return NULL;
147*7688df22SAndroid Build Coastguard Worker }
148*7688df22SAndroid Build Coastguard Worker
149*7688df22SAndroid Build Coastguard Worker return bo;
150*7688df22SAndroid Build Coastguard Worker }
151*7688df22SAndroid Build Coastguard Worker
152*7688df22SAndroid Build Coastguard Worker /* Allocate buffer and fill it with checkerboard pattern, where the tiles *
153*7688df22SAndroid Build Coastguard Worker * have a random color. The caller has to free the buffer. */
create_checkerboard_pattern(unsigned int num_tiles_x,unsigned int num_tiles_y,unsigned int tile_size)154*7688df22SAndroid Build Coastguard Worker static void *create_checkerboard_pattern(unsigned int num_tiles_x,
155*7688df22SAndroid Build Coastguard Worker unsigned int num_tiles_y, unsigned int tile_size)
156*7688df22SAndroid Build Coastguard Worker {
157*7688df22SAndroid Build Coastguard Worker unsigned int *buf;
158*7688df22SAndroid Build Coastguard Worker unsigned int x, y, i, j;
159*7688df22SAndroid Build Coastguard Worker const unsigned int stride = num_tiles_x * tile_size;
160*7688df22SAndroid Build Coastguard Worker
161*7688df22SAndroid Build Coastguard Worker if (posix_memalign((void*)&buf, 64, num_tiles_y * tile_size * stride * 4) != 0)
162*7688df22SAndroid Build Coastguard Worker return NULL;
163*7688df22SAndroid Build Coastguard Worker
164*7688df22SAndroid Build Coastguard Worker for (x = 0; x < num_tiles_x; ++x) {
165*7688df22SAndroid Build Coastguard Worker for (y = 0; y < num_tiles_y; ++y) {
166*7688df22SAndroid Build Coastguard Worker const unsigned int color = 0xff000000 + (random() & 0xffffff);
167*7688df22SAndroid Build Coastguard Worker
168*7688df22SAndroid Build Coastguard Worker for (i = 0; i < tile_size; ++i) {
169*7688df22SAndroid Build Coastguard Worker for (j = 0; j < tile_size; ++j) {
170*7688df22SAndroid Build Coastguard Worker buf[x * tile_size + y * stride * tile_size + i + j * stride] = color;
171*7688df22SAndroid Build Coastguard Worker }
172*7688df22SAndroid Build Coastguard Worker }
173*7688df22SAndroid Build Coastguard Worker }
174*7688df22SAndroid Build Coastguard Worker }
175*7688df22SAndroid Build Coastguard Worker
176*7688df22SAndroid Build Coastguard Worker return buf;
177*7688df22SAndroid Build Coastguard Worker }
178*7688df22SAndroid Build Coastguard Worker
exynos_destroy_buffer(struct exynos_bo * bo)179*7688df22SAndroid Build Coastguard Worker static void exynos_destroy_buffer(struct exynos_bo *bo)
180*7688df22SAndroid Build Coastguard Worker {
181*7688df22SAndroid Build Coastguard Worker exynos_bo_destroy(bo);
182*7688df22SAndroid Build Coastguard Worker }
183*7688df22SAndroid Build Coastguard Worker
wait_for_user_input(int last)184*7688df22SAndroid Build Coastguard Worker static void wait_for_user_input(int last)
185*7688df22SAndroid Build Coastguard Worker {
186*7688df22SAndroid Build Coastguard Worker printf("press <ENTER> to %s\n", last ? "exit test application" :
187*7688df22SAndroid Build Coastguard Worker "skip to next test");
188*7688df22SAndroid Build Coastguard Worker
189*7688df22SAndroid Build Coastguard Worker getchar();
190*7688df22SAndroid Build Coastguard Worker }
191*7688df22SAndroid Build Coastguard Worker
g2d_solid_fill_test(struct exynos_device * dev,struct exynos_bo * dst)192*7688df22SAndroid Build Coastguard Worker static int g2d_solid_fill_test(struct exynos_device *dev, struct exynos_bo *dst)
193*7688df22SAndroid Build Coastguard Worker {
194*7688df22SAndroid Build Coastguard Worker struct g2d_context *ctx;
195*7688df22SAndroid Build Coastguard Worker struct g2d_image img = {0};
196*7688df22SAndroid Build Coastguard Worker unsigned int count, img_w, img_h;
197*7688df22SAndroid Build Coastguard Worker int ret = 0;
198*7688df22SAndroid Build Coastguard Worker
199*7688df22SAndroid Build Coastguard Worker ctx = g2d_init(dev->fd);
200*7688df22SAndroid Build Coastguard Worker if (!ctx)
201*7688df22SAndroid Build Coastguard Worker return -EFAULT;
202*7688df22SAndroid Build Coastguard Worker
203*7688df22SAndroid Build Coastguard Worker img.bo[0] = dst->handle;
204*7688df22SAndroid Build Coastguard Worker
205*7688df22SAndroid Build Coastguard Worker printf("solid fill test.\n");
206*7688df22SAndroid Build Coastguard Worker
207*7688df22SAndroid Build Coastguard Worker srand(time(NULL));
208*7688df22SAndroid Build Coastguard Worker img_w = screen_width;
209*7688df22SAndroid Build Coastguard Worker img_h = screen_height;
210*7688df22SAndroid Build Coastguard Worker
211*7688df22SAndroid Build Coastguard Worker for (count = 0; count < 2; count++) {
212*7688df22SAndroid Build Coastguard Worker unsigned int x, y, w, h;
213*7688df22SAndroid Build Coastguard Worker
214*7688df22SAndroid Build Coastguard Worker x = rand() % (img_w / 2);
215*7688df22SAndroid Build Coastguard Worker y = rand() % (img_h / 2);
216*7688df22SAndroid Build Coastguard Worker w = rand() % (img_w - x);
217*7688df22SAndroid Build Coastguard Worker h = rand() % (img_h - y);
218*7688df22SAndroid Build Coastguard Worker
219*7688df22SAndroid Build Coastguard Worker img.width = img_w;
220*7688df22SAndroid Build Coastguard Worker img.height = img_h;
221*7688df22SAndroid Build Coastguard Worker img.stride = img.width * 4;
222*7688df22SAndroid Build Coastguard Worker img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
223*7688df22SAndroid Build Coastguard Worker img.color = 0xff000000 + (random() & 0xffffff);
224*7688df22SAndroid Build Coastguard Worker
225*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill(ctx, &img, x, y, w, h);
226*7688df22SAndroid Build Coastguard Worker if (ret < 0)
227*7688df22SAndroid Build Coastguard Worker goto err_fini;
228*7688df22SAndroid Build Coastguard Worker
229*7688df22SAndroid Build Coastguard Worker ret = g2d_exec(ctx);
230*7688df22SAndroid Build Coastguard Worker if (ret < 0)
231*7688df22SAndroid Build Coastguard Worker break;
232*7688df22SAndroid Build Coastguard Worker }
233*7688df22SAndroid Build Coastguard Worker
234*7688df22SAndroid Build Coastguard Worker err_fini:
235*7688df22SAndroid Build Coastguard Worker g2d_fini(ctx);
236*7688df22SAndroid Build Coastguard Worker
237*7688df22SAndroid Build Coastguard Worker return ret;
238*7688df22SAndroid Build Coastguard Worker }
239*7688df22SAndroid Build Coastguard Worker
g2d_copy_test(struct exynos_device * dev,struct exynos_bo * src,struct exynos_bo * dst,enum e_g2d_buf_type type)240*7688df22SAndroid Build Coastguard Worker static int g2d_copy_test(struct exynos_device *dev, struct exynos_bo *src,
241*7688df22SAndroid Build Coastguard Worker struct exynos_bo *dst,
242*7688df22SAndroid Build Coastguard Worker enum e_g2d_buf_type type)
243*7688df22SAndroid Build Coastguard Worker {
244*7688df22SAndroid Build Coastguard Worker struct g2d_context *ctx;
245*7688df22SAndroid Build Coastguard Worker struct g2d_image src_img = {0}, dst_img = {0};
246*7688df22SAndroid Build Coastguard Worker unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
247*7688df22SAndroid Build Coastguard Worker unsigned long userptr, size;
248*7688df22SAndroid Build Coastguard Worker int ret;
249*7688df22SAndroid Build Coastguard Worker
250*7688df22SAndroid Build Coastguard Worker ctx = g2d_init(dev->fd);
251*7688df22SAndroid Build Coastguard Worker if (!ctx)
252*7688df22SAndroid Build Coastguard Worker return -EFAULT;
253*7688df22SAndroid Build Coastguard Worker
254*7688df22SAndroid Build Coastguard Worker dst_img.bo[0] = dst->handle;
255*7688df22SAndroid Build Coastguard Worker
256*7688df22SAndroid Build Coastguard Worker src_x = 0;
257*7688df22SAndroid Build Coastguard Worker src_y = 0;
258*7688df22SAndroid Build Coastguard Worker dst_x = 0;
259*7688df22SAndroid Build Coastguard Worker dst_y = 0;
260*7688df22SAndroid Build Coastguard Worker img_w = screen_width;
261*7688df22SAndroid Build Coastguard Worker img_h = screen_height;
262*7688df22SAndroid Build Coastguard Worker
263*7688df22SAndroid Build Coastguard Worker switch (type) {
264*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_GEM:
265*7688df22SAndroid Build Coastguard Worker src_img.bo[0] = src->handle;
266*7688df22SAndroid Build Coastguard Worker break;
267*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_USERPTR:
268*7688df22SAndroid Build Coastguard Worker size = img_w * img_h * 4;
269*7688df22SAndroid Build Coastguard Worker
270*7688df22SAndroid Build Coastguard Worker userptr = (unsigned long)malloc(size);
271*7688df22SAndroid Build Coastguard Worker if (!userptr) {
272*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to allocate userptr.\n");
273*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
274*7688df22SAndroid Build Coastguard Worker goto fail;
275*7688df22SAndroid Build Coastguard Worker }
276*7688df22SAndroid Build Coastguard Worker
277*7688df22SAndroid Build Coastguard Worker src_img.user_ptr[0].userptr = userptr;
278*7688df22SAndroid Build Coastguard Worker src_img.user_ptr[0].size = size;
279*7688df22SAndroid Build Coastguard Worker break;
280*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_COLOR:
281*7688df22SAndroid Build Coastguard Worker default:
282*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
283*7688df22SAndroid Build Coastguard Worker goto fail;
284*7688df22SAndroid Build Coastguard Worker }
285*7688df22SAndroid Build Coastguard Worker
286*7688df22SAndroid Build Coastguard Worker printf("copy test with %s.\n",
287*7688df22SAndroid Build Coastguard Worker type == G2D_IMGBUF_GEM ? "gem" : "userptr");
288*7688df22SAndroid Build Coastguard Worker
289*7688df22SAndroid Build Coastguard Worker src_img.width = img_w;
290*7688df22SAndroid Build Coastguard Worker src_img.height = img_h;
291*7688df22SAndroid Build Coastguard Worker src_img.stride = src_img.width * 4;
292*7688df22SAndroid Build Coastguard Worker src_img.buf_type = type;
293*7688df22SAndroid Build Coastguard Worker src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
294*7688df22SAndroid Build Coastguard Worker src_img.color = 0xffff0000;
295*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill(ctx, &src_img, src_x, src_y, img_w, img_h);
296*7688df22SAndroid Build Coastguard Worker if (ret < 0)
297*7688df22SAndroid Build Coastguard Worker goto err_free_userptr;
298*7688df22SAndroid Build Coastguard Worker
299*7688df22SAndroid Build Coastguard Worker dst_img.width = img_w;
300*7688df22SAndroid Build Coastguard Worker dst_img.height = img_h;
301*7688df22SAndroid Build Coastguard Worker dst_img.stride = dst_img.width * 4;
302*7688df22SAndroid Build Coastguard Worker dst_img.buf_type = G2D_IMGBUF_GEM;
303*7688df22SAndroid Build Coastguard Worker dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
304*7688df22SAndroid Build Coastguard Worker
305*7688df22SAndroid Build Coastguard Worker ret = g2d_copy(ctx, &src_img, &dst_img, src_x, src_y, dst_x, dst_y,
306*7688df22SAndroid Build Coastguard Worker img_w - 4, img_h - 4);
307*7688df22SAndroid Build Coastguard Worker if (ret < 0)
308*7688df22SAndroid Build Coastguard Worker goto err_free_userptr;
309*7688df22SAndroid Build Coastguard Worker
310*7688df22SAndroid Build Coastguard Worker g2d_exec(ctx);
311*7688df22SAndroid Build Coastguard Worker
312*7688df22SAndroid Build Coastguard Worker err_free_userptr:
313*7688df22SAndroid Build Coastguard Worker if (type == G2D_IMGBUF_USERPTR)
314*7688df22SAndroid Build Coastguard Worker if (userptr)
315*7688df22SAndroid Build Coastguard Worker free((void *)userptr);
316*7688df22SAndroid Build Coastguard Worker
317*7688df22SAndroid Build Coastguard Worker fail:
318*7688df22SAndroid Build Coastguard Worker g2d_fini(ctx);
319*7688df22SAndroid Build Coastguard Worker
320*7688df22SAndroid Build Coastguard Worker return ret;
321*7688df22SAndroid Build Coastguard Worker }
322*7688df22SAndroid Build Coastguard Worker
g2d_move_test(struct exynos_device * dev,struct exynos_bo * tmp,struct exynos_bo * buf,enum e_g2d_buf_type type)323*7688df22SAndroid Build Coastguard Worker static int g2d_move_test(struct exynos_device *dev,
324*7688df22SAndroid Build Coastguard Worker struct exynos_bo *tmp,
325*7688df22SAndroid Build Coastguard Worker struct exynos_bo *buf,
326*7688df22SAndroid Build Coastguard Worker enum e_g2d_buf_type type)
327*7688df22SAndroid Build Coastguard Worker {
328*7688df22SAndroid Build Coastguard Worker struct g2d_context *ctx;
329*7688df22SAndroid Build Coastguard Worker struct g2d_image img = {0}, tmp_img = {0};
330*7688df22SAndroid Build Coastguard Worker unsigned int img_w, img_h, count;
331*7688df22SAndroid Build Coastguard Worker int cur_x, cur_y;
332*7688df22SAndroid Build Coastguard Worker void *checkerboard;
333*7688df22SAndroid Build Coastguard Worker int ret;
334*7688df22SAndroid Build Coastguard Worker
335*7688df22SAndroid Build Coastguard Worker static const struct g2d_step {
336*7688df22SAndroid Build Coastguard Worker int x, y;
337*7688df22SAndroid Build Coastguard Worker } steps[] = {
338*7688df22SAndroid Build Coastguard Worker { 1, 0}, { 0, 1},
339*7688df22SAndroid Build Coastguard Worker {-1, 0}, { 0, -1},
340*7688df22SAndroid Build Coastguard Worker { 1, 1}, {-1, -1},
341*7688df22SAndroid Build Coastguard Worker { 1, -1}, {-1, 1},
342*7688df22SAndroid Build Coastguard Worker { 2, 1}, { 1, 2},
343*7688df22SAndroid Build Coastguard Worker {-2, -1}, {-1, -2},
344*7688df22SAndroid Build Coastguard Worker { 2, -1}, { 1, -2},
345*7688df22SAndroid Build Coastguard Worker {-2, 1}, {-1, 2}
346*7688df22SAndroid Build Coastguard Worker };
347*7688df22SAndroid Build Coastguard Worker static const unsigned int num_steps =
348*7688df22SAndroid Build Coastguard Worker sizeof(steps) / sizeof(struct g2d_step);
349*7688df22SAndroid Build Coastguard Worker
350*7688df22SAndroid Build Coastguard Worker ctx = g2d_init(dev->fd);
351*7688df22SAndroid Build Coastguard Worker if (!ctx)
352*7688df22SAndroid Build Coastguard Worker return -EFAULT;
353*7688df22SAndroid Build Coastguard Worker
354*7688df22SAndroid Build Coastguard Worker img.bo[0] = buf->handle;
355*7688df22SAndroid Build Coastguard Worker
356*7688df22SAndroid Build Coastguard Worker /* create pattern of half the screen size */
357*7688df22SAndroid Build Coastguard Worker checkerboard = create_checkerboard_pattern(screen_width / 64, screen_height / 64, 32);
358*7688df22SAndroid Build Coastguard Worker if (!checkerboard) {
359*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
360*7688df22SAndroid Build Coastguard Worker goto fail;
361*7688df22SAndroid Build Coastguard Worker }
362*7688df22SAndroid Build Coastguard Worker
363*7688df22SAndroid Build Coastguard Worker img_w = (screen_width / 64) * 32;
364*7688df22SAndroid Build Coastguard Worker img_h = (screen_height / 64) * 32;
365*7688df22SAndroid Build Coastguard Worker
366*7688df22SAndroid Build Coastguard Worker switch (type) {
367*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_GEM:
368*7688df22SAndroid Build Coastguard Worker memcpy(tmp->vaddr, checkerboard, img_w * img_h * 4);
369*7688df22SAndroid Build Coastguard Worker tmp_img.bo[0] = tmp->handle;
370*7688df22SAndroid Build Coastguard Worker break;
371*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_USERPTR:
372*7688df22SAndroid Build Coastguard Worker tmp_img.user_ptr[0].userptr = (unsigned long)checkerboard;
373*7688df22SAndroid Build Coastguard Worker tmp_img.user_ptr[0].size = img_w * img_h * 4;
374*7688df22SAndroid Build Coastguard Worker break;
375*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_COLOR:
376*7688df22SAndroid Build Coastguard Worker default:
377*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
378*7688df22SAndroid Build Coastguard Worker goto fail;
379*7688df22SAndroid Build Coastguard Worker }
380*7688df22SAndroid Build Coastguard Worker
381*7688df22SAndroid Build Coastguard Worker /* solid fill framebuffer with white color */
382*7688df22SAndroid Build Coastguard Worker img.width = screen_width;
383*7688df22SAndroid Build Coastguard Worker img.height = screen_height;
384*7688df22SAndroid Build Coastguard Worker img.stride = screen_width * 4;
385*7688df22SAndroid Build Coastguard Worker img.buf_type = G2D_IMGBUF_GEM;
386*7688df22SAndroid Build Coastguard Worker img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
387*7688df22SAndroid Build Coastguard Worker img.color = 0xffffffff;
388*7688df22SAndroid Build Coastguard Worker
389*7688df22SAndroid Build Coastguard Worker /* put checkerboard pattern in the center of the framebuffer */
390*7688df22SAndroid Build Coastguard Worker cur_x = (screen_width - img_w) / 2;
391*7688df22SAndroid Build Coastguard Worker cur_y = (screen_height - img_h) / 2;
392*7688df22SAndroid Build Coastguard Worker tmp_img.width = img_w;
393*7688df22SAndroid Build Coastguard Worker tmp_img.height = img_h;
394*7688df22SAndroid Build Coastguard Worker tmp_img.stride = img_w * 4;
395*7688df22SAndroid Build Coastguard Worker tmp_img.buf_type = type;
396*7688df22SAndroid Build Coastguard Worker tmp_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
397*7688df22SAndroid Build Coastguard Worker
398*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill(ctx, &img, 0, 0, screen_width, screen_height) ||
399*7688df22SAndroid Build Coastguard Worker g2d_copy(ctx, &tmp_img, &img, 0, 0, cur_x, cur_y, img_w, img_h);
400*7688df22SAndroid Build Coastguard Worker
401*7688df22SAndroid Build Coastguard Worker if (!ret)
402*7688df22SAndroid Build Coastguard Worker ret = g2d_exec(ctx);
403*7688df22SAndroid Build Coastguard Worker if (ret < 0)
404*7688df22SAndroid Build Coastguard Worker goto fail;
405*7688df22SAndroid Build Coastguard Worker
406*7688df22SAndroid Build Coastguard Worker printf("move test with %s.\n",
407*7688df22SAndroid Build Coastguard Worker type == G2D_IMGBUF_GEM ? "gem" : "userptr");
408*7688df22SAndroid Build Coastguard Worker
409*7688df22SAndroid Build Coastguard Worker srand(time(NULL));
410*7688df22SAndroid Build Coastguard Worker for (count = 0; count < 256; ++count) {
411*7688df22SAndroid Build Coastguard Worker const struct g2d_step *s;
412*7688df22SAndroid Build Coastguard Worker
413*7688df22SAndroid Build Coastguard Worker /* select step and validate it */
414*7688df22SAndroid Build Coastguard Worker while (1) {
415*7688df22SAndroid Build Coastguard Worker s = &steps[random() % num_steps];
416*7688df22SAndroid Build Coastguard Worker
417*7688df22SAndroid Build Coastguard Worker if (cur_x + s->x < 0 || cur_y + s->y < 0 ||
418*7688df22SAndroid Build Coastguard Worker cur_x + img_w + s->x >= screen_width ||
419*7688df22SAndroid Build Coastguard Worker cur_y + img_h + s->y >= screen_height)
420*7688df22SAndroid Build Coastguard Worker continue;
421*7688df22SAndroid Build Coastguard Worker else
422*7688df22SAndroid Build Coastguard Worker break;
423*7688df22SAndroid Build Coastguard Worker }
424*7688df22SAndroid Build Coastguard Worker
425*7688df22SAndroid Build Coastguard Worker ret = g2d_move(ctx, &img, cur_x, cur_y, cur_x + s->x, cur_y + s->y,
426*7688df22SAndroid Build Coastguard Worker img_w, img_h);
427*7688df22SAndroid Build Coastguard Worker if (!ret)
428*7688df22SAndroid Build Coastguard Worker ret = g2d_exec(ctx);
429*7688df22SAndroid Build Coastguard Worker
430*7688df22SAndroid Build Coastguard Worker if (ret < 0)
431*7688df22SAndroid Build Coastguard Worker goto fail;
432*7688df22SAndroid Build Coastguard Worker
433*7688df22SAndroid Build Coastguard Worker cur_x += s->x;
434*7688df22SAndroid Build Coastguard Worker cur_y += s->y;
435*7688df22SAndroid Build Coastguard Worker
436*7688df22SAndroid Build Coastguard Worker usleep(100000);
437*7688df22SAndroid Build Coastguard Worker }
438*7688df22SAndroid Build Coastguard Worker
439*7688df22SAndroid Build Coastguard Worker fail:
440*7688df22SAndroid Build Coastguard Worker g2d_fini(ctx);
441*7688df22SAndroid Build Coastguard Worker
442*7688df22SAndroid Build Coastguard Worker free(checkerboard);
443*7688df22SAndroid Build Coastguard Worker
444*7688df22SAndroid Build Coastguard Worker return ret;
445*7688df22SAndroid Build Coastguard Worker }
446*7688df22SAndroid Build Coastguard Worker
g2d_copy_with_scale_test(struct exynos_device * dev,struct exynos_bo * src,struct exynos_bo * dst,enum e_g2d_buf_type type)447*7688df22SAndroid Build Coastguard Worker static int g2d_copy_with_scale_test(struct exynos_device *dev,
448*7688df22SAndroid Build Coastguard Worker struct exynos_bo *src,
449*7688df22SAndroid Build Coastguard Worker struct exynos_bo *dst,
450*7688df22SAndroid Build Coastguard Worker enum e_g2d_buf_type type)
451*7688df22SAndroid Build Coastguard Worker {
452*7688df22SAndroid Build Coastguard Worker struct g2d_context *ctx;
453*7688df22SAndroid Build Coastguard Worker struct g2d_image src_img = {0}, dst_img = {0};
454*7688df22SAndroid Build Coastguard Worker unsigned int src_x, src_y, img_w, img_h;
455*7688df22SAndroid Build Coastguard Worker unsigned long userptr, size;
456*7688df22SAndroid Build Coastguard Worker int ret;
457*7688df22SAndroid Build Coastguard Worker
458*7688df22SAndroid Build Coastguard Worker ctx = g2d_init(dev->fd);
459*7688df22SAndroid Build Coastguard Worker if (!ctx)
460*7688df22SAndroid Build Coastguard Worker return -EFAULT;
461*7688df22SAndroid Build Coastguard Worker
462*7688df22SAndroid Build Coastguard Worker dst_img.bo[0] = dst->handle;
463*7688df22SAndroid Build Coastguard Worker
464*7688df22SAndroid Build Coastguard Worker src_x = 0;
465*7688df22SAndroid Build Coastguard Worker src_y = 0;
466*7688df22SAndroid Build Coastguard Worker img_w = screen_width;
467*7688df22SAndroid Build Coastguard Worker img_h = screen_height;
468*7688df22SAndroid Build Coastguard Worker
469*7688df22SAndroid Build Coastguard Worker switch (type) {
470*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_GEM:
471*7688df22SAndroid Build Coastguard Worker src_img.bo[0] = src->handle;
472*7688df22SAndroid Build Coastguard Worker break;
473*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_USERPTR:
474*7688df22SAndroid Build Coastguard Worker size = img_w * img_h * 4;
475*7688df22SAndroid Build Coastguard Worker
476*7688df22SAndroid Build Coastguard Worker userptr = (unsigned long)malloc(size);
477*7688df22SAndroid Build Coastguard Worker if (!userptr) {
478*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to allocate userptr.\n");
479*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
480*7688df22SAndroid Build Coastguard Worker goto fail;
481*7688df22SAndroid Build Coastguard Worker }
482*7688df22SAndroid Build Coastguard Worker
483*7688df22SAndroid Build Coastguard Worker src_img.user_ptr[0].userptr = userptr;
484*7688df22SAndroid Build Coastguard Worker src_img.user_ptr[0].size = size;
485*7688df22SAndroid Build Coastguard Worker break;
486*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_COLOR:
487*7688df22SAndroid Build Coastguard Worker default:
488*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
489*7688df22SAndroid Build Coastguard Worker goto fail;
490*7688df22SAndroid Build Coastguard Worker }
491*7688df22SAndroid Build Coastguard Worker
492*7688df22SAndroid Build Coastguard Worker printf("copy and scale test with %s.\n",
493*7688df22SAndroid Build Coastguard Worker type == G2D_IMGBUF_GEM ? "gem" : "userptr");
494*7688df22SAndroid Build Coastguard Worker
495*7688df22SAndroid Build Coastguard Worker src_img.width = img_w;
496*7688df22SAndroid Build Coastguard Worker src_img.height = img_h;
497*7688df22SAndroid Build Coastguard Worker src_img.stride = src_img.width * 4;
498*7688df22SAndroid Build Coastguard Worker src_img.buf_type = type;
499*7688df22SAndroid Build Coastguard Worker src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
500*7688df22SAndroid Build Coastguard Worker src_img.color = 0xffffffff;
501*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill(ctx, &src_img, src_x, src_y, img_w , img_h);
502*7688df22SAndroid Build Coastguard Worker if (ret < 0)
503*7688df22SAndroid Build Coastguard Worker goto err_free_userptr;
504*7688df22SAndroid Build Coastguard Worker
505*7688df22SAndroid Build Coastguard Worker src_img.color = 0xff00ff00;
506*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill(ctx, &src_img, 5, 5, 100, 100);
507*7688df22SAndroid Build Coastguard Worker if (ret < 0)
508*7688df22SAndroid Build Coastguard Worker goto err_free_userptr;
509*7688df22SAndroid Build Coastguard Worker
510*7688df22SAndroid Build Coastguard Worker dst_img.width = img_w;
511*7688df22SAndroid Build Coastguard Worker dst_img.height = img_h;
512*7688df22SAndroid Build Coastguard Worker dst_img.buf_type = G2D_IMGBUF_GEM;
513*7688df22SAndroid Build Coastguard Worker dst_img.stride = dst_img.width * 4;
514*7688df22SAndroid Build Coastguard Worker dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
515*7688df22SAndroid Build Coastguard Worker
516*7688df22SAndroid Build Coastguard Worker ret = g2d_copy_with_scale(ctx, &src_img, &dst_img, 5, 5, 100, 100,
517*7688df22SAndroid Build Coastguard Worker 100, 100, 200, 200, 0);
518*7688df22SAndroid Build Coastguard Worker if (ret < 0)
519*7688df22SAndroid Build Coastguard Worker goto err_free_userptr;
520*7688df22SAndroid Build Coastguard Worker
521*7688df22SAndroid Build Coastguard Worker g2d_exec(ctx);
522*7688df22SAndroid Build Coastguard Worker
523*7688df22SAndroid Build Coastguard Worker err_free_userptr:
524*7688df22SAndroid Build Coastguard Worker if (type == G2D_IMGBUF_USERPTR)
525*7688df22SAndroid Build Coastguard Worker if (userptr)
526*7688df22SAndroid Build Coastguard Worker free((void *)userptr);
527*7688df22SAndroid Build Coastguard Worker
528*7688df22SAndroid Build Coastguard Worker fail:
529*7688df22SAndroid Build Coastguard Worker g2d_fini(ctx);
530*7688df22SAndroid Build Coastguard Worker
531*7688df22SAndroid Build Coastguard Worker return ret;
532*7688df22SAndroid Build Coastguard Worker }
533*7688df22SAndroid Build Coastguard Worker
534*7688df22SAndroid Build Coastguard Worker #ifdef EXYNOS_G2D_USERPTR_TEST
g2d_blend_test(struct exynos_device * dev,struct exynos_bo * src,struct exynos_bo * dst,enum e_g2d_buf_type type)535*7688df22SAndroid Build Coastguard Worker static int g2d_blend_test(struct exynos_device *dev,
536*7688df22SAndroid Build Coastguard Worker struct exynos_bo *src,
537*7688df22SAndroid Build Coastguard Worker struct exynos_bo *dst,
538*7688df22SAndroid Build Coastguard Worker enum e_g2d_buf_type type)
539*7688df22SAndroid Build Coastguard Worker {
540*7688df22SAndroid Build Coastguard Worker struct g2d_context *ctx;
541*7688df22SAndroid Build Coastguard Worker struct g2d_image src_img = {0}, dst_img = {0};
542*7688df22SAndroid Build Coastguard Worker unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
543*7688df22SAndroid Build Coastguard Worker unsigned long userptr, size;
544*7688df22SAndroid Build Coastguard Worker int ret;
545*7688df22SAndroid Build Coastguard Worker
546*7688df22SAndroid Build Coastguard Worker ctx = g2d_init(dev->fd);
547*7688df22SAndroid Build Coastguard Worker if (!ctx)
548*7688df22SAndroid Build Coastguard Worker return -EFAULT;
549*7688df22SAndroid Build Coastguard Worker
550*7688df22SAndroid Build Coastguard Worker dst_img.bo[0] = dst->handle;
551*7688df22SAndroid Build Coastguard Worker
552*7688df22SAndroid Build Coastguard Worker src_x = 0;
553*7688df22SAndroid Build Coastguard Worker src_y = 0;
554*7688df22SAndroid Build Coastguard Worker dst_x = 0;
555*7688df22SAndroid Build Coastguard Worker dst_y = 0;
556*7688df22SAndroid Build Coastguard Worker img_w = screen_width;
557*7688df22SAndroid Build Coastguard Worker img_h = screen_height;
558*7688df22SAndroid Build Coastguard Worker
559*7688df22SAndroid Build Coastguard Worker switch (type) {
560*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_GEM:
561*7688df22SAndroid Build Coastguard Worker src_img.bo[0] = src->handle;
562*7688df22SAndroid Build Coastguard Worker break;
563*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_USERPTR:
564*7688df22SAndroid Build Coastguard Worker size = img_w * img_h * 4;
565*7688df22SAndroid Build Coastguard Worker
566*7688df22SAndroid Build Coastguard Worker userptr = (unsigned long)malloc(size);
567*7688df22SAndroid Build Coastguard Worker if (!userptr) {
568*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to allocate userptr.\n");
569*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
570*7688df22SAndroid Build Coastguard Worker goto fail;
571*7688df22SAndroid Build Coastguard Worker }
572*7688df22SAndroid Build Coastguard Worker
573*7688df22SAndroid Build Coastguard Worker src_img.user_ptr[0].userptr = userptr;
574*7688df22SAndroid Build Coastguard Worker src_img.user_ptr[0].size = size;
575*7688df22SAndroid Build Coastguard Worker break;
576*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_COLOR:
577*7688df22SAndroid Build Coastguard Worker default:
578*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
579*7688df22SAndroid Build Coastguard Worker goto fail;
580*7688df22SAndroid Build Coastguard Worker }
581*7688df22SAndroid Build Coastguard Worker
582*7688df22SAndroid Build Coastguard Worker printf("blend test with %s.\n",
583*7688df22SAndroid Build Coastguard Worker type == G2D_IMGBUF_GEM ? "gem" : "userptr");
584*7688df22SAndroid Build Coastguard Worker
585*7688df22SAndroid Build Coastguard Worker src_img.width = img_w;
586*7688df22SAndroid Build Coastguard Worker src_img.height = img_h;
587*7688df22SAndroid Build Coastguard Worker src_img.stride = src_img.width * 4;
588*7688df22SAndroid Build Coastguard Worker src_img.buf_type = type;
589*7688df22SAndroid Build Coastguard Worker src_img.select_mode = G2D_SELECT_MODE_NORMAL;
590*7688df22SAndroid Build Coastguard Worker src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
591*7688df22SAndroid Build Coastguard Worker src_img.color = 0xffffffff;
592*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill(ctx, &src_img, src_x, src_y, img_w, img_h);
593*7688df22SAndroid Build Coastguard Worker if (ret < 0)
594*7688df22SAndroid Build Coastguard Worker goto err_free_userptr;
595*7688df22SAndroid Build Coastguard Worker
596*7688df22SAndroid Build Coastguard Worker src_img.color = 0x770000ff;
597*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill(ctx, &src_img, 5, 5, 200, 200);
598*7688df22SAndroid Build Coastguard Worker if (ret < 0)
599*7688df22SAndroid Build Coastguard Worker goto err_free_userptr;
600*7688df22SAndroid Build Coastguard Worker
601*7688df22SAndroid Build Coastguard Worker dst_img.width = img_w;
602*7688df22SAndroid Build Coastguard Worker dst_img.height = img_h;
603*7688df22SAndroid Build Coastguard Worker dst_img.stride = dst_img.width * 4;
604*7688df22SAndroid Build Coastguard Worker dst_img.buf_type = G2D_IMGBUF_GEM;
605*7688df22SAndroid Build Coastguard Worker dst_img.select_mode = G2D_SELECT_MODE_NORMAL;
606*7688df22SAndroid Build Coastguard Worker dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
607*7688df22SAndroid Build Coastguard Worker dst_img.color = 0xffffffff;
608*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill(ctx, &dst_img, dst_x, dst_y, img_w, img_h);
609*7688df22SAndroid Build Coastguard Worker if (ret < 0)
610*7688df22SAndroid Build Coastguard Worker goto err_free_userptr;
611*7688df22SAndroid Build Coastguard Worker
612*7688df22SAndroid Build Coastguard Worker dst_img.color = 0x77ff0000;
613*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill(ctx, &dst_img, 105, 105, 200, 200);
614*7688df22SAndroid Build Coastguard Worker if (ret < 0)
615*7688df22SAndroid Build Coastguard Worker goto err_free_userptr;
616*7688df22SAndroid Build Coastguard Worker
617*7688df22SAndroid Build Coastguard Worker ret = g2d_blend(ctx, &src_img, &dst_img, 5, 5, 105, 105, 200, 200,
618*7688df22SAndroid Build Coastguard Worker G2D_OP_OVER);
619*7688df22SAndroid Build Coastguard Worker if (ret < 0)
620*7688df22SAndroid Build Coastguard Worker goto err_free_userptr;
621*7688df22SAndroid Build Coastguard Worker
622*7688df22SAndroid Build Coastguard Worker g2d_exec(ctx);
623*7688df22SAndroid Build Coastguard Worker
624*7688df22SAndroid Build Coastguard Worker err_free_userptr:
625*7688df22SAndroid Build Coastguard Worker if (type == G2D_IMGBUF_USERPTR)
626*7688df22SAndroid Build Coastguard Worker if (userptr)
627*7688df22SAndroid Build Coastguard Worker free((void *)userptr);
628*7688df22SAndroid Build Coastguard Worker
629*7688df22SAndroid Build Coastguard Worker fail:
630*7688df22SAndroid Build Coastguard Worker g2d_fini(ctx);
631*7688df22SAndroid Build Coastguard Worker
632*7688df22SAndroid Build Coastguard Worker return ret;
633*7688df22SAndroid Build Coastguard Worker }
634*7688df22SAndroid Build Coastguard Worker #endif
635*7688df22SAndroid Build Coastguard Worker
g2d_checkerboard_test(struct exynos_device * dev,struct exynos_bo * src,struct exynos_bo * dst,enum e_g2d_buf_type type)636*7688df22SAndroid Build Coastguard Worker static int g2d_checkerboard_test(struct exynos_device *dev,
637*7688df22SAndroid Build Coastguard Worker struct exynos_bo *src,
638*7688df22SAndroid Build Coastguard Worker struct exynos_bo *dst,
639*7688df22SAndroid Build Coastguard Worker enum e_g2d_buf_type type)
640*7688df22SAndroid Build Coastguard Worker {
641*7688df22SAndroid Build Coastguard Worker struct g2d_context *ctx;
642*7688df22SAndroid Build Coastguard Worker struct g2d_image src_img = {0}, dst_img = {0};
643*7688df22SAndroid Build Coastguard Worker unsigned int src_x, src_y, dst_x, dst_y, img_w, img_h;
644*7688df22SAndroid Build Coastguard Worker void *checkerboard = NULL;
645*7688df22SAndroid Build Coastguard Worker int ret;
646*7688df22SAndroid Build Coastguard Worker
647*7688df22SAndroid Build Coastguard Worker ctx = g2d_init(dev->fd);
648*7688df22SAndroid Build Coastguard Worker if (!ctx)
649*7688df22SAndroid Build Coastguard Worker return -EFAULT;
650*7688df22SAndroid Build Coastguard Worker
651*7688df22SAndroid Build Coastguard Worker dst_img.bo[0] = dst->handle;
652*7688df22SAndroid Build Coastguard Worker
653*7688df22SAndroid Build Coastguard Worker src_x = 0;
654*7688df22SAndroid Build Coastguard Worker src_y = 0;
655*7688df22SAndroid Build Coastguard Worker dst_x = 0;
656*7688df22SAndroid Build Coastguard Worker dst_y = 0;
657*7688df22SAndroid Build Coastguard Worker
658*7688df22SAndroid Build Coastguard Worker checkerboard = create_checkerboard_pattern(screen_width / 32, screen_height / 32, 32);
659*7688df22SAndroid Build Coastguard Worker if (!checkerboard) {
660*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
661*7688df22SAndroid Build Coastguard Worker goto fail;
662*7688df22SAndroid Build Coastguard Worker }
663*7688df22SAndroid Build Coastguard Worker
664*7688df22SAndroid Build Coastguard Worker img_w = screen_width - (screen_width % 32);
665*7688df22SAndroid Build Coastguard Worker img_h = screen_height - (screen_height % 32);
666*7688df22SAndroid Build Coastguard Worker
667*7688df22SAndroid Build Coastguard Worker switch (type) {
668*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_GEM:
669*7688df22SAndroid Build Coastguard Worker memcpy(src->vaddr, checkerboard, img_w * img_h * 4);
670*7688df22SAndroid Build Coastguard Worker src_img.bo[0] = src->handle;
671*7688df22SAndroid Build Coastguard Worker break;
672*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_USERPTR:
673*7688df22SAndroid Build Coastguard Worker src_img.user_ptr[0].userptr = (unsigned long)checkerboard;
674*7688df22SAndroid Build Coastguard Worker src_img.user_ptr[0].size = img_w * img_h * 4;
675*7688df22SAndroid Build Coastguard Worker break;
676*7688df22SAndroid Build Coastguard Worker case G2D_IMGBUF_COLOR:
677*7688df22SAndroid Build Coastguard Worker default:
678*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
679*7688df22SAndroid Build Coastguard Worker goto fail;
680*7688df22SAndroid Build Coastguard Worker }
681*7688df22SAndroid Build Coastguard Worker
682*7688df22SAndroid Build Coastguard Worker printf("checkerboard test with %s.\n",
683*7688df22SAndroid Build Coastguard Worker type == G2D_IMGBUF_GEM ? "gem" : "userptr");
684*7688df22SAndroid Build Coastguard Worker
685*7688df22SAndroid Build Coastguard Worker src_img.width = img_w;
686*7688df22SAndroid Build Coastguard Worker src_img.height = img_h;
687*7688df22SAndroid Build Coastguard Worker src_img.stride = src_img.width * 4;
688*7688df22SAndroid Build Coastguard Worker src_img.buf_type = type;
689*7688df22SAndroid Build Coastguard Worker src_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
690*7688df22SAndroid Build Coastguard Worker
691*7688df22SAndroid Build Coastguard Worker dst_img.width = screen_width;
692*7688df22SAndroid Build Coastguard Worker dst_img.height = screen_height;
693*7688df22SAndroid Build Coastguard Worker dst_img.stride = dst_img.width * 4;
694*7688df22SAndroid Build Coastguard Worker dst_img.buf_type = G2D_IMGBUF_GEM;
695*7688df22SAndroid Build Coastguard Worker dst_img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB;
696*7688df22SAndroid Build Coastguard Worker src_img.color = 0xff000000;
697*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill(ctx, &dst_img, src_x, src_y, screen_width, screen_height);
698*7688df22SAndroid Build Coastguard Worker if (ret < 0)
699*7688df22SAndroid Build Coastguard Worker goto fail;
700*7688df22SAndroid Build Coastguard Worker
701*7688df22SAndroid Build Coastguard Worker ret = g2d_copy(ctx, &src_img, &dst_img, src_x, src_y, dst_x, dst_y,
702*7688df22SAndroid Build Coastguard Worker img_w, img_h);
703*7688df22SAndroid Build Coastguard Worker if (ret < 0)
704*7688df22SAndroid Build Coastguard Worker goto fail;
705*7688df22SAndroid Build Coastguard Worker
706*7688df22SAndroid Build Coastguard Worker g2d_exec(ctx);
707*7688df22SAndroid Build Coastguard Worker
708*7688df22SAndroid Build Coastguard Worker fail:
709*7688df22SAndroid Build Coastguard Worker free(checkerboard);
710*7688df22SAndroid Build Coastguard Worker g2d_fini(ctx);
711*7688df22SAndroid Build Coastguard Worker
712*7688df22SAndroid Build Coastguard Worker return ret;
713*7688df22SAndroid Build Coastguard Worker }
714*7688df22SAndroid Build Coastguard Worker
usage(char * name)715*7688df22SAndroid Build Coastguard Worker static void usage(char *name)
716*7688df22SAndroid Build Coastguard Worker {
717*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "usage: %s [-s]\n", name);
718*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "-s <connector_id>@<crtc_id>:<mode>\n");
719*7688df22SAndroid Build Coastguard Worker exit(0);
720*7688df22SAndroid Build Coastguard Worker }
721*7688df22SAndroid Build Coastguard Worker
722*7688df22SAndroid Build Coastguard Worker extern char *optarg;
723*7688df22SAndroid Build Coastguard Worker static const char optstr[] = "s:";
724*7688df22SAndroid Build Coastguard Worker
main(int argc,char ** argv)725*7688df22SAndroid Build Coastguard Worker int main(int argc, char **argv)
726*7688df22SAndroid Build Coastguard Worker {
727*7688df22SAndroid Build Coastguard Worker struct exynos_device *dev;
728*7688df22SAndroid Build Coastguard Worker struct exynos_bo *bo, *src;
729*7688df22SAndroid Build Coastguard Worker struct connector con;
730*7688df22SAndroid Build Coastguard Worker unsigned int fb_id;
731*7688df22SAndroid Build Coastguard Worker uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
732*7688df22SAndroid Build Coastguard Worker drmModeRes *resources;
733*7688df22SAndroid Build Coastguard Worker int ret, fd, c;
734*7688df22SAndroid Build Coastguard Worker
735*7688df22SAndroid Build Coastguard Worker memset(&con, 0, sizeof(struct connector));
736*7688df22SAndroid Build Coastguard Worker
737*7688df22SAndroid Build Coastguard Worker if (argc != 3) {
738*7688df22SAndroid Build Coastguard Worker usage(argv[0]);
739*7688df22SAndroid Build Coastguard Worker return -EINVAL;
740*7688df22SAndroid Build Coastguard Worker }
741*7688df22SAndroid Build Coastguard Worker
742*7688df22SAndroid Build Coastguard Worker while ((c = getopt(argc, argv, optstr)) != -1) {
743*7688df22SAndroid Build Coastguard Worker switch (c) {
744*7688df22SAndroid Build Coastguard Worker case 's':
745*7688df22SAndroid Build Coastguard Worker con.crtc = -1;
746*7688df22SAndroid Build Coastguard Worker if (sscanf(optarg, "%d:0x%64s",
747*7688df22SAndroid Build Coastguard Worker &con.id,
748*7688df22SAndroid Build Coastguard Worker con.mode_str) != 2 &&
749*7688df22SAndroid Build Coastguard Worker sscanf(optarg, "%d@%d:%64s",
750*7688df22SAndroid Build Coastguard Worker &con.id,
751*7688df22SAndroid Build Coastguard Worker &con.crtc,
752*7688df22SAndroid Build Coastguard Worker con.mode_str) != 3)
753*7688df22SAndroid Build Coastguard Worker usage(argv[0]);
754*7688df22SAndroid Build Coastguard Worker break;
755*7688df22SAndroid Build Coastguard Worker default:
756*7688df22SAndroid Build Coastguard Worker usage(argv[0]);
757*7688df22SAndroid Build Coastguard Worker break;
758*7688df22SAndroid Build Coastguard Worker }
759*7688df22SAndroid Build Coastguard Worker }
760*7688df22SAndroid Build Coastguard Worker
761*7688df22SAndroid Build Coastguard Worker fd = drmOpen(DRM_MODULE_NAME, NULL);
762*7688df22SAndroid Build Coastguard Worker if (fd < 0) {
763*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to open.\n");
764*7688df22SAndroid Build Coastguard Worker return fd;
765*7688df22SAndroid Build Coastguard Worker }
766*7688df22SAndroid Build Coastguard Worker
767*7688df22SAndroid Build Coastguard Worker dev = exynos_device_create(fd);
768*7688df22SAndroid Build Coastguard Worker if (!dev) {
769*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
770*7688df22SAndroid Build Coastguard Worker goto err_drm_close;
771*7688df22SAndroid Build Coastguard Worker }
772*7688df22SAndroid Build Coastguard Worker
773*7688df22SAndroid Build Coastguard Worker resources = drmModeGetResources(dev->fd);
774*7688df22SAndroid Build Coastguard Worker if (!resources) {
775*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "drmModeGetResources failed: %s\n",
776*7688df22SAndroid Build Coastguard Worker strerror(errno));
777*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
778*7688df22SAndroid Build Coastguard Worker goto err_dev_destory;
779*7688df22SAndroid Build Coastguard Worker }
780*7688df22SAndroid Build Coastguard Worker
781*7688df22SAndroid Build Coastguard Worker connector_find_mode(dev->fd, &con, resources);
782*7688df22SAndroid Build Coastguard Worker drmModeFreeResources(resources);
783*7688df22SAndroid Build Coastguard Worker
784*7688df22SAndroid Build Coastguard Worker if (!con.mode) {
785*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to find usable connector\n");
786*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
787*7688df22SAndroid Build Coastguard Worker goto err_dev_destory;
788*7688df22SAndroid Build Coastguard Worker }
789*7688df22SAndroid Build Coastguard Worker
790*7688df22SAndroid Build Coastguard Worker screen_width = con.mode->hdisplay;
791*7688df22SAndroid Build Coastguard Worker screen_height = con.mode->vdisplay;
792*7688df22SAndroid Build Coastguard Worker
793*7688df22SAndroid Build Coastguard Worker if (screen_width == 0 || screen_height == 0) {
794*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to find sane resolution on connector\n");
795*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
796*7688df22SAndroid Build Coastguard Worker goto err_dev_destory;
797*7688df22SAndroid Build Coastguard Worker }
798*7688df22SAndroid Build Coastguard Worker
799*7688df22SAndroid Build Coastguard Worker printf("screen width = %d, screen height = %d\n", screen_width,
800*7688df22SAndroid Build Coastguard Worker screen_height);
801*7688df22SAndroid Build Coastguard Worker
802*7688df22SAndroid Build Coastguard Worker bo = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
803*7688df22SAndroid Build Coastguard Worker if (!bo) {
804*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
805*7688df22SAndroid Build Coastguard Worker goto err_dev_destory;
806*7688df22SAndroid Build Coastguard Worker }
807*7688df22SAndroid Build Coastguard Worker
808*7688df22SAndroid Build Coastguard Worker handles[0] = bo->handle;
809*7688df22SAndroid Build Coastguard Worker pitches[0] = screen_width * 4;
810*7688df22SAndroid Build Coastguard Worker offsets[0] = 0;
811*7688df22SAndroid Build Coastguard Worker
812*7688df22SAndroid Build Coastguard Worker ret = drmModeAddFB2(dev->fd, screen_width, screen_height,
813*7688df22SAndroid Build Coastguard Worker DRM_FORMAT_XRGB8888, handles,
814*7688df22SAndroid Build Coastguard Worker pitches, offsets, &fb_id, 0);
815*7688df22SAndroid Build Coastguard Worker if (ret < 0)
816*7688df22SAndroid Build Coastguard Worker goto err_destroy_buffer;
817*7688df22SAndroid Build Coastguard Worker
818*7688df22SAndroid Build Coastguard Worker memset(bo->vaddr, 0xff, screen_width * screen_height * 4);
819*7688df22SAndroid Build Coastguard Worker
820*7688df22SAndroid Build Coastguard Worker ret = drm_set_crtc(dev, &con, fb_id);
821*7688df22SAndroid Build Coastguard Worker if (ret < 0)
822*7688df22SAndroid Build Coastguard Worker goto err_rm_fb;
823*7688df22SAndroid Build Coastguard Worker
824*7688df22SAndroid Build Coastguard Worker ret = g2d_solid_fill_test(dev, bo);
825*7688df22SAndroid Build Coastguard Worker if (ret < 0) {
826*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to solid fill operation.\n");
827*7688df22SAndroid Build Coastguard Worker goto err_rm_fb;
828*7688df22SAndroid Build Coastguard Worker }
829*7688df22SAndroid Build Coastguard Worker
830*7688df22SAndroid Build Coastguard Worker wait_for_user_input(0);
831*7688df22SAndroid Build Coastguard Worker
832*7688df22SAndroid Build Coastguard Worker src = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
833*7688df22SAndroid Build Coastguard Worker if (!src) {
834*7688df22SAndroid Build Coastguard Worker ret = -EFAULT;
835*7688df22SAndroid Build Coastguard Worker goto err_rm_fb;
836*7688df22SAndroid Build Coastguard Worker }
837*7688df22SAndroid Build Coastguard Worker
838*7688df22SAndroid Build Coastguard Worker ret = g2d_copy_test(dev, src, bo, G2D_IMGBUF_GEM);
839*7688df22SAndroid Build Coastguard Worker if (ret < 0) {
840*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to test copy operation.\n");
841*7688df22SAndroid Build Coastguard Worker goto err_free_src;
842*7688df22SAndroid Build Coastguard Worker }
843*7688df22SAndroid Build Coastguard Worker
844*7688df22SAndroid Build Coastguard Worker wait_for_user_input(0);
845*7688df22SAndroid Build Coastguard Worker
846*7688df22SAndroid Build Coastguard Worker ret = g2d_move_test(dev, src, bo, G2D_IMGBUF_GEM);
847*7688df22SAndroid Build Coastguard Worker if (ret < 0) {
848*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to test move operation.\n");
849*7688df22SAndroid Build Coastguard Worker goto err_free_src;
850*7688df22SAndroid Build Coastguard Worker }
851*7688df22SAndroid Build Coastguard Worker
852*7688df22SAndroid Build Coastguard Worker wait_for_user_input(0);
853*7688df22SAndroid Build Coastguard Worker
854*7688df22SAndroid Build Coastguard Worker ret = g2d_copy_with_scale_test(dev, src, bo, G2D_IMGBUF_GEM);
855*7688df22SAndroid Build Coastguard Worker if (ret < 0) {
856*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to test copy and scale operation.\n");
857*7688df22SAndroid Build Coastguard Worker goto err_free_src;
858*7688df22SAndroid Build Coastguard Worker }
859*7688df22SAndroid Build Coastguard Worker
860*7688df22SAndroid Build Coastguard Worker wait_for_user_input(0);
861*7688df22SAndroid Build Coastguard Worker
862*7688df22SAndroid Build Coastguard Worker ret = g2d_checkerboard_test(dev, src, bo, G2D_IMGBUF_GEM);
863*7688df22SAndroid Build Coastguard Worker if (ret < 0) {
864*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to issue checkerboard test.\n");
865*7688df22SAndroid Build Coastguard Worker goto err_free_src;
866*7688df22SAndroid Build Coastguard Worker }
867*7688df22SAndroid Build Coastguard Worker
868*7688df22SAndroid Build Coastguard Worker wait_for_user_input(1);
869*7688df22SAndroid Build Coastguard Worker
870*7688df22SAndroid Build Coastguard Worker /*
871*7688df22SAndroid Build Coastguard Worker * The blend test uses the userptr functionality of exynos-drm, which
872*7688df22SAndroid Build Coastguard Worker * is currently not safe to use. If the kernel hasn't been build with
873*7688df22SAndroid Build Coastguard Worker * exynos-iommu support, then the blend test is going to produce (kernel)
874*7688df22SAndroid Build Coastguard Worker * memory corruption, eventually leading to a system crash.
875*7688df22SAndroid Build Coastguard Worker *
876*7688df22SAndroid Build Coastguard Worker * Disable the test for now, until the kernel code has been sanitized.
877*7688df22SAndroid Build Coastguard Worker */
878*7688df22SAndroid Build Coastguard Worker #ifdef EXYNOS_G2D_USERPTR_TEST
879*7688df22SAndroid Build Coastguard Worker ret = g2d_blend_test(dev, src, bo, G2D_IMGBUF_USERPTR);
880*7688df22SAndroid Build Coastguard Worker if (ret < 0)
881*7688df22SAndroid Build Coastguard Worker fprintf(stderr, "failed to test blend operation.\n");
882*7688df22SAndroid Build Coastguard Worker
883*7688df22SAndroid Build Coastguard Worker getchar();
884*7688df22SAndroid Build Coastguard Worker #endif
885*7688df22SAndroid Build Coastguard Worker
886*7688df22SAndroid Build Coastguard Worker err_free_src:
887*7688df22SAndroid Build Coastguard Worker if (src)
888*7688df22SAndroid Build Coastguard Worker exynos_destroy_buffer(src);
889*7688df22SAndroid Build Coastguard Worker
890*7688df22SAndroid Build Coastguard Worker err_rm_fb:
891*7688df22SAndroid Build Coastguard Worker drmModeRmFB(dev->fd, fb_id);
892*7688df22SAndroid Build Coastguard Worker
893*7688df22SAndroid Build Coastguard Worker err_destroy_buffer:
894*7688df22SAndroid Build Coastguard Worker exynos_destroy_buffer(bo);
895*7688df22SAndroid Build Coastguard Worker
896*7688df22SAndroid Build Coastguard Worker err_dev_destory:
897*7688df22SAndroid Build Coastguard Worker exynos_device_destroy(dev);
898*7688df22SAndroid Build Coastguard Worker
899*7688df22SAndroid Build Coastguard Worker err_drm_close:
900*7688df22SAndroid Build Coastguard Worker drmClose(fd);
901*7688df22SAndroid Build Coastguard Worker
902*7688df22SAndroid Build Coastguard Worker return ret;
903*7688df22SAndroid Build Coastguard Worker }
904