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 "vic41.h" 30d722e3fbSopenharmony_ci 31d722e3fbSopenharmony_cistruct vic41 { 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 vic41_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 vic41 *vic = container_of(v, struct vic41, 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 vic41_blit(struct vic *v, struct vic_image *output, 89d722e3fbSopenharmony_ci struct vic_image *input) 90d722e3fbSopenharmony_ci{ 91d722e3fbSopenharmony_ci struct vic41 *vic = container_of(v, struct vic41, 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 = 255; 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 = 255; 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 vic41_flip(struct vic *v, struct vic_image *output, 158d722e3fbSopenharmony_ci struct vic_image *input) 159d722e3fbSopenharmony_ci{ 160d722e3fbSopenharmony_ci struct vic41 *vic = container_of(v, struct vic41, 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 = 255; 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 = 255; 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 vic41_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 vic41 *vic = container_of(v, struct vic41, 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, NVB1B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID, 1); 238d722e3fbSopenharmony_ci VIC_PUSH_METHOD(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS, (sizeof(ConfigStruct) / 16) << 16); 239d722e3fbSopenharmony_ci VIC_PUSH_BUFFER(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET, vic->config.map, 0, 0); 240d722e3fbSopenharmony_ci VIC_PUSH_BUFFER(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_FILTER_STRUCT_OFFSET, vic->filter.map, 0, 0); 241d722e3fbSopenharmony_ci VIC_PUSH_BUFFER(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET, output->map, 0, 0); 242d722e3fbSopenharmony_ci 243d722e3fbSopenharmony_ci for (i = 0; i < num_inputs; i++) { 244d722e3fbSopenharmony_ci uint32_t method = NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE0_LUMA_OFFSET(0) + (i * 3) * 4; 245d722e3fbSopenharmony_ci 246d722e3fbSopenharmony_ci VIC_PUSH_BUFFER(pushbuf, ptrp, method, inputs[i]->map, 0, 0); 247d722e3fbSopenharmony_ci } 248d722e3fbSopenharmony_ci 249d722e3fbSopenharmony_ci VIC_PUSH_METHOD(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_EXECUTE, 1 << 8); 250d722e3fbSopenharmony_ci 251d722e3fbSopenharmony_ci return 0; 252d722e3fbSopenharmony_ci} 253d722e3fbSopenharmony_ci 254d722e3fbSopenharmony_cistatic void vic41_free(struct vic *v) 255d722e3fbSopenharmony_ci{ 256d722e3fbSopenharmony_ci struct vic41 *vic = container_of(v, struct vic41, base); 257d722e3fbSopenharmony_ci 258d722e3fbSopenharmony_ci drm_tegra_channel_unmap(vic->filter.map); 259d722e3fbSopenharmony_ci drm_tegra_bo_unref(vic->filter.bo); 260d722e3fbSopenharmony_ci 261d722e3fbSopenharmony_ci drm_tegra_channel_unmap(vic->config.map); 262d722e3fbSopenharmony_ci drm_tegra_bo_unref(vic->config.bo); 263d722e3fbSopenharmony_ci 264d722e3fbSopenharmony_ci drm_tegra_syncpoint_free(v->syncpt); 265d722e3fbSopenharmony_ci 266d722e3fbSopenharmony_ci free(vic); 267d722e3fbSopenharmony_ci} 268d722e3fbSopenharmony_ci 269d722e3fbSopenharmony_cistatic const struct vic_ops vic41_ops = { 270d722e3fbSopenharmony_ci .fill = vic41_fill, 271d722e3fbSopenharmony_ci .blit = vic41_blit, 272d722e3fbSopenharmony_ci .flip = vic41_flip, 273d722e3fbSopenharmony_ci .execute = vic41_execute, 274d722e3fbSopenharmony_ci .free = vic41_free, 275d722e3fbSopenharmony_ci}; 276d722e3fbSopenharmony_ci 277d722e3fbSopenharmony_ciint vic41_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, 278d722e3fbSopenharmony_ci struct vic **vicp) 279d722e3fbSopenharmony_ci{ 280d722e3fbSopenharmony_ci struct vic41 *vic; 281d722e3fbSopenharmony_ci void *ptr; 282d722e3fbSopenharmony_ci int err; 283d722e3fbSopenharmony_ci 284d722e3fbSopenharmony_ci vic = calloc(1, sizeof(*vic)); 285d722e3fbSopenharmony_ci if (!vic) 286d722e3fbSopenharmony_ci return -ENOMEM; 287d722e3fbSopenharmony_ci 288d722e3fbSopenharmony_ci vic->base.drm = drm; 289d722e3fbSopenharmony_ci vic->base.channel = channel; 290d722e3fbSopenharmony_ci vic->base.ops = &vic41_ops; 291d722e3fbSopenharmony_ci vic->base.version = 0x18; 292d722e3fbSopenharmony_ci 293d722e3fbSopenharmony_ci err = drm_tegra_syncpoint_new(drm, &vic->base.syncpt); 294d722e3fbSopenharmony_ci if (err < 0) { 295d722e3fbSopenharmony_ci fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err)); 296d722e3fbSopenharmony_ci return err; 297d722e3fbSopenharmony_ci } 298d722e3fbSopenharmony_ci 299d722e3fbSopenharmony_ci err = drm_tegra_bo_new(drm, 0, 16384, &vic->config.bo); 300d722e3fbSopenharmony_ci if (err < 0) { 301d722e3fbSopenharmony_ci fprintf(stderr, "failed to allocate configuration structurer: %s\n", 302d722e3fbSopenharmony_ci strerror(-err)); 303d722e3fbSopenharmony_ci return err; 304d722e3fbSopenharmony_ci } 305d722e3fbSopenharmony_ci 306d722e3fbSopenharmony_ci err = drm_tegra_channel_map(channel, vic->config.bo, DRM_TEGRA_CHANNEL_MAP_READ, 307d722e3fbSopenharmony_ci &vic->config.map); 308d722e3fbSopenharmony_ci if (err < 0) { 309d722e3fbSopenharmony_ci fprintf(stderr, "failed to map configuration structure: %s\n", 310d722e3fbSopenharmony_ci strerror(-err)); 311d722e3fbSopenharmony_ci return err; 312d722e3fbSopenharmony_ci } 313d722e3fbSopenharmony_ci 314d722e3fbSopenharmony_ci err = drm_tegra_bo_new(drm, 0, 16384, &vic->filter.bo); 315d722e3fbSopenharmony_ci if (err < 0) { 316d722e3fbSopenharmony_ci fprintf(stderr, "failed to allocate filter buffer: %s\n", 317d722e3fbSopenharmony_ci strerror(-err)); 318d722e3fbSopenharmony_ci return err; 319d722e3fbSopenharmony_ci } 320d722e3fbSopenharmony_ci 321d722e3fbSopenharmony_ci err = drm_tegra_bo_map(vic->filter.bo, &ptr); 322d722e3fbSopenharmony_ci if (err < 0) { 323d722e3fbSopenharmony_ci fprintf(stderr, "failed to map filter buffer: %s\n", strerror(-err)); 324d722e3fbSopenharmony_ci return err; 325d722e3fbSopenharmony_ci } 326d722e3fbSopenharmony_ci 327d722e3fbSopenharmony_ci memset(ptr, 0, 16384); 328d722e3fbSopenharmony_ci drm_tegra_bo_unmap(vic->filter.bo); 329d722e3fbSopenharmony_ci 330d722e3fbSopenharmony_ci err = drm_tegra_channel_map(channel, vic->filter.bo, DRM_TEGRA_CHANNEL_MAP_READ, 331d722e3fbSopenharmony_ci &vic->filter.map); 332d722e3fbSopenharmony_ci if (err < 0) { 333d722e3fbSopenharmony_ci fprintf(stderr, "failed to map filter buffer: %s\n", 334d722e3fbSopenharmony_ci strerror(-err)); 335d722e3fbSopenharmony_ci return err; 336d722e3fbSopenharmony_ci } 337d722e3fbSopenharmony_ci 338d722e3fbSopenharmony_ci if (vicp) 339d722e3fbSopenharmony_ci *vicp = &vic->base; 340d722e3fbSopenharmony_ci 341d722e3fbSopenharmony_ci return 0; 342d722e3fbSopenharmony_ci} 343