psb_buffer.c revision 2046ea17ddb468c845f542a88761a03b04898fd7
1c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair/*
2c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * Copyright (c) Imagination Technologies Limited, UK
4c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair *
5c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * Permission is hereby granted, free of charge, to any person obtaining a
6c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * copy of this software and associated documentation files (the
7c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * "Software"), to deal in the Software without restriction, including
8c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * without limitation the rights to use, copy, modify, merge, publish,
9c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * distribute, sub license, and/or sell copies of the Software, and to
10c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * permit persons to whom the Software is furnished to do so, subject to
11c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * the following conditions:
12c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair *
13c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * The above copyright notice and this permission notice (including the
14c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * next paragraph) shall be included in all copies or substantial portions
15c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * of the Software.
16c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair *
17c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair *
25c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * Authors:
26c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair *    Waldo Bastian <waldo.bastian@intel.com>
27c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair *
28c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair */
29c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair
30c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include <sys/types.h>
31c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include "psb_buffer.h"
32c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair
33c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include <errno.h>
34c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include <stdlib.h>
35c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include <unistd.h>
36c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include <wsbm/wsbm_manager.h>
37c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair
38c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#ifdef ANDROID
39c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#ifdef BAYTRAIL
40c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include <linux/vxd_drm.h>
41c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#else
42c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include <drm/ttm/ttm_placement.h>
43c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include <linux/psb_drm.h>
44c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#endif
45c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#else
46c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include <psb_drm.h>
47c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#endif
48c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair
49c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include "psb_def.h"
50c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include "psb_drv_debug.h"
51c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include "tng_cmdbuf.h"
52c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair
53c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#ifndef BAYTRAIL
54c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include <pnw_cmdbuf.h>
55c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include "pnw_jpeg.h"
56c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include "pnw_H264ES.h"
57c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include "tng_jpegES.h"
58c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#endif
59c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair
60c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair#include "vsp_fw.h"
61c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair/*
62c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair * Create buffer
63c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair */
64c1de24f1bfa6699e54b069e300af5e4246b34a34chrismairVAStatus psb_buffer_create(psb_driver_data_p driver_data,
65c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair                           unsigned int size,
66c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair                           psb_buffer_type_t type,
67c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair                           psb_buffer_p buf
68c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair                          )
69c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair{
70c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    VAStatus vaStatus = VA_STATUS_SUCCESS;
71c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    int allignment;
72c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    uint32_t placement;
73c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    int ret;
74c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair
75c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    /* reset rar_handle to NULL */
76c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    buf->rar_handle = 0;
77c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    buf->buffer_ofs = 0;
78c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair
79c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    buf->type = type;
80c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    buf->driver_data = driver_data; /* only for RAR buffers */
81c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    buf->size = size;
82c1de24f1bfa6699e54b069e300af5e4246b34a34chrismair    /* TODO: Mask values are a guess */
83    switch (type) {
84    case psb_bt_cpu_vpu:
85        allignment = 1;
86        placement = DRM_PSB_FLAG_MEM_MMU;
87        break;
88    case psb_bt_cpu_vpu_shared:
89        allignment = 1;
90        placement = DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_SHARED;
91        break;
92    case psb_bt_surface:
93        allignment = 0;
94        placement = DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_SHARED;
95        if (IS_CTP(driver_data))  /* CTP support cache snoop */
96            placement |= WSBM_PL_FLAG_CACHED;
97        break;
98    case psb_bt_surface_tt:
99        allignment = 0;
100        placement = WSBM_PL_FLAG_TT | WSBM_PL_FLAG_NO_EVICT | WSBM_PL_FLAG_SHARED;
101        break;
102#ifdef PSBVIDEO_MSVDX_DEC_TILING
103    case psb_bt_surface_tiling:
104            drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate tiled surface from TT heap\n");
105            placement =  WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED;
106            allignment = 2048 * 16; /* Tiled row aligned */
107        break;
108    case psb_bt_mmu_tiling:
109            placement =  DRM_PSB_FLAG_MEM_MMU_TILING | WSBM_PL_FLAG_SHARED;
110            allignment = 2048 * 16; /* Tiled row aligned */
111        break;
112#endif
113    case psb_bt_cpu_vpu_cached:
114        allignment = 1;
115        placement = DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_CACHED;
116        break;
117    case psb_bt_vpu_only:
118        allignment = 1;
119        placement = DRM_PSB_FLAG_MEM_MMU;
120        break;
121    case psb_bt_cpu_only:
122        allignment = 1;
123        placement = WSBM_PL_FLAG_SYSTEM | WSBM_PL_FLAG_CACHED;
124        break;
125#if PSB_MFLD_DUMMY_CODE
126    case psb_bt_camera:
127        allignment = 1;
128        placement = WSBM_PL_FLAG_SHARED;
129        break;
130#endif
131#ifdef ANDROID
132#ifndef BAYTRAIL
133    case psb_bt_imr:
134        allignment = 1;
135        placement = TTM_PL_FLAG_IMR | WSBM_PL_FLAG_SHARED;
136        break;
137#endif
138#endif
139    default:
140        vaStatus = VA_STATUS_ERROR_UNKNOWN;
141        DEBUG_FAILURE;
142        return vaStatus;
143    }
144    ret = LOCK_HARDWARE(driver_data);
145    if (ret) {
146        UNLOCK_HARDWARE(driver_data);
147        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
148        DEBUG_FAILURE_RET;
149        return vaStatus;
150    }
151
152#ifdef VA_EMULATOR
153    placement |= WSBM_PL_FLAG_SHARED;
154#endif
155
156#ifndef ANDROID
157    if(!(placement & WSBM_PL_FLAG_SYSTEM)) {
158        //drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: buffer->pl_flags 0x%08x\n", __func__, placement);
159        placement &= ~WSBM_PL_MASK_MEM;
160        placement &= ~WSBM_PL_FLAG_NO_EVICT;
161        placement |= TTM_PL_FLAG_VRAM;
162        //drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: repleace buffer->pl_flags 0x%08x\n", __func__, placement);
163    }
164#endif
165
166#ifdef MSVDX_VA_EMULATOR
167    placement |= WSBM_PL_FLAG_SHARED;
168#endif
169
170    if(allignment < 4096)
171        allignment = 4096; /* temporily more safe */
172
173    //drv_debug_msg(VIDEO_DEBUG_ERROR, "FIXME: should use geetpagesize() ?\n");
174    ret = wsbmGenBuffers(driver_data->main_pool, 1, &buf->drm_buf,
175                         allignment, placement);
176    if (!buf->drm_buf) {
177        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
178        UNLOCK_HARDWARE(driver_data);
179        return VA_STATUS_ERROR_ALLOCATION_FAILED;
180    }
181
182    /* here use the placement when gen buffer setted */
183    ret = wsbmBOData(buf->drm_buf, size, NULL, NULL, 0);
184    UNLOCK_HARDWARE(driver_data);
185    if (ret) {
186        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc wsbm buffers\n");
187        return VA_STATUS_ERROR_ALLOCATION_FAILED;
188    }
189
190    if (placement & WSBM_PL_FLAG_TT)
191        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create BO with TT placement (%d byte),BO GPU offset hint=0x%08x\n",
192                                 size, wsbmBOOffsetHint(buf->drm_buf));
193
194    buf->pl_flags = placement;
195    buf->status = psb_bs_ready;
196    buf->wsbm_synccpu_flag = 0;
197
198    return VA_STATUS_SUCCESS;
199}
200
201/*
202 * Create buffer
203 */
204VAStatus psb_buffer_create_from_ub(psb_driver_data_p driver_data,
205                           unsigned int size,
206                           psb_buffer_type_t type,
207                           psb_buffer_p buf,
208                           void * vaddr,
209                           int fd,
210                           unsigned int flags
211                          )
212{
213    VAStatus vaStatus = VA_STATUS_SUCCESS;
214    int allignment;
215    uint32_t placement;
216    int ret;
217
218    /* reset rar_handle to NULL */
219    buf->rar_handle = 0;
220    buf->buffer_ofs = 0;
221
222    buf->type = type;
223    buf->driver_data = driver_data; /* only for RAR buffers */
224    buf->user_ptr = vaddr;
225    buf->fd = fd;
226
227    /* Xvideo will share surface buffer, set SHARED flag
228    */
229    placement =  DRM_PSB_FLAG_MEM_MMU | WSBM_PL_FLAG_SHARED ;
230
231    ret = LOCK_HARDWARE(driver_data);
232    if (ret) {
233        UNLOCK_HARDWARE(driver_data);
234        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
235        DEBUG_FAILURE_RET;
236        return vaStatus;
237    }
238
239    allignment = 4096; /* temporily more safe */
240#ifdef PSBVIDEO_MSVDX_DEC_TILING
241    if (type == psb_bt_mmu_tiling) {
242        placement =  DRM_PSB_FLAG_MEM_MMU_TILING | WSBM_PL_FLAG_SHARED ;
243        allignment = 2048 * 16; /* Tiled row aligned */
244    }
245#endif
246
247    if (flags & PSB_USER_BUFFER_WC)
248	placement |= WSBM_PL_FLAG_WC;
249    else if (flags & PSB_USER_BUFFER_UNCACHED)
250	placement |= WSBM_PL_FLAG_UNCACHED;
251    else
252	placement |= WSBM_PL_FLAG_CACHED;
253
254    //drv_debug_msg(VIDEO_DEBUG_ERROR, "FIXME: should use geetpagesize() ?\n");
255    ret = wsbmGenBuffers(driver_data->main_pool, 1, &buf->drm_buf,
256    allignment, placement);
257    if (!buf->drm_buf) {
258        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
259        UNLOCK_HARDWARE(driver_data);
260        return VA_STATUS_ERROR_ALLOCATION_FAILED;
261    }
262
263    /* here use the placement when gen buffer setted */
264    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create BO from user buffer %p, size=%d, fd = %d\n", vaddr, size, fd);
265
266    ret = wsbmBODataUB(buf->drm_buf, size, NULL, NULL, 0, vaddr, fd);
267    if (ret) {
268        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to alloc wsbm buffers, buf->drm_buf is 0x%x, size is %d, vaddr is 0x%x, fd=%d\n", buf->drm_buf, size, vaddr, fd);
269        return 1;
270    }
271
272    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Create BO from user buffer 0x%08x (%d byte), fd=%d, BO GPU offset hint=0x%08x\n",
273    vaddr, size, fd, wsbmBOOffsetHint(buf->drm_buf));
274
275    buf->pl_flags = placement;
276    buf->status = psb_bs_ready;
277    buf->wsbm_synccpu_flag = 0;
278
279    return VA_STATUS_SUCCESS;
280}
281
282#if 0
283/*
284 * buffer setstatus
285 *
286 * Returns 0 on success
287 */
288int psb_buffer_setstatus(psb_buffer_p buf, uint32_t set_placement, uint32_t clr_placement)
289{
290    int ret = 0;
291
292    ASSERT(buf);
293    ASSERT(buf->driver_data);
294
295    ret = wsbmBOSetStatus(buf->drm_buf, set_placement, clr_placement);
296    if (ret == 0)
297        buf->pl_flags = set_placement;
298
299    return ret;
300}
301#endif
302
303VAStatus psb_buffer_reference(psb_driver_data_p driver_data,
304                              psb_buffer_p buf,
305                              psb_buffer_p reference_buf
306                             )
307{
308    int ret = 0;
309    VAStatus vaStatus = VA_STATUS_SUCCESS;
310
311    memcpy(buf, reference_buf, sizeof(*buf));
312    buf->drm_buf = NULL;
313
314    ret = LOCK_HARDWARE(driver_data);
315    if (ret) {
316        UNLOCK_HARDWARE(driver_data);
317        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
318        DEBUG_FAILURE_RET;
319        return vaStatus;
320    }
321
322    ret = wsbmGenBuffers(driver_data->main_pool,
323                         1,
324                         &buf->drm_buf,
325                         4096,  /* page alignment */
326                         0);
327    if (!buf->drm_buf) {
328        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
329        UNLOCK_HARDWARE(driver_data);
330        return VA_STATUS_ERROR_ALLOCATION_FAILED;
331    }
332
333    ret = wsbmBOSetReferenced(buf->drm_buf, wsbmKBufHandle(wsbmKBuf(reference_buf->drm_buf)));
334    UNLOCK_HARDWARE(driver_data);
335    if (ret) {
336        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc wsbm buffers\n");
337        return VA_STATUS_ERROR_ALLOCATION_FAILED;
338    }
339
340    return VA_STATUS_SUCCESS;
341}
342
343VAStatus psb_kbuffer_reference(psb_driver_data_p driver_data,
344                               psb_buffer_p buf,
345                               int kbuf_handle
346                              )
347{
348    int ret = 0;
349    VAStatus vaStatus = VA_STATUS_SUCCESS;
350
351    buf->drm_buf = NULL;
352
353    ret = LOCK_HARDWARE(driver_data);
354    if (ret) {
355        UNLOCK_HARDWARE(driver_data);
356        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
357        DEBUG_FAILURE_RET;
358        return vaStatus;
359    }
360
361    ret = wsbmGenBuffers(driver_data->main_pool,
362                         1,
363                         &buf->drm_buf,
364                         4096,  /* page alignment */
365                         0);
366    if (!buf->drm_buf) {
367        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to gen wsbm buffers\n");
368        UNLOCK_HARDWARE(driver_data);
369        return VA_STATUS_ERROR_ALLOCATION_FAILED;
370    }
371
372    ret = wsbmBOSetReferenced(buf->drm_buf, kbuf_handle);
373    UNLOCK_HARDWARE(driver_data);
374    if (ret) {
375        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc wsbm buffers\n");
376        return VA_STATUS_ERROR_ALLOCATION_FAILED;
377    }
378    buf->pl_flags = wsbmBOPlacementHint(buf->drm_buf);
379    buf->type = psb_bt_surface;
380    buf->status = psb_bs_ready;
381
382    return VA_STATUS_SUCCESS;
383}
384/*
385 * Destroy buffer
386 */
387void psb_buffer_destroy(psb_buffer_p buf)
388{
389    ASSERT(buf);
390    if (buf->drm_buf == NULL)
391        return;
392    if (psb_bs_unfinished != buf->status) {
393        ASSERT(buf->driver_data);
394        wsbmBOUnreference(&buf->drm_buf);
395        if (buf->rar_handle)
396            buf->rar_handle = 0;
397        buf->driver_data = NULL;
398        buf->status = psb_bs_unfinished;
399    }
400}
401
402/*
403 * Map buffer
404 *
405 * Returns 0 on success
406 */
407int psb_buffer_map(psb_buffer_p buf, unsigned char **address /* out */)
408{
409    int ret;
410
411    ASSERT(buf);
412    ASSERT(buf->driver_data);
413
414    /* multiple mapping not allowed */
415    if (buf->wsbm_synccpu_flag) {
416        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Multiple mapping request detected, unmap previous mapping\n");
417        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Need to fix application to unmap at first, then request second mapping request\n");
418
419        psb_buffer_unmap(buf);
420    }
421
422    /* don't think TG deal with READ/WRITE differently */
423    buf->wsbm_synccpu_flag = WSBM_SYNCCPU_READ | WSBM_SYNCCPU_WRITE;
424    if (psb_video_trace_fp) {
425        wsbmBOWaitIdle(buf->drm_buf, 0);
426    } else {
427        ret = wsbmBOSyncForCpu(buf->drm_buf, buf->wsbm_synccpu_flag);
428        if (ret) {
429            drv_debug_msg(VIDEO_DEBUG_ERROR, "faild to sync bo for cpu\n");
430            return ret;
431        }
432    }
433
434    if (buf->user_ptr) /* user mode buffer */
435        *address = buf->user_ptr;
436    else
437        *address = wsbmBOMap(buf->drm_buf, buf->wsbm_synccpu_flag);
438
439    if (*address == NULL) {
440        drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to map buffer\n");
441        return -1;
442    }
443
444    return 0;
445}
446
447/*
448 * Unmap buffer
449 *
450 * Returns 0 on success
451 */
452int psb_buffer_unmap(psb_buffer_p buf)
453{
454    ASSERT(buf);
455    ASSERT(buf->driver_data);
456
457    if (buf->wsbm_synccpu_flag)
458        (void) wsbmBOReleaseFromCpu(buf->drm_buf, buf->wsbm_synccpu_flag);
459
460    buf->wsbm_synccpu_flag = 0;
461
462    if ((buf->type != psb_bt_user_buffer) && !buf->handle)
463        wsbmBOUnmap(buf->drm_buf);
464
465    return 0;
466}
467
468#define _MRFL_DEBUG_CODED_
469
470#ifdef _MRFL_DEBUG_CODED_
471static void psb__trace_coded(VACodedBufferSegment *vaCodedBufSeg)
472{
473    int i, j;
474    int uiPipeIndex = -1;
475    unsigned int *pBuf = NULL;
476    do {
477        ++uiPipeIndex;
478        drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: pipe num %d, size = %d\n", __FUNCTION__, uiPipeIndex, vaCodedBufSeg[uiPipeIndex].size);
479        pBuf = (unsigned int *)(vaCodedBufSeg[uiPipeIndex].buf);
480        pBuf -= 16;
481        for (i = 0; i < 6; i++) {
482            for (j = 0; j < 4; j++) {
483                drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: 0x%08x\n", __FUNCTION__, pBuf[(i*4) + j]);
484            }
485         }
486        drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: \n", __FUNCTION__);
487    } while (vaCodedBufSeg[uiPipeIndex].next);
488
489	return ;
490}
491#endif
492
493#define PROFILE_H264(profile) ((profile>=VAProfileH264Baseline && profile <=VAProfileH264High) || \
494                               (profile == VAProfileH264ConstrainedBaseline))
495static void tng_get_coded_data(
496    object_buffer_p obj_buffer,
497    unsigned char *raw_codedbuf
498)
499{
500    object_context_p obj_context = obj_buffer->context;
501    VACodedBufferSegment *vaCodedBufSeg = &obj_buffer->codedbuf_mapinfo[0];
502    int iPipeIndex = 0;
503    unsigned int uiPipeNum = tng_get_pipe_number(obj_context);
504    unsigned int uiBufOffset = tng_align_KB(obj_buffer->size >> 1);
505    unsigned long *ptmp = NULL;
506    int tmp;
507
508    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s pipenum = 0x%x\n", __FUNCTION__, uiPipeNum);
509    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s offset  = 0x%x\n", __FUNCTION__, uiBufOffset);
510
511    tmp = vaCodedBufSeg[iPipeIndex].size = *(unsigned int *)((unsigned long)raw_codedbuf);
512
513    /*
514     * This is used for DRM over WiDi which only uses H264 BP
515     * Tangier IED encryption operates on the chunks with 16bytes, and we must include
516     * the extra bytes beyond slice data as a whole chunk for decrption
517     * We simply include the padding bytes regardless of IED enable or disable
518     */
519    if (PROFILE_H264(obj_context->profile) && (tmp % 16 != 0)) {
520	tmp = (tmp + 15) & (~15);
521	drv_debug_msg(VIDEO_DEBUG_GENERAL, "Force slice size from %d to %d\n",
522                      vaCodedBufSeg[iPipeIndex].size, tmp);
523	vaCodedBufSeg[iPipeIndex].size  = tmp;
524    }
525
526    vaCodedBufSeg[iPipeIndex].buf = (unsigned char *)(((unsigned int *)((unsigned long)raw_codedbuf)) + 16); /* skip 4DWs */
527
528    ptmp = (unsigned long *)((unsigned long)raw_codedbuf);
529    vaCodedBufSeg[iPipeIndex].reserved = (ptmp[1] >> 6) & 0xf;
530    vaCodedBufSeg[iPipeIndex].next = NULL;
531
532
533    if (uiPipeNum == 2) {
534        /*The second part of coded buffer which generated by core 2 is the
535         * first part of encoded clip, while the first part of coded buffer
536         * is the second part of encoded clip.*/
537        ++iPipeIndex;
538        vaCodedBufSeg[iPipeIndex - 1].next = &vaCodedBufSeg[iPipeIndex];
539        tmp = vaCodedBufSeg[iPipeIndex].size = *(unsigned int *)((unsigned long)raw_codedbuf + uiBufOffset);
540
541        /*
542         * This is used for DRM over WiDi which only uses H264 BP
543         * Tangier IED encryption operates on the chunks with 16bytes, and we must include
544         * the extra bytes beyond slice data as a whole chunk for decryption
545         * We simply include the padding bytes regardless of IED enable or disable
546         */
547        if (PROFILE_H264(obj_context->profile) && (tmp % 16 != 0)) {
548            tmp = (tmp + 15) & (~15);
549            drv_debug_msg(VIDEO_DEBUG_GENERAL,"Force slice size from %d to %d\n",
550                          vaCodedBufSeg[iPipeIndex].size, tmp);
551
552            vaCodedBufSeg[iPipeIndex].size  = tmp;
553        }
554
555        vaCodedBufSeg[iPipeIndex].buf = (unsigned char *)(((unsigned int *)((unsigned long)raw_codedbuf + uiBufOffset)) + 16); /* skip 4DWs */
556        vaCodedBufSeg[iPipeIndex].reserved = vaCodedBufSeg[iPipeIndex - 1].reserved;
557        vaCodedBufSeg[iPipeIndex].next = NULL;
558    }
559
560#ifdef _MRFL_DEBUG_CODED_
561    psb__trace_coded(vaCodedBufSeg);
562#endif
563
564    return ;
565}
566
567/*
568 * Return special data structure for codedbuffer
569 *
570 * Returns 0 on success
571 */
572#define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
573#define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
574int psb_codedbuf_map_mangle(
575    VADriverContextP ctx,
576    object_buffer_p obj_buffer,
577    void **pbuf /* out */
578)
579{
580    object_context_p obj_context = obj_buffer->context;
581    INIT_DRIVER_DATA;
582    VACodedBufferSegment *p = &obj_buffer->codedbuf_mapinfo[0];
583    unsigned char *raw_codedbuf;
584    VAStatus vaStatus = VA_STATUS_SUCCESS;
585    unsigned int next_buf_off;
586    uint32_t i;
587
588    CHECK_INVALID_PARAM(pbuf == NULL);
589
590    if (NULL == obj_context) {
591        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
592        DEBUG_FAILURE;
593
594        psb_buffer_unmap(obj_buffer->psb_buffer);
595        obj_buffer->buffer_data = NULL;
596
597        return vaStatus;
598    }
599
600    raw_codedbuf = *pbuf;
601    /* reset the mapinfo */
602    memset(obj_buffer->codedbuf_mapinfo, 0, sizeof(obj_buffer->codedbuf_mapinfo));
603
604    *pbuf = p = &obj_buffer->codedbuf_mapinfo[0];
605#ifdef PSBVIDEO_MRFL
606    if (IS_MRFL(driver_data)) {
607        object_config_p obj_config = CONFIG(obj_context->config_id);
608        if (NULL == obj_config) {
609            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
610            DEBUG_FAILURE;
611
612            psb_buffer_unmap(obj_buffer->psb_buffer);
613            obj_buffer->buffer_data = NULL;
614
615            return vaStatus;
616        }
617
618        if (VAProfileJPEGBaseline != obj_config->profile
619            && (*((unsigned long *) raw_codedbuf + 1) & SKIP_NEXT_FRAME) != 0) {
620            /*Set frame skip flag*/
621            tng_set_frame_skip_flag(obj_context);
622        }
623        switch (obj_config->profile) {
624            case VAProfileMPEG4Simple:
625            case VAProfileMPEG4AdvancedSimple:
626            case VAProfileMPEG4Main:
627
628            case VAProfileH264Baseline:
629            case VAProfileH264Main:
630            case VAProfileH264High:
631            case VAProfileH264StereoHigh:
632            case VAProfileH264ConstrainedBaseline:
633            case VAProfileH263Baseline:
634                /* 1st segment */
635                tng_get_coded_data(obj_buffer, raw_codedbuf);
636#if 0
637                p->size = *((unsigned long *) raw_codedbuf);
638                p->buf = (unsigned char *)((unsigned long *) raw_codedbuf + 16); /* skip 16DWs */
639                p->next = NULL;
640#ifdef _MRFL_DEBUG_CODED_
641                psb__trace_coded((unsigned int*)raw_codedbuf);
642                psb__trace_coded(p);
643#endif
644#endif
645                break;
646            case VAProfileVP8Version0_3:
647            {
648                /* multi segments*/
649		struct VssVp8encEncodedFrame *t = (struct VssVp8encEncodedFrame *) (raw_codedbuf);
650		int concatenate = 1;
651#if 0
652		for (i = 0; i < t->partitions - 1; i++) {
653                    if (t->partition_start[i+1] != t->partition_start[i] + t->partition_size[i])
654                        concatenate = 0;
655		}
656#endif
657		/* reference frame surface_id */
658                /* default is recon_buffer_mode ==0 */
659                p->reserved = t->surfaceId_of_ref_frame[3];
660
661		if (concatenate) {
662                    /* partitions are concatenate */
663                    p->buf = t->coded_data;
664                    p->size = t->frame_size;
665                    if(t->frame_size == 0){
666                        drv_debug_msg(VIDEO_DEBUG_ERROR,"Frame size is zero, Force it to 3, encoder status is 0x%x\n", t->status);
667                        p->size = 3;
668                        t->coded_data[0]=0;
669                    }
670                    p->next = NULL;
671		} else {
672                    for (i = 0; i < t->partitions; i++) {
673                        /* partition not consecutive */
674                        p->buf = t->coded_data + t->partition_start[i] - t->partition_start[0];
675                        p->size += t->partition_size[i];
676                        p->next = &p[1];
677                        p++;
678		    }
679		    p--;
680		    p->next = NULL;
681		}
682
683		break;
684            }
685            case VAProfileJPEGBaseline:
686                /* 3~6 segment */
687                tng_jpeg_AppendMarkers(obj_context, raw_codedbuf);
688                next_buf_off = 0;
689                /*Max resolution 4096x4096 use 6 segments*/
690                for (i = 0; i < PTG_JPEG_MAX_SCAN_NUM + 1; i++) {
691                    p->size = *(unsigned long *)((unsigned long)raw_codedbuf + next_buf_off);  /* ui32BytesUsed in HEADER_BUFFER*/
692                    p->buf = (unsigned char *)((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 4);  /* skip 4DWs (HEADER_BUFFER) */
693                    next_buf_off = *((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 3);  /* ui32Reserved3 in HEADER_BUFFER*/
694
695                    drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer segment %d size: %d\n", i, p->size);
696                    drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer next segment %d offset: %d\n", i + 1, next_buf_off);
697
698                    if (next_buf_off == 0) {
699                        p->next = NULL;
700                        break;
701                    } else
702                        p->next = &p[1];
703                    p++;
704                }
705                break;
706
707            default:
708                drv_debug_msg(VIDEO_DEBUG_ERROR, "unexpected case\n");
709
710                psb_buffer_unmap(obj_buffer->psb_buffer);
711                obj_buffer->buffer_data = NULL;
712                break;
713        }
714    }
715#endif
716#ifdef PSBVIDEO_MFLD
717    if (IS_MFLD(driver_data)){ /* MFLD */
718        object_config_p obj_config = CONFIG(obj_context->config_id);
719
720        if (NULL == obj_config) {
721            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
722            DEBUG_FAILURE;
723
724            psb_buffer_unmap(obj_buffer->psb_buffer);
725            obj_buffer->buffer_data = NULL;
726
727            return vaStatus;
728        }
729
730        if (VAProfileJPEGBaseline != obj_config->profile
731            && (*((unsigned long *) raw_codedbuf + 1) & SKIP_NEXT_FRAME) != 0) {
732            /*Set frame skip flag*/
733            pnw_set_frame_skip_flag(obj_context);
734        }
735        switch (obj_config->profile) {
736        case VAProfileMPEG4Simple:
737        case VAProfileMPEG4AdvancedSimple:
738        case VAProfileMPEG4Main:
739            /* one segment */
740            p->size = *((unsigned long *) raw_codedbuf);
741            p->buf = (unsigned char *)((unsigned long *) raw_codedbuf + 4); /* skip 4DWs */
742            drv_debug_msg(VIDEO_DEBUG_GENERAL, "coded buffer size %d\n", p->size);
743            break;
744
745        case VAProfileH264Baseline:
746        case VAProfileH264Main:
747        case VAProfileH264High:
748        case VAProfileH264ConstrainedBaseline:
749            i = 0;
750            next_buf_off = ~0xf & (obj_buffer->size / pnw_get_parallel_core_number(obj_context));
751            if (pnw_get_parallel_core_number(obj_context) == 2) {
752                /*The second part of coded buffer which generated by core 2 is the
753                 * first part of encoded clip, while the first part of coded buffer
754                 * is the second part of encoded clip.*/
755                p[i].next = &p[i + 1];
756                p[i].size = *(unsigned long *)((unsigned long)raw_codedbuf + next_buf_off);
757                p[i].buf = (unsigned char *)(((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off)) + 4); /* skip 4DWs */
758
759                if (GET_CODEDBUF_INFO(SLICE_NUM, obj_buffer->codedbuf_aux_info) <= 2 &&
760                        GET_CODEDBUF_INFO(NONE_VCL_NUM, obj_buffer->codedbuf_aux_info) == 0) {
761                    p[i].status =  VA_CODED_BUF_STATUS_SINGLE_NALU;
762                    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Only VCL NAL in this segment %i of coded buffer\n",
763                            i);
764                }
765                drv_debug_msg(VIDEO_DEBUG_GENERAL, "2nd segment coded buffer offset: 0x%08x,  size: %d\n",
766                        next_buf_off, p[i].size);
767
768              i++;
769
770            }
771            /* 1st segment */
772            p[i].size = *((unsigned long *) raw_codedbuf);
773            p[i].buf = (unsigned char *)((unsigned long *) raw_codedbuf + 4); /* skip 4DWs */
774            drv_debug_msg(VIDEO_DEBUG_GENERAL, "1st segment coded buffer size %d\n", p[i].size);
775            if (GET_CODEDBUF_INFO(SLICE_NUM, obj_buffer->codedbuf_aux_info) <= 2 &&
776                    GET_CODEDBUF_INFO(NONE_VCL_NUM, obj_buffer->codedbuf_aux_info) == 0) {
777                p[i].status =  VA_CODED_BUF_STATUS_SINGLE_NALU;
778                drv_debug_msg(VIDEO_DEBUG_GENERAL, "Only VCL NAL in this segment %i of coded buffer\n",
779                        i);
780            }
781            for (i = 0; i < pnw_get_parallel_core_number(obj_context); i++) {
782                if (p[i].size > (next_buf_off - sizeof(unsigned long) * 4)) {
783                    drv_debug_msg(VIDEO_DEBUG_ERROR, "Coded segment %d is too large(%d)"
784                            " and exceed segment boundary(offset %d)", i, p[i].size, next_buf_off);
785                    p[i].size = next_buf_off - sizeof(unsigned long) * 4;
786                }
787            }
788
789            break;
790
791        case VAProfileH263Baseline:
792                /* one segment */
793            p->size = *((unsigned long *) raw_codedbuf);
794            p->buf = (unsigned char *)((unsigned long *) raw_codedbuf + 4); /* skip 4DWs */
795            drv_debug_msg(VIDEO_DEBUG_GENERAL, "coded buffer size %d\n", p->size);
796            break;
797
798        case VAProfileJPEGBaseline:
799            /* 3~6 segment
800                 */
801            pnw_jpeg_AppendMarkers(obj_context, raw_codedbuf);
802            next_buf_off = 0;
803            /*Max resolution 4096x4096 use 6 segments*/
804            for (i = 0; i < PNW_JPEG_MAX_SCAN_NUM + 1; i++) {
805                p->size = *(unsigned long *)((unsigned long)raw_codedbuf + next_buf_off);
806                p->buf = (unsigned char *)((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 4);  /* skip 4DWs */
807                next_buf_off = *((unsigned long *)((unsigned long)raw_codedbuf + next_buf_off) + 3);
808
809                drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer segment %d size: %d\n", i, p->size);
810                drv_debug_msg(VIDEO_DEBUG_GENERAL, "JPEG coded buffer next segment %d offset: %d\n", i + 1, next_buf_off);
811
812                if (next_buf_off == 0) {
813                    p->next = NULL;
814                    break;
815                } else
816                    p->next = &p[1];
817                p++;
818            }
819            break;
820
821        default:
822            drv_debug_msg(VIDEO_DEBUG_ERROR, "unexpected case\n");
823
824            psb_buffer_unmap(obj_buffer->psb_buffer);
825            obj_buffer->buffer_data = NULL;
826            break;
827        }
828    }
829#endif
830
831    return 0;
832}
833
834