Ejemplo n.º 1
0
int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
{
	struct s5p_mfc_ctx *ctx;
	int ret;

	mfc_debug_enter();

	if (!dev) {
		mfc_err("no mfc device to run\n");
		return -EINVAL;
	}

	ctx = dev->ctx[dev->curr_ctx];
	if (!ctx) {
		mfc_err("no mfc context to run\n");
		return -EINVAL;
	}

	ret = wait_event_interruptible_timeout(ctx->queue,
			(test_bit(ctx->num, &dev->hw_lock) == 0),
			msecs_to_jiffies(MFC_INT_TIMEOUT));
	if (ret == 0) {
		mfc_err("Waiting for hardware to finish timed out\n");
		ret = -EIO;
		return ret;
	}

	spin_lock(&dev->condlock);
	set_bit(ctx->num, &dev->hw_lock);
	spin_unlock(&dev->condlock);

	s5p_mfc_clock_on();
	s5p_mfc_clean_dev_int_flags(dev);
	ret = s5p_mfc_sleep_cmd(dev);
	if (ret) {
		mfc_err("Failed to send command to MFC - timeout.\n");
		goto err_mfc_sleep;
	}
	if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SLEEP_RET)) {
		mfc_err("Failed to sleep\n");
		ret = -EIO;
		goto err_mfc_sleep;
	}

	dev->int_cond = 0;
	if (dev->int_err != 0 || dev->int_type !=
						S5P_FIMV_R2H_CMD_SLEEP_RET) {
		/* Failure. */
		mfc_err("Failed to sleep - error: %d"
				" int: %d.\n", dev->int_err, dev->int_type);
		ret = -EIO;
		goto err_mfc_sleep;
	}

