irqreturn_t mfc_irq(int irq, void *dev_id)
{
	unsigned int int_reason;
	unsigned int err_status;

	int_reason = READL(MFC_RISC2HOST_COMMAND) & 0x1FFFF;
	err_status = READL(MFC_RISC2HOST_ARG2);

	mfc_disp_err_status = err_status >> 16;
	mfc_dec_err_status = err_status & 0xFFFF;

	mfc_debug_L0("mfc_irq() : Interrupt !! : %d\n", int_reason);

	
	if(	((int_reason & R2H_CMD_EMPTY)     						== R2H_CMD_EMPTY)      					||
		((int_reason & R2H_CMD_OPEN_INSTANCE_RET)     	== R2H_CMD_OPEN_INSTANCE_RET)      	||
		((int_reason & R2H_CMD_CLOSE_INSTANCE_RET)     	== R2H_CMD_CLOSE_INSTANCE_RET)		||
		((int_reason & R2H_CMD_ERROR_RET)     				== R2H_CMD_ERROR_RET)      				||
		((int_reason & R2H_CMD_SEQ_DONE_RET)     			== R2H_CMD_SEQ_DONE_RET)      		||
		((int_reason & R2H_CMD_FRAME_DONE_RET)     		== R2H_CMD_FRAME_DONE_RET)     		||
		((int_reason & R2H_CMD_SLICE_DONE_RET)     		== R2H_CMD_SLICE_DONE_RET)      		||
		((int_reason & R2H_CMD_ENC_COMPLETE_RET)     	== R2H_CMD_ENC_COMPLETE_RET)  		||
		((int_reason & R2H_CMD_SYS_INIT_RET)     				== R2H_CMD_SYS_INIT_RET)      			||
		((int_reason & R2H_CMD_FW_STATUS_RET)     			== R2H_CMD_FW_STATUS_RET)      		||
		((int_reason & R2H_CMD_SLEEP_RET)     				== R2H_CMD_SLEEP_RET)      				||
		((int_reason & R2H_CMD_WAKEUP_RET)     				== R2H_CMD_WAKEUP_RET)      			||
		((int_reason & R2H_CMD_FLUSH_COMMAND_RET)    	== R2H_CMD_FLUSH_COMMAND_RET) 	||
		((int_reason & R2H_CMD_CMD_ABORT_RET)     		== R2H_CMD_CMD_ABORT_RET)      		||
		((int_reason & R2H_CMD_CMD_BATCH_ENC_RET)     	== R2H_CMD_CMD_BATCH_ENC_RET) 	||
		((int_reason & R2H_CMD_INIT_BUFFERS_RET)     		== R2H_CMD_INIT_BUFFERS_RET) 			||
		((int_reason & R2H_CMD_EDFU_INT_RET)     			== R2H_CMD_EDFU_INT_RET) 				||
		((int_reason & R2H_CMD_DECODE_ERR_RET)     		== R2H_CMD_DECODE_ERR_RET))
	{
		mfc_int_type = int_reason;
		wake_up_interruptible(&mfc_wait_queue);
	}
	else
		mfc_info("Strange Interrupt !! : %d\n", int_reason);


	WRITEL(0, MFC_RISC_HOST_INT);
	WRITEL(0, MFC_RISC2HOST_COMMAND);
	WRITEL(0xffff, MFC_SI_RTN_CHID);

	return IRQ_HANDLED;
}
Exemple #2
0
static long mfc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int ret, ex_ret;
	struct mfc_inst_ctx *mfc_ctx = NULL;
	struct mfc_common_args in_param;

	mutex_lock(&mfc_mutex);
	clk_enable(mfc_sclk);

	ret = copy_from_user(&in_param, (struct mfc_common_args *)arg, sizeof(struct mfc_common_args));
	if (ret < 0) {
		mfc_err("Inparm copy error\n");
		ret = -EIO;
		in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
		goto out_ioctl;
	}

	mfc_ctx = (struct mfc_inst_ctx *)file->private_data;
	mutex_unlock(&mfc_mutex);

	switch (cmd) {
	case IOCTL_MFC_ENC_INIT:
		mutex_lock(&mfc_mutex);

		if (mfc_set_state(mfc_ctx, MFCINST_STATE_ENC_INITIALIZE) < 0) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		/* MFC encode init */
		in_param.ret_code = mfc_init_encode(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_ENC_EXE:
		mutex_lock(&mfc_mutex);
		if (mfc_ctx->MfcState < MFCINST_STATE_ENC_INITIALIZE) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		if (mfc_set_state(mfc_ctx, MFCINST_STATE_ENC_EXE) < 0) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		in_param.ret_code = mfc_exe_encode(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_DEC_INIT:
		mutex_lock(&mfc_mutex);
		if (mfc_set_state(mfc_ctx, MFCINST_STATE_DEC_INITIALIZE) < 0) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		/* MFC decode init */
		in_param.ret_code = mfc_init_decode(mfc_ctx, &(in_param.args));
		if (in_param.ret_code < 0) {
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;
		}

		if (in_param.args.dec_init.out_dpb_cnt <= 0) {
			mfc_err("MFC out_dpb_cnt error\n");
			mutex_unlock(&mfc_mutex);
			break;
		}

		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_DEC_EXE:
		mutex_lock(&mfc_mutex);
		if (mfc_ctx->MfcState < MFCINST_STATE_DEC_INITIALIZE) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		if (mfc_set_state(mfc_ctx, MFCINST_STATE_DEC_EXE) < 0) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		in_param.ret_code = mfc_exe_decode(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_GET_CONFIG:
		mutex_lock(&mfc_mutex);
		if (mfc_ctx->MfcState < MFCINST_STATE_DEC_INITIALIZE) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		in_param.ret_code = mfc_get_config(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_SET_CONFIG:
		mutex_lock(&mfc_mutex);
		in_param.ret_code = mfc_set_config(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_GET_IN_BUF:
		mutex_lock(&mfc_mutex);
		if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		if (in_param.args.mem_alloc.buff_size <= 0) {
			mfc_err("MFCINST_ERR_INVALID_PARAM\n");
			in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		if ((is_dec_codec(in_param.args.mem_alloc.codec_type)) &&
				(in_param.args.mem_alloc.buff_size < (CPB_BUF_SIZE + DESC_BUF_SIZE))) {
			in_param.args.mem_alloc.buff_size = CPB_BUF_SIZE + DESC_BUF_SIZE;
		}

		/* Buffer manager should have 64KB alignment for MFC base addresses */
		in_param.args.mem_alloc.buff_size = ALIGN_TO_8KB(in_param.args.mem_alloc.buff_size);

		/* allocate stream buf for decoder & current YC buf for encoder */
		if (is_dec_codec(in_param.args.mem_alloc.codec_type))
			in_param.ret_code = mfc_allocate_buffer(mfc_ctx, &in_param.args, 0);
		else
			in_param.ret_code = mfc_allocate_buffer(mfc_ctx, &in_param.args, 1);

		mfc_ctx->desc_buff_paddr = in_param.args.mem_alloc.out_paddr + CPB_BUF_SIZE;

		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_FREE_BUF:
		mutex_lock(&mfc_mutex);
		if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		in_param.ret_code = mfc_release_buffer((unsigned char *)in_param.args.mem_free.u_addr);
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_GET_PHYS_ADDR:
		mutex_lock(&mfc_mutex);
		mfc_debug("IOCTL_MFC_GET_PHYS_ADDR\n");

		if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		in_param.ret_code = mfc_get_phys_addr(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_GET_MMAP_SIZE:

		if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
			mfc_err("MFC_RET_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;

			break;
		}

		in_param.ret_code = MFCINST_RET_OK;
		ret = mfc_ctx->port0_mmap_size;

		break;

	case IOCTL_MFC_BUF_CACHE:
		mutex_lock(&mfc_mutex);

		in_param.ret_code = MFCINST_RET_OK;
		mfc_ctx->buf_type = in_param.args.buf_type;

		mutex_unlock(&mfc_mutex);
		break;

	default:
		mfc_err("Requested ioctl command is not defined. (ioctl cmd=0x%08x)\n", cmd);
		in_param.ret_code  = MFCINST_ERR_INVALID_PARAM;
		ret = -EINVAL;
	}

out_ioctl:
	clk_disable(mfc_sclk);

	ex_ret = copy_to_user((struct mfc_common_args *)arg, &in_param, sizeof(struct mfc_common_args));
	if (ex_ret < 0) {
		mfc_err("Outparm copy to user error\n");
		ret = -EIO;
	}

	mfc_debug_L0("---------------IOCTL return = %d ---------------\n", ret);

	return ret;
}
Exemple #3
0
static int mfc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	int ret, ex_ret;
	mfc_inst_ctx *mfc_ctx = NULL;
	mfc_common_args in_param;

	mutex_lock(&mfc_mutex);
#if	Frame_Base_Power_CTR_ON
	if (s5pv210_pd_enable("mfc_pd") < 0) {
		printk(KERN_ERR "[Error]The power is not on for mfc\n");
		return -1;
	}
	clk_enable(mfc_clk);
#endif

	ret = copy_from_user(&in_param, (mfc_common_args *)arg, sizeof(mfc_common_args));
	if (ret < 0)
	{
		mfc_err("Inparm copy error\n");
		ret = -EIO;
		in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
		goto out_ioctl;
	}

	mfc_ctx = (mfc_inst_ctx *)file->private_data;
	mutex_unlock(&mfc_mutex);

	switch (cmd)
	{
		case IOCTL_MFC_ENC_INIT:
			mutex_lock(&mfc_mutex);

#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_ENC_INIT\n");
#endif
			if (mfc_set_state(mfc_ctx, MFCINST_STATE_ENC_INITIALIZE) < 0)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			/* MFC encode init */
			in_param.ret_code = mfc_init_encode(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_ENC_EXE:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_ENC_EXE\n");
#endif

			if (mfc_ctx->MfcState < MFCINST_STATE_ENC_INITIALIZE)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			if (mfc_set_state(mfc_ctx, MFCINST_STATE_ENC_EXE) < 0)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			in_param.ret_code = mfc_exe_encode(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_DEC_INIT:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_DEC_INIT\n");
#endif

			if (mfc_set_state(mfc_ctx, MFCINST_STATE_DEC_INITIALIZE) < 0)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			/* MFC decode init */
			in_param.ret_code = mfc_init_decode(mfc_ctx, &(in_param.args));
			if (in_param.ret_code < 0)
			{
                                mfc_err("MFC_DEC_INIT ERROR ............. ret(%d)\n",in_param.ret_code);
				ret = in_param.ret_code;
				mutex_unlock(&mfc_mutex);
				break;
			}

			if (in_param.args.dec_init.out_dpb_cnt <= 0)
			{
				mfc_err("MFC out_dpb_cnt error\n");
				mutex_unlock(&mfc_mutex);
				break;
			}

			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_DEC_EXE:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_debug_L0("IOCTL_MFC_DEC_EXE\n");
#endif
			if (mfc_ctx->MfcState < MFCINST_STATE_DEC_INITIALIZE)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			if (mfc_set_state(mfc_ctx, MFCINST_STATE_DEC_EXE) < 0)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			in_param.ret_code = mfc_exe_decode(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_GET_CONFIG:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_GET_CONFIG\n");
#endif
			if (mfc_ctx->MfcState < MFCINST_STATE_DEC_INITIALIZE)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			in_param.ret_code = mfc_get_config(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_SET_CONFIG:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_SET_CONFIG\n");
#endif
			in_param.ret_code = mfc_set_config(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_GET_IN_BUF:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_GET_IN_BUF\n");
#endif
			if (mfc_ctx->MfcState < MFCINST_STATE_OPENED)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			if (in_param.args.mem_alloc.buff_size <= 0)
			{
				mfc_err("MFCINST_ERR_INVALID_PARAM\n");
				in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			if ((is_dec_codec(in_param.args.mem_alloc.codec_type)) &&
				(in_param.args.mem_alloc.buff_size < (CPB_BUF_SIZE + DESC_BUF_SIZE)))
			{
				in_param.args.mem_alloc.buff_size = CPB_BUF_SIZE + DESC_BUF_SIZE;
			}

			/* Buffer manager should have 64KB alignment for MFC base addresses */
			in_param.args.mem_alloc.buff_size = ALIGN_TO_8KB(in_param.args.mem_alloc.buff_size);

			/* allocate stream buf for decoder & current YC buf for encoder */
			if (is_dec_codec(in_param.args.mem_alloc.codec_type))
			{
				in_param.ret_code = mfc_allocate_buffer(mfc_ctx, &in_param.args, 0);
			}
			else
			{
				in_param.ret_code = mfc_allocate_buffer(mfc_ctx, &in_param.args, 1);
			}

			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_FREE_BUF:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_FREE_BUF\n");
#endif

			if (mfc_ctx->MfcState < MFCINST_STATE_OPENED)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			in_param.ret_code = mfc_release_buffer((unsigned char *)in_param.args.mem_free.u_addr);
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_GET_PHYS_ADDR:
			mutex_lock(&mfc_mutex);
			mfc_debug("IOCTL_MFC_GET_PHYS_ADDR\n");

			if (mfc_ctx->MfcState < MFCINST_STATE_OPENED)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			in_param.ret_code = mfc_get_phys_addr(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		default:
			mfc_err("Requested ioctl command is not defined. (ioctl cmd=0x%08x)\n", cmd);
			in_param.ret_code  = MFCINST_ERR_INVALID_PARAM;
			ret = -EINVAL;
	}

out_ioctl:
#if	Frame_Base_Power_CTR_ON
	clk_disable(mfc_clk);
	if (s5pv210_pd_disable("mfc_pd") < 0) {
		printk(KERN_ERR "[Error]The power is not off for mfc\n");
		return -1;
	}
#endif

	ex_ret = copy_to_user((mfc_common_args *)arg, &in_param, sizeof(mfc_common_args));
	if (ex_ret < 0)
	{
		mfc_err("Outparm copy to user error\n");
		ret = -EIO;
	}

	mfc_debug_L0("---------------IOCTL return = %d ---------------\n", ret);

	return ret;
}