Message ID | 1349189741-22259-5-git-send-email-arun.kk@samsung.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
> From: Arun Kumar K [mailto:arun.kk@samsung.com] > Sent: 02 October 2012 16:56 > > MFC variant data replaces various macros used in the driver > which will change in a different version of MFC hardware. > Also does a cleanup of MFC context structure and common files. > > Signed-off-by: Jeongtae Park <jtp.park@samsung.com> > Signed-off-by: Janghyuck Kim <janghyuck.kim@samsung.com> > Signed-off-by: Jaeryul Oh <jaeryul.oh@samsung.com> > Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com> > Signed-off-by: Arun Kumar K <arun.kk@samsung.com> Acked-by: Kamil Debski <k.debski@samsung.com> > --- > drivers/media/platform/s5p-mfc/regs-mfc.h | 20 ++ > drivers/media/platform/s5p-mfc/s5p_mfc.c | 78 +++++---- > drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c | 4 +- > drivers/media/platform/s5p-mfc/s5p_mfc_common.h | 85 ++++++---- > drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | 7 +- > drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 44 +---- > drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | 213 +++++++++++++++-------- > 7 files changed, 266 insertions(+), 185 deletions(-) > > diff --git a/drivers/media/platform/s5p-mfc/regs-mfc.h > b/drivers/media/platform/s5p-mfc/regs-mfc.h > index a19bece..f33c54d 100644 > --- a/drivers/media/platform/s5p-mfc/regs-mfc.h > +++ b/drivers/media/platform/s5p-mfc/regs-mfc.h > @@ -12,6 +12,9 @@ > #ifndef _REGS_FIMV_H > #define _REGS_FIMV_H > > +#include <linux/kernel.h> > +#include <linux/sizes.h> > + > #define S5P_FIMV_REG_SIZE (S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) > #define S5P_FIMV_REG_COUNT ((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4) > > @@ -414,5 +417,22 @@ > #define S5P_FIMV_SHARED_EXTENDED_SAR 0x0078 > #define S5P_FIMV_SHARED_H264_I_PERIOD 0x009C > #define S5P_FIMV_SHARED_RC_CONTROL_CONFIG 0x00A0 > +#define S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT 2 > + > +/* Offset used by the hardware to store addresses */ > +#define MFC_OFFSET_SHIFT 11 > + > +#define FIRMWARE_ALIGN (128 * SZ_1K) /* 128KB */ > +#define MFC_H264_CTX_BUF_SIZE (600 * SZ_1K) /* 600KB per H264 instance */ > +#define MFC_CTX_BUF_SIZE (10 * SZ_1K) /* 10KB per instance */ > +#define DESC_BUF_SIZE (128 * SZ_1K) /* 128KB for DESC buffer */ > +#define SHARED_BUF_SIZE (8 * SZ_1K) /* 8KB for shared buffer */ > + > +#define DEF_CPB_SIZE (256 * SZ_1K) /* 256KB */ > +#define MAX_CPB_SIZE (4 * SZ_1M) /* 4MB */ > +#define MAX_FW_SIZE (384 * SZ_1K) > + > +#define MFC_VERSION 0x51 > +#define MFC_NUM_PORTS 2 > > #endif /* _REGS_FIMV_H */ > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c > b/drivers/media/platform/s5p-mfc/s5p_mfc.c > index 3319410..a8299ce 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c > @@ -436,7 +436,6 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, > unsigned int reason, unsigned int err) > { > struct s5p_mfc_dev *dev; > - unsigned int guard_width, guard_height; > > if (ctx == NULL) > return; > @@ -450,40 +449,8 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, > ctx->img_height = s5p_mfc_hw_call(dev->mfc_ops, get_img_height, > dev); > > - ctx->buf_width = ALIGN(ctx->img_width, > - S5P_FIMV_NV12MT_HALIGN); > - ctx->buf_height = ALIGN(ctx->img_height, > - S5P_FIMV_NV12MT_VALIGN); > - mfc_debug(2, "SEQ Done: Movie dimensions %dx%d, " > - "buffer dimensions: %dx%d\n", ctx->img_width, > - ctx->img_height, ctx->buf_width, > - ctx->buf_height); > - if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) { > - ctx->luma_size = ALIGN(ctx->buf_width * > - ctx->buf_height, S5P_FIMV_DEC_BUF_ALIGN); > - ctx->chroma_size = ALIGN(ctx->buf_width * > - ALIGN((ctx->img_height >> 1), > - S5P_FIMV_NV12MT_VALIGN), > - S5P_FIMV_DEC_BUF_ALIGN); > - ctx->mv_size = ALIGN(ctx->buf_width * > - ALIGN((ctx->buf_height >> 2), > - S5P_FIMV_NV12MT_VALIGN), > - S5P_FIMV_DEC_BUF_ALIGN); > - } else { > - guard_width = ALIGN(ctx->img_width + 24, > - S5P_FIMV_NV12MT_HALIGN); > - guard_height = ALIGN(ctx->img_height + 16, > - S5P_FIMV_NV12MT_VALIGN); > - ctx->luma_size = ALIGN(guard_width * > - guard_height, S5P_FIMV_DEC_BUF_ALIGN); > - guard_width = ALIGN(ctx->img_width + 16, > - S5P_FIMV_NV12MT_HALIGN); > - guard_height = ALIGN((ctx->img_height >> 1) + 4, > - S5P_FIMV_NV12MT_VALIGN); > - ctx->chroma_size = ALIGN(guard_width * > - guard_height, S5P_FIMV_DEC_BUF_ALIGN); > - ctx->mv_size = 0; > - } > + s5p_mfc_hw_call(dev->mfc_ops, dec_calc_dpb_size, ctx); > + > ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count, > dev); > if (ctx->img_width == 0 || ctx->img_height == 0) > @@ -993,6 +960,9 @@ static int s5p_mfc_probe(struct platform_device *pdev) > return -ENODEV; > } > > + dev->variant = (struct s5p_mfc_variant *) > + platform_get_device_id(pdev)->driver_data; > + > ret = s5p_mfc_init_pm(dev); > if (ret < 0) { > dev_err(&pdev->dev, "failed to get mfc clock source\n"); > @@ -1235,9 +1205,43 @@ static const struct dev_pm_ops s5p_mfc_pm_ops = { > NULL) > }; > > +struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = { > + .h264_ctx = MFC_H264_CTX_BUF_SIZE, > + .non_h264_ctx = MFC_CTX_BUF_SIZE, > + .dsc = DESC_BUF_SIZE, > + .shm = SHARED_BUF_SIZE, > +}; > + > +struct s5p_mfc_buf_size buf_size_v5 = { > + .fw = MAX_FW_SIZE, > + .cpb = MAX_CPB_SIZE, > + .priv = &mfc_buf_size_v5, > +}; > + > +struct s5p_mfc_buf_align mfc_buf_align_v5 = { > + .base = MFC_BASE_ALIGN_ORDER, > +}; > + > +static struct s5p_mfc_variant mfc_drvdata_v5 = { > + .version = MFC_VERSION, > + .port_num = MFC_NUM_PORTS, > + .buf_size = &buf_size_v5, > + .buf_align = &mfc_buf_align_v5, > +}; > + > +static struct platform_device_id mfc_driver_ids[] = { > + { > + .name = "s5p-mfc", > + .driver_data = (unsigned long)&mfc_drvdata_v5, > + }, > + {}, > +}; > +MODULE_DEVICE_TABLE(platform, mfc_driver_ids); > + > static struct platform_driver s5p_mfc_driver = { > - .probe = s5p_mfc_probe, > - .remove = __devexit_p(s5p_mfc_remove), > + .probe = s5p_mfc_probe, > + .remove = __devexit_p(s5p_mfc_remove), > + .id_table = mfc_driver_ids, > .driver = { > .name = S5P_MFC_NAME, > .owner = THIS_MODULE, > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c > b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c > index f3d7874..344b31e 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c > @@ -113,8 +113,8 @@ int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx) > h2r_args.arg[0] = S5P_FIMV_CODEC_NONE; > }; > h2r_args.arg[1] = 0; /* no crc & no pixelcache */ > - h2r_args.arg[2] = ctx->ctx_ofs; > - h2r_args.arg[3] = ctx->ctx_size; > + h2r_args.arg[2] = ctx->ctx.ofs; > + h2r_args.arg[3] = ctx->ctx.size; > ret = s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE, > &h2r_args); > if (ret) { > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h > b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h > index ccb59ac..e9e89ac 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h > @@ -30,17 +30,6 @@ > * while mmaping */ > #define DST_QUEUE_OFF_BASE (TASK_SIZE / 2) > > -/* Offset used by the hardware to store addresses */ > -#define MFC_OFFSET_SHIFT 11 > - > -#define FIRMWARE_ALIGN 0x20000 /* 128KB */ > -#define MFC_H264_CTX_BUF_SIZE 0x96000 /* 600KB per H264 instance > */ > -#define MFC_CTX_BUF_SIZE 0x2800 /* 10KB per instance */ > -#define DESC_BUF_SIZE 0x20000 /* 128KB for DESC buffer */ > -#define SHARED_BUF_SIZE 0x2000 /* 8KB for shared buffer */ > - > -#define DEF_CPB_SIZE 0x40000 /* 512KB */ > - > #define MFC_BANK1_ALLOC_CTX 0 > #define MFC_BANK2_ALLOC_CTX 1 > > @@ -207,6 +196,48 @@ struct s5p_mfc_pm { > struct device *device; > }; > > +struct s5p_mfc_buf_size_v5 { > + unsigned int h264_ctx; > + unsigned int non_h264_ctx; > + unsigned int dsc; > + unsigned int shm; > +}; > + > +struct s5p_mfc_buf_size { > + unsigned int fw; > + unsigned int cpb; > + void *priv; > +}; > + > +struct s5p_mfc_buf_align { > + unsigned int base; > +}; > + > +struct s5p_mfc_variant { > + unsigned int version; > + unsigned int port_num; > + struct s5p_mfc_buf_size *buf_size; > + struct s5p_mfc_buf_align *buf_align; > +}; > + > +/** > + * struct s5p_mfc_priv_buf - represents internal used buffer > + * @alloc: allocation-specific context for each buffer > + * (videobuf2 allocator) > + * @ofs: offset of each buffer, will be used for MFC > + * @virt: kernel virtual address, only valid when the > + * buffer accessed by driver > + * @dma: DMA address, only valid when kernel DMA API used > + * @size: size of the buffer > + */ > +struct s5p_mfc_priv_buf { > + void *alloc; > + unsigned long ofs; > + void *virt; > + dma_addr_t dma; > + size_t size; > +}; > + > /** > * struct s5p_mfc_dev - The struct containing driver internal parameters. > * > @@ -221,6 +252,7 @@ struct s5p_mfc_pm { > * @dec_ctrl_handler: control framework handler for decoding > * @enc_ctrl_handler: control framework handler for encoding > * @pm: power management control > + * @variant: MFC hardware variant information > * @num_inst: couter of active MFC instances > * @irqlock: lock for operations on videobuf2 queues > * @condlock: lock for changing/checking if a context is ready to be > @@ -259,6 +291,7 @@ struct s5p_mfc_dev { > struct v4l2_ctrl_handler dec_ctrl_handler; > struct v4l2_ctrl_handler enc_ctrl_handler; > struct s5p_mfc_pm pm; > + struct s5p_mfc_variant *variant; > int num_inst; > spinlock_t irqlock; /* lock when operating on videobuf2 queues */ > spinlock_t condlock; /* lock when changing/checking if a context is > @@ -299,7 +332,6 @@ struct s5p_mfc_h264_enc_params { > u8 max_ref_pic; > u8 num_ref_pic_4p; > int _8x8_transform; > - int rc_mb; > int rc_mb_dark; > int rc_mb_smooth; > int rc_mb_static; > @@ -318,6 +350,7 @@ struct s5p_mfc_h264_enc_params { > enum v4l2_mpeg_video_h264_level level_v4l2; > int level; > u16 cpb_size; > + int interlace; > }; > > /** > @@ -356,6 +389,7 @@ struct s5p_mfc_enc_params { > u8 pad_cb; > u8 pad_cr; > int rc_frame; > + int rc_mb; > u32 rc_bitrate; > u16 rc_reaction_coeff; > u16 vbv_size; > @@ -367,7 +401,6 @@ struct s5p_mfc_enc_params { > u8 num_b_frame; > u32 rc_framerate_num; > u32 rc_framerate_denom; > - int interlace; > > union { > struct s5p_mfc_h264_enc_params h264; > @@ -452,14 +485,9 @@ struct s5p_mfc_codec_ops { > * @dpb_count: count of the DPB buffers required by MFC hw > * @total_dpb_count: count of DPB buffers with additional buffers > * requested by the application > - * @ctx_buf: handle to the memory associated with this context > - * @ctx_phys: address of the memory associated with this context > - * @ctx_size: size of the memory associated with this context > - * @desc_buf: description buffer for decoding handle > - * @desc_phys: description buffer for decoding address > - * @shm_alloc: handle for the shared memory buffer > - * @shm: virtual address for the shared memory buffer > - * @shm_ofs: address offset for shared memory > + * @ctx: context buffer information > + * @dsc: descriptor buffer information > + * @shm: shared memory buffer information > * @enc_params: encoding parameters for MFC > * @enc_dst_buf_size: size of the buffers for encoder output > * @frame_type: used to force the type of the next encoded frame > @@ -544,18 +572,9 @@ struct s5p_mfc_ctx { > int total_dpb_count; > > /* Buffers */ > - void *ctx_buf; > - size_t ctx_phys; > - size_t ctx_ofs; > - size_t ctx_size; > - > - void *desc_buf; > - size_t desc_phys; > - > - > - void *shm_alloc; > - void *shm; > - size_t shm_ofs; > + struct s5p_mfc_priv_buf ctx; > + struct s5p_mfc_priv_buf dsc; > + struct s5p_mfc_priv_buf shm; > > struct s5p_mfc_enc_params enc_params; > > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c > b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c > index 4a39e5e..524380c 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c > @@ -43,7 +43,12 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev) > mfc_err("Firmware is not present in the /lib/firmware directory nor > compiled in kernel\n"); > return -EINVAL; > } > - dev->fw_size = ALIGN(fw_blob->size, FIRMWARE_ALIGN); > + dev->fw_size = dev->variant->buf_size->fw; > + if (fw_blob->size > dev->fw_size) { > + mfc_err("MFC firmware is too big to be loaded\n"); > + release_firmware(fw_blob); > + return -ENOMEM; > + } > if (s5p_mfc_bitproc_buf) { > mfc_err("Attempting to allocate firmware when it seems that it is > already loaded\n"); > release_firmware(fw_blob); > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > index 02e1a94..fe34f17 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c > @@ -985,45 +985,13 @@ static int vidioc_s_fmt(struct file *file, void *priv, > struct v4l2_format *f) > mfc_debug(2, "fmt - w: %d, h: %d, ctx - w: %d, h: %d\n", > pix_fmt_mp->width, pix_fmt_mp->height, > ctx->img_width, ctx->img_height); > - if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) { > - ctx->buf_width = ALIGN(ctx->img_width, > - S5P_FIMV_NV12M_HALIGN); > - ctx->luma_size = ALIGN(ctx->img_width, > - S5P_FIMV_NV12M_HALIGN) * ALIGN(ctx->img_height, > - S5P_FIMV_NV12M_LVALIGN); > - ctx->chroma_size = ALIGN(ctx->img_width, > - S5P_FIMV_NV12M_HALIGN) * ALIGN((ctx->img_height > - >> 1), S5P_FIMV_NV12M_CVALIGN); > - > - ctx->luma_size = ALIGN(ctx->luma_size, > - S5P_FIMV_NV12M_SALIGN); > - ctx->chroma_size = ALIGN(ctx->chroma_size, > - S5P_FIMV_NV12M_SALIGN); > - > - pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size; > - pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width; > - pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size; > - pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width; > - > - } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) { > - ctx->buf_width = ALIGN(ctx->img_width, > - S5P_FIMV_NV12MT_HALIGN); > - ctx->luma_size = ALIGN(ctx->img_width, > - S5P_FIMV_NV12MT_HALIGN) * ALIGN(ctx->img_height, > - S5P_FIMV_NV12MT_VALIGN); > - ctx->chroma_size = ALIGN(ctx->img_width, > - S5P_FIMV_NV12MT_HALIGN) * ALIGN((ctx->img_height > - >> 1), S5P_FIMV_NV12MT_VALIGN); > - ctx->luma_size = ALIGN(ctx->luma_size, > - S5P_FIMV_NV12MT_SALIGN); > - ctx->chroma_size = ALIGN(ctx->chroma_size, > - S5P_FIMV_NV12MT_SALIGN); > - > - pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size; > - pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width; > - pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size; > - pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width; > - } > + > + s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx); > + pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size; > + pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width; > + pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size; > + pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width; > + > ctx->src_bufs_cnt = 0; > ctx->output_state = QUEUE_FREE; > } else { > @@ -1349,7 +1317,7 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl) > p->codec.h264._8x8_transform = ctrl->val; > break; > case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: > - p->codec.h264.rc_mb = ctrl->val; > + p->rc_mb = ctrl->val; > break; > case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: > p->codec.h264.rc_frame_qp = ctrl->val; > diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c > b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c > index fe36c92..f1871e7 100644 > --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c > +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c > @@ -36,28 +36,29 @@ > /* Allocate temporary buffers for decoding */ > int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx) > { > - void *desc_virt; > struct s5p_mfc_dev *dev = ctx->dev; > + struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; > > - ctx->desc_buf = vb2_dma_contig_memops.alloc( > - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], DESC_BUF_SIZE); > - if (IS_ERR_VALUE((int)ctx->desc_buf)) { > - ctx->desc_buf = NULL; > + ctx->dsc.alloc = vb2_dma_contig_memops.alloc( > + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], > + buf_size->dsc); > + if (IS_ERR_VALUE((int)ctx->dsc.alloc)) { > + ctx->dsc.alloc = NULL; > mfc_err("Allocating DESC buffer failed\n"); > return -ENOMEM; > } > - ctx->desc_phys = s5p_mfc_mem_cookie( > - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->desc_buf); > - BUG_ON(ctx->desc_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); > - desc_virt = vb2_dma_contig_memops.vaddr(ctx->desc_buf); > - if (desc_virt == NULL) { > - vb2_dma_contig_memops.put(ctx->desc_buf); > - ctx->desc_phys = 0; > - ctx->desc_buf = NULL; > + ctx->dsc.dma = s5p_mfc_mem_cookie( > + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->dsc.alloc); > + BUG_ON(ctx->dsc.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); > + ctx->dsc.virt = vb2_dma_contig_memops.vaddr(ctx->dsc.alloc); > + if (ctx->dsc.virt == NULL) { > + vb2_dma_contig_memops.put(ctx->dsc.alloc); > + ctx->dsc.dma = 0; > + ctx->dsc.alloc = NULL; > mfc_err("Remapping DESC buffer failed\n"); > return -ENOMEM; > } > - memset(desc_virt, 0, DESC_BUF_SIZE); > + memset(ctx->dsc.virt, 0, buf_size->dsc); > wmb(); > return 0; > } > @@ -65,10 +66,10 @@ int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx > *ctx) > /* Release temporary buffers for decoding */ > void s5p_mfc_release_dec_desc_buffer_v5(struct s5p_mfc_ctx *ctx) > { > - if (ctx->desc_phys) { > - vb2_dma_contig_memops.put(ctx->desc_buf); > - ctx->desc_phys = 0; > - ctx->desc_buf = NULL; > + if (ctx->dsc.dma) { > + vb2_dma_contig_memops.put(ctx->dsc.alloc); > + ctx->dsc.alloc = NULL; > + ctx->dsc.dma = 0; > } > } > > @@ -229,60 +230,60 @@ void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx > *ctx) > /* Allocate memory for instance data buffer */ > int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx) > { > - void *context_virt; > struct s5p_mfc_dev *dev = ctx->dev; > + struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; > > - if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC || > - ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) > - ctx->ctx_size = MFC_H264_CTX_BUF_SIZE; > + if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || > + ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) > + ctx->ctx.size = buf_size->h264_ctx; > else > - ctx->ctx_size = MFC_CTX_BUF_SIZE; > - ctx->ctx_buf = vb2_dma_contig_memops.alloc( > - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_size); > - if (IS_ERR(ctx->ctx_buf)) { > + ctx->ctx.size = buf_size->non_h264_ctx; > + ctx->ctx.alloc = vb2_dma_contig_memops.alloc( > + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.size); > + if (IS_ERR(ctx->ctx.alloc)) { > mfc_err("Allocating context buffer failed\n"); > - ctx->ctx_phys = 0; > - ctx->ctx_buf = NULL; > + ctx->ctx.alloc = NULL; > return -ENOMEM; > } > - ctx->ctx_phys = s5p_mfc_mem_cookie( > - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_buf); > - BUG_ON(ctx->ctx_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); > - ctx->ctx_ofs = OFFSETA(ctx->ctx_phys); > - context_virt = vb2_dma_contig_memops.vaddr(ctx->ctx_buf); > - if (context_virt == NULL) { > + ctx->ctx.dma = s5p_mfc_mem_cookie( > + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.alloc); > + BUG_ON(ctx->ctx.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); > + ctx->ctx.ofs = OFFSETA(ctx->ctx.dma); > + ctx->ctx.virt = vb2_dma_contig_memops.vaddr(ctx->ctx.alloc); > + if (!ctx->ctx.virt) { > mfc_err("Remapping instance buffer failed\n"); > - vb2_dma_contig_memops.put(ctx->ctx_buf); > - ctx->ctx_phys = 0; > - ctx->ctx_buf = NULL; > + vb2_dma_contig_memops.put(ctx->ctx.alloc); > + ctx->ctx.alloc = NULL; > + ctx->ctx.ofs = 0; > + ctx->ctx.dma = 0; > return -ENOMEM; > } > /* Zero content of the allocated memory */ > - memset(context_virt, 0, ctx->ctx_size); > + memset(ctx->ctx.virt, 0, ctx->ctx.size); > wmb(); > > /* Initialize shared memory */ > - ctx->shm_alloc = vb2_dma_contig_memops.alloc( > - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], SHARED_BUF_SIZE); > - if (IS_ERR(ctx->shm_alloc)) { > + ctx->shm.alloc = vb2_dma_contig_memops.alloc( > + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], buf_size->shm); > + if (IS_ERR(ctx->shm.alloc)) { > mfc_err("failed to allocate shared memory\n"); > - return PTR_ERR(ctx->shm_alloc); > + return PTR_ERR(ctx->shm.alloc); > } > /* shared memory offset only keeps the offset from base (port a) */ > - ctx->shm_ofs = s5p_mfc_mem_cookie( > - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->shm_alloc) > + ctx->shm.ofs = s5p_mfc_mem_cookie( > + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->shm.alloc) > - dev->bank1; > - BUG_ON(ctx->shm_ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); > + BUG_ON(ctx->shm.ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); > > - ctx->shm = vb2_dma_contig_memops.vaddr(ctx->shm_alloc); > - if (!ctx->shm) { > - vb2_dma_contig_memops.put(ctx->shm_alloc); > - ctx->shm_ofs = 0; > - ctx->shm_alloc = NULL; > + ctx->shm.virt = vb2_dma_contig_memops.vaddr(ctx->shm.alloc); > + if (!ctx->shm.virt) { > + vb2_dma_contig_memops.put(ctx->shm.alloc); > + ctx->shm.alloc = NULL; > + ctx->shm.ofs = 0; > mfc_err("failed to virt addr of shared memory\n"); > return -ENOMEM; > } > - memset((void *)ctx->shm, 0, SHARED_BUF_SIZE); > + memset((void *)ctx->shm.virt, 0, buf_size->shm); > wmb(); > return 0; > } > @@ -290,15 +291,18 @@ int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx > *ctx) > /* Release instance buffer */ > void s5p_mfc_release_instance_buffer_v5(struct s5p_mfc_ctx *ctx) > { > - if (ctx->ctx_buf) { > - vb2_dma_contig_memops.put(ctx->ctx_buf); > - ctx->ctx_phys = 0; > - ctx->ctx_buf = NULL; > + if (ctx->ctx.alloc) { > + vb2_dma_contig_memops.put(ctx->ctx.alloc); > + ctx->ctx.alloc = NULL; > + ctx->ctx.ofs = 0; > + ctx->ctx.virt = NULL; > + ctx->ctx.dma = 0; > } > - if (ctx->shm_alloc) { > - vb2_dma_contig_memops.put(ctx->shm_alloc); > - ctx->shm_alloc = NULL; > - ctx->shm = NULL; > + if (ctx->shm.alloc) { > + vb2_dma_contig_memops.put(ctx->shm.alloc); > + ctx->shm.alloc = NULL; > + ctx->shm.ofs = 0; > + ctx->shm.virt = NULL; > } > } > > @@ -317,7 +321,7 @@ void s5p_mfc_release_dev_context_buffer_v5(struct > s5p_mfc_dev *dev) > static void s5p_mfc_write_info_v5(struct s5p_mfc_ctx *ctx, unsigned int data, > unsigned int ofs) > { > - writel(data, (ctx->shm + ofs)); > + writel(data, (ctx->shm.virt + ofs)); > wmb(); > } > > @@ -325,33 +329,94 @@ static unsigned int s5p_mfc_read_info_v5(struct > s5p_mfc_ctx *ctx, > unsigned int ofs) > { > rmb(); > - return readl(ctx->shm + ofs); > + return readl(ctx->shm.virt + ofs); > } > > void s5p_mfc_dec_calc_dpb_size_v5(struct s5p_mfc_ctx *ctx) > { > - /* NOP */ > + unsigned int guard_width, guard_height; > + > + ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN); > + ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN); > + mfc_debug(2, > + "SEQ Done: Movie dimensions %dx%d, buffer dimensions: %dx%d\n", > + ctx->img_width, ctx->img_height, ctx->buf_width, > + ctx->buf_height); > + > + if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC) { > + ctx->luma_size = ALIGN(ctx->buf_width * ctx->buf_height, > + S5P_FIMV_DEC_BUF_ALIGN); > + ctx->chroma_size = ALIGN(ctx->buf_width * > + ALIGN((ctx->img_height >> 1), > + S5P_FIMV_NV12MT_VALIGN), > + S5P_FIMV_DEC_BUF_ALIGN); > + ctx->mv_size = ALIGN(ctx->buf_width * > + ALIGN((ctx->buf_height >> 2), > + S5P_FIMV_NV12MT_VALIGN), > + S5P_FIMV_DEC_BUF_ALIGN); > + } else { > + guard_width = > + ALIGN(ctx->img_width + 24, S5P_FIMV_NV12MT_HALIGN); > + guard_height = > + ALIGN(ctx->img_height + 16, S5P_FIMV_NV12MT_VALIGN); > + ctx->luma_size = ALIGN(guard_width * guard_height, > + S5P_FIMV_DEC_BUF_ALIGN); > + > + guard_width = > + ALIGN(ctx->img_width + 16, S5P_FIMV_NV12MT_HALIGN); > + guard_height = > + ALIGN((ctx->img_height >> 1) + 4, > + S5P_FIMV_NV12MT_VALIGN); > + ctx->chroma_size = ALIGN(guard_width * guard_height, > + S5P_FIMV_DEC_BUF_ALIGN); > + > + ctx->mv_size = 0; > + } > } > > void s5p_mfc_enc_calc_src_size_v5(struct s5p_mfc_ctx *ctx) > { > - /* NOP */ > + if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) { > + ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN); > + > + ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN) > + * ALIGN(ctx->img_height, S5P_FIMV_NV12M_LVALIGN); > + ctx->chroma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN) > + * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12M_CVALIGN); > + > + ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12M_SALIGN); > + ctx->chroma_size = > + ALIGN(ctx->chroma_size, S5P_FIMV_NV12M_SALIGN); > + } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) { > + ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN); > + > + ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN) > + * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN); > + ctx->chroma_size = > + ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN) > + * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN); > + > + ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12MT_SALIGN); > + ctx->chroma_size = > + ALIGN(ctx->chroma_size, S5P_FIMV_NV12MT_SALIGN); > + } > } > > /* Set registers for decoding temporary buffers */ > static void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx) > { > struct s5p_mfc_dev *dev = ctx->dev; > + struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; > > - mfc_write(dev, OFFSETA(ctx->desc_phys), S5P_FIMV_SI_CH0_DESC_ADR); > - mfc_write(dev, DESC_BUF_SIZE, S5P_FIMV_SI_CH0_DESC_SIZE); > + mfc_write(dev, OFFSETA(ctx->dsc.dma), S5P_FIMV_SI_CH0_DESC_ADR); > + mfc_write(dev, buf_size->dsc, S5P_FIMV_SI_CH0_DESC_SIZE); > } > > /* Set registers for shared buffer */ > static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx) > { > struct s5p_mfc_dev *dev = ctx->dev; > - mfc_write(dev, ctx->shm_ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR); > + mfc_write(dev, ctx->shm.ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR); > } > > /* Set registers for decoding stream buffer */ > @@ -775,9 +840,9 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx > *ctx) > reg |= p_264->profile; > mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE); > /* interlace */ > - mfc_write(dev, p->interlace, S5P_FIMV_ENC_PIC_STRUCT); > + mfc_write(dev, p_264->interlace, S5P_FIMV_ENC_PIC_STRUCT); > /* height */ > - if (p->interlace) > + if (p_264->interlace) > mfc_write(dev, ctx->img_height >> 1, S5P_FIMV_ENC_VSIZE_PX); > /* loopfilter ctrl */ > mfc_write(dev, p_264->loop_filter_mode, S5P_FIMV_ENC_LF_CTRL); > @@ -819,7 +884,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx > *ctx) > reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG); > /* macroblock level rate control */ > reg &= ~(0x1 << 8); > - reg |= (p_264->rc_mb << 8); > + reg |= (p->rc_mb << 8); > /* frame QP */ > reg &= ~(0x3F); > reg |= p_264->rc_frame_qp; > @@ -840,7 +905,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx > *ctx) > reg |= p_264->rc_min_qp; > mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND); > /* macroblock adaptive scaling features */ > - if (p_264->rc_mb) { > + if (p->rc_mb) { > reg = mfc_read(dev, S5P_FIMV_ENC_RC_MB_CTRL); > /* dark region */ > reg &= ~(0x1 << 3); > @@ -856,8 +921,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx > *ctx) > reg |= p_264->rc_mb_activity; > mfc_write(dev, reg, S5P_FIMV_ENC_RC_MB_CTRL); > } > - if (!p->rc_frame && > - !p_264->rc_mb) { > + if (!p->rc_frame && !p->rc_mb) { > shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP); > shm &= ~(0xFFF); > shm |= ((p_264->rc_b_frame_qp & 0x3F) << 6); > @@ -1487,8 +1551,9 @@ int s5p_mfc_get_dec_frame_type_v5(struct s5p_mfc_dev *dev) > > int s5p_mfc_get_disp_frame_type_v5(struct s5p_mfc_ctx *ctx) > { > - /* NOP */ > - return -1; > + return (s5p_mfc_read_info_v5(ctx, DISP_PIC_FRAME_TYPE) >> > + S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT) & > + S5P_FIMV_DECODE_FRAME_MASK; > } > > int s5p_mfc_get_consumed_stream_v5(struct s5p_mfc_dev *dev) > -- > 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc.h b/drivers/media/platform/s5p-mfc/regs-mfc.h index a19bece..f33c54d 100644 --- a/drivers/media/platform/s5p-mfc/regs-mfc.h +++ b/drivers/media/platform/s5p-mfc/regs-mfc.h @@ -12,6 +12,9 @@ #ifndef _REGS_FIMV_H #define _REGS_FIMV_H +#include <linux/kernel.h> +#include <linux/sizes.h> + #define S5P_FIMV_REG_SIZE (S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) #define S5P_FIMV_REG_COUNT ((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4) @@ -414,5 +417,22 @@ #define S5P_FIMV_SHARED_EXTENDED_SAR 0x0078 #define S5P_FIMV_SHARED_H264_I_PERIOD 0x009C #define S5P_FIMV_SHARED_RC_CONTROL_CONFIG 0x00A0 +#define S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT 2 + +/* Offset used by the hardware to store addresses */ +#define MFC_OFFSET_SHIFT 11 + +#define FIRMWARE_ALIGN (128 * SZ_1K) /* 128KB */ +#define MFC_H264_CTX_BUF_SIZE (600 * SZ_1K) /* 600KB per H264 instance */ +#define MFC_CTX_BUF_SIZE (10 * SZ_1K) /* 10KB per instance */ +#define DESC_BUF_SIZE (128 * SZ_1K) /* 128KB for DESC buffer */ +#define SHARED_BUF_SIZE (8 * SZ_1K) /* 8KB for shared buffer */ + +#define DEF_CPB_SIZE (256 * SZ_1K) /* 256KB */ +#define MAX_CPB_SIZE (4 * SZ_1M) /* 4MB */ +#define MAX_FW_SIZE (384 * SZ_1K) + +#define MFC_VERSION 0x51 +#define MFC_NUM_PORTS 2 #endif /* _REGS_FIMV_H */ diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 3319410..a8299ce 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -436,7 +436,6 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, unsigned int reason, unsigned int err) { struct s5p_mfc_dev *dev; - unsigned int guard_width, guard_height; if (ctx == NULL) return; @@ -450,40 +449,8 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, ctx->img_height = s5p_mfc_hw_call(dev->mfc_ops, get_img_height, dev); - ctx->buf_width = ALIGN(ctx->img_width, - S5P_FIMV_NV12MT_HALIGN); - ctx->buf_height = ALIGN(ctx->img_height, - S5P_FIMV_NV12MT_VALIGN); - mfc_debug(2, "SEQ Done: Movie dimensions %dx%d, " - "buffer dimensions: %dx%d\n", ctx->img_width, - ctx->img_height, ctx->buf_width, - ctx->buf_height); - if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) { - ctx->luma_size = ALIGN(ctx->buf_width * - ctx->buf_height, S5P_FIMV_DEC_BUF_ALIGN); - ctx->chroma_size = ALIGN(ctx->buf_width * - ALIGN((ctx->img_height >> 1), - S5P_FIMV_NV12MT_VALIGN), - S5P_FIMV_DEC_BUF_ALIGN); - ctx->mv_size = ALIGN(ctx->buf_width * - ALIGN((ctx->buf_height >> 2), - S5P_FIMV_NV12MT_VALIGN), - S5P_FIMV_DEC_BUF_ALIGN); - } else { - guard_width = ALIGN(ctx->img_width + 24, - S5P_FIMV_NV12MT_HALIGN); - guard_height = ALIGN(ctx->img_height + 16, - S5P_FIMV_NV12MT_VALIGN); - ctx->luma_size = ALIGN(guard_width * - guard_height, S5P_FIMV_DEC_BUF_ALIGN); - guard_width = ALIGN(ctx->img_width + 16, - S5P_FIMV_NV12MT_HALIGN); - guard_height = ALIGN((ctx->img_height >> 1) + 4, - S5P_FIMV_NV12MT_VALIGN); - ctx->chroma_size = ALIGN(guard_width * - guard_height, S5P_FIMV_DEC_BUF_ALIGN); - ctx->mv_size = 0; - } + s5p_mfc_hw_call(dev->mfc_ops, dec_calc_dpb_size, ctx); + ctx->dpb_count = s5p_mfc_hw_call(dev->mfc_ops, get_dpb_count, dev); if (ctx->img_width == 0 || ctx->img_height == 0) @@ -993,6 +960,9 @@ static int s5p_mfc_probe(struct platform_device *pdev) return -ENODEV; } + dev->variant = (struct s5p_mfc_variant *) + platform_get_device_id(pdev)->driver_data; + ret = s5p_mfc_init_pm(dev); if (ret < 0) { dev_err(&pdev->dev, "failed to get mfc clock source\n"); @@ -1235,9 +1205,43 @@ static const struct dev_pm_ops s5p_mfc_pm_ops = { NULL) }; +struct s5p_mfc_buf_size_v5 mfc_buf_size_v5 = { + .h264_ctx = MFC_H264_CTX_BUF_SIZE, + .non_h264_ctx = MFC_CTX_BUF_SIZE, + .dsc = DESC_BUF_SIZE, + .shm = SHARED_BUF_SIZE, +}; + +struct s5p_mfc_buf_size buf_size_v5 = { + .fw = MAX_FW_SIZE, + .cpb = MAX_CPB_SIZE, + .priv = &mfc_buf_size_v5, +}; + +struct s5p_mfc_buf_align mfc_buf_align_v5 = { + .base = MFC_BASE_ALIGN_ORDER, +}; + +static struct s5p_mfc_variant mfc_drvdata_v5 = { + .version = MFC_VERSION, + .port_num = MFC_NUM_PORTS, + .buf_size = &buf_size_v5, + .buf_align = &mfc_buf_align_v5, +}; + +static struct platform_device_id mfc_driver_ids[] = { + { + .name = "s5p-mfc", + .driver_data = (unsigned long)&mfc_drvdata_v5, + }, + {}, +}; +MODULE_DEVICE_TABLE(platform, mfc_driver_ids); + static struct platform_driver s5p_mfc_driver = { - .probe = s5p_mfc_probe, - .remove = __devexit_p(s5p_mfc_remove), + .probe = s5p_mfc_probe, + .remove = __devexit_p(s5p_mfc_remove), + .id_table = mfc_driver_ids, .driver = { .name = S5P_MFC_NAME, .owner = THIS_MODULE, diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c index f3d7874..344b31e 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c @@ -113,8 +113,8 @@ int s5p_mfc_open_inst_cmd_v5(struct s5p_mfc_ctx *ctx) h2r_args.arg[0] = S5P_FIMV_CODEC_NONE; }; h2r_args.arg[1] = 0; /* no crc & no pixelcache */ - h2r_args.arg[2] = ctx->ctx_ofs; - h2r_args.arg[3] = ctx->ctx_size; + h2r_args.arg[2] = ctx->ctx.ofs; + h2r_args.arg[3] = ctx->ctx.size; ret = s5p_mfc_cmd_host2risc_v5(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE, &h2r_args); if (ret) { diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index ccb59ac..e9e89ac 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -30,17 +30,6 @@ * while mmaping */ #define DST_QUEUE_OFF_BASE (TASK_SIZE / 2) -/* Offset used by the hardware to store addresses */ -#define MFC_OFFSET_SHIFT 11 - -#define FIRMWARE_ALIGN 0x20000 /* 128KB */ -#define MFC_H264_CTX_BUF_SIZE 0x96000 /* 600KB per H264 instance */ -#define MFC_CTX_BUF_SIZE 0x2800 /* 10KB per instance */ -#define DESC_BUF_SIZE 0x20000 /* 128KB for DESC buffer */ -#define SHARED_BUF_SIZE 0x2000 /* 8KB for shared buffer */ - -#define DEF_CPB_SIZE 0x40000 /* 512KB */ - #define MFC_BANK1_ALLOC_CTX 0 #define MFC_BANK2_ALLOC_CTX 1 @@ -207,6 +196,48 @@ struct s5p_mfc_pm { struct device *device; }; +struct s5p_mfc_buf_size_v5 { + unsigned int h264_ctx; + unsigned int non_h264_ctx; + unsigned int dsc; + unsigned int shm; +}; + +struct s5p_mfc_buf_size { + unsigned int fw; + unsigned int cpb; + void *priv; +}; + +struct s5p_mfc_buf_align { + unsigned int base; +}; + +struct s5p_mfc_variant { + unsigned int version; + unsigned int port_num; + struct s5p_mfc_buf_size *buf_size; + struct s5p_mfc_buf_align *buf_align; +}; + +/** + * struct s5p_mfc_priv_buf - represents internal used buffer + * @alloc: allocation-specific context for each buffer + * (videobuf2 allocator) + * @ofs: offset of each buffer, will be used for MFC + * @virt: kernel virtual address, only valid when the + * buffer accessed by driver + * @dma: DMA address, only valid when kernel DMA API used + * @size: size of the buffer + */ +struct s5p_mfc_priv_buf { + void *alloc; + unsigned long ofs; + void *virt; + dma_addr_t dma; + size_t size; +}; + /** * struct s5p_mfc_dev - The struct containing driver internal parameters. * @@ -221,6 +252,7 @@ struct s5p_mfc_pm { * @dec_ctrl_handler: control framework handler for decoding * @enc_ctrl_handler: control framework handler for encoding * @pm: power management control + * @variant: MFC hardware variant information * @num_inst: couter of active MFC instances * @irqlock: lock for operations on videobuf2 queues * @condlock: lock for changing/checking if a context is ready to be @@ -259,6 +291,7 @@ struct s5p_mfc_dev { struct v4l2_ctrl_handler dec_ctrl_handler; struct v4l2_ctrl_handler enc_ctrl_handler; struct s5p_mfc_pm pm; + struct s5p_mfc_variant *variant; int num_inst; spinlock_t irqlock; /* lock when operating on videobuf2 queues */ spinlock_t condlock; /* lock when changing/checking if a context is @@ -299,7 +332,6 @@ struct s5p_mfc_h264_enc_params { u8 max_ref_pic; u8 num_ref_pic_4p; int _8x8_transform; - int rc_mb; int rc_mb_dark; int rc_mb_smooth; int rc_mb_static; @@ -318,6 +350,7 @@ struct s5p_mfc_h264_enc_params { enum v4l2_mpeg_video_h264_level level_v4l2; int level; u16 cpb_size; + int interlace; }; /** @@ -356,6 +389,7 @@ struct s5p_mfc_enc_params { u8 pad_cb; u8 pad_cr; int rc_frame; + int rc_mb; u32 rc_bitrate; u16 rc_reaction_coeff; u16 vbv_size; @@ -367,7 +401,6 @@ struct s5p_mfc_enc_params { u8 num_b_frame; u32 rc_framerate_num; u32 rc_framerate_denom; - int interlace; union { struct s5p_mfc_h264_enc_params h264; @@ -452,14 +485,9 @@ struct s5p_mfc_codec_ops { * @dpb_count: count of the DPB buffers required by MFC hw * @total_dpb_count: count of DPB buffers with additional buffers * requested by the application - * @ctx_buf: handle to the memory associated with this context - * @ctx_phys: address of the memory associated with this context - * @ctx_size: size of the memory associated with this context - * @desc_buf: description buffer for decoding handle - * @desc_phys: description buffer for decoding address - * @shm_alloc: handle for the shared memory buffer - * @shm: virtual address for the shared memory buffer - * @shm_ofs: address offset for shared memory + * @ctx: context buffer information + * @dsc: descriptor buffer information + * @shm: shared memory buffer information * @enc_params: encoding parameters for MFC * @enc_dst_buf_size: size of the buffers for encoder output * @frame_type: used to force the type of the next encoded frame @@ -544,18 +572,9 @@ struct s5p_mfc_ctx { int total_dpb_count; /* Buffers */ - void *ctx_buf; - size_t ctx_phys; - size_t ctx_ofs; - size_t ctx_size; - - void *desc_buf; - size_t desc_phys; - - - void *shm_alloc; - void *shm; - size_t shm_ofs; + struct s5p_mfc_priv_buf ctx; + struct s5p_mfc_priv_buf dsc; + struct s5p_mfc_priv_buf shm; struct s5p_mfc_enc_params enc_params; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index 4a39e5e..524380c 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c @@ -43,7 +43,12 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev) mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); return -EINVAL; } - dev->fw_size = ALIGN(fw_blob->size, FIRMWARE_ALIGN); + dev->fw_size = dev->variant->buf_size->fw; + if (fw_blob->size > dev->fw_size) { + mfc_err("MFC firmware is too big to be loaded\n"); + release_firmware(fw_blob); + return -ENOMEM; + } if (s5p_mfc_bitproc_buf) { mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n"); release_firmware(fw_blob); diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 02e1a94..fe34f17 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -985,45 +985,13 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) mfc_debug(2, "fmt - w: %d, h: %d, ctx - w: %d, h: %d\n", pix_fmt_mp->width, pix_fmt_mp->height, ctx->img_width, ctx->img_height); - if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) { - ctx->buf_width = ALIGN(ctx->img_width, - S5P_FIMV_NV12M_HALIGN); - ctx->luma_size = ALIGN(ctx->img_width, - S5P_FIMV_NV12M_HALIGN) * ALIGN(ctx->img_height, - S5P_FIMV_NV12M_LVALIGN); - ctx->chroma_size = ALIGN(ctx->img_width, - S5P_FIMV_NV12M_HALIGN) * ALIGN((ctx->img_height - >> 1), S5P_FIMV_NV12M_CVALIGN); - - ctx->luma_size = ALIGN(ctx->luma_size, - S5P_FIMV_NV12M_SALIGN); - ctx->chroma_size = ALIGN(ctx->chroma_size, - S5P_FIMV_NV12M_SALIGN); - - pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size; - pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width; - pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size; - pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width; - - } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) { - ctx->buf_width = ALIGN(ctx->img_width, - S5P_FIMV_NV12MT_HALIGN); - ctx->luma_size = ALIGN(ctx->img_width, - S5P_FIMV_NV12MT_HALIGN) * ALIGN(ctx->img_height, - S5P_FIMV_NV12MT_VALIGN); - ctx->chroma_size = ALIGN(ctx->img_width, - S5P_FIMV_NV12MT_HALIGN) * ALIGN((ctx->img_height - >> 1), S5P_FIMV_NV12MT_VALIGN); - ctx->luma_size = ALIGN(ctx->luma_size, - S5P_FIMV_NV12MT_SALIGN); - ctx->chroma_size = ALIGN(ctx->chroma_size, - S5P_FIMV_NV12MT_SALIGN); - - pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size; - pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width; - pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size; - pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width; - } + + s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx); + pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size; + pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width; + pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size; + pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width; + ctx->src_bufs_cnt = 0; ctx->output_state = QUEUE_FREE; } else { @@ -1349,7 +1317,7 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl) p->codec.h264._8x8_transform = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: - p->codec.h264.rc_mb = ctrl->val; + p->rc_mb = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: p->codec.h264.rc_frame_qp = ctrl->val; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index fe36c92..f1871e7 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c @@ -36,28 +36,29 @@ /* Allocate temporary buffers for decoding */ int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx) { - void *desc_virt; struct s5p_mfc_dev *dev = ctx->dev; + struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; - ctx->desc_buf = vb2_dma_contig_memops.alloc( - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], DESC_BUF_SIZE); - if (IS_ERR_VALUE((int)ctx->desc_buf)) { - ctx->desc_buf = NULL; + ctx->dsc.alloc = vb2_dma_contig_memops.alloc( + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], + buf_size->dsc); + if (IS_ERR_VALUE((int)ctx->dsc.alloc)) { + ctx->dsc.alloc = NULL; mfc_err("Allocating DESC buffer failed\n"); return -ENOMEM; } - ctx->desc_phys = s5p_mfc_mem_cookie( - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->desc_buf); - BUG_ON(ctx->desc_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); - desc_virt = vb2_dma_contig_memops.vaddr(ctx->desc_buf); - if (desc_virt == NULL) { - vb2_dma_contig_memops.put(ctx->desc_buf); - ctx->desc_phys = 0; - ctx->desc_buf = NULL; + ctx->dsc.dma = s5p_mfc_mem_cookie( + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->dsc.alloc); + BUG_ON(ctx->dsc.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); + ctx->dsc.virt = vb2_dma_contig_memops.vaddr(ctx->dsc.alloc); + if (ctx->dsc.virt == NULL) { + vb2_dma_contig_memops.put(ctx->dsc.alloc); + ctx->dsc.dma = 0; + ctx->dsc.alloc = NULL; mfc_err("Remapping DESC buffer failed\n"); return -ENOMEM; } - memset(desc_virt, 0, DESC_BUF_SIZE); + memset(ctx->dsc.virt, 0, buf_size->dsc); wmb(); return 0; } @@ -65,10 +66,10 @@ int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx) /* Release temporary buffers for decoding */ void s5p_mfc_release_dec_desc_buffer_v5(struct s5p_mfc_ctx *ctx) { - if (ctx->desc_phys) { - vb2_dma_contig_memops.put(ctx->desc_buf); - ctx->desc_phys = 0; - ctx->desc_buf = NULL; + if (ctx->dsc.dma) { + vb2_dma_contig_memops.put(ctx->dsc.alloc); + ctx->dsc.alloc = NULL; + ctx->dsc.dma = 0; } } @@ -229,60 +230,60 @@ void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx) /* Allocate memory for instance data buffer */ int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx) { - void *context_virt; struct s5p_mfc_dev *dev = ctx->dev; + struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; - if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC || - ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) - ctx->ctx_size = MFC_H264_CTX_BUF_SIZE; + if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || + ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) + ctx->ctx.size = buf_size->h264_ctx; else - ctx->ctx_size = MFC_CTX_BUF_SIZE; - ctx->ctx_buf = vb2_dma_contig_memops.alloc( - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_size); - if (IS_ERR(ctx->ctx_buf)) { + ctx->ctx.size = buf_size->non_h264_ctx; + ctx->ctx.alloc = vb2_dma_contig_memops.alloc( + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.size); + if (IS_ERR(ctx->ctx.alloc)) { mfc_err("Allocating context buffer failed\n"); - ctx->ctx_phys = 0; - ctx->ctx_buf = NULL; + ctx->ctx.alloc = NULL; return -ENOMEM; } - ctx->ctx_phys = s5p_mfc_mem_cookie( - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_buf); - BUG_ON(ctx->ctx_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); - ctx->ctx_ofs = OFFSETA(ctx->ctx_phys); - context_virt = vb2_dma_contig_memops.vaddr(ctx->ctx_buf); - if (context_virt == NULL) { + ctx->ctx.dma = s5p_mfc_mem_cookie( + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx.alloc); + BUG_ON(ctx->ctx.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); + ctx->ctx.ofs = OFFSETA(ctx->ctx.dma); + ctx->ctx.virt = vb2_dma_contig_memops.vaddr(ctx->ctx.alloc); + if (!ctx->ctx.virt) { mfc_err("Remapping instance buffer failed\n"); - vb2_dma_contig_memops.put(ctx->ctx_buf); - ctx->ctx_phys = 0; - ctx->ctx_buf = NULL; + vb2_dma_contig_memops.put(ctx->ctx.alloc); + ctx->ctx.alloc = NULL; + ctx->ctx.ofs = 0; + ctx->ctx.dma = 0; return -ENOMEM; } /* Zero content of the allocated memory */ - memset(context_virt, 0, ctx->ctx_size); + memset(ctx->ctx.virt, 0, ctx->ctx.size); wmb(); /* Initialize shared memory */ - ctx->shm_alloc = vb2_dma_contig_memops.alloc( - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], SHARED_BUF_SIZE); - if (IS_ERR(ctx->shm_alloc)) { + ctx->shm.alloc = vb2_dma_contig_memops.alloc( + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], buf_size->shm); + if (IS_ERR(ctx->shm.alloc)) { mfc_err("failed to allocate shared memory\n"); - return PTR_ERR(ctx->shm_alloc); + return PTR_ERR(ctx->shm.alloc); } /* shared memory offset only keeps the offset from base (port a) */ - ctx->shm_ofs = s5p_mfc_mem_cookie( - dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->shm_alloc) + ctx->shm.ofs = s5p_mfc_mem_cookie( + dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->shm.alloc) - dev->bank1; - BUG_ON(ctx->shm_ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); + BUG_ON(ctx->shm.ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); - ctx->shm = vb2_dma_contig_memops.vaddr(ctx->shm_alloc); - if (!ctx->shm) { - vb2_dma_contig_memops.put(ctx->shm_alloc); - ctx->shm_ofs = 0; - ctx->shm_alloc = NULL; + ctx->shm.virt = vb2_dma_contig_memops.vaddr(ctx->shm.alloc); + if (!ctx->shm.virt) { + vb2_dma_contig_memops.put(ctx->shm.alloc); + ctx->shm.alloc = NULL; + ctx->shm.ofs = 0; mfc_err("failed to virt addr of shared memory\n"); return -ENOMEM; } - memset((void *)ctx->shm, 0, SHARED_BUF_SIZE); + memset((void *)ctx->shm.virt, 0, buf_size->shm); wmb(); return 0; } @@ -290,15 +291,18 @@ int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx) /* Release instance buffer */ void s5p_mfc_release_instance_buffer_v5(struct s5p_mfc_ctx *ctx) { - if (ctx->ctx_buf) { - vb2_dma_contig_memops.put(ctx->ctx_buf); - ctx->ctx_phys = 0; - ctx->ctx_buf = NULL; + if (ctx->ctx.alloc) { + vb2_dma_contig_memops.put(ctx->ctx.alloc); + ctx->ctx.alloc = NULL; + ctx->ctx.ofs = 0; + ctx->ctx.virt = NULL; + ctx->ctx.dma = 0; } - if (ctx->shm_alloc) { - vb2_dma_contig_memops.put(ctx->shm_alloc); - ctx->shm_alloc = NULL; - ctx->shm = NULL; + if (ctx->shm.alloc) { + vb2_dma_contig_memops.put(ctx->shm.alloc); + ctx->shm.alloc = NULL; + ctx->shm.ofs = 0; + ctx->shm.virt = NULL; } } @@ -317,7 +321,7 @@ void s5p_mfc_release_dev_context_buffer_v5(struct s5p_mfc_dev *dev) static void s5p_mfc_write_info_v5(struct s5p_mfc_ctx *ctx, unsigned int data, unsigned int ofs) { - writel(data, (ctx->shm + ofs)); + writel(data, (ctx->shm.virt + ofs)); wmb(); } @@ -325,33 +329,94 @@ static unsigned int s5p_mfc_read_info_v5(struct s5p_mfc_ctx *ctx, unsigned int ofs) { rmb(); - return readl(ctx->shm + ofs); + return readl(ctx->shm.virt + ofs); } void s5p_mfc_dec_calc_dpb_size_v5(struct s5p_mfc_ctx *ctx) { - /* NOP */ + unsigned int guard_width, guard_height; + + ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN); + ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN); + mfc_debug(2, + "SEQ Done: Movie dimensions %dx%d, buffer dimensions: %dx%d\n", + ctx->img_width, ctx->img_height, ctx->buf_width, + ctx->buf_height); + + if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC) { + ctx->luma_size = ALIGN(ctx->buf_width * ctx->buf_height, + S5P_FIMV_DEC_BUF_ALIGN); + ctx->chroma_size = ALIGN(ctx->buf_width * + ALIGN((ctx->img_height >> 1), + S5P_FIMV_NV12MT_VALIGN), + S5P_FIMV_DEC_BUF_ALIGN); + ctx->mv_size = ALIGN(ctx->buf_width * + ALIGN((ctx->buf_height >> 2), + S5P_FIMV_NV12MT_VALIGN), + S5P_FIMV_DEC_BUF_ALIGN); + } else { + guard_width = + ALIGN(ctx->img_width + 24, S5P_FIMV_NV12MT_HALIGN); + guard_height = + ALIGN(ctx->img_height + 16, S5P_FIMV_NV12MT_VALIGN); + ctx->luma_size = ALIGN(guard_width * guard_height, + S5P_FIMV_DEC_BUF_ALIGN); + + guard_width = + ALIGN(ctx->img_width + 16, S5P_FIMV_NV12MT_HALIGN); + guard_height = + ALIGN((ctx->img_height >> 1) + 4, + S5P_FIMV_NV12MT_VALIGN); + ctx->chroma_size = ALIGN(guard_width * guard_height, + S5P_FIMV_DEC_BUF_ALIGN); + + ctx->mv_size = 0; + } } void s5p_mfc_enc_calc_src_size_v5(struct s5p_mfc_ctx *ctx) { - /* NOP */ + if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) { + ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN); + + ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN) + * ALIGN(ctx->img_height, S5P_FIMV_NV12M_LVALIGN); + ctx->chroma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN) + * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12M_CVALIGN); + + ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12M_SALIGN); + ctx->chroma_size = + ALIGN(ctx->chroma_size, S5P_FIMV_NV12M_SALIGN); + } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) { + ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN); + + ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN) + * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN); + ctx->chroma_size = + ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN) + * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN); + + ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12MT_SALIGN); + ctx->chroma_size = + ALIGN(ctx->chroma_size, S5P_FIMV_NV12MT_SALIGN); + } } /* Set registers for decoding temporary buffers */ static void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; + struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv; - mfc_write(dev, OFFSETA(ctx->desc_phys), S5P_FIMV_SI_CH0_DESC_ADR); - mfc_write(dev, DESC_BUF_SIZE, S5P_FIMV_SI_CH0_DESC_SIZE); + mfc_write(dev, OFFSETA(ctx->dsc.dma), S5P_FIMV_SI_CH0_DESC_ADR); + mfc_write(dev, buf_size->dsc, S5P_FIMV_SI_CH0_DESC_SIZE); } /* Set registers for shared buffer */ static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; - mfc_write(dev, ctx->shm_ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR); + mfc_write(dev, ctx->shm.ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR); } /* Set registers for decoding stream buffer */ @@ -775,9 +840,9 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) reg |= p_264->profile; mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE); /* interlace */ - mfc_write(dev, p->interlace, S5P_FIMV_ENC_PIC_STRUCT); + mfc_write(dev, p_264->interlace, S5P_FIMV_ENC_PIC_STRUCT); /* height */ - if (p->interlace) + if (p_264->interlace) mfc_write(dev, ctx->img_height >> 1, S5P_FIMV_ENC_VSIZE_PX); /* loopfilter ctrl */ mfc_write(dev, p_264->loop_filter_mode, S5P_FIMV_ENC_LF_CTRL); @@ -819,7 +884,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG); /* macroblock level rate control */ reg &= ~(0x1 << 8); - reg |= (p_264->rc_mb << 8); + reg |= (p->rc_mb << 8); /* frame QP */ reg &= ~(0x3F); reg |= p_264->rc_frame_qp; @@ -840,7 +905,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) reg |= p_264->rc_min_qp; mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND); /* macroblock adaptive scaling features */ - if (p_264->rc_mb) { + if (p->rc_mb) { reg = mfc_read(dev, S5P_FIMV_ENC_RC_MB_CTRL); /* dark region */ reg &= ~(0x1 << 3); @@ -856,8 +921,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) reg |= p_264->rc_mb_activity; mfc_write(dev, reg, S5P_FIMV_ENC_RC_MB_CTRL); } - if (!p->rc_frame && - !p_264->rc_mb) { + if (!p->rc_frame && !p->rc_mb) { shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP); shm &= ~(0xFFF); shm |= ((p_264->rc_b_frame_qp & 0x3F) << 6); @@ -1487,8 +1551,9 @@ int s5p_mfc_get_dec_frame_type_v5(struct s5p_mfc_dev *dev) int s5p_mfc_get_disp_frame_type_v5(struct s5p_mfc_ctx *ctx) { - /* NOP */ - return -1; + return (s5p_mfc_read_info_v5(ctx, DISP_PIC_FRAME_TYPE) >> + S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT) & + S5P_FIMV_DECODE_FRAME_MASK; } int s5p_mfc_get_consumed_stream_v5(struct s5p_mfc_dev *dev)