129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Copyright (C) 2008 The Android Open Source Project
39ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R * Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved.
49ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R *
59ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R * Not a Contribution, Apache license notifications and license are retained
69ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R * for attribution purposes only.
729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * you may not use this file except in compliance with the License.
1029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * You may obtain a copy of the License at
1129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
1229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
1329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
1429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Unless required by applicable law or agreed to in writing, software
1529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
1629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * See the License for the specific language governing permissions and
1829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * limitations under the License.
1929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
2029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <cutils/log.h>
2229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <linux/msm_mdp.h>
2429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <linux/fb.h>
2529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <stdint.h>
2729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <string.h>
2829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <unistd.h>
2929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <errno.h>
3029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <fcntl.h>
3129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <sys/ioctl.h>
3329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <sys/types.h>
3429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <sys/mman.h>
3529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <copybit.h>
3729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "gralloc_priv.h"
3929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "software_converter.h"
4029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define DEBUG_MDP_ERRORS 1
4229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/******************************************************************************/
4429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define MAX_SCALE_FACTOR    (4)
4629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define MAX_DIMENSION       (4096)
4729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/******************************************************************************/
4910a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampsonstruct blitReq{
5010a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    struct  mdp_buf_sync sync;
5110a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    uint32_t count;
5210a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    struct mdp_blit_req req[10];
5310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson};
5429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** State information for each device instance */
5629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstruct copybit_context_t {
5729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t device;
5829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int     mFD;
5929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    uint8_t mAlpha;
6029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int     mFlags;
6131da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed    bool    mBlitToFB;
6210a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    int     acqFence[MDP_MAX_FENCE_FD];
6310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    int     relFence;
6410a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    struct  mdp_buf_sync sync;
6510a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    struct  blitReq list;
6629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
6729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/**
6929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Common hardware methods
7029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
7129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
7329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        struct hw_device_t** device);
7429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic struct hw_module_methods_t copybit_module_methods = {
7629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedopen:  open_copybit
7729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
7829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
8029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * The COPYBIT Module
8129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
8229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstruct copybit_module_t HAL_MODULE_INFO_SYM = {
8329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedcommon: {
8429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedtag: HARDWARE_MODULE_TAG,
8529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     version_major: 1,
8629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     version_minor: 0,
8729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     id: COPYBIT_HARDWARE_MODULE_ID,
8829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     name: "QCT MSM7K COPYBIT Module",
8929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     author: "Google, Inc.",
9029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     methods: &copybit_module_methods
9129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
9229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
9329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
9429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/******************************************************************************/
9529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
9629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** min of int a, b */
9729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic inline int min(int a, int b) {
9829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return (a<b) ? a : b;
9929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
10029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
10129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** max of int a, b */
10229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic inline int max(int a, int b) {
10329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return (a>b) ? a : b;
10429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
10529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
10629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** scale each parameter by mul/div. Assume div isn't 0 */
10729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic inline void MULDIV(uint32_t *a, uint32_t *b, int mul, int div) {
10829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (mul != div) {
10929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        *a = (mul * *a) / div;
11029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        *b = (mul * *b) / div;
11129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
11229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
11329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
11429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Determine the intersection of lhs & rhs store in out */
11529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void intersect(struct copybit_rect_t *out,
11629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *lhs,
11729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *rhs) {
11829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->l = max(lhs->l, rhs->l);
11929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->t = max(lhs->t, rhs->t);
12029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->r = min(lhs->r, rhs->r);
12129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->b = min(lhs->b, rhs->b);
12229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
12329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
12429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** convert COPYBIT_FORMAT to MDP format */
12529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get_format(int format) {
12629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch (format) {
12729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:       return MDP_RGB_565;
12829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:     return MDP_RGBX_8888;
12929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGB_888:       return MDP_RGB_888;
13029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:     return MDP_RGBA_8888;
13129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_BGRA_8888:     return MDP_BGRA_8888;
1328b68763922271a460cbfdeb36d845404756c105bRaj kamal        case HAL_PIXEL_FORMAT_YCrCb_422_SP:  return MDP_Y_CRCB_H2V1;
1338b68763922271a460cbfdeb36d845404756c105bRaj kamal        case HAL_PIXEL_FORMAT_YCrCb_420_SP:  return MDP_Y_CRCB_H2V2;
1348b68763922271a460cbfdeb36d845404756c105bRaj kamal        case HAL_PIXEL_FORMAT_YCbCr_422_SP:  return MDP_Y_CBCR_H2V1;
1358b68763922271a460cbfdeb36d845404756c105bRaj kamal        case HAL_PIXEL_FORMAT_YCbCr_420_SP:  return MDP_Y_CBCR_H2V2;
13629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
1370ab081c1c95f7394ce5a352900da6d61e513a724Radhika Ranjan Soni        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: return MDP_Y_CBCR_H2V2_VENUS;
1389ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2;
13929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
14029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return -1;
14129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
14229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
14329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** convert from copybit image to mdp image structure */
14429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void set_image(struct mdp_img *img, const struct copybit_image_t *rhs)
14529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
14629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t* hnd = (private_handle_t*)rhs->handle;
14729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(hnd == NULL){
14829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("copybit: Invalid handle");
14929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return;
15029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
15129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->width      = rhs->w;
15229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->height     = rhs->h;
15329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->format     = get_format(rhs->format);
15429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->offset     = hnd->offset;
15529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->memory_id  = hnd->fd;
15629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
15729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** setup rectangles */
15829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void set_rects(struct copybit_context_t *dev,
15929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      struct mdp_blit_req *e,
16029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *dst,
16129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *src,
16229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *scissor,
16329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      uint32_t horiz_padding,
16429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      uint32_t vert_padding) {
16529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t clip;
16629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    intersect(&clip, scissor, dst);
16729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
16829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.x  = clip.l;
16929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.y  = clip.t;
17029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.w  = clip.r - clip.l;
17129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.h  = clip.b - clip.t;
17229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
17329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    uint32_t W, H, delta_x, delta_y;
17429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
17529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_x = (clip.t - dst->t);
17629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_y = (dst->r - clip.r);
17729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.w = (clip.b - clip.t);
17829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.h = (clip.r - clip.l);
17929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        W = dst->b - dst->t;
18029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        H = dst->r - dst->l;
18129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
18229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_x  = (clip.l - dst->l);
18329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_y  = (clip.t - dst->t);
18429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.w  = (clip.r - clip.l);
18529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.h  = (clip.b - clip.t);
18629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        W = dst->r - dst->l;
18729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        H = dst->b - dst->t;
18829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
18929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
19029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    MULDIV(&delta_x, &e->src_rect.w, src->r - src->l, W);
19129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    MULDIV(&delta_y, &e->src_rect.h, src->b - src->t, H);
19229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
19329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->src_rect.x = delta_x + src->l;
19429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->src_rect.y = delta_y + src->t;
19529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
19629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_V) {
19729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
19829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
19929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }else{
20029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
20129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
20229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
20329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
20429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_H) {
20529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
20629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
20729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }else{
20829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
20929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
21029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
21129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
21229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
21329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** setup mdp request */
21429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void set_infos(struct copybit_context_t *dev,
21529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      struct mdp_blit_req *req, int flags)
21629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
21729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->alpha = dev->mAlpha;
21829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->transp_mask = MDP_TRANSP_NOP;
21929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->flags = dev->mFlags | flags;
22031da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed    // check if we are blitting to f/b
22131da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed    if (COPYBIT_ENABLE == dev->mBlitToFB) {
22231da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed        req->flags |= MDP_MEMORY_ID_TYPE_FB;
22331da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed    }
22429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#if defined(COPYBIT_QSD8K)
22529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->flags |= MDP_BLEND_FG_PREMULT;
22629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#endif
22729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
22829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
22929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** copy the bits */
23029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int msm_copybit(struct copybit_context_t *dev, void const *list)
23129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
23210a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    int err = ioctl(dev->mFD, MSMFB_ASYNC_BLIT,
23310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson                    (struct mdp_async_blit_req_list const*)list);
23429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ALOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
23529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (err == 0) {
23629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return 0;
23729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
23829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#if DEBUG_MDP_ERRORS
23910a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson        struct mdp_async_blit_req_list const* l =
24010a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            (struct mdp_async_blit_req_list const*)list;
241b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed        for (unsigned int i=0 ; i<l->count ; i++) {
24229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%d: src={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
24329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  "    dst={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
244b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed                  "    flags=%08x"
24529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  ,
24629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  i,
24729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src.width,
24829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src.height,
24929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src.format,
25029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.x,
25129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.y,
25229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.w,
25329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.h,
25429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst.width,
25529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst.height,
25629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst.format,
25729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.x,
25829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.y,
25929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.w,
26029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.h,
26129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].flags
26229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                 );
26329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
26429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#endif
26529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -errno;
26629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
26729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
26829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
26929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*****************************************************************************/
27029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
27129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Set a parameter to value */
27229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int set_parameter_copybit(
27329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
27429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int name,
27529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int value)
27629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
27729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
27829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = 0;
27929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
28029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        switch(name) {
28129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_ROTATION_DEG:
28229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                switch (value) {
28329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 0:
28429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
28529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
28629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 90:
28729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
28829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags |= MDP_ROT_90;
28929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
29029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 180:
29129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
29229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags |= MDP_ROT_180;
29329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
29429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 270:
29529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
29629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags |= MDP_ROT_270;
29729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
29829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    default:
29929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ALOGE("Invalid value for COPYBIT_ROTATION_DEG");
30029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        status = -EINVAL;
30129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
30229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
30329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
30429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_PLANE_ALPHA:
30529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value < 0)      value = MDP_ALPHA_NOP;
30629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value >= 256)   value = 255;
30729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ctx->mAlpha = value;
30829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
30929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_DITHER:
31029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value == COPYBIT_ENABLE) {
31129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags |= MDP_DITHER;
31229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                } else if (value == COPYBIT_DISABLE) {
31329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags &= ~MDP_DITHER;
31429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
31529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
31629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_BLUR:
31729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value == COPYBIT_ENABLE) {
31829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags |= MDP_BLUR;
31929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                } else if (value == COPYBIT_DISABLE) {
32029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags &= ~MDP_BLUR;
32129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
32229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
3239ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            case COPYBIT_BLEND_MODE:
3249ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                if(value == COPYBIT_BLENDING_PREMULT) {
32529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags |= MDP_BLEND_FG_PREMULT;
3269ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                } else {
32729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags &= ~MDP_BLEND_FG_PREMULT;
32829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
32929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
33029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_TRANSFORM:
33129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ctx->mFlags &= ~0x7;
33229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ctx->mFlags |= value & 0x7;
33329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
33431da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed            case COPYBIT_BLIT_TO_FRAMEBUFFER:
33531da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                if (COPYBIT_ENABLE == value) {
33631da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                    ctx->mBlitToFB = value;
33731da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                } else if (COPYBIT_DISABLE == value) {
33831da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                    ctx->mBlitToFB = value;
33931da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                } else {
34031da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                    ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d",
34131da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                            __FUNCTION__, value);
34231da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                }
34331da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                break;
3447fedef6549adbbffe15188e96ac6a5de272de27eShivaraj Shetty            case COPYBIT_FG_LAYER:
3457fedef6549adbbffe15188e96ac6a5de272de27eShivaraj Shetty                if(value == COPYBIT_ENABLE) {
3467fedef6549adbbffe15188e96ac6a5de272de27eShivaraj Shetty                     ctx->mFlags |= MDP_IS_FG;
3477fedef6549adbbffe15188e96ac6a5de272de27eShivaraj Shetty                } else if (value == COPYBIT_DISABLE) {
3487fedef6549adbbffe15188e96ac6a5de272de27eShivaraj Shetty                    ctx->mFlags &= ~MDP_IS_FG;
3497fedef6549adbbffe15188e96ac6a5de272de27eShivaraj Shetty                }
3507fedef6549adbbffe15188e96ac6a5de272de27eShivaraj Shetty                break ;
35129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            default:
35229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                status = -EINVAL;
35329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
35429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
35529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
35629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = -EINVAL;
35729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
35829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
35929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
36029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
36129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Get a static info value */
36229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get(struct copybit_device_t *dev, int name)
36329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
36429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
36529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int value;
36629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
36729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        switch(name) {
36829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_MINIFICATION_LIMIT:
36929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = MAX_SCALE_FACTOR;
37029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
37129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_MAGNIFICATION_LIMIT:
37229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = MAX_SCALE_FACTOR;
37329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
37429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_SCALING_FRAC_BITS:
37529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = 32;
37629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
37729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_ROTATION_STEP_DEG:
37829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = 90;
37929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
38029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            default:
38129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = -EINVAL;
38229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
38329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
38429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        value = -EINVAL;
38529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
38629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return value;
38729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
38829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
38910a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampsonstatic int set_sync_copybit(struct copybit_device_t *dev,
39010a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    int acquireFenceFd)
39110a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson{
39210a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
39310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    if (acquireFenceFd != -1) {
3941c187f10a13479adfd719ead24eda6c1bb502795Terence Hampson        if (ctx->list.sync.acq_fen_fd_cnt < (MDP_MAX_FENCE_FD - 1)) {
3951c187f10a13479adfd719ead24eda6c1bb502795Terence Hampson            ctx->acqFence[ctx->list.sync.acq_fen_fd_cnt++] = acquireFenceFd;
39610a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson        } else {
39710a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            int ret = -EINVAL;
39810a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            struct blitReq *list = &ctx->list;
39910a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson
40010a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            // Since fence is full kick off what is already in the list
40110a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            ret = msm_copybit(ctx, list);
40210a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            if (ret < 0) {
40310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson                ALOGE("%s: Blit call failed", __FUNCTION__);
40410a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson                return -EINVAL;
40510a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            }
40610a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            list->count = 0;
4071c187f10a13479adfd719ead24eda6c1bb502795Terence Hampson            list->sync.acq_fen_fd_cnt = 0;
4081c187f10a13479adfd719ead24eda6c1bb502795Terence Hampson            ctx->acqFence[list->sync.acq_fen_fd_cnt++] = acquireFenceFd;
40910a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            ctx->relFence = -1;
41010a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson        }
41110a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    }
41210a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    return 0;
41310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson}
41410a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson
41529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** do a stretch blit type operation */
41629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int stretch_copybit(
41729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
41829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *dst,
41929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *src,
42029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t const *dst_rect,
42129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t const *src_rect,
42229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_region_t const *region)
42329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
42429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
42510a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    struct blitReq *list;
42629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = 0;
42729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t *yv12_handle = NULL;
42810a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson
42929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
43010a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson        list = &ctx->list;
43129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
43229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (ctx->mAlpha < 255) {
43329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            switch (src->format) {
43429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                // we don't support plane alpha with RGBA formats
43529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                case HAL_PIXEL_FORMAT_RGBA_8888:
43629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                case HAL_PIXEL_FORMAT_BGRA_8888:
43729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__,
43829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           src->format);
43929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    return -EINVAL;
44029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
44129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
44229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4439ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w ||
4449ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            src_rect->t < 0 || (uint32_t)src_rect->b > src->h) {
44529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            // this is always invalid
44629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\
44729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                   __FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b);
44829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
44929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return -EINVAL;
45029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
45129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
45229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
45329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h);
45429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return -EINVAL;
45529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
45629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
45729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
45829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h);
45929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return -EINVAL;
46029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
46129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
46229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if(src->format ==  HAL_PIXEL_FORMAT_YV12) {
4639ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            int usage =
464e67c709079b4da35667a3bbc5a00d54530a83a87Terence Hampson            GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED;
46529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
46629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                  src->format, usage)){
46729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){
46829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (const_cast<copybit_image_t *>(src))->format =
46929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        HAL_PIXEL_FORMAT_YCrCb_420_SP;
47029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (const_cast<copybit_image_t *>(src))->handle =
47129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        yv12_handle;
47229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (const_cast<copybit_image_t *>(src))->base =
47329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        (void *)yv12_handle->base;
47429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
47529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                else{
47629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ALOGE("Error copybit conversion from yv12 failed");
47729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    if(yv12_handle)
47829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        free_buffer(yv12_handle);
47929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    return -EINVAL;
48029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
48129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
48229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            else{
48329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("Error:unable to allocate memeory for yv12 software conversion");
48429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                return -EINVAL;
48529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
48629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
48710a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson        const uint32_t maxCount = sizeof(list->req)/sizeof(list->req[0]);
488b46eaaa52014d32f650fa50b6896fee179d9e721Dhivya Subramanian        const struct copybit_rect_t bounds = { 0, 0, (int)dst->w, (int)dst->h };
48929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct copybit_rect_t clip;
49029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = 0;
49129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        while ((status == 0) && region->next(region, &clip)) {
49229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            intersect(&clip, &bounds, &clip);
49310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            mdp_blit_req* req = &list->req[list->count];
49429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            int flags = 0;
49529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
49629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            private_handle_t* src_hnd = (private_handle_t*)src->handle;
49729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if(src_hnd != NULL && src_hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
49829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                flags |=  MDP_BLIT_NON_CACHED;
49929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
50029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
50129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_infos(ctx, req, flags);
50229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_image(&req->dst, dst);
50329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_image(&req->src, src);
50429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_rects(ctx, req, dst_rect, src_rect, &clip, src->horiz_padding, src->vert_padding);
50529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
50629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (req->src_rect.w<=0 || req->src_rect.h<=0)
50729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                continue;
50829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
50929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (req->dst_rect.w<=0 || req->dst_rect.h<=0)
51029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                continue;
51129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
51210a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            if (++list->count == maxCount) {
51310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson                status = msm_copybit(ctx, list);
51410a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson                if (ctx->relFence != -1) {
5151c187f10a13479adfd719ead24eda6c1bb502795Terence Hampson                    list->sync.acq_fen_fd_cnt = 0;
51610a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson                }
51710a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson                list->count = 0;
51829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
51929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
520c95c8f7c0a55bf2d6489bf3666d523def43496ecTerence Hampson        if(yv12_handle) {
521c95c8f7c0a55bf2d6489bf3666d523def43496ecTerence Hampson            //Before freeing the buffer we need buffer passed through blit call
522c95c8f7c0a55bf2d6489bf3666d523def43496ecTerence Hampson            if (list->count != 0) {
523c95c8f7c0a55bf2d6489bf3666d523def43496ecTerence Hampson                status = msm_copybit(ctx, list);
524c95c8f7c0a55bf2d6489bf3666d523def43496ecTerence Hampson                if (ctx->relFence != -1) {
5251c187f10a13479adfd719ead24eda6c1bb502795Terence Hampson                    list->sync.acq_fen_fd_cnt = 0;
526c95c8f7c0a55bf2d6489bf3666d523def43496ecTerence Hampson                }
527c95c8f7c0a55bf2d6489bf3666d523def43496ecTerence Hampson                list->count = 0;
528c95c8f7c0a55bf2d6489bf3666d523def43496ecTerence Hampson            }
529c95c8f7c0a55bf2d6489bf3666d523def43496ecTerence Hampson            free_buffer(yv12_handle);
530c95c8f7c0a55bf2d6489bf3666d523def43496ecTerence Hampson        }
53129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
53229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__);
53329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = -EINVAL;
53429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
53529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
53629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
53729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
53829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Perform a blit type operation */
53929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int blit_copybit(
54029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
54129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *dst,
54229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *src,
54329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_region_t const *region)
54429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
545b46eaaa52014d32f650fa50b6896fee179d9e721Dhivya Subramanian    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
546b46eaaa52014d32f650fa50b6896fee179d9e721Dhivya Subramanian    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
54729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return stretch_copybit(dev, dst, src, &dr, &sr, region);
54829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
54929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5509ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.Rstatic int finish_copybit(struct copybit_device_t *dev)
5519ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R{
5529ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // NOP for MDP copybit
553e67c709079b4da35667a3bbc5a00d54530a83a87Terence Hampson    return 0;
5549ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R}
5559ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
55629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*****************************************************************************/
55729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
55829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Close the copybit device */
55929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int close_copybit(struct hw_device_t *dev)
56029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
56129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
56229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
56329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        close(ctx->mFD);
56429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        free(ctx);
56529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
56629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
56729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
56829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
569e67c709079b4da35667a3bbc5a00d54530a83a87Terence Hampsonstatic int flush_get_fence(struct copybit_device_t *dev, int* fd)
570e67c709079b4da35667a3bbc5a00d54530a83a87Terence Hampson{
57110a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
57210a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    struct blitReq *list = &ctx->list;
57310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    int ret = -EINVAL;
57410a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson
57510a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    if (list->count) {
57610a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson        ret = msm_copybit(ctx, list);
57710a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson        if (ret < 0)
57810a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson            ALOGE("%s: Blit call failed", __FUNCTION__);
57910a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson        list->count = 0;
58010a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    }
58110a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    *fd = ctx->relFence;
5821c187f10a13479adfd719ead24eda6c1bb502795Terence Hampson    list->sync.acq_fen_fd_cnt = 0;
58310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    ctx->relFence = -1;
58410a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    return ret;
585e67c709079b4da35667a3bbc5a00d54530a83a87Terence Hampson}
586e67c709079b4da35667a3bbc5a00d54530a83a87Terence Hampson
58729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Open a new instance of a copybit device using name */
58829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
58929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        struct hw_device_t** device)
59029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
59129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = -EINVAL;
59229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    copybit_context_t *ctx;
59329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t));
59429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    memset(ctx, 0, sizeof(*ctx));
59529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
59629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
59729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.version = 1;
59829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.module = const_cast<hw_module_t*>(module);
59929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.close = close_copybit;
60029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.set_parameter = set_parameter_copybit;
60129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.get = get;
60229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.blit = blit_copybit;
60310a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    ctx->device.set_sync = set_sync_copybit;
60429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.stretch = stretch_copybit;
6059ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->device.finish = finish_copybit;
606e67c709079b4da35667a3bbc5a00d54530a83a87Terence Hampson    ctx->device.flush_get_fence = flush_get_fence;
60729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->mAlpha = MDP_ALPHA_NOP;
60829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->mFlags = 0;
60910a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    ctx->sync.flags = 0;
61010a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    ctx->sync.acq_fen_fd = ctx->acqFence;
61110a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    ctx->sync.rel_fen_fd = &ctx->relFence;
61210a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    ctx->list.count = 0;
6131c187f10a13479adfd719ead24eda6c1bb502795Terence Hampson    ctx->list.sync.acq_fen_fd_cnt = 0;
61410a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    ctx->list.sync.rel_fen_fd = ctx->sync.rel_fen_fd;
61510a67f20cf26b7a6e37ced8443b66c1cd93cc4d2Terence Hampson    ctx->list.sync.acq_fen_fd = ctx->sync.acq_fen_fd;
61629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0);
61729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx->mFD < 0) {
61829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = errno;
61929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("Error opening frame buffer errno=%d (%s)",
62029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed              status, strerror(status));
62129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = -status;
62229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
623e67c709079b4da35667a3bbc5a00d54530a83a87Terence Hampson        status = 0;
62429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        *device = &ctx->device.common;
62529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
62629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
62729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
628