mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
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:
parent
50f8458679
commit
3176776cf1
2 changed files with 484 additions and 6 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue