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