1d722e3fbSopenharmony_ci/* 2d722e3fbSopenharmony_ci * Copyright © 2018 NVIDIA Corporation 3d722e3fbSopenharmony_ci * 4d722e3fbSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5d722e3fbSopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6d722e3fbSopenharmony_ci * to deal in the Software without restriction, including without limitation 7d722e3fbSopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8d722e3fbSopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9d722e3fbSopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10d722e3fbSopenharmony_ci * 11d722e3fbSopenharmony_ci * The above copyright notice and this permission notice shall be included in 12d722e3fbSopenharmony_ci * all copies or substantial portions of the Software. 13d722e3fbSopenharmony_ci * 14d722e3fbSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15d722e3fbSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16d722e3fbSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17d722e3fbSopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18d722e3fbSopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19d722e3fbSopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20d722e3fbSopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 21d722e3fbSopenharmony_ci */ 22d722e3fbSopenharmony_ci 23d722e3fbSopenharmony_ci#include <errno.h> 24d722e3fbSopenharmony_ci#include <string.h> 25d722e3fbSopenharmony_ci 26d722e3fbSopenharmony_ci#include "private.h" 27d722e3fbSopenharmony_ci#include "tegra.h" 28d722e3fbSopenharmony_ci#include "vic.h" 29d722e3fbSopenharmony_ci#include "vic40.h" 30d722e3fbSopenharmony_ci 31d722e3fbSopenharmony_cistruct vic40 { 32d722e3fbSopenharmony_ci struct vic base; 33d722e3fbSopenharmony_ci 34d722e3fbSopenharmony_ci struct { 35d722e3fbSopenharmony_ci struct drm_tegra_mapping *map; 36d722e3fbSopenharmony_ci struct drm_tegra_bo *bo; 37d722e3fbSopenharmony_ci } config; 38d722e3fbSopenharmony_ci 39d722e3fbSopenharmony_ci struct { 40d722e3fbSopenharmony_ci struct drm_tegra_mapping *map; 41d722e3fbSopenharmony_ci struct drm_tegra_bo *bo; 42d722e3fbSopenharmony_ci } filter; 43d722e3fbSopenharmony_ci}; 44d722e3fbSopenharmony_ci 45d722e3fbSopenharmony_cistatic int vic40_fill(struct vic *v, struct vic_image *output, 46d722e3fbSopenharmony_ci unsigned int left, unsigned int top, 47d722e3fbSopenharmony_ci unsigned int right, unsigned int bottom, 48d722e3fbSopenharmony_ci unsigned int alpha, unsigned int red, 49d722e3fbSopenharmony_ci unsigned int green, unsigned int blue) 50d722e3fbSopenharmony_ci{ 51d722e3fbSopenharmony_ci struct vic40 *vic = container_of(v, struct vic40, base); 52d722e3fbSopenharmony_ci ConfigStruct *c; 53d722e3fbSopenharmony_ci int err; 54d722e3fbSopenharmony_ci 55d722e3fbSopenharmony_ci err = drm_tegra_bo_map(vic->config.bo, (void **)&c); 56d722e3fbSopenharmony_ci if (err < 0) { 57d722e3fbSopenharmony_ci fprintf(stderr, "failed to map configuration structure: %s\n", 58d722e3fbSopenharmony_ci strerror(-err)); 59d722e3fbSopenharmony_ci return err; 60d722e3fbSopenharmony_ci } 61d722e3fbSopenharmony_ci 62d722e3fbSopenharmony_ci memset(c, 0, sizeof(*c)); 63d722e3fbSopenharmony_ci 64d722e3fbSopenharmony_ci c->outputConfig.TargetRectTop = top; 65d722e3fbSopenharmony_ci c->outputConfig.TargetRectLeft = left; 66d722e3fbSopenharmony_ci c->outputConfig.TargetRectRight = right; 67d722e3fbSopenharmony_ci c->outputConfig.TargetRectBottom = bottom; 68d722e3fbSopenharmony_ci c->outputConfig.BackgroundAlpha = alpha; 69d722e3fbSopenharmony_ci c->outputConfig.BackgroundR = red; 70d722e3fbSopenharmony_ci c->outputConfig.BackgroundG = green; 71d722e3fbSopenharmony_ci c->outputConfig.BackgroundB = blue; 72d722e3fbSopenharmony_ci 73d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutPixelFormat = output->format; 74d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutBlkKind = output->kind; 75d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutBlkHeight = 0; 76d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; 77d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; 78d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; 79d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutLumaHeight = output->height - 1; 80d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutChromaWidth = 16383; 81d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutChromaHeight = 16383; 82d722e3fbSopenharmony_ci 83d722e3fbSopenharmony_ci drm_tegra_bo_unmap(vic->config.bo); 84d722e3fbSopenharmony_ci 85d722e3fbSopenharmony_ci return 0; 86d722e3fbSopenharmony_ci} 87d722e3fbSopenharmony_ci 88d722e3fbSopenharmony_cistatic int vic40_blit(struct vic *v, struct vic_image *output, 89d722e3fbSopenharmony_ci struct vic_image *input) 90d722e3fbSopenharmony_ci{ 91d722e3fbSopenharmony_ci struct vic40 *vic = container_of(v, struct vic40, base); 92d722e3fbSopenharmony_ci SlotSurfaceConfig *surface; 93d722e3fbSopenharmony_ci SlotConfig *slot; 94d722e3fbSopenharmony_ci ConfigStruct *c; 95d722e3fbSopenharmony_ci int err; 96d722e3fbSopenharmony_ci 97d722e3fbSopenharmony_ci err = drm_tegra_bo_map(vic->config.bo, (void **)&c); 98d722e3fbSopenharmony_ci if (err < 0) { 99d722e3fbSopenharmony_ci fprintf(stderr, "failed to map configuration structure: %s\n", 100d722e3fbSopenharmony_ci strerror(-err)); 101d722e3fbSopenharmony_ci return err; 102d722e3fbSopenharmony_ci } 103d722e3fbSopenharmony_ci 104d722e3fbSopenharmony_ci memset(c, 0, sizeof(*c)); 105d722e3fbSopenharmony_ci 106d722e3fbSopenharmony_ci c->outputConfig.TargetRectTop = 0; 107d722e3fbSopenharmony_ci c->outputConfig.TargetRectLeft = 0; 108d722e3fbSopenharmony_ci c->outputConfig.TargetRectRight = output->width - 1; 109d722e3fbSopenharmony_ci c->outputConfig.TargetRectBottom = output->height - 1; 110d722e3fbSopenharmony_ci c->outputConfig.BackgroundAlpha = 1023; 111d722e3fbSopenharmony_ci c->outputConfig.BackgroundR = 1023; 112d722e3fbSopenharmony_ci c->outputConfig.BackgroundG = 1023; 113d722e3fbSopenharmony_ci c->outputConfig.BackgroundB = 1023; 114d722e3fbSopenharmony_ci 115d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutPixelFormat = output->format; 116d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutBlkKind = output->kind; 117d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutBlkHeight = 0; 118d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; 119d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; 120d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; 121d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutLumaHeight = output->height - 1; 122d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutChromaWidth = 16383; 123d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutChromaHeight = 16383; 124d722e3fbSopenharmony_ci 125d722e3fbSopenharmony_ci slot = &c->slotStruct[0].slotConfig; 126d722e3fbSopenharmony_ci slot->SlotEnable = 1; 127d722e3fbSopenharmony_ci slot->CurrentFieldEnable = 1; 128d722e3fbSopenharmony_ci slot->PlanarAlpha = 1023; 129d722e3fbSopenharmony_ci slot->ConstantAlpha = 1; 130d722e3fbSopenharmony_ci slot->SourceRectLeft = 0 << 16; 131d722e3fbSopenharmony_ci slot->SourceRectRight = (input->width - 1) << 16; 132d722e3fbSopenharmony_ci slot->SourceRectTop = 0 << 16; 133d722e3fbSopenharmony_ci slot->SourceRectBottom = (input->height - 1) << 16; 134d722e3fbSopenharmony_ci slot->DestRectLeft = 0; 135d722e3fbSopenharmony_ci slot->DestRectRight = output->width - 1; 136d722e3fbSopenharmony_ci slot->DestRectTop = 0; 137d722e3fbSopenharmony_ci slot->DestRectBottom = output->height - 1; 138d722e3fbSopenharmony_ci slot->SoftClampHigh = 1023; 139d722e3fbSopenharmony_ci 140d722e3fbSopenharmony_ci surface = &c->slotStruct[0].slotSurfaceConfig; 141d722e3fbSopenharmony_ci surface->SlotPixelFormat = input->format; 142d722e3fbSopenharmony_ci surface->SlotBlkKind = input->kind; 143d722e3fbSopenharmony_ci surface->SlotBlkHeight = 0; /* XXX */ 144d722e3fbSopenharmony_ci surface->SlotCacheWidth = VIC_CACHE_WIDTH_64Bx4; /* XXX */ 145d722e3fbSopenharmony_ci surface->SlotSurfaceWidth = input->width - 1; 146d722e3fbSopenharmony_ci surface->SlotSurfaceHeight = input->height - 1; 147d722e3fbSopenharmony_ci surface->SlotLumaWidth = input->stride - 1; 148d722e3fbSopenharmony_ci surface->SlotLumaHeight = input->height - 1; 149d722e3fbSopenharmony_ci surface->SlotChromaWidth = 16383; 150d722e3fbSopenharmony_ci surface->SlotChromaHeight = 16383; 151d722e3fbSopenharmony_ci 152d722e3fbSopenharmony_ci drm_tegra_bo_unmap(vic->config.bo); 153d722e3fbSopenharmony_ci 154d722e3fbSopenharmony_ci return 0; 155d722e3fbSopenharmony_ci} 156d722e3fbSopenharmony_ci 157d722e3fbSopenharmony_cistatic int vic40_flip(struct vic *v, struct vic_image *output, 158d722e3fbSopenharmony_ci struct vic_image *input) 159d722e3fbSopenharmony_ci{ 160d722e3fbSopenharmony_ci struct vic40 *vic = container_of(v, struct vic40, base); 161d722e3fbSopenharmony_ci SlotSurfaceConfig *surface; 162d722e3fbSopenharmony_ci SlotConfig *slot; 163d722e3fbSopenharmony_ci ConfigStruct *c; 164d722e3fbSopenharmony_ci int err; 165d722e3fbSopenharmony_ci 166d722e3fbSopenharmony_ci err = drm_tegra_bo_map(vic->config.bo, (void **)&c); 167d722e3fbSopenharmony_ci if (err < 0) { 168d722e3fbSopenharmony_ci fprintf(stderr, "failed to map configuration structure: %s\n", 169d722e3fbSopenharmony_ci strerror(-err)); 170d722e3fbSopenharmony_ci return err; 171d722e3fbSopenharmony_ci } 172d722e3fbSopenharmony_ci 173d722e3fbSopenharmony_ci memset(c, 0, sizeof(*c)); 174d722e3fbSopenharmony_ci 175d722e3fbSopenharmony_ci c->outputConfig.TargetRectTop = 0; 176d722e3fbSopenharmony_ci c->outputConfig.TargetRectLeft = 0; 177d722e3fbSopenharmony_ci c->outputConfig.TargetRectRight = output->width - 1; 178d722e3fbSopenharmony_ci c->outputConfig.TargetRectBottom = output->height - 1; 179d722e3fbSopenharmony_ci c->outputConfig.BackgroundAlpha = 1023; 180d722e3fbSopenharmony_ci c->outputConfig.BackgroundR = 1023; 181d722e3fbSopenharmony_ci c->outputConfig.BackgroundG = 1023; 182d722e3fbSopenharmony_ci c->outputConfig.BackgroundB = 1023; 183d722e3fbSopenharmony_ci c->outputConfig.OutputFlipY = 1; 184d722e3fbSopenharmony_ci 185d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutPixelFormat = output->format; 186d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutBlkKind = output->kind; 187d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutBlkHeight = 0; 188d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; 189d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; 190d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; 191d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutLumaHeight = output->height - 1; 192d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutChromaWidth = 16383; 193d722e3fbSopenharmony_ci c->outputSurfaceConfig.OutChromaHeight = 16383; 194d722e3fbSopenharmony_ci 195d722e3fbSopenharmony_ci slot = &c->slotStruct[0].slotConfig; 196d722e3fbSopenharmony_ci slot->SlotEnable = 1; 197d722e3fbSopenharmony_ci slot->CurrentFieldEnable = 1; 198d722e3fbSopenharmony_ci slot->PlanarAlpha = 1023; 199d722e3fbSopenharmony_ci slot->ConstantAlpha = 1; 200d722e3fbSopenharmony_ci slot->SourceRectLeft = 0 << 16; 201d722e3fbSopenharmony_ci slot->SourceRectRight = (input->width - 1) << 16; 202d722e3fbSopenharmony_ci slot->SourceRectTop = 0 << 16; 203d722e3fbSopenharmony_ci slot->SourceRectBottom = (input->height - 1) << 16; 204d722e3fbSopenharmony_ci slot->DestRectLeft = 0; 205d722e3fbSopenharmony_ci slot->DestRectRight = output->width - 1; 206d722e3fbSopenharmony_ci slot->DestRectTop = 0; 207d722e3fbSopenharmony_ci slot->DestRectBottom = output->height - 1; 208d722e3fbSopenharmony_ci slot->SoftClampHigh = 1023; 209d722e3fbSopenharmony_ci 210d722e3fbSopenharmony_ci surface = &c->slotStruct[0].slotSurfaceConfig; 211d722e3fbSopenharmony_ci surface->SlotPixelFormat = input->format; 212d722e3fbSopenharmony_ci surface->SlotBlkKind = input->kind; 213d722e3fbSopenharmony_ci surface->SlotBlkHeight = 0; /* XXX */ 214d722e3fbSopenharmony_ci surface->SlotCacheWidth = VIC_CACHE_WIDTH_64Bx4; /* XXX */ 215d722e3fbSopenharmony_ci surface->SlotSurfaceWidth = input->width - 1; 216d722e3fbSopenharmony_ci surface->SlotSurfaceHeight = input->height - 1; 217d722e3fbSopenharmony_ci surface->SlotLumaWidth = input->stride - 1; 218d722e3fbSopenharmony_ci surface->SlotLumaHeight = input->height - 1; 219d722e3fbSopenharmony_ci surface->SlotChromaWidth = 16383; 220d722e3fbSopenharmony_ci surface->SlotChromaHeight = 16383; 221d722e3fbSopenharmony_ci 222d722e3fbSopenharmony_ci drm_tegra_bo_unmap(vic->config.bo); 223d722e3fbSopenharmony_ci 224d722e3fbSopenharmony_ci return 0; 225d722e3fbSopenharmony_ci} 226d722e3fbSopenharmony_ci 227d722e3fbSopenharmony_cistatic int vic40_execute(struct vic *v, struct drm_tegra_pushbuf *pushbuf, 228d722e3fbSopenharmony_ci uint32_t **ptrp, struct vic_image *output, 229d722e3fbSopenharmony_ci struct vic_image **inputs, unsigned int num_inputs) 230d722e3fbSopenharmony_ci{ 231d722e3fbSopenharmony_ci struct vic40 *vic = container_of(v, struct vic40, base); 232d722e3fbSopenharmony_ci unsigned int i; 233d722e3fbSopenharmony_ci 234d722e3fbSopenharmony_ci if (num_inputs > 1) 235d722e3fbSopenharmony_ci return -EINVAL; 236d722e3fbSopenharmony_ci 237d722e3fbSopenharmony_ci VIC_PUSH_METHOD(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID, 1); 238d722e3fbSopenharmony_ci VIC_PUSH_METHOD(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS, (sizeof(ConfigStruct) / 16) << 16); 239d722e3fbSopenharmony_ci VIC_PUSH_BUFFER(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET, vic->config.map, 0, 0); 240d722e3fbSopenharmony_ci VIC_PUSH_BUFFER(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET, output->map, 0, 0); 241d722e3fbSopenharmony_ci 242d722e3fbSopenharmony_ci for (i = 0; i < num_inputs; i++) 243d722e3fbSopenharmony_ci VIC_PUSH_BUFFER(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_SET_SURFACE0_SLOT0_LUMA_OFFSET, inputs[i]->map, 0, 0); 244d722e3fbSopenharmony_ci 245d722e3fbSopenharmony_ci VIC_PUSH_METHOD(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_EXECUTE, 1 << 8); 246d722e3fbSopenharmony_ci 247d722e3fbSopenharmony_ci return 0; 248d722e3fbSopenharmony_ci} 249d722e3fbSopenharmony_ci 250d722e3fbSopenharmony_cistatic void vic40_free(struct vic *v) 251d722e3fbSopenharmony_ci{ 252d722e3fbSopenharmony_ci struct vic40 *vic = container_of(v, struct vic40, base); 253d722e3fbSopenharmony_ci 254d722e3fbSopenharmony_ci drm_tegra_channel_unmap(vic->filter.map); 255d722e3fbSopenharmony_ci drm_tegra_bo_unref(vic->filter.bo); 256d722e3fbSopenharmony_ci 257d722e3fbSopenharmony_ci drm_tegra_channel_unmap(vic->config.map); 258d722e3fbSopenharmony_ci drm_tegra_bo_unref(vic->config.bo); 259d722e3fbSopenharmony_ci 260d722e3fbSopenharmony_ci drm_tegra_syncpoint_free(v->syncpt); 261d722e3fbSopenharmony_ci 262d722e3fbSopenharmony_ci free(vic); 263d722e3fbSopenharmony_ci} 264d722e3fbSopenharmony_ci 265d722e3fbSopenharmony_cistatic const struct vic_ops vic40_ops = { 266d722e3fbSopenharmony_ci .fill = vic40_fill, 267d722e3fbSopenharmony_ci .blit = vic40_blit, 268d722e3fbSopenharmony_ci .flip = vic40_flip, 269d722e3fbSopenharmony_ci .execute = vic40_execute, 270d722e3fbSopenharmony_ci .free = vic40_free, 271d722e3fbSopenharmony_ci}; 272d722e3fbSopenharmony_ci 273d722e3fbSopenharmony_ciint vic40_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, 274d722e3fbSopenharmony_ci struct vic **vicp) 275d722e3fbSopenharmony_ci{ 276d722e3fbSopenharmony_ci struct vic40 *vic; 277d722e3fbSopenharmony_ci void *ptr; 278d722e3fbSopenharmony_ci int err; 279d722e3fbSopenharmony_ci 280d722e3fbSopenharmony_ci vic = calloc(1, sizeof(*vic)); 281d722e3fbSopenharmony_ci if (!vic) 282d722e3fbSopenharmony_ci return -ENOMEM; 283d722e3fbSopenharmony_ci 284d722e3fbSopenharmony_ci vic->base.drm = drm; 285d722e3fbSopenharmony_ci vic->base.channel = channel; 286d722e3fbSopenharmony_ci vic->base.ops = &vic40_ops; 287d722e3fbSopenharmony_ci vic->base.version = 0x21; 288d722e3fbSopenharmony_ci 289d722e3fbSopenharmony_ci err = drm_tegra_syncpoint_new(drm, &vic->base.syncpt); 290d722e3fbSopenharmony_ci if (err < 0) { 291d722e3fbSopenharmony_ci fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err)); 292d722e3fbSopenharmony_ci return err; 293d722e3fbSopenharmony_ci } 294d722e3fbSopenharmony_ci 295d722e3fbSopenharmony_ci err = drm_tegra_bo_new(drm, 0, 16384, &vic->config.bo); 296d722e3fbSopenharmony_ci if (err < 0) { 297d722e3fbSopenharmony_ci fprintf(stderr, "failed to allocate configuration structurer: %s\n", 298d722e3fbSopenharmony_ci strerror(-err)); 299d722e3fbSopenharmony_ci return err; 300d722e3fbSopenharmony_ci } 301d722e3fbSopenharmony_ci 302d722e3fbSopenharmony_ci err = drm_tegra_channel_map(channel, vic->config.bo, DRM_TEGRA_CHANNEL_MAP_READ, 303d722e3fbSopenharmony_ci &vic->config.map); 304d722e3fbSopenharmony_ci if (err < 0) { 305d722e3fbSopenharmony_ci fprintf(stderr, "failed to map configuration structure: %s\n", 306d722e3fbSopenharmony_ci strerror(-err)); 307d722e3fbSopenharmony_ci return err; 308d722e3fbSopenharmony_ci } 309d722e3fbSopenharmony_ci 310d722e3fbSopenharmony_ci err = drm_tegra_bo_new(drm, 0, 16384, &vic->filter.bo); 311d722e3fbSopenharmony_ci if (err < 0) { 312d722e3fbSopenharmony_ci fprintf(stderr, "failed to allocate filter buffer: %s\n", 313d722e3fbSopenharmony_ci strerror(-err)); 314d722e3fbSopenharmony_ci return err; 315d722e3fbSopenharmony_ci } 316d722e3fbSopenharmony_ci 317d722e3fbSopenharmony_ci err = drm_tegra_bo_map(vic->filter.bo, &ptr); 318d722e3fbSopenharmony_ci if (err < 0) { 319d722e3fbSopenharmony_ci fprintf(stderr, "failed to map filter buffer: %s\n", strerror(-err)); 320d722e3fbSopenharmony_ci return err; 321d722e3fbSopenharmony_ci } 322d722e3fbSopenharmony_ci 323d722e3fbSopenharmony_ci memset(ptr, 0, 16384); 324d722e3fbSopenharmony_ci drm_tegra_bo_unmap(vic->filter.bo); 325d722e3fbSopenharmony_ci 326d722e3fbSopenharmony_ci err = drm_tegra_channel_map(channel, vic->filter.bo, DRM_TEGRA_CHANNEL_MAP_READ, 327d722e3fbSopenharmony_ci &vic->filter.map); 328d722e3fbSopenharmony_ci if (err < 0) { 329d722e3fbSopenharmony_ci fprintf(stderr, "failed to map filter buffer: %s\n", 330d722e3fbSopenharmony_ci strerror(-err)); 331d722e3fbSopenharmony_ci return err; 332d722e3fbSopenharmony_ci } 333d722e3fbSopenharmony_ci 334d722e3fbSopenharmony_ci if (vicp) 335d722e3fbSopenharmony_ci *vicp = &vic->base; 336d722e3fbSopenharmony_ci 337d722e3fbSopenharmony_ci return 0; 338d722e3fbSopenharmony_ci} 339