Esempio n. 1
0
/* Get cropping information */
static int vidioc_g_crop(struct file *file, void *priv,
		struct v4l2_crop *cr)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	struct s5p_mfc_dev *dev = ctx->dev;
	u32 left, right, top, bottom;

	if (ctx->state != MFCINST_HEAD_PARSED &&
	ctx->state != MFCINST_RUNNING && ctx->state != MFCINST_FINISHING
					&& ctx->state != MFCINST_FINISHED) {
			mfc_err("Cannont set crop\n");
			return -EINVAL;
		}
	if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) {
		left = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_h, ctx);
		right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT;
		left = left & S5P_FIMV_SHARED_CROP_LEFT_MASK;
		top = s5p_mfc_hw_call(dev->mfc_ops, get_crop_info_v, ctx);
		bottom = top >> S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT;
		top = top & S5P_FIMV_SHARED_CROP_TOP_MASK;
		cr->c.left = left;
		cr->c.top = top;
		cr->c.width = ctx->img_width - left - right;
		cr->c.height = ctx->img_height - top - bottom;
		mfc_debug(2, "Cropping info [h264]: l=%d t=%d "
			"w=%d h=%d (r=%d b=%d fw=%d fh=%d\n", left, top,
			cr->c.width, cr->c.height, right, bottom,
			ctx->buf_width, ctx->buf_height);
	} else {
Esempio n. 2
0
static int reqbufs_capture(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx,
				struct v4l2_requestbuffers *reqbufs)
{
	int ret = 0;

	s5p_mfc_clock_on();

	if (reqbufs->count == 0) {
		mfc_debug(2, "Freeing buffers\n");
		ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
		if (ret)
			goto out;
		s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
		ctx->dst_bufs_cnt = 0;
	} else if (ctx->capture_state == QUEUE_FREE) {
		WARN_ON(ctx->dst_bufs_cnt != 0);
		mfc_debug(2, "Allocating %d buffers for CAPTURE queue\n",
				reqbufs->count);
		ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
		if (ret)
			goto out;

		ctx->capture_state = QUEUE_BUFS_REQUESTED;
		ctx->total_dpb_count = reqbufs->count;

		ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_codec_buffers, ctx);
		if (ret) {
			mfc_err("Failed to allocate decoding buffers\n");
			reqbufs->count = 0;
			vb2_reqbufs(&ctx->vq_dst, reqbufs);
			ret = -ENOMEM;
			ctx->capture_state = QUEUE_FREE;
			goto out;
		}

		WARN_ON(ctx->dst_bufs_cnt != ctx->total_dpb_count);
		ctx->capture_state = QUEUE_BUFS_MMAPED;

		if (s5p_mfc_ctx_ready(ctx))
			set_work_bit_irqsave(ctx);
		s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
		s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_INIT_BUFFERS_RET,
					  0);
	} else {
		mfc_err("Buffers have already been requested\n");
		ret = -EINVAL;
	}
