brintos

brintos / linux-shallow public Read only

0
0
Text · 50.4 KiB · 365f552 Raw
1640 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * drivers/media/platform/samsung/mfc5/s5p_mfc_opr_v5.c4 *5 * Samsung MFC (Multi Function Codec - FIMV) driver6 * This file contains hw related functions.7 *8 * Kamil Debski, Copyright (c) 2011 Samsung Electronics9 * http://www.samsung.com/10 */11 12#include "s5p_mfc_common.h"13#include "s5p_mfc_cmd.h"14#include "s5p_mfc_ctrl.h"15#include "s5p_mfc_debug.h"16#include "s5p_mfc_intr.h"17#include "s5p_mfc_pm.h"18#include "s5p_mfc_opr.h"19#include "s5p_mfc_opr_v5.h"20#include <asm/cacheflush.h>21#include <linux/delay.h>22#include <linux/dma-mapping.h>23#include <linux/err.h>24#include <linux/firmware.h>25#include <linux/io.h>26#include <linux/jiffies.h>27#include <linux/mm.h>28#include <linux/sched.h>29 30#define OFFSETA(x)		(((x) - dev->dma_base[BANK_L_CTX]) >> MFC_OFFSET_SHIFT)31#define OFFSETB(x)		(((x) - dev->dma_base[BANK_R_CTX]) >> MFC_OFFSET_SHIFT)32 33/* Allocate temporary buffers for decoding */34static int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx)35{36	struct s5p_mfc_dev *dev = ctx->dev;37	const struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;38	int ret;39 40	ctx->dsc.size = buf_size->dsc;41	ret =  s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &ctx->dsc);42	if (ret) {43		mfc_err("Failed to allocate temporary buffer\n");44		return ret;45	}46 47	BUG_ON(ctx->dsc.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));48	memset(ctx->dsc.virt, 0, ctx->dsc.size);49	wmb();50	return 0;51}52 53 54/* Release temporary buffers for decoding */55static void s5p_mfc_release_dec_desc_buffer_v5(struct s5p_mfc_ctx *ctx)56{57	s5p_mfc_release_priv_buf(ctx->dev, &ctx->dsc);58}59 60/* Allocate codec buffers */61static int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx)62{63	struct s5p_mfc_dev *dev = ctx->dev;64	unsigned int enc_ref_y_size = 0;65	unsigned int enc_ref_c_size = 0;66	unsigned int guard_width, guard_height;67	int ret;68 69	if (ctx->type == MFCINST_DECODER) {70		mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",71			  ctx->luma_size, ctx->chroma_size, ctx->mv_size);72		mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);73	} else if (ctx->type == MFCINST_ENCODER) {74		enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)75			* ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);76		enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);77 78		if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) {79			enc_ref_c_size = ALIGN(ctx->img_width,80						S5P_FIMV_NV12MT_HALIGN)81						* ALIGN(ctx->img_height >> 1,82						S5P_FIMV_NV12MT_VALIGN);83			enc_ref_c_size = ALIGN(enc_ref_c_size,84							S5P_FIMV_NV12MT_SALIGN);85		} else {86			guard_width = ALIGN(ctx->img_width + 16,87							S5P_FIMV_NV12MT_HALIGN);88			guard_height = ALIGN((ctx->img_height >> 1) + 4,89							S5P_FIMV_NV12MT_VALIGN);90			enc_ref_c_size = ALIGN(guard_width * guard_height,91					       S5P_FIMV_NV12MT_SALIGN);92		}93		mfc_debug(2, "recon luma size: %d chroma size: %d\n",94			  enc_ref_y_size, enc_ref_c_size);95	} else {96		return -EINVAL;97	}98	/* Codecs have different memory requirements */99	switch (ctx->codec_mode) {100	case S5P_MFC_CODEC_H264_DEC:101		ctx->bank1.size =102		    ALIGN(S5P_FIMV_DEC_NB_IP_SIZE +103					S5P_FIMV_DEC_VERT_NB_MV_SIZE,104					S5P_FIMV_DEC_BUF_ALIGN);105		ctx->bank2.size = ctx->total_dpb_count * ctx->mv_size;106		break;107	case S5P_MFC_CODEC_MPEG4_DEC:108		ctx->bank1.size =109		    ALIGN(S5P_FIMV_DEC_NB_DCAC_SIZE +110				     S5P_FIMV_DEC_UPNB_MV_SIZE +111				     S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +112				     S5P_FIMV_DEC_STX_PARSER_SIZE +113				     S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE,114				     S5P_FIMV_DEC_BUF_ALIGN);115		ctx->bank2.size = 0;116		break;117	case S5P_MFC_CODEC_VC1RCV_DEC:118	case S5P_MFC_CODEC_VC1_DEC:119		ctx->bank1.size =120		    ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +121			     S5P_FIMV_DEC_UPNB_MV_SIZE +122			     S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +123			     S5P_FIMV_DEC_NB_DCAC_SIZE +124			     3 * S5P_FIMV_DEC_VC1_BITPLANE_SIZE,125			     S5P_FIMV_DEC_BUF_ALIGN);126		ctx->bank2.size = 0;127		break;128	case S5P_MFC_CODEC_MPEG2_DEC:129		ctx->bank1.size = 0;130		ctx->bank2.size = 0;131		break;132	case S5P_MFC_CODEC_H263_DEC:133		ctx->bank1.size =134		    ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +135			     S5P_FIMV_DEC_UPNB_MV_SIZE +136			     S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +137			     S5P_FIMV_DEC_NB_DCAC_SIZE,138			     S5P_FIMV_DEC_BUF_ALIGN);139		ctx->bank2.size = 0;140		break;141	case S5P_MFC_CODEC_H264_ENC:142		ctx->bank1.size = (enc_ref_y_size * 2) +143				   S5P_FIMV_ENC_UPMV_SIZE +144				   S5P_FIMV_ENC_COLFLG_SIZE +145				   S5P_FIMV_ENC_INTRAMD_SIZE +146				   S5P_FIMV_ENC_NBORINFO_SIZE;147		ctx->bank2.size = (enc_ref_y_size * 2) +148				   (enc_ref_c_size * 4) +149				   S5P_FIMV_ENC_INTRAPRED_SIZE;150		break;151	case S5P_MFC_CODEC_MPEG4_ENC:152		ctx->bank1.size = (enc_ref_y_size * 2) +153				   S5P_FIMV_ENC_UPMV_SIZE +154				   S5P_FIMV_ENC_COLFLG_SIZE +155				   S5P_FIMV_ENC_ACDCCOEF_SIZE;156		ctx->bank2.size = (enc_ref_y_size * 2) +157				   (enc_ref_c_size * 4);158		break;159	case S5P_MFC_CODEC_H263_ENC:160		ctx->bank1.size = (enc_ref_y_size * 2) +161				   S5P_FIMV_ENC_UPMV_SIZE +162				   S5P_FIMV_ENC_ACDCCOEF_SIZE;163		ctx->bank2.size = (enc_ref_y_size * 2) +164				   (enc_ref_c_size * 4);165		break;166	default:167		break;168	}169	/* Allocate only if memory from bank 1 is necessary */170	if (ctx->bank1.size > 0) {171 172		ret = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &ctx->bank1);173		if (ret) {174			mfc_err("Failed to allocate Bank1 temporary buffer\n");175			return ret;176		}177		BUG_ON(ctx->bank1.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));178	}179	/* Allocate only if memory from bank 2 is necessary */180	if (ctx->bank2.size > 0) {181		ret = s5p_mfc_alloc_priv_buf(dev, BANK_R_CTX, &ctx->bank2);182		if (ret) {183			mfc_err("Failed to allocate Bank2 temporary buffer\n");184			s5p_mfc_release_priv_buf(ctx->dev, &ctx->bank1);185			return ret;186		}187		BUG_ON(ctx->bank2.dma & ((1 << MFC_BANK2_ALIGN_ORDER) - 1));188	}189	return 0;190}191 192/* Release buffers allocated for codec */193static void s5p_mfc_release_codec_buffers_v5(struct s5p_mfc_ctx *ctx)194{195	s5p_mfc_release_priv_buf(ctx->dev, &ctx->bank1);196	s5p_mfc_release_priv_buf(ctx->dev, &ctx->bank2);197}198 199/* Allocate memory for instance data buffer */200static int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx)201{202	struct s5p_mfc_dev *dev = ctx->dev;203	const struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;204	int ret;205 206	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC ||207		ctx->codec_mode == S5P_MFC_CODEC_H264_ENC)208		ctx->ctx.size = buf_size->h264_ctx;209	else210		ctx->ctx.size = buf_size->non_h264_ctx;211 212	ret = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &ctx->ctx);213	if (ret) {214		mfc_err("Failed to allocate instance buffer\n");215		return ret;216	}217	ctx->ctx.ofs = OFFSETA(ctx->ctx.dma);218 219	/* Zero content of the allocated memory */220	memset(ctx->ctx.virt, 0, ctx->ctx.size);221	wmb();222 223	/* Initialize shared memory */224	ctx->shm.size = buf_size->shm;225	ret = s5p_mfc_alloc_priv_buf(dev, BANK_L_CTX, &ctx->shm);226	if (ret) {227		mfc_err("Failed to allocate shared memory buffer\n");228		s5p_mfc_release_priv_buf(dev, &ctx->ctx);229		return ret;230	}231 232	/* shared memory offset only keeps the offset from base (port a) */233	ctx->shm.ofs = ctx->shm.dma - dev->dma_base[BANK_L_CTX];234	BUG_ON(ctx->shm.ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));235 236	memset(ctx->shm.virt, 0, buf_size->shm);237	wmb();238	return 0;239}240 241/* Release instance buffer */242static void s5p_mfc_release_instance_buffer_v5(struct s5p_mfc_ctx *ctx)243{244	s5p_mfc_release_priv_buf(ctx->dev, &ctx->ctx);245	s5p_mfc_release_priv_buf(ctx->dev, &ctx->shm);246}247 248static int s5p_mfc_alloc_dev_context_buffer_v5(struct s5p_mfc_dev *dev)249{250	/* NOP */251 252	return 0;253}254 255static void s5p_mfc_release_dev_context_buffer_v5(struct s5p_mfc_dev *dev)256{257	/* NOP */258}259 260static void s5p_mfc_write_info_v5(struct s5p_mfc_ctx *ctx, unsigned int data,261			unsigned int ofs)262{263	*(u32 *)(ctx->shm.virt + ofs) = data;264	wmb();265}266 267static unsigned int s5p_mfc_read_info_v5(struct s5p_mfc_ctx *ctx,268				unsigned long ofs)269{270	rmb();271	return *(u32 *)(ctx->shm.virt + ofs);272}273 274static void s5p_mfc_dec_calc_dpb_size_v5(struct s5p_mfc_ctx *ctx)275{276	unsigned int guard_width, guard_height;277 278	ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN);279	ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);280	mfc_debug(2,281		"SEQ Done: Movie dimensions %dx%d, buffer dimensions: %dx%d\n",282		ctx->img_width,	ctx->img_height, ctx->buf_width,283		ctx->buf_height);284 285	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC) {286		ctx->luma_size = ALIGN(ctx->buf_width * ctx->buf_height,287				S5P_FIMV_DEC_BUF_ALIGN);288		ctx->chroma_size = ALIGN(ctx->buf_width *289				ALIGN((ctx->img_height >> 1),290					S5P_FIMV_NV12MT_VALIGN),291				S5P_FIMV_DEC_BUF_ALIGN);292		ctx->mv_size = ALIGN(ctx->buf_width *293				ALIGN((ctx->buf_height >> 2),294					S5P_FIMV_NV12MT_VALIGN),295				S5P_FIMV_DEC_BUF_ALIGN);296	} else {297		guard_width =298			ALIGN(ctx->img_width + 24, S5P_FIMV_NV12MT_HALIGN);299		guard_height =300			ALIGN(ctx->img_height + 16, S5P_FIMV_NV12MT_VALIGN);301		ctx->luma_size = ALIGN(guard_width * guard_height,302				S5P_FIMV_DEC_BUF_ALIGN);303 304		guard_width =305			ALIGN(ctx->img_width + 16, S5P_FIMV_NV12MT_HALIGN);306		guard_height =307			ALIGN((ctx->img_height >> 1) + 4,308					S5P_FIMV_NV12MT_VALIGN);309		ctx->chroma_size = ALIGN(guard_width * guard_height,310				S5P_FIMV_DEC_BUF_ALIGN);311 312		ctx->mv_size = 0;313	}314}315 316static void s5p_mfc_enc_calc_src_size_v5(struct s5p_mfc_ctx *ctx)317{318	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) {319		ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN);320 321		ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN)322			* ALIGN(ctx->img_height, S5P_FIMV_NV12M_LVALIGN);323		ctx->chroma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN)324			* ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12M_CVALIGN);325 326		ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12M_SALIGN);327		ctx->chroma_size =328			ALIGN(ctx->chroma_size, S5P_FIMV_NV12M_SALIGN);329	} else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) {330		ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN);331 332		ctx->luma_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)333			* ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);334		ctx->chroma_size =335			ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)336			* ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN);337 338		ctx->luma_size = ALIGN(ctx->luma_size, S5P_FIMV_NV12MT_SALIGN);339		ctx->chroma_size =340			ALIGN(ctx->chroma_size, S5P_FIMV_NV12MT_SALIGN);341	}342}343 344/* Set registers for decoding temporary buffers */345static void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx)346{347	struct s5p_mfc_dev *dev = ctx->dev;348	const struct s5p_mfc_buf_size_v5 *buf_size = dev->variant->buf_size->priv;349 350	mfc_write(dev, OFFSETA(ctx->dsc.dma), S5P_FIMV_SI_CH0_DESC_ADR);351	mfc_write(dev, buf_size->dsc, S5P_FIMV_SI_CH0_DESC_SIZE);352}353 354/* Set registers for shared buffer */355static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx)356{357	struct s5p_mfc_dev *dev = ctx->dev;358	mfc_write(dev, ctx->shm.ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR);359}360 361/* Set registers for decoding stream buffer */362static int s5p_mfc_set_dec_stream_buffer_v5(struct s5p_mfc_ctx *ctx,363		int buf_addr, unsigned int start_num_byte,364		unsigned int buf_size)365{366	struct s5p_mfc_dev *dev = ctx->dev;367 368	mfc_write(dev, OFFSETA(buf_addr), S5P_FIMV_SI_CH0_SB_ST_ADR);369	mfc_write(dev, ctx->dec_src_buf_size, S5P_FIMV_SI_CH0_CPB_SIZE);370	mfc_write(dev, buf_size, S5P_FIMV_SI_CH0_SB_FRM_SIZE);371	s5p_mfc_write_info_v5(ctx, start_num_byte, START_BYTE_NUM);372	return 0;373}374 375/* Set decoding frame buffer */376static int s5p_mfc_set_dec_frame_buffer_v5(struct s5p_mfc_ctx *ctx)377{378	unsigned int frame_size_lu, i;379	unsigned int frame_size_ch, frame_size_mv;380	struct s5p_mfc_dev *dev = ctx->dev;381	unsigned int dpb;382	size_t buf_addr1, buf_addr2;383	int buf_size1, buf_size2;384 385	buf_addr1 = ctx->bank1.dma;386	buf_size1 = ctx->bank1.size;387	buf_addr2 = ctx->bank2.dma;388	buf_size2 = ctx->bank2.size;389	dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) &390						~S5P_FIMV_DPB_COUNT_MASK;391	mfc_write(dev, ctx->total_dpb_count | dpb,392						S5P_FIMV_SI_CH0_DPB_CONF_CTRL);393	s5p_mfc_set_shared_buffer(ctx);394	switch (ctx->codec_mode) {395	case S5P_MFC_CODEC_H264_DEC:396		mfc_write(dev, OFFSETA(buf_addr1),397						S5P_FIMV_H264_VERT_NB_MV_ADR);398		buf_addr1 += S5P_FIMV_DEC_VERT_NB_MV_SIZE;399		buf_size1 -= S5P_FIMV_DEC_VERT_NB_MV_SIZE;400		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H264_NB_IP_ADR);401		buf_addr1 += S5P_FIMV_DEC_NB_IP_SIZE;402		buf_size1 -= S5P_FIMV_DEC_NB_IP_SIZE;403		break;404	case S5P_MFC_CODEC_MPEG4_DEC:405		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_NB_DCAC_ADR);406		buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;407		buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;408		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_UP_NB_MV_ADR);409		buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;410		buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;411		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_SA_MV_ADR);412		buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;413		buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;414		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_SP_ADR);415		buf_addr1 += S5P_FIMV_DEC_STX_PARSER_SIZE;416		buf_size1 -= S5P_FIMV_DEC_STX_PARSER_SIZE;417		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_OT_LINE_ADR);418		buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;419		buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;420		break;421	case S5P_MFC_CODEC_H263_DEC:422		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_OT_LINE_ADR);423		buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;424		buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;425		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_UP_NB_MV_ADR);426		buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;427		buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;428		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_SA_MV_ADR);429		buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;430		buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;431		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_NB_DCAC_ADR);432		buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;433		buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;434		break;435	case S5P_MFC_CODEC_VC1_DEC:436	case S5P_MFC_CODEC_VC1RCV_DEC:437		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_NB_DCAC_ADR);438		buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;439		buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;440		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_OT_LINE_ADR);441		buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;442		buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;443		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_UP_NB_MV_ADR);444		buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;445		buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;446		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_SA_MV_ADR);447		buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;448		buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;449		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE3_ADR);450		buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;451		buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;452		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE2_ADR);453		buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;454		buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;455		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE1_ADR);456		buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;457		buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;458		break;459	case S5P_MFC_CODEC_MPEG2_DEC:460		break;461	default:462		mfc_err("Unknown codec for decoding (%x)\n",463			ctx->codec_mode);464		return -EINVAL;465	}466	frame_size_lu = ctx->luma_size;467	frame_size_ch = ctx->chroma_size;468	frame_size_mv = ctx->mv_size;469	mfc_debug(2, "Frm size: %d ch: %d mv: %d\n", frame_size_lu, frame_size_ch,470								frame_size_mv);471	for (i = 0; i < ctx->total_dpb_count; i++) {472		/* Bank2 */473		mfc_debug(2, "Luma %d: %zx\n", i,474					ctx->dst_bufs[i].cookie.raw.luma);475		mfc_write(dev, OFFSETB(ctx->dst_bufs[i].cookie.raw.luma),476						S5P_FIMV_DEC_LUMA_ADR + i * 4);477		mfc_debug(2, "\tChroma %d: %zx\n", i,478					ctx->dst_bufs[i].cookie.raw.chroma);479		mfc_write(dev, OFFSETA(ctx->dst_bufs[i].cookie.raw.chroma),480					       S5P_FIMV_DEC_CHROMA_ADR + i * 4);481		if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC) {482			mfc_debug(2, "\tBuf2: %zx, size: %d\n",483							buf_addr2, buf_size2);484			mfc_write(dev, OFFSETB(buf_addr2),485						S5P_FIMV_H264_MV_ADR + i * 4);486			buf_addr2 += frame_size_mv;487			buf_size2 -= frame_size_mv;488		}489	}490	mfc_debug(2, "Buf1: %zu, buf_size1: %d\n", buf_addr1, buf_size1);491	mfc_debug(2, "Buf 1/2 size after: %d/%d (frames %d)\n",492			buf_size1,  buf_size2, ctx->total_dpb_count);493	if (buf_size1 < 0 || buf_size2 < 0) {494		mfc_debug(2, "Not enough memory has been allocated\n");495		return -ENOMEM;496	}497	s5p_mfc_write_info_v5(ctx, frame_size_lu, ALLOC_LUMA_DPB_SIZE);498	s5p_mfc_write_info_v5(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE);499	if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC)500		s5p_mfc_write_info_v5(ctx, frame_size_mv, ALLOC_MV_SIZE);501	mfc_write(dev, ((S5P_FIMV_CH_INIT_BUFS & S5P_FIMV_CH_MASK)502					<< S5P_FIMV_CH_SHIFT) | (ctx->inst_no),503						S5P_FIMV_SI_CH0_INST_ID);504	return 0;505}506 507/* Set registers for encoding stream buffer */508static int s5p_mfc_set_enc_stream_buffer_v5(struct s5p_mfc_ctx *ctx,509		unsigned long addr, unsigned int size)510{511	struct s5p_mfc_dev *dev = ctx->dev;512 513	mfc_write(dev, OFFSETA(addr), S5P_FIMV_ENC_SI_CH0_SB_ADR);514	mfc_write(dev, size, S5P_FIMV_ENC_SI_CH0_SB_SIZE);515	return 0;516}517 518static void s5p_mfc_set_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,519		unsigned long y_addr, unsigned long c_addr,520		unsigned long c_1_addr)521{522	struct s5p_mfc_dev *dev = ctx->dev;523 524	mfc_write(dev, OFFSETB(y_addr), S5P_FIMV_ENC_SI_CH0_CUR_Y_ADR);525	mfc_write(dev, OFFSETB(c_addr), S5P_FIMV_ENC_SI_CH0_CUR_C_ADR);526}527 528static void s5p_mfc_get_enc_frame_buffer_v5(struct s5p_mfc_ctx *ctx,529		unsigned long *y_addr, unsigned long *c_addr,530		unsigned long *c_1_addr)531{532	struct s5p_mfc_dev *dev = ctx->dev;533 534	*y_addr = dev->dma_base[BANK_R_CTX] +535		  (mfc_read(dev, S5P_FIMV_ENCODED_Y_ADDR) << MFC_OFFSET_SHIFT);536	*c_addr = dev->dma_base[BANK_R_CTX] +537		  (mfc_read(dev, S5P_FIMV_ENCODED_C_ADDR) << MFC_OFFSET_SHIFT);538}539 540/* Set encoding ref & codec buffer */541static int s5p_mfc_set_enc_ref_buffer_v5(struct s5p_mfc_ctx *ctx)542{543	struct s5p_mfc_dev *dev = ctx->dev;544	size_t buf_addr1, buf_addr2;545	size_t buf_size1, buf_size2;546	unsigned int enc_ref_y_size, enc_ref_c_size;547	unsigned int guard_width, guard_height;548	int i;549 550	buf_addr1 = ctx->bank1.dma;551	buf_size1 = ctx->bank1.size;552	buf_addr2 = ctx->bank2.dma;553	buf_size2 = ctx->bank2.size;554	enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)555		* ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);556	enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);557	if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) {558		enc_ref_c_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)559			* ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN);560		enc_ref_c_size = ALIGN(enc_ref_c_size, S5P_FIMV_NV12MT_SALIGN);561	} else {562		guard_width = ALIGN(ctx->img_width + 16,563						S5P_FIMV_NV12MT_HALIGN);564		guard_height = ALIGN((ctx->img_height >> 1) + 4,565						S5P_FIMV_NV12MT_VALIGN);566		enc_ref_c_size = ALIGN(guard_width * guard_height,567				       S5P_FIMV_NV12MT_SALIGN);568	}569	mfc_debug(2, "buf_size1: %zu, buf_size2: %zu\n", buf_size1, buf_size2);570	switch (ctx->codec_mode) {571	case S5P_MFC_CODEC_H264_ENC:572		for (i = 0; i < 2; i++) {573			mfc_write(dev, OFFSETA(buf_addr1),574				S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));575			buf_addr1 += enc_ref_y_size;576			buf_size1 -= enc_ref_y_size;577 578			mfc_write(dev, OFFSETB(buf_addr2),579				S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));580			buf_addr2 += enc_ref_y_size;581			buf_size2 -= enc_ref_y_size;582		}583		for (i = 0; i < 4; i++) {584			mfc_write(dev, OFFSETB(buf_addr2),585				S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));586			buf_addr2 += enc_ref_c_size;587			buf_size2 -= enc_ref_c_size;588		}589		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H264_UP_MV_ADR);590		buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;591		buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;592		mfc_write(dev, OFFSETA(buf_addr1),593					S5P_FIMV_H264_COZERO_FLAG_ADR);594		buf_addr1 += S5P_FIMV_ENC_COLFLG_SIZE;595		buf_size1 -= S5P_FIMV_ENC_COLFLG_SIZE;596		mfc_write(dev, OFFSETA(buf_addr1),597					S5P_FIMV_H264_UP_INTRA_MD_ADR);598		buf_addr1 += S5P_FIMV_ENC_INTRAMD_SIZE;599		buf_size1 -= S5P_FIMV_ENC_INTRAMD_SIZE;600		mfc_write(dev, OFFSETB(buf_addr2),601					S5P_FIMV_H264_UP_INTRA_PRED_ADR);602		buf_addr2 += S5P_FIMV_ENC_INTRAPRED_SIZE;603		buf_size2 -= S5P_FIMV_ENC_INTRAPRED_SIZE;604		mfc_write(dev, OFFSETA(buf_addr1),605					S5P_FIMV_H264_NBOR_INFO_ADR);606		buf_addr1 += S5P_FIMV_ENC_NBORINFO_SIZE;607		buf_size1 -= S5P_FIMV_ENC_NBORINFO_SIZE;608		mfc_debug(2, "buf_size1: %zu, buf_size2: %zu\n",609			buf_size1, buf_size2);610		break;611	case S5P_MFC_CODEC_MPEG4_ENC:612		for (i = 0; i < 2; i++) {613			mfc_write(dev, OFFSETA(buf_addr1),614				S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));615			buf_addr1 += enc_ref_y_size;616			buf_size1 -= enc_ref_y_size;617			mfc_write(dev, OFFSETB(buf_addr2),618				S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));619			buf_addr2 += enc_ref_y_size;620			buf_size2 -= enc_ref_y_size;621		}622		for (i = 0; i < 4; i++) {623			mfc_write(dev, OFFSETB(buf_addr2),624				S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));625			buf_addr2 += enc_ref_c_size;626			buf_size2 -= enc_ref_c_size;627		}628		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_UP_MV_ADR);629		buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;630		buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;631		mfc_write(dev, OFFSETA(buf_addr1),632						S5P_FIMV_MPEG4_COZERO_FLAG_ADR);633		buf_addr1 += S5P_FIMV_ENC_COLFLG_SIZE;634		buf_size1 -= S5P_FIMV_ENC_COLFLG_SIZE;635		mfc_write(dev, OFFSETA(buf_addr1),636						S5P_FIMV_MPEG4_ACDC_COEF_ADR);637		buf_addr1 += S5P_FIMV_ENC_ACDCCOEF_SIZE;638		buf_size1 -= S5P_FIMV_ENC_ACDCCOEF_SIZE;639		mfc_debug(2, "buf_size1: %zu, buf_size2: %zu\n",640			buf_size1, buf_size2);641		break;642	case S5P_MFC_CODEC_H263_ENC:643		for (i = 0; i < 2; i++) {644			mfc_write(dev, OFFSETA(buf_addr1),645				S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));646			buf_addr1 += enc_ref_y_size;647			buf_size1 -= enc_ref_y_size;648			mfc_write(dev, OFFSETB(buf_addr2),649				S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));650			buf_addr2 += enc_ref_y_size;651			buf_size2 -= enc_ref_y_size;652		}653		for (i = 0; i < 4; i++) {654			mfc_write(dev, OFFSETB(buf_addr2),655				S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));656			buf_addr2 += enc_ref_c_size;657			buf_size2 -= enc_ref_c_size;658		}659		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_UP_MV_ADR);660		buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;661		buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;662		mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_ACDC_COEF_ADR);663		buf_addr1 += S5P_FIMV_ENC_ACDCCOEF_SIZE;664		buf_size1 -= S5P_FIMV_ENC_ACDCCOEF_SIZE;665		mfc_debug(2, "buf_size1: %zu, buf_size2: %zu\n",666			buf_size1, buf_size2);667		break;668	default:669		mfc_err("Unknown codec set for encoding: %d\n",670			ctx->codec_mode);671		return -EINVAL;672	}673	return 0;674}675 676static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)677{678	struct s5p_mfc_dev *dev = ctx->dev;679	const struct s5p_mfc_enc_params *p = &ctx->enc_params;680	unsigned int reg;681	unsigned int shm;682 683	/* width */684	mfc_write(dev, ctx->img_width, S5P_FIMV_ENC_HSIZE_PX);685	/* height */686	mfc_write(dev, ctx->img_height, S5P_FIMV_ENC_VSIZE_PX);687	/* pictype : enable, IDR period */688	reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);689	reg |= (1 << 18);690	reg &= ~(0xFFFF);691	reg |= p->gop_size;692	mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);693	mfc_write(dev, 0, S5P_FIMV_ENC_B_RECON_WRITE_ON);694	/* multi-slice control */695	/* multi-slice MB number or bit size */696	mfc_write(dev, p->slice_mode, S5P_FIMV_ENC_MSLICE_CTRL);697	if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {698		mfc_write(dev, p->slice_mb, S5P_FIMV_ENC_MSLICE_MB);699	} else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {700		mfc_write(dev, p->slice_bit, S5P_FIMV_ENC_MSLICE_BIT);701	} else {702		mfc_write(dev, 0, S5P_FIMV_ENC_MSLICE_MB);703		mfc_write(dev, 0, S5P_FIMV_ENC_MSLICE_BIT);704	}705	/* cyclic intra refresh */706	mfc_write(dev, p->intra_refresh_mb, S5P_FIMV_ENC_CIR_CTRL);707	/* memory structure cur. frame */708	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)709		mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);710	else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)711		mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);712	/* padding control & value */713	reg = mfc_read(dev, S5P_FIMV_ENC_PADDING_CTRL);714	if (p->pad) {715		/** enable */716		reg |= (1UL << 31);717		/** cr value */718		reg &= ~(0xFF << 16);719		reg |= (p->pad_cr << 16);720		/** cb value */721		reg &= ~(0xFF << 8);722		reg |= (p->pad_cb << 8);723		/** y value */724		reg &= ~(0xFF);725		reg |= (p->pad_luma);726	} else {727		/** disable & all value clear */728		reg = 0;729	}730	mfc_write(dev, reg, S5P_FIMV_ENC_PADDING_CTRL);731	/* rate control config. */732	reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);733	/** frame-level rate control */734	reg &= ~(0x1 << 9);735	reg |= (p->rc_frame << 9);736	mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);737	/* bit rate */738	if (p->rc_frame)739		mfc_write(dev, p->rc_bitrate,740			S5P_FIMV_ENC_RC_BIT_RATE);741	else742		mfc_write(dev, 0, S5P_FIMV_ENC_RC_BIT_RATE);743	/* reaction coefficient */744	if (p->rc_frame)745		mfc_write(dev, p->rc_reaction_coeff, S5P_FIMV_ENC_RC_RPARA);746	shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);747	/* seq header ctrl */748	shm &= ~(0x1 << 3);749	shm |= (p->seq_hdr_mode << 3);750	/* frame skip mode */751	shm &= ~(0x3 << 1);752	shm |= (p->frame_skip_mode << 1);753	s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);754	/* fixed target bit */755	s5p_mfc_write_info_v5(ctx, p->fixed_target_bit, RC_CONTROL_CONFIG);756	return 0;757}758 759static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)760{761	struct s5p_mfc_dev *dev = ctx->dev;762	const struct s5p_mfc_enc_params *p = &ctx->enc_params;763	const struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264;764	unsigned int reg;765	unsigned int shm;766 767	s5p_mfc_set_enc_params(ctx);768	/* pictype : number of B */769	reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);770	/* num_b_frame - 0 ~ 2 */771	reg &= ~(0x3 << 16);772	reg |= (p->num_b_frame << 16);773	mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);774	/* profile & level */775	reg = mfc_read(dev, S5P_FIMV_ENC_PROFILE);776	/* level */777	reg &= ~(0xFF << 8);778	reg |= (p_264->level << 8);779	/* profile - 0 ~ 2 */780	reg &= ~(0x3F);781	reg |= p_264->profile;782	mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);783	/* interlace  */784	mfc_write(dev, p_264->interlace, S5P_FIMV_ENC_PIC_STRUCT);785	/* height */786	if (p_264->interlace)787		mfc_write(dev, ctx->img_height >> 1, S5P_FIMV_ENC_VSIZE_PX);788	/* loopfilter ctrl */789	mfc_write(dev, p_264->loop_filter_mode, S5P_FIMV_ENC_LF_CTRL);790	/* loopfilter alpha offset */791	if (p_264->loop_filter_alpha < 0) {792		reg = 0x10;793		reg |= (0xFF - p_264->loop_filter_alpha) + 1;794	} else {795		reg = 0x00;796		reg |= (p_264->loop_filter_alpha & 0xF);797	}798	mfc_write(dev, reg, S5P_FIMV_ENC_ALPHA_OFF);799	/* loopfilter beta offset */800	if (p_264->loop_filter_beta < 0) {801		reg = 0x10;802		reg |= (0xFF - p_264->loop_filter_beta) + 1;803	} else {804		reg = 0x00;805		reg |= (p_264->loop_filter_beta & 0xF);806	}807	mfc_write(dev, reg, S5P_FIMV_ENC_BETA_OFF);808	/* entropy coding mode */809	if (p_264->entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)810		mfc_write(dev, 1, S5P_FIMV_ENC_H264_ENTROPY_MODE);811	else812		mfc_write(dev, 0, S5P_FIMV_ENC_H264_ENTROPY_MODE);813	/* number of ref. picture */814	reg = mfc_read(dev, S5P_FIMV_ENC_H264_NUM_OF_REF);815	/* num of ref. pictures of P */816	reg &= ~(0x3 << 5);817	reg |= (p_264->num_ref_pic_4p << 5);818	/* max number of ref. pictures */819	reg &= ~(0x1F);820	reg |= p_264->max_ref_pic;821	mfc_write(dev, reg, S5P_FIMV_ENC_H264_NUM_OF_REF);822	/* 8x8 transform enable */823	mfc_write(dev, p_264->_8x8_transform, S5P_FIMV_ENC_H264_TRANS_FLAG);824	/* rate control config. */825	reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);826	/* macroblock level rate control */827	reg &= ~(0x1 << 8);828	reg |= (p->rc_mb << 8);829	/* frame QP */830	reg &= ~(0x3F);831	reg |= p_264->rc_frame_qp;832	mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);833	/* frame rate */834	if (p->rc_frame && p->rc_framerate_denom)835		mfc_write(dev, p->rc_framerate_num * 1000836			/ p->rc_framerate_denom, S5P_FIMV_ENC_RC_FRAME_RATE);837	else838		mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);839	/* max & min value of QP */840	reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);841	/* max QP */842	reg &= ~(0x3F << 8);843	reg |= (p_264->rc_max_qp << 8);844	/* min QP */845	reg &= ~(0x3F);846	reg |= p_264->rc_min_qp;847	mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);848	/* macroblock adaptive scaling features */849	if (p->rc_mb) {850		reg = mfc_read(dev, S5P_FIMV_ENC_RC_MB_CTRL);851		/* dark region */852		reg &= ~(0x1 << 3);853		reg |= (p_264->rc_mb_dark << 3);854		/* smooth region */855		reg &= ~(0x1 << 2);856		reg |= (p_264->rc_mb_smooth << 2);857		/* static region */858		reg &= ~(0x1 << 1);859		reg |= (p_264->rc_mb_static << 1);860		/* high activity region */861		reg &= ~(0x1);862		reg |= p_264->rc_mb_activity;863		mfc_write(dev, reg, S5P_FIMV_ENC_RC_MB_CTRL);864	}865	if (!p->rc_frame && !p->rc_mb) {866		shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP);867		shm &= ~(0xFFF);868		shm |= ((p_264->rc_b_frame_qp & 0x3F) << 6);869		shm |= (p_264->rc_p_frame_qp & 0x3F);870		s5p_mfc_write_info_v5(ctx, shm, P_B_FRAME_QP);871	}872	/* extended encoder ctrl */873	shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);874	/* AR VUI control */875	shm &= ~(0x1 << 15);876	shm |= (p_264->vui_sar << 1);877	s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);878	if (p_264->vui_sar) {879		/* aspect ration IDC */880		shm = s5p_mfc_read_info_v5(ctx, SAMPLE_ASPECT_RATIO_IDC);881		shm &= ~(0xFF);882		shm |= p_264->vui_sar_idc;883		s5p_mfc_write_info_v5(ctx, shm, SAMPLE_ASPECT_RATIO_IDC);884		if (p_264->vui_sar_idc == 0xFF) {885			/* sample  AR info */886			shm = s5p_mfc_read_info_v5(ctx, EXTENDED_SAR);887			shm &= ~(0xFFFFFFFF);888			shm |= p_264->vui_ext_sar_width << 16;889			shm |= p_264->vui_ext_sar_height;890			s5p_mfc_write_info_v5(ctx, shm, EXTENDED_SAR);891		}892	}893	/* intra picture period for H.264 */894	shm = s5p_mfc_read_info_v5(ctx, H264_I_PERIOD);895	/* control */896	shm &= ~(0x1 << 16);897	shm |= (p_264->open_gop << 16);898	/* value */899	if (p_264->open_gop) {900		shm &= ~(0xFFFF);901		shm |= p_264->open_gop_size;902	}903	s5p_mfc_write_info_v5(ctx, shm, H264_I_PERIOD);904	/* extended encoder ctrl */905	shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);906	/* vbv buffer size */907	if (p->frame_skip_mode ==908			V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {909		shm &= ~(0xFFFF << 16);910		shm |= (p_264->cpb_size << 16);911	}912	s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);913	return 0;914}915 916static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)917{918	struct s5p_mfc_dev *dev = ctx->dev;919	const struct s5p_mfc_enc_params *p = &ctx->enc_params;920	const struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;921	unsigned int reg;922	unsigned int shm;923	unsigned int framerate;924 925	s5p_mfc_set_enc_params(ctx);926	/* pictype : number of B */927	reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);928	/* num_b_frame - 0 ~ 2 */929	reg &= ~(0x3 << 16);930	reg |= (p->num_b_frame << 16);931	mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);932	/* profile & level */933	reg = mfc_read(dev, S5P_FIMV_ENC_PROFILE);934	/* level */935	reg &= ~(0xFF << 8);936	reg |= (p_mpeg4->level << 8);937	/* profile - 0 ~ 2 */938	reg &= ~(0x3F);939	reg |= p_mpeg4->profile;940	mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);941	/* quarter_pixel */942	mfc_write(dev, p_mpeg4->quarter_pixel, S5P_FIMV_ENC_MPEG4_QUART_PXL);943	/* qp */944	if (!p->rc_frame) {945		shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP);946		shm &= ~(0xFFF);947		shm |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 6);948		shm |= (p_mpeg4->rc_p_frame_qp & 0x3F);949		s5p_mfc_write_info_v5(ctx, shm, P_B_FRAME_QP);950	}951	/* frame rate */952	if (p->rc_frame) {953		if (p->rc_framerate_denom > 0) {954			framerate = p->rc_framerate_num * 1000 /955						p->rc_framerate_denom;956			mfc_write(dev, framerate,957				S5P_FIMV_ENC_RC_FRAME_RATE);958			shm = s5p_mfc_read_info_v5(ctx, RC_VOP_TIMING);959			shm &= ~(0xFFFFFFFF);960			shm |= (1UL << 31);961			shm |= ((p->rc_framerate_num & 0x7FFF) << 16);962			shm |= (p->rc_framerate_denom & 0xFFFF);963			s5p_mfc_write_info_v5(ctx, shm, RC_VOP_TIMING);964		}965	} else {966		mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);967	}968	/* rate control config. */969	reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);970	/* frame QP */971	reg &= ~(0x3F);972	reg |= p_mpeg4->rc_frame_qp;973	mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);974	/* max & min value of QP */975	reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);976	/* max QP */977	reg &= ~(0x3F << 8);978	reg |= (p_mpeg4->rc_max_qp << 8);979	/* min QP */980	reg &= ~(0x3F);981	reg |= p_mpeg4->rc_min_qp;982	mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);983	/* extended encoder ctrl */984	shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);985	/* vbv buffer size */986	if (p->frame_skip_mode ==987			V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {988		shm &= ~(0xFFFF << 16);989		shm |= (p->vbv_size << 16);990	}991	s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);992	return 0;993}994 995static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)996{997	struct s5p_mfc_dev *dev = ctx->dev;998	const struct s5p_mfc_enc_params *p = &ctx->enc_params;999	const struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;1000	unsigned int reg;1001	unsigned int shm;1002 1003	s5p_mfc_set_enc_params(ctx);1004	/* qp */1005	if (!p->rc_frame) {1006		shm = s5p_mfc_read_info_v5(ctx, P_B_FRAME_QP);1007		shm &= ~(0xFFF);1008		shm |= (p_h263->rc_p_frame_qp & 0x3F);1009		s5p_mfc_write_info_v5(ctx, shm, P_B_FRAME_QP);1010	}1011	/* frame rate */1012	if (p->rc_frame && p->rc_framerate_denom)1013		mfc_write(dev, p->rc_framerate_num * 10001014			/ p->rc_framerate_denom, S5P_FIMV_ENC_RC_FRAME_RATE);1015	else1016		mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);1017	/* rate control config. */1018	reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);1019	/* frame QP */1020	reg &= ~(0x3F);1021	reg |= p_h263->rc_frame_qp;1022	mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);1023	/* max & min value of QP */1024	reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);1025	/* max QP */1026	reg &= ~(0x3F << 8);1027	reg |= (p_h263->rc_max_qp << 8);1028	/* min QP */1029	reg &= ~(0x3F);1030	reg |= p_h263->rc_min_qp;1031	mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);1032	/* extended encoder ctrl */1033	shm = s5p_mfc_read_info_v5(ctx, EXT_ENC_CONTROL);1034	/* vbv buffer size */1035	if (p->frame_skip_mode ==1036			V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {1037		shm &= ~(0xFFFF << 16);1038		shm |= (p->vbv_size << 16);1039	}1040	s5p_mfc_write_info_v5(ctx, shm, EXT_ENC_CONTROL);1041	return 0;1042}1043 1044/* Initialize decoding */1045static int s5p_mfc_init_decode_v5(struct s5p_mfc_ctx *ctx)1046{1047	struct s5p_mfc_dev *dev = ctx->dev;1048 1049	s5p_mfc_set_shared_buffer(ctx);1050	/* Setup loop filter, for decoding this is only valid for MPEG4 */1051	if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_DEC)1052		mfc_write(dev, ctx->loop_filter_mpeg4, S5P_FIMV_ENC_LF_CTRL);1053	else1054		mfc_write(dev, 0, S5P_FIMV_ENC_LF_CTRL);1055	mfc_write(dev, ((ctx->slice_interface & S5P_FIMV_SLICE_INT_MASK) <<1056		S5P_FIMV_SLICE_INT_SHIFT) | (ctx->display_delay_enable <<1057		S5P_FIMV_DDELAY_ENA_SHIFT) | ((ctx->display_delay &1058		S5P_FIMV_DDELAY_VAL_MASK) << S5P_FIMV_DDELAY_VAL_SHIFT),1059		S5P_FIMV_SI_CH0_DPB_CONF_CTRL);1060	mfc_write(dev,1061	((S5P_FIMV_CH_SEQ_HEADER & S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT)1062				| (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);1063	return 0;1064}1065 1066static void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)1067{1068	struct s5p_mfc_dev *dev = ctx->dev;1069	unsigned int dpb;1070 1071	if (flush)1072		dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) | (1073			S5P_FIMV_DPB_FLUSH_MASK << S5P_FIMV_DPB_FLUSH_SHIFT);1074	else1075		dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) &1076			~(S5P_FIMV_DPB_FLUSH_MASK << S5P_FIMV_DPB_FLUSH_SHIFT);1077	mfc_write(dev, dpb, S5P_FIMV_SI_CH0_DPB_CONF_CTRL);1078}1079 1080/* Decode a single frame */1081static int s5p_mfc_decode_one_frame_v5(struct s5p_mfc_ctx *ctx,1082					enum s5p_mfc_decode_arg last_frame)1083{1084	struct s5p_mfc_dev *dev = ctx->dev;1085 1086	mfc_write(dev, ctx->dec_dst_flag, S5P_FIMV_SI_CH0_RELEASE_BUF);1087	s5p_mfc_set_shared_buffer(ctx);1088	s5p_mfc_set_flush(ctx, ctx->dpb_flush_flag);1089	/* Issue different commands to instance basing on whether it1090	 * is the last frame or not. */1091	switch (last_frame) {1092	case MFC_DEC_FRAME:1093		mfc_write(dev, ((S5P_FIMV_CH_FRAME_START & S5P_FIMV_CH_MASK) <<1094		S5P_FIMV_CH_SHIFT) | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);1095		break;1096	case MFC_DEC_LAST_FRAME:1097		mfc_write(dev, ((S5P_FIMV_CH_LAST_FRAME & S5P_FIMV_CH_MASK) <<1098		S5P_FIMV_CH_SHIFT) | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);1099		break;1100	case MFC_DEC_RES_CHANGE:1101		mfc_write(dev, ((S5P_FIMV_CH_FRAME_START_REALLOC &1102		S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT) | (ctx->inst_no),1103		S5P_FIMV_SI_CH0_INST_ID);1104		break;1105	}1106	mfc_debug(2, "Decoding a usual frame\n");1107	return 0;1108}1109 1110static int s5p_mfc_init_encode_v5(struct s5p_mfc_ctx *ctx)1111{1112	struct s5p_mfc_dev *dev = ctx->dev;1113 1114	if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC)1115		s5p_mfc_set_enc_params_h264(ctx);1116	else if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_ENC)1117		s5p_mfc_set_enc_params_mpeg4(ctx);1118	else if (ctx->codec_mode == S5P_MFC_CODEC_H263_ENC)1119		s5p_mfc_set_enc_params_h263(ctx);1120	else {1121		mfc_err("Unknown codec for encoding (%x)\n",1122			ctx->codec_mode);1123		return -EINVAL;1124	}1125	s5p_mfc_set_shared_buffer(ctx);1126	mfc_write(dev, ((S5P_FIMV_CH_SEQ_HEADER << 16) & 0x70000) |1127		(ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);1128	return 0;1129}1130 1131/* Encode a single frame */1132static int s5p_mfc_encode_one_frame_v5(struct s5p_mfc_ctx *ctx)1133{1134	struct s5p_mfc_dev *dev = ctx->dev;1135	int cmd;1136	/* memory structure cur. frame */1137	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)1138		mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);1139	else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)1140		mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);1141	s5p_mfc_set_shared_buffer(ctx);1142 1143	if (ctx->state == MFCINST_FINISHING)1144		cmd = S5P_FIMV_CH_LAST_FRAME;1145	else1146		cmd = S5P_FIMV_CH_FRAME_START;1147	mfc_write(dev, ((cmd & S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT)1148				| (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);1149 1150	return 0;1151}1152 1153static void s5p_mfc_run_res_change(struct s5p_mfc_ctx *ctx)1154{1155	struct s5p_mfc_dev *dev = ctx->dev;1156 1157	s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0);1158	dev->curr_ctx = ctx->num;1159	s5p_mfc_decode_one_frame_v5(ctx, MFC_DEC_RES_CHANGE);1160}1161 1162static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame)1163{1164	struct s5p_mfc_dev *dev = ctx->dev;1165	struct s5p_mfc_buf *temp_vb;1166 1167	if (ctx->state == MFCINST_FINISHING) {1168		last_frame = MFC_DEC_LAST_FRAME;1169		s5p_mfc_set_dec_stream_buffer_v5(ctx, 0, 0, 0);1170		dev->curr_ctx = ctx->num;1171		s5p_mfc_decode_one_frame_v5(ctx, last_frame);1172		return 0;1173	}1174 1175	/* Frames are being decoded */1176	if (list_empty(&ctx->src_queue)) {1177		mfc_debug(2, "No src buffers\n");1178		return -EAGAIN;1179	}1180	/* Get the next source buffer */1181	temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);1182	temp_vb->flags |= MFC_BUF_FLAG_USED;1183	s5p_mfc_set_dec_stream_buffer_v5(ctx,1184		vb2_dma_contig_plane_dma_addr(&temp_vb->b->vb2_buf, 0),1185		ctx->consumed_stream, temp_vb->b->vb2_buf.planes[0].bytesused);1186	dev->curr_ctx = ctx->num;1187	if (temp_vb->b->vb2_buf.planes[0].bytesused == 0) {1188		last_frame = MFC_DEC_LAST_FRAME;1189		mfc_debug(2, "Setting ctx->state to FINISHING\n");1190		ctx->state = MFCINST_FINISHING;1191	}1192	s5p_mfc_decode_one_frame_v5(ctx, last_frame);1193	return 0;1194}1195 1196static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)1197{1198	struct s5p_mfc_dev *dev = ctx->dev;1199	struct s5p_mfc_buf *dst_mb;1200	struct s5p_mfc_buf *src_mb;1201	unsigned long src_y_addr, src_c_addr, dst_addr;1202	unsigned int dst_size;1203 1204	if (list_empty(&ctx->src_queue) && ctx->state != MFCINST_FINISHING) {1205		mfc_debug(2, "no src buffers\n");1206		return -EAGAIN;1207	}1208	if (list_empty(&ctx->dst_queue)) {1209		mfc_debug(2, "no dst buffers\n");1210		return -EAGAIN;1211	}1212	if (list_empty(&ctx->src_queue)) {1213		/* send null frame */1214		s5p_mfc_set_enc_frame_buffer_v5(ctx, dev->dma_base[BANK_R_CTX],1215						dev->dma_base[BANK_R_CTX], 0);1216		src_mb = NULL;1217	} else {1218		src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,1219									list);1220		src_mb->flags |= MFC_BUF_FLAG_USED;1221		if (src_mb->b->vb2_buf.planes[0].bytesused == 0) {1222			/* send null frame */1223			s5p_mfc_set_enc_frame_buffer_v5(ctx,1224						dev->dma_base[BANK_R_CTX],1225						dev->dma_base[BANK_R_CTX], 0);1226			ctx->state = MFCINST_FINISHING;1227		} else {1228			src_y_addr = vb2_dma_contig_plane_dma_addr(1229					&src_mb->b->vb2_buf, 0);1230			src_c_addr = vb2_dma_contig_plane_dma_addr(1231					&src_mb->b->vb2_buf, 1);1232			s5p_mfc_set_enc_frame_buffer_v5(ctx, src_y_addr,1233								src_c_addr, 0);1234			if (src_mb->flags & MFC_BUF_FLAG_EOS)1235				ctx->state = MFCINST_FINISHING;1236		}1237	}1238	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);1239	dst_mb->flags |= MFC_BUF_FLAG_USED;1240	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);1241	dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);1242	s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size);1243	dev->curr_ctx = ctx->num;1244	mfc_debug(2, "encoding buffer with index=%d state=%d\n",1245		  src_mb ? src_mb->b->vb2_buf.index : -1, ctx->state);1246	s5p_mfc_encode_one_frame_v5(ctx);1247	return 0;1248}1249 1250static void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)1251{1252	struct s5p_mfc_dev *dev = ctx->dev;1253	struct s5p_mfc_buf *temp_vb;1254 1255	/* Initializing decoding - parsing header */1256	mfc_debug(2, "Preparing to init decoding\n");1257	temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);1258	s5p_mfc_set_dec_desc_buffer(ctx);1259	mfc_debug(2, "Header size: %d\n",1260			temp_vb->b->vb2_buf.planes[0].bytesused);1261	s5p_mfc_set_dec_stream_buffer_v5(ctx,1262			vb2_dma_contig_plane_dma_addr(&temp_vb->b->vb2_buf, 0),1263			0, temp_vb->b->vb2_buf.planes[0].bytesused);1264	dev->curr_ctx = ctx->num;1265	s5p_mfc_init_decode_v5(ctx);1266}1267 1268static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)1269{1270	struct s5p_mfc_dev *dev = ctx->dev;1271	struct s5p_mfc_buf *dst_mb;1272	unsigned long dst_addr;1273	unsigned int dst_size;1274 1275	s5p_mfc_set_enc_ref_buffer_v5(ctx);1276	dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);1277	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0);1278	dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0);1279	s5p_mfc_set_enc_stream_buffer_v5(ctx, dst_addr, dst_size);1280	dev->curr_ctx = ctx->num;1281	s5p_mfc_init_encode_v5(ctx);1282}1283 1284static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)1285{1286	struct s5p_mfc_dev *dev = ctx->dev;1287	struct s5p_mfc_buf *temp_vb;1288	int ret;1289 1290	/*1291	 * Header was parsed now starting processing1292	 * First set the output frame buffers1293	 */1294	if (ctx->capture_state != QUEUE_BUFS_MMAPED) {1295		mfc_err("It seems that not all destination buffers were mmapped\nMFC requires that all destination are mmapped before starting processing\n");1296		return -EAGAIN;1297	}1298	if (list_empty(&ctx->src_queue)) {1299		mfc_err("Header has been deallocated in the middle of initialization\n");1300		return -EIO;1301	}1302	temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);1303	mfc_debug(2, "Header size: %d\n",1304			temp_vb->b->vb2_buf.planes[0].bytesused);1305	s5p_mfc_set_dec_stream_buffer_v5(ctx,1306			vb2_dma_contig_plane_dma_addr(&temp_vb->b->vb2_buf, 0),1307			0, temp_vb->b->vb2_buf.planes[0].bytesused);1308	dev->curr_ctx = ctx->num;1309	ret = s5p_mfc_set_dec_frame_buffer_v5(ctx);1310	if (ret) {1311		mfc_err("Failed to alloc frame mem\n");1312		ctx->state = MFCINST_ERROR;1313	}1314	return ret;1315}1316 1317/* Try running an operation on hardware */1318static void s5p_mfc_try_run_v5(struct s5p_mfc_dev *dev)1319{1320	struct s5p_mfc_ctx *ctx;1321	int new_ctx;1322	unsigned int ret = 0;1323 1324	if (test_bit(0, &dev->enter_suspend)) {1325		mfc_debug(1, "Entering suspend so do not schedule any jobs\n");1326		return;1327	}1328	/* Check whether hardware is not running */1329	if (test_and_set_bit(0, &dev->hw_lock) != 0) {1330		/* This is perfectly ok, the scheduled ctx should wait */1331		mfc_debug(1, "Couldn't lock HW\n");1332		return;1333	}1334	/* Choose the context to run */1335	new_ctx = s5p_mfc_get_new_ctx(dev);1336	if (new_ctx < 0) {1337		/* No contexts to run */1338		if (test_and_clear_bit(0, &dev->hw_lock) == 0) {1339			mfc_err("Failed to unlock hardware\n");1340			return;1341		}1342		mfc_debug(1, "No ctx is scheduled to be run\n");1343		return;1344	}1345	ctx = dev->ctx[new_ctx];1346	/* Got context to run in ctx */1347	/*1348	 * Last frame has already been sent to MFC.1349	 * Now obtaining frames from MFC buffer1350	 */1351	s5p_mfc_clock_on(dev);1352	s5p_mfc_clean_ctx_int_flags(ctx);1353 1354	if (ctx->type == MFCINST_DECODER) {1355		s5p_mfc_set_dec_desc_buffer(ctx);1356		switch (ctx->state) {1357		case MFCINST_FINISHING:1358			s5p_mfc_run_dec_frame(ctx, MFC_DEC_LAST_FRAME);1359			break;1360		case MFCINST_RUNNING:1361			ret = s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME);1362			break;1363		case MFCINST_INIT:1364			ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd,1365					ctx);1366			break;1367		case MFCINST_RETURN_INST:1368			ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd,1369					ctx);1370			break;1371		case MFCINST_GOT_INST:1372			s5p_mfc_run_init_dec(ctx);1373			break;1374		case MFCINST_HEAD_PARSED:1375			ret = s5p_mfc_run_init_dec_buffers(ctx);1376			mfc_debug(1, "head parsed\n");1377			break;1378		case MFCINST_RES_CHANGE_INIT:1379			s5p_mfc_run_res_change(ctx);1380			break;1381		case MFCINST_RES_CHANGE_FLUSH:1382			s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME);1383			break;1384		case MFCINST_RES_CHANGE_END:1385			mfc_debug(2, "Finished remaining frames after resolution change\n");1386			ctx->capture_state = QUEUE_FREE;1387			mfc_debug(2, "Will re-init the codec\n");1388			s5p_mfc_run_init_dec(ctx);1389			break;1390		default:1391			ret = -EAGAIN;1392		}1393	} else if (ctx->type == MFCINST_ENCODER) {1394		switch (ctx->state) {1395		case MFCINST_FINISHING:1396		case MFCINST_RUNNING:1397			ret = s5p_mfc_run_enc_frame(ctx);1398			break;1399		case MFCINST_INIT:1400			ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd,1401					ctx);1402			break;1403		case MFCINST_RETURN_INST:1404			ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd,1405					ctx);1406			break;1407		case MFCINST_GOT_INST:1408			s5p_mfc_run_init_enc(ctx);1409			break;1410		default:1411			ret = -EAGAIN;1412		}1413	} else {1414		mfc_err("Invalid context type: %d\n", ctx->type);1415		ret = -EAGAIN;1416	}1417 1418	if (ret) {1419		/* Free hardware lock */1420		if (test_and_clear_bit(0, &dev->hw_lock) == 0)1421			mfc_err("Failed to unlock hardware\n");1422 1423		/* This is indeed important, as no operation has been1424		 * scheduled, reduce the clock count as no one will1425		 * ever do this, because no interrupt related to this try_run1426		 * will ever come from hardware. */1427		s5p_mfc_clock_off(dev);1428	}1429}1430 1431static void s5p_mfc_clear_int_flags_v5(struct s5p_mfc_dev *dev)1432{1433	mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT);1434	mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);1435	mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID);1436}1437 1438static int s5p_mfc_get_dspl_y_adr_v5(struct s5p_mfc_dev *dev)1439{1440	return mfc_read(dev, S5P_FIMV_SI_DISPLAY_Y_ADR) << MFC_OFFSET_SHIFT;1441}1442 1443static int s5p_mfc_get_dec_y_adr_v5(struct s5p_mfc_dev *dev)1444{1445	return mfc_read(dev, S5P_FIMV_SI_DECODE_Y_ADR) << MFC_OFFSET_SHIFT;1446}1447 1448static int s5p_mfc_get_dspl_status_v5(struct s5p_mfc_dev *dev)1449{1450	return mfc_read(dev, S5P_FIMV_SI_DISPLAY_STATUS);1451}1452 1453static int s5p_mfc_get_dec_status_v5(struct s5p_mfc_dev *dev)1454{1455	return mfc_read(dev, S5P_FIMV_SI_DECODE_STATUS);1456}1457 1458static int s5p_mfc_get_dec_frame_type_v5(struct s5p_mfc_dev *dev)1459{1460	return mfc_read(dev, S5P_FIMV_DECODE_FRAME_TYPE) &1461		S5P_FIMV_DECODE_FRAME_MASK;1462}1463 1464static int s5p_mfc_get_disp_frame_type_v5(struct s5p_mfc_ctx *ctx)1465{1466	return (s5p_mfc_read_info_v5(ctx, DISP_PIC_FRAME_TYPE) >>1467			S5P_FIMV_SHARED_DISP_FRAME_TYPE_SHIFT) &1468			S5P_FIMV_DECODE_FRAME_MASK;1469}1470 1471static int s5p_mfc_get_consumed_stream_v5(struct s5p_mfc_dev *dev)1472{1473	return mfc_read(dev, S5P_FIMV_SI_CONSUMED_BYTES);1474}1475 1476static int s5p_mfc_get_int_reason_v5(struct s5p_mfc_dev *dev)1477{1478	int reason;1479	reason = mfc_read(dev, S5P_FIMV_RISC2HOST_CMD) &1480		S5P_FIMV_RISC2HOST_CMD_MASK;1481	switch (reason) {1482	case S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET:1483		reason = S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET;1484		break;1485	case S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET:1486		reason = S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET;1487		break;1488	case S5P_FIMV_R2H_CMD_SEQ_DONE_RET:1489		reason = S5P_MFC_R2H_CMD_SEQ_DONE_RET;1490		break;1491	case S5P_FIMV_R2H_CMD_FRAME_DONE_RET:1492		reason = S5P_MFC_R2H_CMD_FRAME_DONE_RET;1493		break;1494	case S5P_FIMV_R2H_CMD_SLICE_DONE_RET:1495		reason = S5P_MFC_R2H_CMD_SLICE_DONE_RET;1496		break;1497	case S5P_FIMV_R2H_CMD_SYS_INIT_RET:1498		reason = S5P_MFC_R2H_CMD_SYS_INIT_RET;1499		break;1500	case S5P_FIMV_R2H_CMD_FW_STATUS_RET:1501		reason = S5P_MFC_R2H_CMD_FW_STATUS_RET;1502		break;1503	case S5P_FIMV_R2H_CMD_SLEEP_RET:1504		reason = S5P_MFC_R2H_CMD_SLEEP_RET;1505		break;1506	case S5P_FIMV_R2H_CMD_WAKEUP_RET:1507		reason = S5P_MFC_R2H_CMD_WAKEUP_RET;1508		break;1509	case S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET:1510		reason = S5P_MFC_R2H_CMD_INIT_BUFFERS_RET;1511		break;1512	case S5P_FIMV_R2H_CMD_ENC_COMPLETE_RET:1513		reason = S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET;1514		break;1515	case S5P_FIMV_R2H_CMD_ERR_RET:1516		reason = S5P_MFC_R2H_CMD_ERR_RET;1517		break;1518	default:1519		reason = S5P_MFC_R2H_CMD_EMPTY;1520	}1521	return reason;1522}1523 1524static int s5p_mfc_get_int_err_v5(struct s5p_mfc_dev *dev)1525{1526	return mfc_read(dev, S5P_FIMV_RISC2HOST_ARG2);1527}1528 1529static int s5p_mfc_err_dec_v5(unsigned int err)1530{1531	return (err & S5P_FIMV_ERR_DEC_MASK) >> S5P_FIMV_ERR_DEC_SHIFT;1532}1533 1534static int s5p_mfc_get_img_width_v5(struct s5p_mfc_dev *dev)1535{1536	return mfc_read(dev, S5P_FIMV_SI_HRESOL);1537}1538 1539static int s5p_mfc_get_img_height_v5(struct s5p_mfc_dev *dev)1540{1541	return mfc_read(dev, S5P_FIMV_SI_VRESOL);1542}1543 1544static int s5p_mfc_get_dpb_count_v5(struct s5p_mfc_dev *dev)1545{1546	return mfc_read(dev, S5P_FIMV_SI_BUF_NUMBER);1547}1548 1549static int s5p_mfc_get_mv_count_v5(struct s5p_mfc_dev *dev)1550{1551	/* NOP */1552	return -1;1553}1554 1555static int s5p_mfc_get_inst_no_v5(struct s5p_mfc_dev *dev)1556{1557	return mfc_read(dev, S5P_FIMV_RISC2HOST_ARG1);1558}1559 1560static int s5p_mfc_get_enc_strm_size_v5(struct s5p_mfc_dev *dev)1561{1562	return mfc_read(dev, S5P_FIMV_ENC_SI_STRM_SIZE);1563}1564 1565static int s5p_mfc_get_enc_slice_type_v5(struct s5p_mfc_dev *dev)1566{1567	return mfc_read(dev, S5P_FIMV_ENC_SI_SLICE_TYPE);1568}1569 1570static int s5p_mfc_get_enc_dpb_count_v5(struct s5p_mfc_dev *dev)1571{1572	return -1;1573}1574 1575static unsigned int s5p_mfc_get_pic_type_top_v5(struct s5p_mfc_ctx *ctx)1576{1577	return s5p_mfc_read_info_v5(ctx, PIC_TIME_TOP);1578}1579 1580static unsigned int s5p_mfc_get_pic_type_bot_v5(struct s5p_mfc_ctx *ctx)1581{1582	return s5p_mfc_read_info_v5(ctx, PIC_TIME_BOT);1583}1584 1585static unsigned int s5p_mfc_get_crop_info_h_v5(struct s5p_mfc_ctx *ctx)1586{1587	return s5p_mfc_read_info_v5(ctx, CROP_INFO_H);1588}1589 1590static unsigned int s5p_mfc_get_crop_info_v_v5(struct s5p_mfc_ctx *ctx)1591{1592	return s5p_mfc_read_info_v5(ctx, CROP_INFO_V);1593}1594 1595/* Initialize opr function pointers for MFC v5 */1596static const struct s5p_mfc_hw_ops s5p_mfc_ops_v5 = {1597	.alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v5,1598	.release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v5,1599	.alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v5,1600	.release_codec_buffers = s5p_mfc_release_codec_buffers_v5,1601	.alloc_instance_buffer = s5p_mfc_alloc_instance_buffer_v5,1602	.release_instance_buffer = s5p_mfc_release_instance_buffer_v5,1603	.alloc_dev_context_buffer = s5p_mfc_alloc_dev_context_buffer_v5,1604	.release_dev_context_buffer = s5p_mfc_release_dev_context_buffer_v5,1605	.dec_calc_dpb_size = s5p_mfc_dec_calc_dpb_size_v5,1606	.enc_calc_src_size = s5p_mfc_enc_calc_src_size_v5,1607	.set_enc_stream_buffer = s5p_mfc_set_enc_stream_buffer_v5,1608	.set_enc_frame_buffer = s5p_mfc_set_enc_frame_buffer_v5,1609	.get_enc_frame_buffer = s5p_mfc_get_enc_frame_buffer_v5,1610	.try_run = s5p_mfc_try_run_v5,1611	.clear_int_flags = s5p_mfc_clear_int_flags_v5,1612	.get_dspl_y_adr = s5p_mfc_get_dspl_y_adr_v5,1613	.get_dec_y_adr = s5p_mfc_get_dec_y_adr_v5,1614	.get_dspl_status = s5p_mfc_get_dspl_status_v5,1615	.get_dec_status = s5p_mfc_get_dec_status_v5,1616	.get_dec_frame_type = s5p_mfc_get_dec_frame_type_v5,1617	.get_disp_frame_type = s5p_mfc_get_disp_frame_type_v5,1618	.get_consumed_stream = s5p_mfc_get_consumed_stream_v5,1619	.get_int_reason = s5p_mfc_get_int_reason_v5,1620	.get_int_err = s5p_mfc_get_int_err_v5,1621	.err_dec = s5p_mfc_err_dec_v5,1622	.get_img_width = s5p_mfc_get_img_width_v5,1623	.get_img_height = s5p_mfc_get_img_height_v5,1624	.get_dpb_count = s5p_mfc_get_dpb_count_v5,1625	.get_mv_count = s5p_mfc_get_mv_count_v5,1626	.get_inst_no = s5p_mfc_get_inst_no_v5,1627	.get_enc_strm_size = s5p_mfc_get_enc_strm_size_v5,1628	.get_enc_slice_type = s5p_mfc_get_enc_slice_type_v5,1629	.get_enc_dpb_count = s5p_mfc_get_enc_dpb_count_v5,1630	.get_pic_type_top = s5p_mfc_get_pic_type_top_v5,1631	.get_pic_type_bot = s5p_mfc_get_pic_type_bot_v5,1632	.get_crop_info_h = s5p_mfc_get_crop_info_h_v5,1633	.get_crop_info_v = s5p_mfc_get_crop_info_v_v5,1634};1635 1636const struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v5(void)1637{1638	return &s5p_mfc_ops_v5;1639}1640