/* 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;
}
/* 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_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;
}
예제 #4
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;
}
/* 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;
}
예제 #6
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;
}
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;
}
/* 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;
}
예제 #10
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;
}
예제 #11
0
/* 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;
	int ret;

	mfc_debug_enter();

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

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

	ret = s5p_mfc_cmd_host2risc(S5P_FIMV_H2R_CMD_OPEN_INSTANCE, &h2r_args);

	mfc_debug_leave();

	return ret;
}
예제 #12
0
/* 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;
	struct s5p_mfc_dec *dec = ctx->dec_priv;
	int ret;

	mfc_debug_enter();

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

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

	ret = s5p_mfc_cmd_host2risc(S5P_FIMV_H2R_CMD_OPEN_INSTANCE, &h2r_args);

	mfc_debug_leave();

	return ret;
}
예제 #13
0
int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev,
					enum mfc_buf_usage_type buf_type)
{
	struct s5p_mfc_buf_size_v6 *buf_size;
	struct s5p_mfc_extra_buf *ctx_buf, *dis_shm_buf;
	int ret;

	mfc_debug_enter();

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

	buf_size = dev->variant->buf_size->buf;
	ctx_buf = &dev->ctx_buf;
	dis_shm_buf = &dev->dis_shm_buf;
#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
	if (buf_type == MFCBUF_DRM) {
		ctx_buf = &dev->ctx_buf_drm;
		dis_shm_buf = &dev->dis_shm_buf_drm;
	}
#endif
	s5p_mfc_write_reg(dev, ctx_buf->ofs, S5P_FIMV_CONTEXT_MEM_ADDR);
	s5p_mfc_write_reg(dev, buf_size->dev_ctx, S5P_FIMV_CONTEXT_MEM_SIZE);
	if (IS_MFCv7X(dev)) {
		s5p_mfc_write_reg(dev, dis_shm_buf->ofs,
					S5P_FIMV_DIS_SHARED_MEM_ADDR);
		mfc_debug(2, "Setting shared memory = 0x%x\n",
					(unsigned int)dis_shm_buf->ofs);
	}

	ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SYS_INIT, NULL);

	mfc_debug_leave();

	return ret;
}
예제 #14
0
/* Initialize hardware */
int mfc_init_hw(struct s5p_mfc_dev *dev, enum mfc_buf_usage_type buf_type)
{
	char fimv_info;
	int fw_ver;
	int ret = 0;
	int curr_ctx_backup;

	mfc_debug_enter();

	if (!dev) {
		mfc_err("no mfc device to run\n");
		return -EINVAL;
	}
	curr_ctx_backup = dev->curr_ctx_drm;
	dev->sys_init_status = 0;
	/* RMVME: */
	if (!dev->fw_info.alloc)
		return -EINVAL;

	/* 0. MFC reset */
	mfc_debug(2, "MFC reset...\n");

	/* At init time, do not call secure API */
	if (buf_type == MFCBUF_NORMAL)
		dev->curr_ctx_drm = 0;
	else if (buf_type == MFCBUF_DRM)
		dev->curr_ctx_drm = 1;

	ret = s5p_mfc_clock_on(dev);
	if (ret) {
		mfc_err_dev("Failed to enable clock before reset(%d)\n", ret);
		dev->curr_ctx_drm = curr_ctx_backup;
		return ret;
	}

	dev->sys_init_status = 1;
	ret = s5p_mfc_reset(dev);
	if (ret) {
		mfc_err_dev("Failed to reset MFC - timeout.\n");
		goto err_init_hw;
	}
	mfc_debug(2, "Done MFC reset...\n");

	/* 1. Set DRAM base Addr */
	s5p_mfc_init_memctrl(dev, buf_type);

	/* 2. Initialize registers of channel I/F */
	s5p_mfc_clear_cmds(dev);
	s5p_mfc_clean_dev_int_flags(dev);

	/* 3. Release reset signal to the RISC */
	if (IS_MFCV6(dev))
		s5p_mfc_write_reg(dev, 0x1, S5P_FIMV_RISC_ON);
	else
		s5p_mfc_write_reg(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_FIMV_R2H_CMD_FW_STATUS_RET)) {
		mfc_err_dev("Failed to load firmware.\n");
		s5p_mfc_clean_dev_int_flags(dev);
		ret = -EIO;
		goto err_init_hw;
	}

	s5p_mfc_clean_dev_int_flags(dev);
	/* 4. Initialize firmware */
	ret = s5p_mfc_sys_init_cmd(dev, buf_type);
	if (ret) {
		mfc_err_dev("Failed to send command to MFC - timeout.\n");
		goto err_init_hw;
	}
	mfc_debug(2, "Ok, now will write a command to init the system\n");
	if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SYS_INIT_RET)) {
		mfc_err_dev("Failed to load firmware\n");
		ret = -EIO;
		goto err_init_hw;
	}

	dev->int_cond = 0;
	if (dev->int_err != 0 || dev->int_type !=
						S5P_FIMV_R2H_CMD_SYS_INIT_RET) {
		/* Failure. */
		mfc_err_dev("Failed to init firmware - error: %d"
				" int: %d.\n", dev->int_err, dev->int_type);
		ret = -EIO;
		goto err_init_hw;
	}

	fimv_info = MFC_GET_REG(SYS_FW_FIMV_INFO);
	if (fimv_info != 'D' && fimv_info != 'E')
		fimv_info = 'N';

	mfc_info_dev("MFC v%x.%x, F/W: %02xyy, %02xmm, %02xdd (%c)\n",
		 MFC_VER_MAJOR(dev),
		 MFC_VER_MINOR(dev),
		 MFC_GET_REG(SYS_FW_VER_YEAR),
		 MFC_GET_REG(SYS_FW_VER_MONTH),
		 MFC_GET_REG(SYS_FW_VER_DATE),
		 fimv_info);

	dev->fw.date = MFC_GET_REG(SYS_FW_VER_ALL);
	/* Check MFC version and F/W version */
	if (IS_MFCV6(dev) && FW_HAS_VER_INFO(dev)) {
		fw_ver = MFC_GET_REG(SYS_MFC_VER);
		if (fw_ver != mfc_version(dev)) {
			mfc_err_dev("Invalid F/W version(0x%x) for MFC H/W(0x%x)\n",
					fw_ver, mfc_version(dev));
			ret = -EIO;
			goto err_init_hw;
		}
	}

#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
	/* Cache flush for base address change */
	if (FW_HAS_BASE_CHANGE(dev)) {
		s5p_mfc_clean_dev_int_flags(dev);
		s5p_mfc_cmd_host2risc(dev, S5P_FIMV_CH_CACHE_FLUSH, NULL);
		if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_CACHE_FLUSH_RET)) {
			mfc_err_dev("Failed to flush cache\n");
			ret = -EIO;
			goto err_init_hw;
		}

		if (buf_type == MFCBUF_DRM && !curr_ctx_backup) {
			s5p_mfc_clock_off(dev);
			dev->curr_ctx_drm = curr_ctx_backup;
			s5p_mfc_clock_on_with_base(dev, MFCBUF_NORMAL);
		} else if (buf_type == MFCBUF_NORMAL && curr_ctx_backup) {
			s5p_mfc_init_memctrl(dev, MFCBUF_DRM);
		}
	}
#endif

err_init_hw:
	s5p_mfc_clock_off(dev);
	dev->curr_ctx_drm = curr_ctx_backup;
	mfc_debug_leave();

	return ret;
}