err_mfc_sleep:
	s5p_mfc_clock_off();
	mfc_debug_leave();

	return ret;
}
int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
{
	struct firmware *fw_blob;
	int err;

	mfc_debug_enter();
	err = request_firmware((const struct firmware **)&fw_blob,
				     "s5p-mfc.fw", dev->v4l2_dev.dev);
	if (err != 0) {
		mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
		return -EINVAL;
	}
	if (fw_blob->size > dev->fw_size) {
		mfc_err("MFC firmware is too big to be loaded\n");
		release_firmware(fw_blob);
		return -ENOMEM;
	}
	if (s5p_mfc_bitproc_buf == 0 || s5p_mfc_bitproc_phys == 0) {
		mfc_err("MFC firmware is not allocated or was not mapped correctly\n");
		release_firmware(fw_blob);
		return -EINVAL;
	}
	memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
	wmb();
	release_firmware(fw_blob);
	mfc_debug_leave();
	return 0;
}
Ejemplo n.º 3
0
/* Open a new instance and get its number */
int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx)
{
	struct s5p_mfc_dev *dev;
	int ret;

	mfc_debug_enter();

	if (!ctx) {
		mfc_err("no mfc context to run\n");
		return -EINVAL;
	}
	dev = ctx->dev;
	mfc_debug(2, "Requested codec mode: %d\n", ctx->codec_mode);

	s5p_mfc_write_reg(dev, ctx->codec_mode, S5P_FIMV_CODEC_TYPE);
	s5p_mfc_write_reg(dev, ctx->ctx.ofs, S5P_FIMV_CONTEXT_MEM_ADDR);
	s5p_mfc_write_reg(dev, ctx->ctx_buf_size, S5P_FIMV_CONTEXT_MEM_SIZE);
	if (ctx->type == MFCINST_DECODER)
		s5p_mfc_write_reg(dev, ctx->dec_priv->crc_enable,
							S5P_FIMV_D_CRC_CTRL);

	ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE, NULL);

	mfc_debug_leave();

	return ret;
}
int s5p_mfc_reset(struct s5p_mfc_dev *dev)
{
	unsigned int mc_status;
	unsigned long timeout;

	mfc_debug_enter();
	
	
	mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
	
	mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
	mdelay(10);

	timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
	
	do {
		if (time_after(jiffies, timeout)) {
			mfc_err("Timeout while resetting MFC\n");
			return -EIO;
		}

		mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);

	} while (mc_status & 0x3);

	mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
	mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
	mfc_debug_leave();
	return 0;
}
Ejemplo n.º 5
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_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_FIMV_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_FIMV_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;
}
/* Open a new instance and get its number */
int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx)
{
	struct s5p_mfc_cmd_args h2r_args;
	unsigned int crc = 0;
	struct s5p_mfc_dec *dec = ctx->dec_priv;
	int ret;

	mfc_debug_enter();

	mfc_debug(2, "Requested codec mode: %d\n", ctx->codec_mode);

	if (ctx->type == MFCINST_DECODER)
		crc = dec->crc_enable;

	memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
	h2r_args.arg[0] = ctx->codec_mode;
	h2r_args.arg[1] = crc << 31; /* no pixelcache */
	h2r_args.arg[2] = ctx->ctx.ofs;
	h2r_args.arg[3] = ctx->ctx_buf_size;

	ret = s5p_mfc_cmd_host2risc(S5P_FIMV_H2R_CMD_OPEN_INSTANCE, &h2r_args);

	mfc_debug_leave();

	return ret;
}
/* Reset the device */
static int s5p_mfc_reset_v6(struct s5p_mfc_dev *dev)
{
	int i;
	mfc_debug_enter();

	/* Zero Initialization of MFC registers */
	mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6);
	mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6);
	mfc_write(dev, 0, S5P_FIMV_FW_VERSION_V6);

	for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++)
		mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));

	/* check bus reset control before reset */
	if (dev->risc_on)
		if (s5p_mfc_bus_reset(dev))
			return -EIO;
	/* Reset
	 * set RISC_ON to 0 during power_on & wake_up.
	 * V6 needs RISC_ON set to 0 during reset also.
	 */
	if ((!dev->risc_on) || (!IS_MFCV7(dev)))
		mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6);

	mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6);
	mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6);

	mfc_debug_leave();
	return 0;
}
Ejemplo n.º 8
0
/* Query buffer */
static int vidioc_querybuf(struct file *file, void *priv,
						   struct v4l2_buffer *buf)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	int ret;
	int i;

	if (buf->memory != V4L2_MEMORY_MMAP) {
		mfc_err("Only mmaped buffers can be used\n");
		return -EINVAL;
	}
	mfc_debug(2, "State: %d, buf->type: %d\n", ctx->state, buf->type);
	if (ctx->state == MFCINST_INIT &&
			buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		ret = vb2_querybuf(&ctx->vq_src, buf);
	} else if (ctx->state == MFCINST_RUNNING &&
			buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
		ret = vb2_querybuf(&ctx->vq_dst, buf);
		for (i = 0; i < buf->length; i++)
			buf->m.planes[i].m.mem_offset += DST_QUEUE_OFF_BASE;
	} else {
		mfc_err("vidioc_querybuf called in an inappropriate state\n");
		ret = -EINVAL;
	}
	mfc_debug_leave();
	return ret;
}
Ejemplo 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_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(dev))
		s5p_mfc_write_reg(0x1, S5P_FIMV_RISC_ON);
	else
		s5p_mfc_write_reg(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_FIMV_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_FIMV_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;
}
Ejemplo n.º 10
0
/* Reset the device */
static int s5p_mfc_reset(struct s5p_mfc_dev *dev)
{
	int i;
	unsigned int mc_status;
	unsigned long timeout;

	mfc_debug_enter();

	/* Stop procedure */
	/* FIXME: F/W can be access invalid address */
	/* Reset VI */
	/*
	s5p_mfc_write_reg(0x3f7, S5P_FIMV_SW_RESET);
	*/

	if (IS_MFCV6(dev)) {
		/* Reset IP */
		s5p_mfc_write_reg(0xFEE, S5P_FIMV_MFC_RESET);	/*  except RISC, reset */
		s5p_mfc_write_reg(0x0, S5P_FIMV_MFC_RESET);	/*  reset release */

		/* Zero Initialization of MFC registers */
		s5p_mfc_write_reg(0, S5P_FIMV_RISC2HOST_CMD);
		s5p_mfc_write_reg(0, S5P_FIMV_HOST2RISC_CMD);
		s5p_mfc_write_reg(0, S5P_FIMV_FW_VERSION);

		for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT; i++)
			s5p_mfc_write_reg(0, S5P_FIMV_REG_CLEAR_BEGIN + (i*4));

		/* Reset */
		s5p_mfc_write_reg(0, S5P_FIMV_RISC_ON);
		s5p_mfc_write_reg(0x1FFF, S5P_FIMV_MFC_RESET);
		s5p_mfc_write_reg(0, S5P_FIMV_MFC_RESET);
	} else {
		s5p_mfc_write_reg(0x3f6, S5P_FIMV_SW_RESET);	/*  reset RISC */
		s5p_mfc_write_reg(0x3e2, S5P_FIMV_SW_RESET);	/*  All reset except for MC */
		mdelay(10);

		timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);

		/* Check MC status */
		do {
			if (time_after(jiffies, timeout)) {
				mfc_err("Timeout while resetting MFC.\n");
				return -EIO;
			}

			mc_status = s5p_mfc_read_reg(S5P_FIMV_MC_STATUS);

		} while (mc_status & 0x3);

		s5p_mfc_write_reg(0x0, S5P_FIMV_SW_RESET);
		s5p_mfc_write_reg(0x3fe, S5P_FIMV_SW_RESET);
	}

	mfc_debug_leave();

	return 0;
}
Ejemplo n.º 11
0
/* Reset the device */
int s5p_mfc_reset(struct s5p_mfc_dev *dev)
{
	unsigned int mc_status;
	unsigned long timeout;
	int i;

	mfc_debug_enter();

	if (IS_MFCV6_PLUS(dev)) {
		/* Zero Initialization of MFC registers */
		mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6);
		mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6);
		mfc_write(dev, 0, S5P_FIMV_FW_VERSION_V6);

		for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++)
			mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));

		/* check bus reset control before reset */
		if (dev->risc_on)
			if (s5p_mfc_bus_reset(dev))
				return -EIO;
		/* Reset
		 * set RISC_ON to 0 during power_on & wake_up.
		 * V6 needs RISC_ON set to 0 during reset also.
		 */
		if ((!dev->risc_on) || (!IS_MFCV7_PLUS(dev)))
			mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6);

		mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6);
		mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6);
	} else {
		/* Stop procedure */
		/*  reset RISC */
		mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
		/*  All reset except for MC */
		mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
		mdelay(10);

		timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
		/* Check MC status */
		do {
			if (time_after(jiffies, timeout)) {
				mfc_err("Timeout while resetting MFC\n");
				return -EIO;
			}

			mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);

		} while (mc_status & 0x3);

		mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
		mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
	}

	mfc_debug_leave();
	return 0;
}
Ejemplo n.º 12
0
/* Load firmware to MFC */
int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
{
	struct firmware *fw_blob;
	unsigned int firmware_size;
	int err;

	if (!dev) {
		mfc_err("no mfc device to run\n");
		return -EINVAL;
	}

	firmware_size = dev->variant->buf_size->firmware_code;

	/* Firmare has to be present as a separate file or compiled
	 * into kernel. */
	mfc_debug_enter();
	mfc_info("Requesting fw\n");
	err = request_firmware((const struct firmware **)&fw_blob,
					MFC_FW_NAME, dev->v4l2_dev.dev);

	if (err != 0) {
		mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel.\n");
		return -EINVAL;
	}

	mfc_debug(2, "Ret of request_firmware: %d Size: %d\n", err, fw_blob->size);

	if (fw_blob->size > firmware_size) {
		mfc_err("MFC firmware is too big to be loaded.\n");
		release_firmware(fw_blob);
		return -ENOMEM;
	}
	if (s5p_mfc_bitproc_buf == 0 || s5p_mfc_bitproc_phys == 0) {
		mfc_err("MFC firmware is not allocated or was not mapped correctly.\n");
		release_firmware(fw_blob);
		return -EINVAL;
	}
	memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
	/*
	s5p_mfc_bitproc_dma = dma_map_single(dev->v4l2_dev.dev,
					     s5p_mfc_bitproc_virt,
					     FIRMWARE_CODE_SIZE,
					     DMA_TO_DEVICE);
	*/
	s5p_mfc_mem_clean_priv(s5p_mfc_bitproc_buf, s5p_mfc_bitproc_virt, 0,
			fw_blob->size);

	dev->fw.dva = s5p_mfc_bitproc_phys;
	dev->fw.kva = s5p_mfc_bitproc_virt;
	dev->fw.ctx = s5p_mfc_bitproc_buf;
	dev->fw.size = fw_blob->size;

	release_firmware(fw_blob);
	mfc_debug_leave();
	return 0;
}
Ejemplo n.º 13
0
/* Get format */
static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	struct v4l2_pix_format_mplane *pix_mp;

	mfc_debug_enter();
	pix_mp = &f->fmt.pix_mp;
	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
	    (ctx->state == MFCINST_GOT_INST || ctx->state ==
						MFCINST_RES_CHANGE_END)) {
		/* If the MFC is parsing the header,
		 * so wait until it is finished */
		s5p_mfc_clean_ctx_int_flags(ctx);
		s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_SEQ_DONE_RET,
									0);
	}
	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
	    ctx->state >= MFCINST_HEAD_PARSED &&
	    ctx->state < MFCINST_ABORT) {
		/* This is run on CAPTURE (decode output) */
		/* Width and height are set to the dimensions
		   of the movie, the buffer is bigger and
		   further processing stages should crop to this
		   rectangle. */
		pix_mp->width = ctx->buf_width;
		pix_mp->height = ctx->buf_height;
		pix_mp->field = V4L2_FIELD_NONE;
		pix_mp->num_planes = 2;
		/* Set pixelformat to the format in which MFC
		   outputs the decoded frame */
		pix_mp->pixelformat = ctx->dst_fmt->fourcc;
		pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
		pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
		pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
		pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		/* This is run on OUTPUT
		   The buffer contains compressed image
		   so width and height have no meaning */
		pix_mp->width = 0;
		pix_mp->height = 0;
		pix_mp->field = V4L2_FIELD_NONE;
		pix_mp->plane_fmt[0].bytesperline = ctx->dec_src_buf_size;
		pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size;
		pix_mp->pixelformat = ctx->src_fmt->fourcc;
		pix_mp->num_planes = ctx->src_fmt->num_planes;
	} else {
		mfc_err("Format could not be read\n");
		mfc_debug(2, "%s-- with error\n", __func__);
		return -EINVAL;
	}
	mfc_debug_leave();
	return 0;
}
Ejemplo n.º 14
0
/* Reset the device */
int s5p_mfc_reset(struct s5p_mfc_dev *dev)
{
    unsigned int mc_status;
    unsigned long timeout;
    int i;

    mfc_debug_enter();

    if (IS_MFCV6_PLUS(dev)) {
        /* Reset IP */
        /*  except RISC, reset */
        mfc_write(dev, 0xFEE, S5P_FIMV_MFC_RESET_V6);
        /*  reset release */
        mfc_write(dev, 0x0, S5P_FIMV_MFC_RESET_V6);

        /* Zero Initialization of MFC registers */
        mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6);
        mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD_V6);
        mfc_write(dev, 0, S5P_FIMV_FW_VERSION_V6);

        for (i = 0; i < S5P_FIMV_REG_CLEAR_COUNT_V6; i++)
            mfc_write(dev, 0, S5P_FIMV_REG_CLEAR_BEGIN_V6 + (i*4));

        /* Reset */
        mfc_write(dev, 0, S5P_FIMV_RISC_ON_V6);
        mfc_write(dev, 0x1FFF, S5P_FIMV_MFC_RESET_V6);
        mfc_write(dev, 0, S5P_FIMV_MFC_RESET_V6);
    } else {
        /* Stop procedure */
        /*  reset RISC */
        mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
        /*  All reset except for MC */
        mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
        mdelay(10);

        timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
        /* Check MC status */
        do {
            if (time_after(jiffies, timeout)) {
                mfc_err("Timeout while resetting MFC\n");
                return -EIO;
            }

            mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);

        } while (mc_status & 0x3);

        mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
        mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
    }

    mfc_debug_leave();
    return 0;
}
Ejemplo n.º 15
0
int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev)
{
	int ret;

	mfc_debug_enter();

	ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_WAKEUP, NULL);

	mfc_debug_leave();

	return ret;
}
Ejemplo n.º 16
0
/* Set format */
static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
	struct s5p_mfc_dev *dev = video_drvdata(file);
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	int ret = 0;
	struct v4l2_pix_format_mplane *pix_mp;
	struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;

	mfc_debug_enter();
	ret = vidioc_try_fmt(file, priv, f);
	pix_mp = &f->fmt.pix_mp;
	if (ret)
		return ret;
	if (ctx->vq_src.streaming || ctx->vq_dst.streaming) {
		v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
		ret = -EBUSY;
		goto out;
	}
	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
		/* dst_fmt is validated by call to vidioc_try_fmt */
		ctx->dst_fmt = find_format(f, MFC_FMT_RAW);
		ret = 0;
		goto out;
	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		/* src_fmt is validated by call to vidioc_try_fmt */
		ctx->src_fmt = find_format(f, MFC_FMT_DEC);
		ctx->codec_mode = ctx->src_fmt->codec_mode;
		mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
		pix_mp->height = 0;
		pix_mp->width = 0;
		if (pix_mp->plane_fmt[0].sizeimage == 0)
			pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size =
								DEF_CPB_SIZE;
		else if (pix_mp->plane_fmt[0].sizeimage > buf_size->cpb)
			ctx->dec_src_buf_size = buf_size->cpb;
		else
			ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
		pix_mp->plane_fmt[0].bytesperline = 0;
		ctx->state = MFCINST_INIT;
		ret = 0;
		goto out;
	} else {
		mfc_err("Wrong type error for S_FMT : %d", f->type);
		ret = -EINVAL;
		goto out;
	}

