msm: rotator: Enable support for 2-pass fast YUV mode

Add support for 2-pass rotator operation for downscaling
and 90 degree rotation when rotator operates in fast YUV
mode. 2-pass is supported for 420 H2V2 formats.

Change-Id: Ib8ce802a5a8aabe10c88422e3b8d82708c5b05d4
Signed-off-by: Padmanabhan Komanduru <pkomandu@codeaurora.org>
This commit is contained in:
Padmanabhan Komanduru 2013-04-12 17:22:00 +05:30 committed by Artem Borisov
parent 50f8458679
commit 3176776cf1
2 changed files with 484 additions and 6 deletions

View file

@ -155,6 +155,8 @@ struct msm_rotator_session {
struct msm_rotator_img_info img_info;
struct msm_rotator_fd_info fd_info;
int fast_yuv_enable;
int enable_2pass;
u32 mem_hid;
};
struct msm_rotator_commit_info {
@ -179,6 +181,7 @@ struct msm_rotator_commit_info {
int session_index;
struct sync_fence *acq_fen;
int fast_yuv_en;
int enable_2pass;
};
struct msm_rotator_dev {
@ -222,6 +225,9 @@ struct msm_rotator_dev {
atomic_t commit_q_r;
atomic_t commit_q_w;
atomic_t commit_q_cnt;
struct rot_buf_type *y_rot_buf;
struct rot_buf_type *chroma_rot_buf;
struct rot_buf_type *chroma2_rot_buf;
};
#define COMPONENT_5BITS 1
@ -248,6 +254,129 @@ static struct res_mmu_clk rot_mmu_clks[] = {
{"smmu_iface_clk"}
};
u32 rotator_allocate_2pass_buf(struct rot_buf_type *rot_buf, int s_ndx)
{
ion_phys_addr_t addr, read_addr = 0;
size_t buffer_size;
unsigned long len;
if (!rot_buf) {
pr_err("Rot_buf NULL pointer %s %i", __func__, __LINE__);
return 0;
}
if (rot_buf->write_addr || !IS_ERR_OR_NULL(rot_buf->ihdl))
return 0;
buffer_size = roundup(1920 * 1088, SZ_4K);
if (!IS_ERR_OR_NULL(mrd->client)) {
pr_info("%s:%d ion based allocation\n",
__func__, __LINE__);
rot_buf->ihdl = ion_alloc(mrd->client, buffer_size, SZ_4K,
mrd->rot_session[s_ndx]->mem_hid, 0);
if (!IS_ERR_OR_NULL(rot_buf->ihdl)) {
if (rot_iommu_split_domain) {
if (ion_map_iommu(mrd->client, rot_buf->ihdl,
ROTATOR_SRC_DOMAIN, GEN_POOL, SZ_4K,
0, &read_addr, &len, 0, 0)) {
pr_err("ion_map_iommu() read failed\n");
return -ENOMEM;
}
if (mrd->rot_session[s_ndx]->mem_hid &
ION_SECURE) {
if (ion_phys(mrd->client, rot_buf->ihdl,
&addr, (size_t *)&len)) {
pr_err(
"%s:%d: ion_phys map failed\n",
__func__, __LINE__);
return -ENOMEM;
}
} else {
if (ion_map_iommu(mrd->client,
rot_buf->ihdl, ROTATOR_DST_DOMAIN,
GEN_POOL, SZ_4K, 0, &addr, &len,
0, 0)) {
pr_err("ion_map_iommu() failed\n");
return -ENOMEM;
}
}
} else {
if (ion_map_iommu(mrd->client, rot_buf->ihdl,
ROTATOR_SRC_DOMAIN, GEN_POOL, SZ_4K,
0, &addr, &len, 0, 0)) {
pr_err("ion_map_iommu() write failed\n");
return -ENOMEM;
}
}
} else {
pr_err("%s:%d: ion_alloc failed\n", __func__,
__LINE__);
return -ENOMEM;
}
} else {
addr = allocate_contiguous_memory_nomap(buffer_size,
mrd->rot_session[s_ndx]->mem_hid, 4);
}
if (addr) {
pr_info("allocating %d bytes at write=%x, read=%x for 2-pass\n",
buffer_size, (u32) addr, (u32) read_addr);
rot_buf->write_addr = addr;
if (read_addr)
rot_buf->read_addr = read_addr;
else
rot_buf->read_addr = rot_buf->write_addr;
return 0;
} else {
pr_err("%s cannot allocate memory for rotator 2-pass!\n",
__func__);
return -ENOMEM;
}
}
void rotator_free_2pass_buf(struct rot_buf_type *rot_buf, int s_ndx)
{
if (!rot_buf) {
pr_err("Rot_buf NULL pointer %s %i", __func__, __LINE__);
return;
}
if (!rot_buf->write_addr)
return;
if (!IS_ERR_OR_NULL(mrd->client)) {
if (!IS_ERR_OR_NULL(rot_buf->ihdl)) {
if (rot_iommu_split_domain) {
if (!(mrd->rot_session[s_ndx]->mem_hid &
ION_SECURE))
ion_unmap_iommu(mrd->client,
rot_buf->ihdl, ROTATOR_DST_DOMAIN,
GEN_POOL);
ion_unmap_iommu(mrd->client, rot_buf->ihdl,
ROTATOR_SRC_DOMAIN, GEN_POOL);
} else {
ion_unmap_iommu(mrd->client, rot_buf->ihdl,
ROTATOR_SRC_DOMAIN, GEN_POOL);
}
ion_free(mrd->client, rot_buf->ihdl);
rot_buf->ihdl = NULL;
pr_info("%s:%d Free rotator 2pass memory",
__func__, __LINE__);
}
} else {
if (rot_buf->write_addr) {
free_contiguous_memory_by_paddr(rot_buf->write_addr);
pr_debug("%s:%d Free rotator 2pass pmem\n", __func__,
__LINE__);
}
}
rot_buf->write_addr = 0;
rot_buf->read_addr = 0;
}
int msm_rotator_iommu_map_buf(int mem_id, int domain,
unsigned long *start, unsigned long *len,
struct ion_handle **pihdl, unsigned int secure)
@ -1024,7 +1153,7 @@ static int msm_rotator_ycxcx_h2v2(struct msm_rotator_img_info *info,
MSM_ROTATOR_OUT_PACK_PATTERN1);
}
iowrite32((3 << 18) | /* chroma sampling 3=4:2:0 */
iowrite32((3 << 18) | /* chroma sampling 3=4:2:0 */
(ROTATIONS_TO_BITMASK(info->rotations) << 9) |
1 << 8 | /* ROT_EN */
fast_yuv_en << 4 | /*fast YUV*/
@ -1035,6 +1164,307 @@ static int msm_rotator_ycxcx_h2v2(struct msm_rotator_img_info *info,
iowrite32((is_tile ? 2 : 0) << 29 | /* frame format */
(use_imem ? 0 : 1) << 22 | /* tile size */
(in_chroma2_paddr ? 1 : 2) << 19 | /* fetch planes */
0 << 18 | /* unpack align */
1 << 17 | /* unpack tight */
1 << 13 | /* unpack count 0=1 component */
0 << 9 | /* src Bpp 0=1 byte ... */
0 << 8 | /* has alpha */
0 << 6 | /* alpha bits 3=8bits */
3 << 4 | /* R/Cr bits 1=5 2=6 3=8 */
3 << 2 | /* B/Cb bits 1=5 2=6 3=8 */
3 << 0, /* G/Y bits 1=5 2=6 3=8 */
MSM_ROTATOR_SRC_FORMAT);
}
return 0;
}
static int msm_rotator_ycxcx_h2v2_2pass(struct msm_rotator_img_info *info,
unsigned int in_paddr,
unsigned int out_paddr,
unsigned int use_imem,
int new_session,
unsigned int in_chroma_paddr,
unsigned int out_chroma_paddr,
unsigned int in_chroma2_paddr,
unsigned int out_chroma2_paddr,
int fast_yuv_en,
int enable_2pass,
int session_index)
{
uint32_t pass2_src_format, pass1_dst_format, dst_format;
int is_tile = 0, post_pass1_buf_is_planar = 0;
unsigned int status;
int post_pass1_ystride = info->src_rect.w >> info->downscale_ratio;
int post_pass1_height = info->src_rect.h >> info->downscale_ratio;
/* DST format = SRC format for non-tiled SRC formats
* when fast YUV is enabled. For TILED formats,
* DST format of MDP_Y_CRCB_H2V2_TILE = MDP_Y_CRCB_H2V2
* DST format of MDP_Y_CBCR_H2V2_TILE = MDP_Y_CBCR_H2V2
*/
switch (info->src.format) {
case MDP_Y_CRCB_H2V2_TILE:
is_tile = 1;
dst_format = MDP_Y_CRCB_H2V2;
pass1_dst_format = MDP_Y_CRCB_H2V2;
pass2_src_format = pass1_dst_format;
break;
case MDP_Y_CR_CB_H2V2:
case MDP_Y_CR_CB_GH2V2:
case MDP_Y_CB_CR_H2V2:
post_pass1_buf_is_planar = 1;
case MDP_Y_CRCB_H2V2:
case MDP_Y_CBCR_H2V2:
dst_format = info->src.format;
pass1_dst_format = info->src.format;
pass2_src_format = pass1_dst_format;
break;
case MDP_Y_CBCR_H2V2_TILE:
is_tile = 1;
dst_format = MDP_Y_CBCR_H2V2;
pass1_dst_format = info->src.format;
pass2_src_format = pass1_dst_format;
break;
default:
return -EINVAL;
}
if (info->dst.format != dst_format)
return -EINVAL;
/* Beginning of Pass-1 */
/* rotator expects YCbCr for planar input format */
if ((info->src.format == MDP_Y_CR_CB_H2V2 ||
info->src.format == MDP_Y_CR_CB_GH2V2) &&
rotator_hw_revision < ROTATOR_REVISION_V2)
swap(in_chroma_paddr, in_chroma2_paddr);
iowrite32(in_paddr, MSM_ROTATOR_SRCP0_ADDR);
iowrite32(in_chroma_paddr, MSM_ROTATOR_SRCP1_ADDR);
iowrite32(in_chroma2_paddr, MSM_ROTATOR_SRCP2_ADDR);
if (new_session) {
if (in_chroma2_paddr) {
if (info->src.format == MDP_Y_CR_CB_GH2V2) {
iowrite32(ALIGN(info->src.width, 16) |
ALIGN((info->src.width / 2), 16) << 16,
MSM_ROTATOR_SRC_YSTRIDE1);
iowrite32(ALIGN((info->src.width / 2), 16),
MSM_ROTATOR_SRC_YSTRIDE2);
} else {
iowrite32(info->src.width |
(info->src.width / 2) << 16,
MSM_ROTATOR_SRC_YSTRIDE1);
iowrite32((info->src.width / 2),
MSM_ROTATOR_SRC_YSTRIDE2);
}
} else {
iowrite32(info->src.width |
info->src.width << 16,
MSM_ROTATOR_SRC_YSTRIDE1);
}
}
pr_debug("src_rect.w=%i src_rect.h=%i src_rect.x=%i src_rect.y=%i",
info->src_rect.w, info->src_rect.h, info->src_rect.x,
info->src_rect.y);
pr_debug("src.width=%i src.height=%i src_format=%i",
info->src.width, info->src.height, info->src.format);
pr_debug("dst_width=%i dst_height=%i dst.x=%i dst.y=%i",
info->dst.width, info->dst.height, info->dst_x, info->dst_y);
pr_debug("post_pass1_ystride=%i post_pass1_height=%i downscale=%i",
post_pass1_ystride, post_pass1_height, info->downscale_ratio);
rotator_allocate_2pass_buf(mrd->y_rot_buf, session_index);
rotator_allocate_2pass_buf(mrd->chroma_rot_buf, session_index);
if (post_pass1_buf_is_planar)
rotator_allocate_2pass_buf(mrd->chroma2_rot_buf, session_index);
iowrite32(mrd->y_rot_buf->write_addr, MSM_ROTATOR_OUTP0_ADDR);
iowrite32(mrd->chroma_rot_buf->write_addr, MSM_ROTATOR_OUTP1_ADDR);
if (post_pass1_buf_is_planar)
iowrite32(mrd->chroma2_rot_buf->write_addr,
MSM_ROTATOR_OUTP2_ADDR);
if (post_pass1_buf_is_planar) {
if (pass1_dst_format == MDP_Y_CR_CB_GH2V2) {
iowrite32(ALIGN(post_pass1_ystride, 16) |
ALIGN((post_pass1_ystride / 2), 16) << 16,
MSM_ROTATOR_OUT_YSTRIDE1);
iowrite32(ALIGN((post_pass1_ystride / 2), 16),
MSM_ROTATOR_OUT_YSTRIDE2);
} else {
iowrite32(post_pass1_ystride |
post_pass1_ystride / 2 << 16,
MSM_ROTATOR_OUT_YSTRIDE1);
iowrite32(post_pass1_ystride / 2,
MSM_ROTATOR_OUT_YSTRIDE2);
}
} else {
iowrite32(post_pass1_ystride |
post_pass1_ystride << 16,
MSM_ROTATOR_OUT_YSTRIDE1);
}
if (pass1_dst_format == MDP_Y_CBCR_H2V2 ||
pass1_dst_format == MDP_Y_CB_CR_H2V2) {
iowrite32(GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8),
MSM_ROTATOR_SRC_UNPACK_PATTERN1);
iowrite32(GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8),
MSM_ROTATOR_OUT_PACK_PATTERN1);
} else {
iowrite32(GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8),
MSM_ROTATOR_SRC_UNPACK_PATTERN1);
iowrite32(GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8),
MSM_ROTATOR_OUT_PACK_PATTERN1);
}
iowrite32((3 << 18) | /* chroma sampling 3=4:2:0 */
0 << 9 | /* Pass-1 No Rotation */
1 << 8 | /* ROT_EN */
fast_yuv_en << 4 | /*fast YUV*/
info->downscale_ratio << 2 | /* downscale v ratio */
info->downscale_ratio, /* downscale h ratio */
MSM_ROTATOR_SUB_BLOCK_CFG);
iowrite32((is_tile ? 2 : 0) << 29 | /* frame format */
(use_imem ? 0 : 1) << 22 | /* tile size */
(in_chroma2_paddr ? 1 : 2) << 19 | /* fetch planes */
0 << 18 | /* unpack align */
1 << 17 | /* unpack tight */
1 << 13 | /* unpack count 0=1 component */
0 << 9 | /* src Bpp 0=1 byte ... */
0 << 8 | /* has alpha */
0 << 6 | /* alpha bits 3=8bits */
3 << 4 | /* R/Cr bits 1=5 2=6 3=8 */
3 << 2 | /* B/Cb bits 1=5 2=6 3=8 */
3 << 0, /* G/Y bits 1=5 2=6 3=8 */
MSM_ROTATOR_SRC_FORMAT);
iowrite32(3, MSM_ROTATOR_INTR_ENABLE);
msm_rotator_dev->processing = 1;
iowrite32(0x1, MSM_ROTATOR_START);
mutex_unlock(&msm_rotator_dev->rotator_lock);
/* End of Pass-1 */
wait_event(msm_rotator_dev->wq,
(msm_rotator_dev->processing == 0));
/* Beginning of Pass-2 */
mutex_lock(&msm_rotator_dev->rotator_lock);
status = (unsigned char)ioread32(MSM_ROTATOR_INTR_STATUS);
if ((status & 0x03) != 0x01) {
pr_err("%s(): AXI Bus Error, issuing SW_RESET\n",
__func__);
iowrite32(0x1, MSM_ROTATOR_SW_RESET);
}
iowrite32(0, MSM_ROTATOR_INTR_ENABLE);
iowrite32(3, MSM_ROTATOR_INTR_CLEAR);
if (use_imem)
iowrite32(0x42, MSM_ROTATOR_MAX_BURST_SIZE);
iowrite32(((post_pass1_height & 0x1fff)
<< 16) |
(post_pass1_ystride & 0x1fff),
MSM_ROTATOR_SRC_SIZE);
iowrite32(0 << 16 | 0,
MSM_ROTATOR_SRC_XY);
iowrite32(((post_pass1_height & 0x1fff)
<< 16) |
(post_pass1_ystride & 0x1fff),
MSM_ROTATOR_SRC_IMAGE_SIZE);
/* rotator expects YCbCr for planar input format */
if ((pass2_src_format == MDP_Y_CR_CB_H2V2 ||
pass2_src_format == MDP_Y_CR_CB_GH2V2) &&
rotator_hw_revision < ROTATOR_REVISION_V2)
swap(mrd->chroma_rot_buf->read_addr,
mrd->chroma2_rot_buf->read_addr);
iowrite32(mrd->y_rot_buf->read_addr, MSM_ROTATOR_SRCP0_ADDR);
iowrite32(mrd->chroma_rot_buf->read_addr,
MSM_ROTATOR_SRCP1_ADDR);
if (mrd->chroma2_rot_buf->read_addr)
iowrite32(mrd->chroma2_rot_buf->read_addr,
MSM_ROTATOR_SRCP2_ADDR);
if (post_pass1_buf_is_planar) {
if (pass2_src_format == MDP_Y_CR_CB_GH2V2) {
iowrite32(ALIGN(post_pass1_ystride, 16) |
ALIGN((post_pass1_ystride / 2), 16) << 16,
MSM_ROTATOR_SRC_YSTRIDE1);
iowrite32(ALIGN((post_pass1_ystride / 2), 16),
MSM_ROTATOR_SRC_YSTRIDE2);
} else {
iowrite32(post_pass1_ystride |
(post_pass1_ystride / 2) << 16,
MSM_ROTATOR_SRC_YSTRIDE1);
iowrite32((post_pass1_ystride / 2),
MSM_ROTATOR_SRC_YSTRIDE2);
}
} else {
iowrite32(post_pass1_ystride |
post_pass1_ystride << 16,
MSM_ROTATOR_SRC_YSTRIDE1);
}
iowrite32(out_paddr +
((info->dst_y * info->dst.width) + info->dst_x),
MSM_ROTATOR_OUTP0_ADDR);
iowrite32(out_chroma_paddr +
(((info->dst_y * info->dst.width)/2) + info->dst_x),
MSM_ROTATOR_OUTP1_ADDR);
if (out_chroma2_paddr)
iowrite32(out_chroma2_paddr +
(((info->dst_y * info->dst.width)/2) + info->dst_x),
MSM_ROTATOR_OUTP2_ADDR);
if (new_session) {
if (out_chroma2_paddr) {
if (info->dst.format == MDP_Y_CR_CB_GH2V2) {
iowrite32(ALIGN(info->dst.width, 16) |
ALIGN((info->dst.width / 2), 16) << 16,
MSM_ROTATOR_OUT_YSTRIDE1);
iowrite32(ALIGN((info->dst.width / 2), 16),
MSM_ROTATOR_OUT_YSTRIDE2);
} else {
iowrite32(info->dst.width |
info->dst.width/2 << 16,
MSM_ROTATOR_OUT_YSTRIDE1);
iowrite32(info->dst.width/2,
MSM_ROTATOR_OUT_YSTRIDE2);
}
} else {
iowrite32(info->dst.width |
info->dst.width << 16,
MSM_ROTATOR_OUT_YSTRIDE1);
}
if (dst_format == MDP_Y_CBCR_H2V2 ||
dst_format == MDP_Y_CB_CR_H2V2) {
iowrite32(GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8),
MSM_ROTATOR_SRC_UNPACK_PATTERN1);
iowrite32(GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8),
MSM_ROTATOR_OUT_PACK_PATTERN1);
} else {
iowrite32(GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8),
MSM_ROTATOR_SRC_UNPACK_PATTERN1);
iowrite32(GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8),
MSM_ROTATOR_OUT_PACK_PATTERN1);
}
iowrite32((3 << 18) | /* chroma sampling 3=4:2:0 */
(ROTATIONS_TO_BITMASK(info->rotations) << 9) |
1 << 8 | /* ROT_EN */
fast_yuv_en << 4 | /*fast YUV*/
0 << 2 | /* No downscale in Pass-2 */
0, /* No downscale in Pass-2 */
MSM_ROTATOR_SUB_BLOCK_CFG);
iowrite32(0 << 29 |
/* Output of Pass-1 will always be non-tiled */
(use_imem ? 0 : 1) << 22 | /* tile size */
(in_chroma2_paddr ? 1 : 2) << 19 | /* fetch planes */
0 << 18 | /* unpack align */
1 << 17 | /* unpack tight */
1 << 13 | /* unpack count 0=1 component */
@ -1514,6 +1944,7 @@ static int msm_rotator_rotate_prepare(
commit_info->session_index = s;
commit_info->acq_fen = msm_rotator_dev->sync_info[s].acq_fen;
commit_info->fast_yuv_en = mrd->rot_session[s]->fast_yuv_enable;
commit_info->enable_2pass = mrd->rot_session[s]->enable_2pass;
mutex_unlock(&msm_rotator_dev->rotator_lock);
return 0;
@ -1634,7 +2065,8 @@ static int msm_rotator_do_rotate_sub(
case MDP_Y_CR_CB_GH2V2:
case MDP_Y_CRCB_H2V2_TILE:
case MDP_Y_CBCR_H2V2_TILE:
rc = msm_rotator_ycxcx_h2v2(img_info,
if (!commit_info->enable_2pass)
rc = msm_rotator_ycxcx_h2v2(img_info,
in_paddr, out_paddr, use_imem,
msm_rotator_dev->last_session_idx
!= s,
@ -1643,6 +2075,18 @@ static int msm_rotator_do_rotate_sub(
in_chroma2_paddr,
out_chroma2_paddr,
commit_info->fast_yuv_en);
else
rc = msm_rotator_ycxcx_h2v2_2pass(img_info,
in_paddr, out_paddr, use_imem,
msm_rotator_dev->last_session_idx
!= s,
in_chroma_paddr,
out_chroma_paddr,
in_chroma2_paddr,
out_chroma2_paddr,
commit_info->fast_yuv_en,
commit_info->enable_2pass,
s);
break;
case MDP_Y_CBCR_H2V1:
case MDP_Y_CRCB_H2V1:
@ -1929,7 +2373,7 @@ static int msm_rotator_start(unsigned long arg,
int first_free_idx = INVALID_SESSION;
unsigned int dst_w, dst_h;
unsigned int is_planar420 = 0;
int fast_yuv_en = 0;
int fast_yuv_en = 0, enable_2pass = 0;
struct rot_sync_info *sync_info;
if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
@ -1970,9 +2414,7 @@ static int msm_rotator_start(unsigned long arg,
case MDP_Y_CRCB_H2V2:
case MDP_Y_CRCB_H2V2_TILE:
case MDP_Y_CBCR_H2V2_TILE:
if (rotator_hw_revision >= ROTATOR_REVISION_V2 &&
!(info.downscale_ratio &&
(info.rotations & MDP_ROT_90)))
if (rotator_hw_revision >= ROTATOR_REVISION_V2) {
fast_yuv_en = !fast_yuv_invalid_size_checker(
info.rotations,
info.src.width,
@ -1981,6 +2423,10 @@ static int msm_rotator_start(unsigned long arg,
dst_h,
dst_w,
is_planar420);
if (fast_yuv_en && info.downscale_ratio &&
(info.rotations & MDP_ROT_90))
enable_2pass = 1;
}
break;
default:
fast_yuv_en = 0;
@ -2054,6 +2500,7 @@ static int msm_rotator_start(unsigned long arg,
rot_session->img_info = info;
rot_session->fd_info = *fd_info;
rot_session->fast_yuv_enable = fast_yuv_en;
rot_session->enable_2pass = enable_2pass;
if (msm_rotator_dev->last_session_idx == s)
msm_rotator_dev->last_session_idx =
@ -2084,6 +2531,18 @@ static int msm_rotator_start(unsigned long arg,
rot_session->img_info = info;
rot_session->fd_info = *fd_info;
rot_session->fast_yuv_enable = fast_yuv_en;
rot_session->enable_2pass = enable_2pass;
if (!IS_ERR_OR_NULL(mrd->client)) {
if (rot_session->img_info.secure) {
rot_session->mem_hid &= ~BIT(ION_IOMMU_HEAP_ID);
rot_session->mem_hid |= ION_SECURE;
} else {
rot_session->mem_hid |= BIT(ION_IOMMU_HEAP_ID);
rot_session->mem_hid &= ~ION_SECURE;
}
}
s = first_free_idx;
} else if (s == MAX_SESSIONS) {
dev_dbg(msm_rotator_dev->device, "%s: all sessions in use\n",
@ -2140,6 +2599,11 @@ static int msm_rotator_finish(unsigned long arg)
INVALID_SESSION;
msm_rotator_signal_timeline(s);
msm_rotator_release_acq_fence(s);
if (msm_rotator_dev->rot_session[s]->enable_2pass) {
rotator_free_2pass_buf(mrd->y_rot_buf, s);
rotator_free_2pass_buf(mrd->chroma_rot_buf, s);
rotator_free_2pass_buf(mrd->chroma2_rot_buf, s);
}
kfree(msm_rotator_dev->rot_session[s]);
msm_rotator_dev->rot_session[s] = NULL;
break;
@ -2308,6 +2772,14 @@ static int __devinit msm_rotator_probe(struct platform_device *pdev)
msm_rotator_dev->core_clk = NULL;
msm_rotator_dev->pclk = NULL;
mrd->y_rot_buf = kmalloc(sizeof(struct rot_buf_type), GFP_KERNEL);
mrd->chroma_rot_buf = kmalloc(sizeof(struct rot_buf_type), GFP_KERNEL);
mrd->chroma2_rot_buf = kmalloc(sizeof(struct rot_buf_type), GFP_KERNEL);
memset((void *)mrd->y_rot_buf, 0, sizeof(struct rot_buf_type));
memset((void *)mrd->chroma_rot_buf, 0, sizeof(struct rot_buf_type));
memset((void *)mrd->chroma2_rot_buf, 0, sizeof(struct rot_buf_type));
#ifdef CONFIG_MSM_BUS_SCALING
if (!msm_rotator_dev->bus_client_handle && pdata &&
pdata->bus_scale_table) {

View file

@ -30,6 +30,12 @@ struct msm_rotator_buf_sync {
int rel_fen_fd;
};
struct rot_buf_type {
struct ion_handle *ihdl;
uint32_t write_addr;
uint32_t read_addr;
};
struct msm_rotator_img_info {
unsigned int session_id;
struct msmfb_img src;