psb_buffer_dm.c revision dc1209519284865899ca8d990b3a2c7dbca8ae08
1/* 2 * INTEL CONFIDENTIAL 3 * Copyright 2007 Intel Corporation. All Rights Reserved. 4 * 5 * The source code contained or described herein and all documents related to 6 * the source code ("Material") are owned by Intel Corporation or its suppliers 7 * or licensors. Title to the Material remains with Intel Corporation or its 8 * suppliers and licensors. The Material may contain trade secrets and 9 * proprietary and confidential information of Intel Corporation and its 10 * suppliers and licensors, and is protected by worldwide copyright and trade 11 * secret laws and treaty provisions. No part of the Material may be used, 12 * copied, reproduced, modified, published, uploaded, posted, transmitted, 13 * distributed, or disclosed in any way without Intel's prior express written 14 * permission. 15 * 16 * No license under any patent, copyright, trade secret or other intellectual 17 * property right is granted to or conferred upon you by disclosure or delivery 18 * of the Materials, either expressly, by implication, inducement, estoppel or 19 * otherwise. Any license under such intellectual property rights must be 20 * express and approved by Intel in writing. 21 */ 22 23#include "psb_buffer.h" 24 25#include <errno.h> 26#include <stdlib.h> 27#include <unistd.h> 28#include <wsbm/wsbm_manager.h> 29/* #include <linux/rar_register.h> */ 30 31#include "psb_drm.h" 32#include "psb_def.h" 33 34 35static VAStatus psb_buffer_offset_camerav4l2(psb_driver_data_p driver_data, 36 psb_buffer_p buf, 37 unsigned int v4l2_buf_offset, 38 unsigned int *bo_offset 39 ) 40{ 41 *bo_offset = v4l2_buf_offset; 42 return VA_STATUS_SUCCESS; 43} 44 45 46static VAStatus psb_buffer_offset_cameraci(psb_driver_data_p driver_data, 47 psb_buffer_p buf, 48 unsigned int ci_frame_offset_or_handle, 49 unsigned int *bo_offset 50 ) 51{ 52 *bo_offset = ci_frame_offset_or_handle; 53 54 return VA_STATUS_SUCCESS; 55} 56 57 58static int psb_buffer_info_ci(psb_driver_data_p driver_data) 59{ 60 struct drm_lnc_video_getparam_arg arg; 61 unsigned long camera_info[2] = {0, 0}; 62 int ret = 0; 63 64 driver_data->camera_phyaddr = driver_data->camera_size = 0; 65 66 arg.key = LNC_VIDEO_GETPARAM_CI_INFO; 67 arg.value = (uint64_t)((unsigned long) & camera_info[0]); 68 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 69 &arg, sizeof(arg)); 70 if (ret == 0) { 71 driver_data->camera_phyaddr = camera_info[0]; 72 driver_data->camera_size = camera_info[1]; 73 psb__information_message("CI region physical address = 0x%08x, size=%dK\n", 74 driver_data->camera_phyaddr, driver_data->camera_size / 1024); 75 76 return ret; 77 } 78 79 psb__information_message("CI region get_info failed\n"); 80 return ret; 81} 82 83/* 84 * Allocate global BO which maps camear device memory as encode MMU memory 85 * the global BO shared by several encode surfaces created from camear memory 86 */ 87static VAStatus psb_buffer_init_camera(psb_driver_data_p driver_data) 88{ 89 int ret = 0; 90 91 /* hasn't grab camera device memory region 92 * grab the whole 4M camera device memory 93 */ 94 driver_data->camera_bo = calloc(1, sizeof(struct psb_buffer_s)); 95 if (driver_data->camera_bo == NULL) 96 return VA_STATUS_ERROR_ALLOCATION_FAILED; 97 98 psb__information_message("Grab whole camera device memory\n"); 99 ret = psb_buffer_create(driver_data, driver_data->camera_size, psb_bt_camera, (psb_buffer_p) driver_data->camera_bo); 100 101 if (ret != VA_STATUS_SUCCESS) { 102 free(driver_data->camera_bo); 103 driver_data->camera_bo = NULL; 104 105 psb__error_message("Grab camera device memory failed\n"); 106 } 107 108 return ret; 109} 110 111 112/* 113 * Create one buffer from camera device memory 114 * is_v4l2 means if the buffer is V4L2 buffer 115 * id_or_ofs is CI frame ID (actually now is frame offset), or V4L2 buffer offset 116 */ 117VAStatus psb_buffer_create_camera(psb_driver_data_p driver_data, 118 psb_buffer_p buf, 119 int is_v4l2, 120 int id_or_ofs 121 ) 122{ 123 VAStatus vaStatus; 124 int ret = 0; 125 unsigned int camera_offset = 0; 126 127 if (driver_data->camera_bo == NULL) { 128 if (psb_buffer_info_ci(driver_data)) { 129 psb__error_message("Can't get CI region information\n"); 130 return VA_STATUS_ERROR_UNKNOWN; 131 } 132 133 vaStatus = psb_buffer_init_camera(driver_data); 134 if (vaStatus != VA_STATUS_SUCCESS) { 135 psb__error_message("Grab camera device memory failed\n"); 136 return ret; 137 } 138 } 139 140 /* reference the global camear BO */ 141 ret = psb_buffer_reference(driver_data, buf, (psb_buffer_p) driver_data->camera_bo); 142 if (ret != VA_STATUS_SUCCESS) { 143 psb__error_message("Reference camera device memory failed\n"); 144 return ret; 145 } 146 147 if (is_v4l2) 148 ret = psb_buffer_offset_camerav4l2(driver_data, buf, id_or_ofs, &camera_offset); 149 else 150 ret = psb_buffer_offset_cameraci(driver_data, buf, id_or_ofs, &camera_offset); 151 152 buf->buffer_ofs = camera_offset; 153 154 return ret; 155} 156 157/* 158 * Create one buffer from user buffer 159 * id_or_ofs is CI frame ID (actually now is frame offset), or V4L2 buffer offset 160 * user_ptr :virtual address of user buffer start. 161 */ 162VAStatus psb_buffer_create_camera_from_ub(psb_driver_data_p driver_data, 163 psb_buffer_p buf, 164 int id_or_ofs, 165 int size, 166 const unsigned long * user_ptr) 167{ 168 VAStatus vaStatus = VA_STATUS_SUCCESS; 169 int allignment; 170 uint32_t placement; 171 int ret; 172 173 buf->rar_handle = 0; 174 buf->buffer_ofs = 0; 175 buf->type = psb_bt_user_buffer; 176 buf->user_ptr = (void *)user_ptr; 177 buf->driver_data = driver_data; 178 179 allignment = 4096; 180 placement = DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_TT | WSBM_PL_FLAG_CACHED | WSBM_PL_FLAG_SHARED ; 181 ret = LOCK_HARDWARE(driver_data); 182 if (ret) { 183 UNLOCK_HARDWARE(driver_data); 184 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 185 DEBUG_FAILURE_RET; 186 return vaStatus; 187 } 188 ret = wsbmGenBuffers(driver_data->main_pool, 1, &buf->drm_buf, 189 allignment, placement); 190 if (!buf->drm_buf) { 191 psb__error_message("failed to gen wsbm buffers\n"); 192 UNLOCK_HARDWARE(driver_data); 193 return VA_STATUS_ERROR_ALLOCATION_FAILED; 194 } 195 196#ifndef ANDROID 197 extern int wsbmBODataUB(struct _WsbmBufferObject *buf, 198 unsigned size, const void *data, 199 struct _WsbmBufferPool *newPool, uint32_t placement, const unsigned long *user_ptr); 200 201 /* here use the placement when gen buffer setted */ 202 ret = wsbmBODataUB(buf->drm_buf, size, NULL, NULL, 0, user_ptr); 203 UNLOCK_HARDWARE(driver_data); 204 if (ret) { 205 psb__error_message("failed to alloc wsbm buffers\n"); 206 return VA_STATUS_ERROR_ALLOCATION_FAILED; 207 } 208 psb__information_message("Create BO from user buffer 0x%08x (%d byte),BO GPU offset hint=0x%08x\n", 209 user_ptr, size, wsbmBOOffsetHint(buf->drm_buf)); 210 211#endif 212 213 buf->pl_flags = placement; 214 buf->status = psb_bs_ready; 215 buf->wsbm_synccpu_flag = 0; 216 217 return VA_STATUS_SUCCESS; 218} 219 220 221static int psb_buffer_info_rar(psb_driver_data_p driver_data) 222{ 223 struct drm_lnc_video_getparam_arg arg; 224 unsigned long rar_info[2] = {0, 0}; 225 int ret = 0; 226 227 driver_data->rar_phyaddr = driver_data->rar_size = 0; 228 229 arg.key = LNC_VIDEO_GETPARAM_RAR_INFO; 230 arg.value = (uint64_t)((unsigned long) & rar_info[0]); 231 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 232 &arg, sizeof(arg)); 233 if (ret == 0) { 234 driver_data->rar_phyaddr = rar_info[0]; 235 driver_data->rar_size = rar_info[1]; 236 psb__information_message("RAR region physical address = 0x%08x, size=%dK\n", 237 driver_data->rar_phyaddr, driver_data->rar_size / 1024); 238 239 return ret; 240 } 241 242 psb__information_message("RAR region get size failed\n"); 243 return ret; 244} 245 246 247static int psb_buffer_offset_rar(psb_driver_data_p driver_data, 248 psb_buffer_p buf, 249 uint32_t rar_handle, 250 unsigned int *bo_offset 251 ) 252{ 253 struct drm_lnc_video_getparam_arg arg; 254 unsigned long offset; 255 int ret = 0; 256 257 *bo_offset = 0; 258 259 arg.key = LNC_VIDEO_GETPARAM_RAR_HANDLER_OFFSET; 260 arg.arg = (uint64_t)((unsigned long) & rar_handle); 261 arg.value = (uint64_t)((unsigned long) & offset); 262 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 263 &arg, sizeof(arg)); 264 if (ret == 0) { 265 *bo_offset = offset; 266 267 return ret; 268 } 269 270 psb__information_message("RAR buffer 0x%08x, get offset failed\n", rar_handle); 271 return ret; 272} 273 274 275static VAStatus psb_buffer_init_rar(psb_driver_data_p driver_data) 276{ 277 int ret = 0; 278 RAR_desc_t *rar_rd; 279 280 /* hasn't grab RAR device memory region 281 * grab the whole 8M RAR device memory 282 */ 283 driver_data->rar_bo = calloc(1, sizeof(struct psb_buffer_s)); 284 if (driver_data->rar_bo == NULL) 285 goto exit_error; 286 287 driver_data->rar_rd = calloc(1, sizeof(RAR_desc_t)); 288 if (driver_data->rar_rd == NULL) 289 goto exit_error; 290 291 memset(driver_data->rar_rd, 0, sizeof(RAR_desc_t)); 292 293 psb__information_message("Init RAR device\n"); 294 295 ret = RAR_init(driver_data->rar_rd); 296 if (ret != 0) { 297 psb__error_message("RAR device init failed\n"); 298 goto exit_error; 299 } 300 301 if (psb_buffer_info_rar(driver_data)) { 302 psb__error_message("Get RAR region size failed\n"); 303 goto exit_error; 304 } 305 306 psb__information_message("Grab whole camera device memory\n"); 307 ret = psb_buffer_create(driver_data, driver_data->rar_size, psb_bt_rar, (psb_buffer_p) driver_data->rar_bo); 308 309 if (ret != VA_STATUS_SUCCESS) { 310 psb__error_message("Grab RAR device memory failed\n"); 311 goto exit_error; 312 } 313 314 return VA_STATUS_SUCCESS; 315 316exit_error: 317 rar_rd = driver_data->rar_rd; 318 319 if (rar_rd) { 320 if (rar_rd->mrfd) 321 RAR_fini(driver_data->rar_rd); 322 free(rar_rd); 323 } 324 325 if (driver_data->rar_bo) 326 free(driver_data->rar_bo); 327 328 driver_data->rar_bo = NULL; 329 driver_data->rar_rd = NULL; 330 331 return VA_STATUS_ERROR_ALLOCATION_FAILED; 332} 333 334 335 336/* 337 * Create RAR buffer 338 * Only used when create a protected surface 339 */ 340VAStatus psb_buffer_create_rar(psb_driver_data_p driver_data, 341 unsigned int size, 342 psb_buffer_p buf 343 ) 344{ 345 VAStatus vaStatus; 346 uint32_t rar_handle = 0; 347 unsigned int rar_offset = 0; 348 RAR_desc_t *rar_rd; 349 int ret; 350 351 if (driver_data->rar_rd == NULL) { 352 vaStatus = psb_buffer_init_rar(driver_data); 353 if (vaStatus != VA_STATUS_SUCCESS) { 354 psb__error_message("RAR init failed!\n"); 355 return vaStatus; 356 } 357 } 358 359 rar_rd = driver_data->rar_rd; 360 361 /* Call RAR interface to allocate RAR buffers */ 362 ret = RAR_reserve(rar_rd, size, RAR_TYPE_VIDEO, &rar_handle); 363 if (ret != 0) { 364 psb__error_message("RAR reserver memory failed\n"); 365 RAR_fini(rar_rd); 366 367 return VA_STATUS_ERROR_UNKNOWN; 368 } 369 370 ret = psb_buffer_offset_rar(driver_data, buf, rar_handle, &rar_offset); 371 if (ret != 0) { 372 psb__error_message("Get buffer offset of RAR device memory failed!\n"); 373 return ret; 374 } 375 376 /* reference the global RAR BO */ 377 ret = psb_buffer_reference(driver_data, buf, (psb_buffer_p) driver_data->rar_bo); 378 if (ret != VA_STATUS_SUCCESS) { 379 psb__error_message("Reference RAR device memory failed\n"); 380 return ret; 381 } 382 383 buf->rar_handle = rar_handle; 384 buf->buffer_ofs = rar_offset; 385 386 /* reference the global RAR buffer, reset buffer type */ 387 buf->type = psb_bt_rar_surface; /* need RAR_release */ 388 389 psb__information_message("Create RAR buffer, handle 0x%08x, RAR region offset =0x%08x, RAR BO GPU offset hint=0x%08x\n", 390 rar_handle, rar_offset, wsbmBOOffsetHint(buf->drm_buf)); 391 392 return VA_STATUS_SUCCESS; 393} 394 395 396/* 397 * Destroy RAR buffer 398 */ 399VAStatus psb_buffer_destroy_rar(psb_driver_data_p driver_data, 400 psb_buffer_p buf 401 ) 402{ 403 RAR_desc_t *rar_rd; 404 int ret; 405 406 ASSERT(driver_data->rar_rd); 407 408 if (buf->type == psb_bt_rar_slice) { 409 psb__information_message("return RAR slice buffer to application\n"); 410 buf->rar_handle = 0; 411 return VA_STATUS_SUCCESS; 412 } 413 414 415 rar_rd = driver_data->rar_rd; 416 417 ret = RAR_release(rar_rd, buf->rar_handle); 418 if (ret != 0) 419 psb__error_message("RAR release memory failed\n"); 420 421 buf->rar_handle = 0; 422 423 return VA_STATUS_SUCCESS; 424} 425 426/* 427 * Reference one RAR buffer from handle 428 * only used to reference a slice RAR buffer which is created outside of video driver 429 */ 430VAStatus psb_buffer_reference_rar(psb_driver_data_p driver_data, 431 uint32_t rar_handle, 432 psb_buffer_p buf 433 ) 434{ 435 VAStatus vaStatus; 436 unsigned int rar_offset = 0; 437 int ret; 438 439 if (driver_data->rar_rd == NULL) { 440 vaStatus = psb_buffer_init_rar(driver_data); 441 if (vaStatus != VA_STATUS_SUCCESS) { 442 psb__error_message("RAR init failed!\n"); 443 return vaStatus; 444 } 445 } 446 447 /* don't need to assign the handle to buffer 448 * so that when destroy the buffer, we just 449 * need to unreference 450 */ 451 /* buf->rar_handle = rar_handle; */ 452 453 ret = psb_buffer_offset_rar(driver_data, buf, rar_handle, &rar_offset); 454 if (ret != VA_STATUS_SUCCESS) { 455 psb__error_message("Get surfae offset of RAR device memory failed!\n"); 456 return ret; 457 } 458 459 /* reference the global RAR BO */ 460 ret = psb_buffer_reference(driver_data, buf, (psb_buffer_p) driver_data->rar_bo); 461 if (ret != VA_STATUS_SUCCESS) { 462 psb__error_message("Reference RAR device memory failed\n"); 463 return ret; 464 } 465 466 buf->rar_handle = rar_handle; 467 buf->buffer_ofs = rar_offset; 468 /* reference the global RAR buffer, reset buffer type */ 469 buf->type = psb_bt_rar_slice; /* don't need to RAR_release */ 470 471 psb__information_message("Reference RAR buffer, handle 0x%08x, RAR region offset =0x%08x, RAR BO GPU offset hint=0x%08x\n", 472 rar_handle, rar_offset, wsbmBOOffsetHint(buf->drm_buf)); 473 474 return VA_STATUS_SUCCESS; 475} 476