out:
	s5p_mfc_clock_off();
	if (ret)
		mfc_err("Failed allocating buffers for CAPTURE queue\n");
	return ret;
}
Esempio n. 3
0
int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
{
    int ret;

    mfc_debug_enter();
    s5p_mfc_clock_on();
    s5p_mfc_clean_dev_int_flags(dev);
    ret = s5p_mfc_hw_call(dev->mfc_cmds, sleep_cmd, dev);
    if (ret) {
        mfc_err("Failed to send command to MFC - timeout\n");
        return ret;
    }
    if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SLEEP_RET)) {
        mfc_err("Failed to sleep\n");
        return -EIO;
    }
    s5p_mfc_clock_off();
    dev->int_cond = 0;
    if (dev->int_err != 0 || dev->int_type !=
            S5P_MFC_R2H_CMD_SLEEP_RET) {
        /* Failure. */
        mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err,
                dev->int_type);
        return -EIO;
    }
    mfc_debug_leave();
    return ret;
}
Esempio n. 4
0
static int s5p_mfc_wait_wakeup(struct s5p_mfc_dev *dev)
{
	int ret;

	/* Send MFC wakeup command */
	ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev);
	if (ret) {
		mfc_err("Failed to send command to MFC - timeout\n");
		return ret;
	}

	/* Release reset signal to the RISC */
	if (IS_MFCV6_PLUS(dev)) {
		dev->risc_on = 1;
		mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
	} else {
		mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
	}

	if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) {
		mfc_err("Failed to wakeup MFC\n");
		return -EIO;
	}
	return ret;
}
Esempio n. 5
0
static int s5p_mfc_v8_wait_wakeup(struct s5p_mfc_dev *dev)
{
	int ret;

	/* Release reset signal to the RISC */
	dev->risc_on = 1;
	mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);

	if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) {
		mfc_err("Failed to reset MFCV8\n");
		return -EIO;
	}
	mfc_debug(2, "Write command to wakeup MFCV8\n");
	ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev);
	if (ret) {
		mfc_err("Failed to send command to MFCV8 - timeout\n");
		return ret;
	}

	if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) {
		mfc_err("Failed to wakeup MFC\n");
		return -EIO;
	}
	return ret;
}
Esempio n. 6
0
/* Stream on */
static int vidioc_streamon(struct file *file, void *priv,
			   enum v4l2_buf_type type)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	struct s5p_mfc_dev *dev = ctx->dev;
	int ret = -EINVAL;

	mfc_debug_enter();
	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {

		if (ctx->state == MFCINST_INIT) {
			ctx->dst_bufs_cnt = 0;
			ctx->src_bufs_cnt = 0;
			ctx->capture_state = QUEUE_FREE;
			ctx->output_state = QUEUE_FREE;
			s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer,
					ctx);
			s5p_mfc_hw_call(dev->mfc_ops, alloc_dec_temp_buffers,
					ctx);
			set_work_bit_irqsave(ctx);
			s5p_mfc_clean_ctx_int_flags(ctx);
			s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);

			if (s5p_mfc_wait_for_done_ctx(ctx,
				S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
				/* Error or timeout */
				mfc_err("Error getting instance from hardware\n");
				s5p_mfc_hw_call(dev->mfc_ops,
						release_instance_buffer, ctx);
				s5p_mfc_hw_call(dev->mfc_ops,
						release_dec_desc_buffer, ctx);
				return -EIO;
			}
			mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
		}
		ret = vb2_streamon(&ctx->vq_src, type);
		}
	else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
		ret = vb2_streamon(&ctx->vq_dst, type);
	mfc_debug_leave();
	return ret;
}
Esempio n. 7
0
static int s5p_mfc_sys_init_cmd_v6(struct s5p_mfc_dev *dev)
{
	struct s5p_mfc_cmd_args h2r_args;
	struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv;

	s5p_mfc_hw_call(dev->mfc_ops, alloc_dev_context_buffer, dev);
	mfc_write(dev, dev->ctx_buf.dma, S5P_FIMV_CONTEXT_MEM_ADDR_V6);
	mfc_write(dev, buf_size->dev_ctx, S5P_FIMV_CONTEXT_MEM_SIZE_V6);
	return s5p_mfc_cmd_host2risc_v6(dev, S5P_FIMV_H2R_CMD_SYS_INIT_V6,
					&h2r_args);
}
Esempio n. 8
0
int s5p_mfc_open_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
{
    int ret = 0;

    ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx);
    if (ret) {
        mfc_err("Failed allocating instance buffer\n");
        goto err;
    }

    if (ctx->type == MFCINST_DECODER) {
        ret = s5p_mfc_hw_call(dev->mfc_ops,
                              alloc_dec_temp_buffers, ctx);
        if (ret) {
            mfc_err("Failed allocating temporary buffers\n");
            goto err_free_inst_buf;
        }
    }

    set_work_bit_irqsave(ctx);
    s5p_mfc_clean_ctx_int_flags(ctx);
    s5p_mfc_hw_call_void(dev->mfc_ops, try_run, dev);
    if (s5p_mfc_wait_for_done_ctx(ctx,
                                  S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
        /* Error or timeout */
        mfc_err("Error getting instance from hardware\n");
        ret = -EIO;
        goto err_free_desc_buf;
    }

    mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
    return ret;

err_free_desc_buf:
    if (ctx->type == MFCINST_DECODER)
        s5p_mfc_hw_call_void(dev->mfc_ops, release_dec_desc_buffer, ctx);
err_free_inst_buf:
    s5p_mfc_hw_call_void(dev->mfc_ops, release_instance_buffer, ctx);
err:
    return ret;
}
Esempio n. 9
0
int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
{
    int ret;

    mfc_debug_enter();
    /* 0. MFC reset */
    mfc_debug(2, "MFC reset..\n");
    s5p_mfc_clock_on();
    ret = s5p_mfc_reset(dev);
    if (ret) {
        mfc_err("Failed to reset MFC - timeout\n");
        return ret;
    }
    mfc_debug(2, "Done MFC reset..\n");
    /* 1. Set DRAM base Addr */
    s5p_mfc_init_memctrl(dev);
    /* 2. Initialize registers of channel I/F */
    s5p_mfc_clear_cmds(dev);
    s5p_mfc_clean_dev_int_flags(dev);
    /* 3. Initialize firmware */
    ret = s5p_mfc_hw_call(dev->mfc_cmds, wakeup_cmd, dev);
    if (ret) {
        mfc_err("Failed to send command to MFC - timeout\n");
        return ret;
    }
    /* 4. Release reset signal to the RISC */
    if (IS_MFCV6_PLUS(dev))
        mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
    else
        mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
    mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
    if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_WAKEUP_RET)) {
        mfc_err("Failed to load firmware\n");
        return -EIO;
    }
    s5p_mfc_clock_off();
    dev->int_cond = 0;
    if (dev->int_err != 0 || dev->int_type !=
            S5P_MFC_R2H_CMD_WAKEUP_RET) {
        /* Failure. */
        mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err,
                dev->int_type);
        return -EIO;
    }
    mfc_debug_leave();
    return 0;
}
Esempio n. 10
0
/* Reqeust buffers */
static int vidioc_reqbufs(struct file *file, void *priv,
					  struct v4l2_requestbuffers *reqbufs)
{
	struct s5p_mfc_dev *dev = video_drvdata(file);
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	int ret = 0;

