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; }
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; }
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; }