@@ -30,8 +30,11 @@ const u16 vdec_hevc_parser_cmd[] = {
void codec_hevc_setup_decode_head(struct amvdec_session *sess, int is_10bit)
{
struct amvdec_core *core = sess->core;
- u32 body_size = amvdec_am21c_body_size(sess->width, sess->height);
- u32 head_size = amvdec_am21c_head_size(sess->width, sess->height);
+ u32 use_mmu = codec_hevc_use_mmu(core->platform->revision,
+ sess->pixfmt_cap, is_10bit);
+ u32 body_size = amvdec_amfbc_body_size(sess->width, sess->height,
+ is_10bit, use_mmu);
+ u32 head_size = amvdec_amfbc_head_size(sess->width, sess->height);
if (!codec_hevc_use_fbc(sess->pixfmt_cap, is_10bit)) {
/* Enable 2-plane reference read mode */
@@ -154,7 +157,12 @@ void codec_hevc_free_fbc_buffers(struct amvdec_session *sess,
struct codec_hevc_common *comm)
{
struct device *dev = sess->core->dev;
- u32 am21_size = amvdec_am21c_size(sess->width, sess->height);
+ u32 use_mmu = codec_hevc_use_mmu(sess->core->platform->revision,
+ sess->pixfmt_cap,
+ sess->bitdepth == 10 ? 1 : 0);
+ u32 am21_size = amvdec_amfbc_size(sess->width, sess->height,
+ sess->bitdepth == 10 ? 1 : 0,
+ use_mmu);
int i;
for (i = 0; i < MAX_REF_PIC_NUM; ++i) {
@@ -173,7 +181,12 @@ static int codec_hevc_alloc_fbc_buffers(struct amvdec_session *sess,
{
struct device *dev = sess->core->dev;
struct v4l2_m2m_buffer *buf;
- u32 am21_size = amvdec_am21c_size(sess->width, sess->height);
+ u32 use_mmu = codec_hevc_use_mmu(sess->core->platform->revision,
+ sess->pixfmt_cap,
+ sess->bitdepth == 10 ? 1 : 0);
+ u32 am21_size = amvdec_amfbc_size(sess->width, sess->height,
+ sess->bitdepth == 10 ? 1 : 0,
+ use_mmu);
v4l2_m2m_for_each_dst_buf(sess->m2m_ctx, buf) {
u32 idx = buf->vb.vb2_buf.index;
@@ -280,7 +293,12 @@ void codec_hevc_fill_mmu_map(struct amvdec_session *sess,
struct codec_hevc_common *comm,
struct vb2_buffer *vb)
{
- u32 size = amvdec_am21c_size(sess->width, sess->height);
+ u32 use_mmu = codec_hevc_use_mmu(sess->core->platform->revision,
+ sess->pixfmt_cap,
+ sess->bitdepth == 10 ? 1 : 0);
+ u32 size = amvdec_amfbc_size(sess->width, sess->height,
+ sess->bitdepth == 10 ? 1 : 0,
+ use_mmu);
u32 nb_pages = size / PAGE_SIZE;
u32 *mmu_map = comm->mmu_map_vaddr;
u32 first_page;
@@ -1147,6 +1147,8 @@ static void codec_vp9_set_mc(struct amvdec_session *sess,
struct codec_vp9 *vp9)
{
struct amvdec_core *core = sess->core;
+ u32 use_mmu = codec_hevc_use_mmu(core->platform->revision,
+ sess->pixfmt_cap, vp9->is_10bit);
u32 scale = 0;
u32 sz;
int i;
@@ -1166,8 +1168,9 @@ static void codec_vp9_set_mc(struct amvdec_session *sess,
vp9->frame_refs[i]->height != vp9->height)
scale = 1;
- sz = amvdec_am21c_body_size(vp9->frame_refs[i]->width,
- vp9->frame_refs[i]->height);
+ sz = amvdec_amfbc_body_size(vp9->frame_refs[i]->width,
+ vp9->frame_refs[i]->height,
+ vp9->is_10bit, use_mmu);
amvdec_write_dos(core, VP9D_MPP_REFINFO_DATA,
vp9->frame_refs[i]->width);
@@ -50,32 +50,47 @@ void amvdec_write_parser(struct amvdec_core *core, u32 reg, u32 val)
}
EXPORT_SYMBOL_GPL(amvdec_write_parser);
-/* 4 KiB per 64x32 block */
-u32 amvdec_am21c_body_size(u32 width, u32 height)
+/* AMFBC body is made out of 64x32 blocks with varying block size */
+u32 amvdec_amfbc_body_size(u32 width, u32 height, u32 is_10bit, u32 use_mmu)
{
u32 width_64 = ALIGN(width, 64) / 64;
u32 height_32 = ALIGN(height, 32) / 32;
+ u32 blk_size = 4096;
- return SZ_4K * width_64 * height_32;
+ if (!is_10bit) {
+ if (use_mmu)
+ blk_size = 3200;
+ else
+ blk_size = 3072;
+ }
+
+ return blk_size * width_64 * height_32;
}
-EXPORT_SYMBOL_GPL(amvdec_am21c_body_size);
+EXPORT_SYMBOL_GPL(amvdec_amfbc_body_size);
/* 32 bytes per 128x64 block */
-u32 amvdec_am21c_head_size(u32 width, u32 height)
+u32 amvdec_amfbc_head_size(u32 width, u32 height)
{
u32 width_128 = ALIGN(width, 128) / 128;
u32 height_64 = ALIGN(height, 64) / 64;
return 32 * width_128 * height_64;
}
-EXPORT_SYMBOL_GPL(amvdec_am21c_head_size);
+EXPORT_SYMBOL_GPL(amvdec_amfbc_head_size);
+
+u32 amvdec_amfbc_size(u32 width, u32 height, u32 is_10bit, u32 use_mmu)
+{
+ return ALIGN(amvdec_amfbc_body_size(width, height, is_10bit, use_mmu) +
+ amvdec_amfbc_head_size(width, height), SZ_64K);
+}
+EXPORT_SYMBOL_GPL(amvdec_amfbc_size);
-u32 amvdec_am21c_size(u32 width, u32 height)
+u32 amvdec_is_dst_fbc(struct amvdec_session *sess)
{
- return ALIGN(amvdec_am21c_body_size(width, height) +
- amvdec_am21c_head_size(width, height), SZ_64K);
+ return sess->pixfmt_cap == V4L2_PIX_FMT_YUV420_8BIT ||
+ sess->pixfmt_cap == V4L2_PIX_FMT_YUV420_10BIT;
}
-EXPORT_SYMBOL_GPL(amvdec_am21c_size);
+EXPORT_SYMBOL_GPL(amvdec_is_dst_fbc);
static int canvas_alloc(struct amvdec_session *sess, u8 *canvas_id)
{
@@ -27,9 +27,11 @@ void amvdec_clear_dos_bits(struct amvdec_core *core, u32 reg, u32 val);
u32 amvdec_read_parser(struct amvdec_core *core, u32 reg);
void amvdec_write_parser(struct amvdec_core *core, u32 reg, u32 val);
-u32 amvdec_am21c_body_size(u32 width, u32 height);
-u32 amvdec_am21c_head_size(u32 width, u32 height);
-u32 amvdec_am21c_size(u32 width, u32 height);
+/* Helpers for the Amlogic compressed framebuffer format */
+u32 amvdec_amfbc_body_size(u32 width, u32 height, u32 is_10bit, u32 use_mmu);
+u32 amvdec_amfbc_head_size(u32 width, u32 height);
+u32 amvdec_amfbc_size(u32 width, u32 height, u32 is_10bit, u32 use_mmu);
+u32 amvdec_is_dst_fbc(struct amvdec_session *sess);
/**
* amvdec_dst_buf_done_idx() - Signal that a buffer is done decoding