	if (reqbufs->memory != V4L2_MEMORY_MMAP) {
		mfc_err("Only V4L2_MEMORY_MAP is supported\n");
		return -EINVAL;
	}
	if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		/* Can only request buffers after an instance has been opened.*/
		if (ctx->state == MFCINST_INIT) {
			ctx->src_bufs_cnt = 0;
			if (reqbufs->count == 0) {
				mfc_debug(2, "Freeing buffers\n");
				s5p_mfc_clock_on();
				ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
				s5p_mfc_clock_off();
				return ret;
			}
			/* Decoding */
			if (ctx->output_state != QUEUE_FREE) {
				mfc_err("Bufs have already been requested\n");
				return -EINVAL;
			}
			s5p_mfc_clock_on();
			ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
			s5p_mfc_clock_off();
			if (ret) {
				mfc_err("vb2_reqbufs on output failed\n");
				return ret;
			}
			mfc_debug(2, "vb2_reqbufs: %d\n", ret);
			ctx->output_state = QUEUE_BUFS_REQUESTED;
		}
	} else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
		ctx->dst_bufs_cnt = 0;
		if (reqbufs->count == 0) {
			mfc_debug(2, "Freeing buffers\n");
			s5p_mfc_clock_on();
			ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
			s5p_mfc_clock_off();
			return ret;
		}
		if (ctx->capture_state != QUEUE_FREE) {
			mfc_err("Bufs have already been requested\n");
			return -EINVAL;
		}
		ctx->capture_state = QUEUE_BUFS_REQUESTED;
		s5p_mfc_clock_on();
		ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
		s5p_mfc_clock_off();
		if (ret) {
			mfc_err("vb2_reqbufs on capture failed\n");
			return ret;
		}
		if (reqbufs->count < ctx->dpb_count) {
			mfc_err("Not enough buffers allocated\n");
			reqbufs->count = 0;
			s5p_mfc_clock_on();
			ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
			s5p_mfc_clock_off();
			return -ENOMEM;
		}
		ctx->total_dpb_count = reqbufs->count;
		ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_codec_buffers, ctx);
		if (ret) {
			mfc_err("Failed to allocate decoding buffers\n");
			reqbufs->count = 0;
			s5p_mfc_clock_on();
			ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
			s5p_mfc_clock_off();
			return -ENOMEM;
		}
		if (ctx->dst_bufs_cnt == ctx->total_dpb_count) {
			ctx->capture_state = QUEUE_BUFS_MMAPED;
		} else {
			mfc_err("Not all buffers passed to buf_init\n");
			reqbufs->count = 0;
			s5p_mfc_clock_on();
			ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
			s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers,
					ctx);
			s5p_mfc_clock_off();
			return -ENOMEM;
		}
		if (s5p_mfc_ctx_ready(ctx))
			set_work_bit_irqsave(ctx);
		s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
		s5p_mfc_wait_for_done_ctx(ctx,
					S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, 0);
	}
	return ret;
}
Esempio n. 11
0
/* Initialize hardware */
int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
{
    unsigned int ver;
    int ret;

    mfc_debug_enter();
    if (!dev->fw_virt_addr) {
        mfc_err("Firmware memory is not allocated.\n");
        return -EINVAL;
    }

    /* 0. MFC reset */
    mfc_debug(2, "MFC reset..\n");
    s5p_mfc_clock_on();
    ret = s5p_mfc_reset(dev);
    if (ret) {
        mfc_err("Failed to reset MFC - timeout\n");
        return ret;
    }
    mfc_debug(2, "Done MFC reset..\n");
    /* 1. Set DRAM base Addr */
    s5p_mfc_init_memctrl(dev);
    /* 2. Initialize registers of channel I/F */
    s5p_mfc_clear_cmds(dev);
    /* 3. Release reset signal to the RISC */
    s5p_mfc_clean_dev_int_flags(dev);
    if (IS_MFCV6_PLUS(dev))
        mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);
    else
        mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
    mfc_debug(2, "Will now wait for completion of firmware transfer\n");
    if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) {
        mfc_err("Failed to load firmware\n");
        s5p_mfc_reset(dev);
        s5p_mfc_clock_off();
        return -EIO;
    }
    s5p_mfc_clean_dev_int_flags(dev);
    /* 4. Initialize firmware */
    ret = s5p_mfc_hw_call(dev->mfc_cmds, sys_init_cmd, dev);
    if (ret) {
        mfc_err("Failed to send command to MFC - timeout\n");
        s5p_mfc_reset(dev);
        s5p_mfc_clock_off();
        return ret;
    }
    mfc_debug(2, "Ok, now will wait for completion of hardware init\n");
    if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_SYS_INIT_RET)) {
        mfc_err("Failed to init hardware\n");
        s5p_mfc_reset(dev);
        s5p_mfc_clock_off();
        return -EIO;
    }
    dev->int_cond = 0;
    if (dev->int_err != 0 || dev->int_type !=
            S5P_MFC_R2H_CMD_SYS_INIT_RET) {
        /* Failure. */
        mfc_err("Failed to init firmware - error: %d int: %d\n",
                dev->int_err, dev->int_type);
        s5p_mfc_reset(dev);
        s5p_mfc_clock_off();
        return -EIO;
    }
    if (IS_MFCV6_PLUS(dev))
        ver = mfc_read(dev, S5P_FIMV_FW_VERSION_V6);
    else
        ver = mfc_read(dev, S5P_FIMV_FW_VERSION);

    mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n",
              (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
    s5p_mfc_clock_off();
    mfc_debug_leave();
    return 0;
}