Skip to content

Commit

Permalink
[media] s5p-mfc: Add MFC variant data to device context
Browse files Browse the repository at this point in the history
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>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Arun Kumar K authored and Mauro Carvalho Chehab committed Oct 6, 2012
1 parent 43a1ea1 commit 8f532a7
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 187 deletions.
20 changes: 20 additions & 0 deletions drivers/media/platform/s5p-mfc/regs-mfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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 */
78 changes: 41 additions & 37 deletions drivers/media/platform/s5p-mfc/s5p_mfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,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;
Expand All @@ -491,40 +490,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)
Expand Down Expand Up @@ -1066,6 +1033,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");
Expand Down Expand Up @@ -1309,9 +1279,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,
Expand Down
4 changes: 2 additions & 2 deletions drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v5.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
85 changes: 52 additions & 33 deletions drivers/media/platform/s5p-mfc/s5p_mfc_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -210,6 +199,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.
*
Expand All @@ -224,6 +255,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
Expand Down Expand Up @@ -262,6 +294,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
Expand Down Expand Up @@ -302,7 +335,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;
Expand All @@ -321,6 +353,7 @@ struct s5p_mfc_h264_enc_params {
enum v4l2_mpeg_video_h264_level level_v4l2;
int level;
u16 cpb_size;
int interlace;
};

/**
Expand Down Expand Up @@ -359,6 +392,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;
Expand All @@ -370,7 +404,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;
Expand Down Expand Up @@ -455,14 +488,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
Expand Down Expand Up @@ -547,18 +575,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;

Expand Down
7 changes: 6 additions & 1 deletion drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
48 changes: 8 additions & 40 deletions drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,45 +977,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 {
Expand Down Expand Up @@ -1357,7 +1325,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;
Expand Down
Loading

0 comments on commit 8f532a7

Please sign in to comment.