out:
	mfc_debug_leave();
	return ret;
}
Ejemplo n.º 17
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);
	int ret = -EINVAL;

	mfc_debug_enter();
	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
		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;
}
Ejemplo n.º 18
0
/* Close instance */
int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx)
{
	struct s5p_mfc_dev *dev = ctx->dev;
	int ret;

	mfc_debug_enter();

	s5p_mfc_write_reg(dev, ctx->inst_no, S5P_FIMV_INSTANCE_ID);

	ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_CLOSE_INSTANCE, NULL);

	mfc_debug_leave();

	return ret;
}
Ejemplo n.º 19
0
int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev)
{
	struct s5p_mfc_cmd_args h2r_args;
	int ret;

	mfc_debug_enter();

	memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));

	ret = s5p_mfc_cmd_host2risc(S5P_FIMV_H2R_CMD_WAKEUP, &h2r_args);

	mfc_debug_leave();

	return ret;
}
Ejemplo n.º 20
0
int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev)
{
	struct s5p_mfc_cmd_args h2r_args;
	int ret;

	mfc_debug_enter();

	memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
	h2r_args.arg[0] = FIRMWARE_CODE_SIZE;

	ret = s5p_mfc_cmd_host2risc(S5P_FIMV_H2R_CMD_SYS_INIT, &h2r_args);

	mfc_debug_leave();

	return ret;
}
int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev)
{
	struct s5p_mfc_cmd_args h2r_args;
	struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size;
	int ret;

	mfc_debug_enter();

	memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
	h2r_args.arg[0] = buf_size->firmware_code;

	ret = s5p_mfc_cmd_host2risc(S5P_FIMV_H2R_CMD_SYS_INIT, &h2r_args);

	mfc_debug_leave();

	return ret;
}
Ejemplo n.º 22
0
/* Load firmware to MFC */
int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
{
	struct firmware *fw_blob;
	size_t firmware_size;
	int err;

	if (!dev) {
		mfc_err("no mfc device to run\n");
		return -EINVAL;
	}

	firmware_size = dev->variant->buf_size->firmware_code;

	/* Firmare has to be present as a separate file or compiled
	 * into kernel. */
	mfc_debug_enter();
	mfc_debug(2, "Requesting fw\n");
	err = request_firmware((const struct firmware **)&fw_blob,
					MFC_FW_NAME, dev->v4l2_dev.dev);

	if (err != 0) {
		mfc_err_dev("Firmware is not present in the /lib/firmware directory nor compiled in kernel.\n");
		return -EINVAL;
	}

	mfc_debug(2, "Ret of request_firmware: %d Size: %zu\n", err, fw_blob->size);

	if (fw_blob->size > firmware_size) {
		mfc_err_dev("MFC firmware is too big to be loaded.\n");
		release_firmware(fw_blob);
		return -ENOMEM;
	}

	if (dev->fw_info.alloc == 0 || dev->fw_info.ofs == 0) {
		mfc_err_dev("MFC firmware is not allocated or was not mapped correctly.\n");
		release_firmware(fw_blob);
		return -EINVAL;
	}
	dev->fw_size = fw_blob->size;
	memcpy(dev->fw_info.virt, fw_blob->data, fw_blob->size);
	s5p_mfc_mem_clean_priv(dev->fw_info.alloc, dev->fw_info.virt, 0,
			fw_blob->size);
	release_firmware(fw_blob);
	mfc_debug_leave();
	return 0;
}
Ejemplo n.º 23
0
/* Set format */
static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
{
	struct s5p_mfc_dev *dev = video_drvdata(file);
	struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
	int ret = 0;
	struct s5p_mfc_fmt *fmt;
	struct v4l2_pix_format_mplane *pix_mp;

	mfc_debug_enter();
	ret = vidioc_try_fmt(file, priv, f);
	pix_mp = &f->fmt.pix_mp;
	if (ret)
		return ret;
	if (ctx->vq_src.streaming || ctx->vq_dst.streaming) {
		v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
		ret = -EBUSY;
		goto out;
	}
	fmt = find_format(f, MFC_FMT_DEC);
	if (!fmt || fmt->codec_mode == S5P_FIMV_CODEC_NONE) {
		mfc_err("Unknown codec\n");
		ret = -EINVAL;
		goto out;
	}
	if (fmt->type != MFC_FMT_DEC) {
		mfc_err("Wrong format selected, you should choose "
					"format for decoding\n");
		ret = -EINVAL;
		goto out;
	}
	ctx->src_fmt = fmt;
	ctx->codec_mode = fmt->codec_mode;
	mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
	pix_mp->height = 0;
	pix_mp->width = 0;
	if (pix_mp->plane_fmt[0].sizeimage)
		ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
	else
		pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size =
								DEF_CPB_SIZE;
	pix_mp->plane_fmt[0].bytesperline = 0;
	ctx->state = MFCINST_INIT;
out:
	mfc_debug_leave();
	return ret;
}
int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
{
	int ret;

	mfc_debug_enter();
	
	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");
	
	s5p_mfc_init_memctrl(dev);
	
	s5p_mfc_clear_cmds(dev);
	s5p_mfc_clean_dev_int_flags(dev);
	
	ret = s5p_mfc_wakeup_cmd(dev);
	if (ret) {
		mfc_err("Failed to send command to MFC - timeout\n");
		return ret;
	}
	
	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_FIMV_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_FIMV_R2H_CMD_WAKEUP_RET) {
		
		mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err,
								dev->int_type);
		return -EIO;
	}
	mfc_debug_leave();
	return 0;
}
/* Initialize MFC V6 hardware */
static int s5p_mfc_init_hw_v6(struct s5p_mfc_dev *dev)
{
	unsigned int ver;
	int ret;

	mfc_debug_enter();
	ret = s5p_mfc_load_firmware(dev);
	if (ret) {
		mfc_err("Failed to reload FW\n");
		return ret;
	}

	/* 0. MFC reset */
	mfc_debug(2, "MFC reset..\n");
	WARN_ON(dev->risc_on);
	s5p_mfc_clock_on(dev);
	ret = s5p_mfc_ctrl_ops_call(dev, reset, dev);
	if (ret) {
		mfc_err("Failed to reset MFC - timeout\n");
		s5p_mfc_clock_off(dev);
		return ret;
	}
	mfc_debug(2, "Done MFC reset..\n");
	/* 1. Set DRAM base Addr */
	s5p_mfc_init_memctrl_v6(dev);
	/* 2. Release reset signal to the RISC */
	s5p_mfc_clean_dev_int_flags(dev);
	mfc_write(dev, 0x1, S5P_FIMV_RISC_ON_V6);

	ret = s5p_mfc_init_fw(dev);
	if (ret) {
		s5p_mfc_clock_off(dev);
		return ret;
	}

	ver = mfc_read(dev, S5P_FIMV_FW_VERSION_V6);
	mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n",
		(ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
	s5p_mfc_clock_off(dev);
	dev->risc_on = 1;
	mfc_debug_leave();
	return ret;
}
Ejemplo n.º 26
0
int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev)
{
	struct s5p_mfc_cmd_args h2r_args;
	struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->buf;
	int ret;

	mfc_debug_enter();

	s5p_mfc_alloc_dev_context_buffer(dev);

	s5p_mfc_write_reg(dev->ctx_buf.ofs, S5P_FIMV_CONTEXT_MEM_ADDR);
	s5p_mfc_write_reg(buf_size->dev_ctx, S5P_FIMV_CONTEXT_MEM_SIZE);

	ret = s5p_mfc_cmd_host2risc(S5P_FIMV_H2R_CMD_SYS_INIT, &h2r_args);

	mfc_debug_leave();

	return ret;
}
Ejemplo n.º 27
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;
}
static int s5p_mfc_wakeup_v6(struct s5p_mfc_dev *dev)
{
	int ret;

	mfc_debug_enter();
	/* 0. MFC reset */
	mfc_debug(2, "MFC reset..\n");
	WARN_ON(dev->risc_on);
	s5p_mfc_clock_on(dev);
	ret = s5p_mfc_ctrl_ops_call(dev, reset, dev);
	if (ret) {
		mfc_err("Failed to reset MFC - timeout\n");
		s5p_mfc_clock_off(dev);
		return ret;
	}
	mfc_debug(2, "Done MFC reset..\n");
	/* 1. Set DRAM base Addr */
	s5p_mfc_init_memctrl_v6(dev);
	/* 2. Initialize registers of channel I/F */
	s5p_mfc_clean_dev_int_flags(dev);
	/* 3. Send MFC wakeup command and wait for completion*/
	if (IS_MFCV8(dev))
		ret = s5p_mfc_wait_wakeup_v8(dev);
	else
		ret = s5p_mfc_wait_wakeup_v6(dev);

	s5p_mfc_clock_off(dev);
	if (ret)
		return ret;

	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;
	}
	dev->risc_on = 1;
	mfc_debug_leave();
	return 0;
}
Ejemplo n.º 29
0
/* Close instance */
int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx)
{
	struct s5p_mfc_cmd_args h2r_args;
	int ret = 0;

	mfc_debug_enter();

	if (ctx->state != MFCINST_FREE) {
		s5p_mfc_write_reg(ctx->inst_no, S5P_FIMV_INSTANCE_ID);

		ret = s5p_mfc_cmd_host2risc(S5P_FIMV_H2R_CMD_CLOSE_INSTANCE,
					    &h2r_args);
	} else {
		ret = -EINVAL;
	}

	mfc_debug_leave();

	return ret;
}
Ejemplo n.º 30
0
/* Close instance */
int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx)
{
	struct s5p_mfc_cmd_args h2r_args;
	int ret = 0;

	mfc_debug_enter();

	if (ctx->state != MFCINST_FREE) {
		memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
		h2r_args.arg[0] = ctx->inst_no;

		ret = s5p_mfc_cmd_host2risc(S5P_FIMV_H2R_CMD_CLOSE_INSTANCE,
					    &h2r_args);
	} else {
		ret = -EINVAL;
	}

	mfc_debug_leave();

	return ret;
}