Esempio n. 1
0
unsigned int mfc_mem_hole_size(void)
{
	if (mfc_mem_data_size(1))
		return mfc_mem_data_base(1) -
			(mfc_mem_data_base(0) + mfc_mem_data_size(0));
	else
		return 0;
}
Esempio n. 2
0
unsigned long mfc_mem_data_ofs(unsigned long addr, int contig)
{
	unsigned int offset;
	int i;
	int port;

	port = mfc_mem_addr_port(addr);
	if (port < 0)
		return 0;

	offset = addr - mfc_mem_data_base(port);

	if (contig) {
		for (i = 0; i < port; i++)
			offset += mfc_mem_data_size(i);
	}

	return offset;
}
Esempio n. 3
0
unsigned int mfc_mem_data_ofs(unsigned int addr, int contig)
{
	unsigned int offset;
	int i;
	int port;

#ifdef CONFIG_EXYNOS4_CONTENT_PATH_PROTECTION
	port = 0;
#else
	port = mfc_mem_addr_port(addr);
#endif
	if (port < 0)
		return 0;

	offset = addr - mfc_mem_data_base(port);

	if (contig) {
		for (i = 0; i < port; i++)
			offset += mfc_mem_data_size(i);
	}

	return offset;
}
Esempio n. 4
0
static int mfc_mmap(struct file *file, struct vm_area_struct *vma)
{
	unsigned long user_size = vma->vm_end - vma->vm_start;
	unsigned long real_size;
	struct mfc_inst_ctx *mfc_ctx;
#if !(defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(CONFIG_S5P_VMEM))
	/* mmap support */
	unsigned long pfn;
	unsigned long remap_offset, remap_size;
	struct mfc_dev *dev;
#ifdef SYSMMU_MFC_ON
	/* kernel virtual memory allocator */
	char *ptr;
	unsigned long start, size;
#endif
#endif
	mfc_ctx = (struct mfc_inst_ctx *)file->private_data;
	if (!mfc_ctx)
		return -EINVAL;

#if !(defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(CONFIG_S5P_VMEM))
	dev = mfc_ctx->dev;
#endif

	mfc_dbg("vm_start: 0x%08lx, vm_end: 0x%08lx, size: %ld(%ldMB)\n",
		vma->vm_start, vma->vm_end, user_size, (user_size >> 20));

	real_size = (unsigned long)(mfc_mem_data_size(0) + mfc_mem_data_size(1));

	mfc_dbg("port 0 size: %d, port 1 size: %d, total: %ld\n",
		mfc_mem_data_size(0),
		mfc_mem_data_size(1),
		real_size);

	/*
	 * if memory size required from appl. mmap() is bigger than max data memory
	 * size allocated in the driver.
	 */
	if (user_size > real_size) {
		mfc_err("user requeste mem(%ld) is bigger than available mem(%ld)\n",
			user_size, real_size);
		return -EINVAL;
	}
#ifdef SYSMMU_MFC_ON
#if (defined(CONFIG_VIDEO_MFC_VCM_UMP) || defined(CONFIG_S5P_VMEM))
	vma->vm_flags |= VM_RESERVED | VM_IO;
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
	vma->vm_ops = &mfc_vm_ops;
	vma->vm_private_data = mfc_ctx;

	mfc_ctx->userbase = vma->vm_start;
#else	/* not CONFIG_VIDEO_MFC_VCM_UMP && not CONFIG_S5P_VMEM */
	/* kernel virtual memory allocator */
	if (dev->mem_ports == 1) {
		remap_offset = 0;
		remap_size = user_size;

		vma->vm_flags |= VM_RESERVED | VM_IO;
		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

		/*
		 * Port 0 mapping for stream buf & frame buf (chroma + MV + luma)
		 */
		ptr = (char *)mfc_mem_data_base(0);
		start = remap_offset;
		size = remap_size;
		while (size > 0) {
			pfn = vmalloc_to_pfn(ptr);
			if (remap_pfn_range(vma, vma->vm_start + start, pfn,
				PAGE_SIZE, vma->vm_page_prot)) {

				mfc_err("failed to remap port 0\n");
				return -EAGAIN;
			}

			start += PAGE_SIZE;
			ptr += PAGE_SIZE;
			size -= PAGE_SIZE;
		}
	} else {
		remap_offset = 0;
		remap_size = min((unsigned long)mfc_mem_data_size(0), user_size);

		vma->vm_flags |= VM_RESERVED | VM_IO;
		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

		/*
		 * Port 0 mapping for stream buf & frame buf (chroma + MV)
		 */
		ptr = (char *)mfc_mem_data_base(0);
		start = remap_offset;
		size = remap_size;
		while (size > 0) {
			pfn = vmalloc_to_pfn(ptr);
			if (remap_pfn_range(vma, vma->vm_start + start, pfn,
				PAGE_SIZE, vma->vm_page_prot)) {

				mfc_err("failed to remap port 0\n");
				return -EAGAIN;
			}

			start += PAGE_SIZE;
			ptr += PAGE_SIZE;
			size -= PAGE_SIZE;
		}

		remap_offset = remap_size;
		remap_size = min((unsigned long)mfc_mem_data_size(1),
			user_size - remap_offset);

		vma->vm_flags |= VM_RESERVED | VM_IO;
		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

		/*
		 * Port 1 mapping for frame buf (luma)
		 */
		ptr = (void *)mfc_mem_data_base(1);
		start = remap_offset;
		size = remap_size;
		while (size > 0) {
			pfn = vmalloc_to_pfn(ptr);
			if (remap_pfn_range(vma, vma->vm_start + start, pfn,
				PAGE_SIZE, vma->vm_page_prot)) {

				mfc_err("failed to remap port 1\n");
				return -EAGAIN;
			}

			start += PAGE_SIZE;
			ptr += PAGE_SIZE;
			size -= PAGE_SIZE;
		}
	}

	mfc_ctx->userbase = vma->vm_start;

	mfc_dbg("user request mem = %ld, available data mem = %ld\n",
		  user_size, real_size);

	if ((remap_offset + remap_size) < real_size)
		mfc_warn("The MFC reserved memory dose not mmap fully [%ld: %ld]\n",
		  real_size, (remap_offset + remap_size));
#endif	/* end of CONFIG_VIDEO_MFC_VCM_UMP */
#else	/* not SYSMMU_MFC_ON */
	/* early allocator */
	/* CMA or bootmem(memblock) */
	if (dev->mem_ports == 1) {
		remap_offset = 0;
		remap_size = user_size;

		vma->vm_flags |= VM_RESERVED | VM_IO;

		if(mfc_ctx->buf_cache_type == NO_CACHE){
			vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
			mfc_info("CONFIG_VIDEO_MFC_CACHE is not enabled\n");
		}else
			mfc_info("CONFIG_VIDEO_MFC_CACHE is enabled\n");


		/*
		 * Port 0 mapping for stream buf & frame buf (chroma + MV + luma)
		 */
		pfn = __phys_to_pfn(mfc_mem_data_base(0));
		if (remap_pfn_range(vma, vma->vm_start + remap_offset, pfn,
			remap_size, vma->vm_page_prot)) {

			mfc_err("failed to remap port 0\n");
			return -EINVAL;
		}
	} else {
		remap_offset = 0;
		remap_size = min((unsigned long)mfc_mem_data_size(0), user_size);

		vma->vm_flags |= VM_RESERVED | VM_IO;

		if(mfc_ctx->buf_cache_type == NO_CACHE){
			vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
			mfc_info("CONFIG_VIDEO_MFC_CACHE is not enabled\n");
		}else
			mfc_info("CONFIG_VIDEO_MFC_CACHE is enabled\n");



		/*
		 * Port 0 mapping for stream buf & frame buf (chroma + MV)
		 */
		pfn = __phys_to_pfn(mfc_mem_data_base(0));
		if (remap_pfn_range(vma, vma->vm_start + remap_offset, pfn,
			remap_size, vma->vm_page_prot)) {

			mfc_err("failed to remap port 0\n");
			return -EINVAL;
		}

		remap_offset = remap_size;
		remap_size = min((unsigned long)mfc_mem_data_size(1),
			user_size - remap_offset);

		vma->vm_flags |= VM_RESERVED | VM_IO;

		if(mfc_ctx->buf_cache_type == NO_CACHE)
			vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);


		/*
		 * Port 1 mapping for frame buf (luma)
		 */
		pfn = __phys_to_pfn(mfc_mem_data_base(1));
		if (remap_pfn_range(vma, vma->vm_start + remap_offset, pfn,
			remap_size, vma->vm_page_prot)) {

			mfc_err("failed to remap port 1\n");
			return -EINVAL;
		}
	}

	mfc_ctx->userbase = vma->vm_start;

	mfc_dbg("user request mem = %ld, available data mem = %ld\n",
		  user_size, real_size);

	if ((remap_offset + remap_size) < real_size)
		mfc_warn("The MFC reserved memory dose not mmap fully [%ld: %ld]\n",
		  real_size, (remap_offset + remap_size));
#endif	/* end of SYSMMU_MFC_ON */
	return 0;
}
Esempio n. 5
0
/* FIXME: add request firmware ioctl */
static long mfc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{

	struct mfc_inst_ctx *mfc_ctx;
	int ret, ex_ret;
	struct mfc_common_args in_param;
	struct mfc_buf_alloc_arg buf_arg;
	int port;

	struct mfc_dev *dev;
	int i;

	struct mfc_set_config_arg *set_cnf_arg;

	mfc_ctx = (struct mfc_inst_ctx *)file->private_data;
	if (!mfc_ctx)
		return -EINVAL;

	dev = mfc_ctx->dev;

	mutex_lock(&dev->lock);

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

	mutex_unlock(&dev->lock);

	/* FIXME: add locking */

	mfc_dbg("cmd: 0x%08x\n", cmd);

	switch (cmd) {

	case IOCTL_MFC_DEC_INIT:
		mutex_lock(&dev->lock);

		if (mfc_chk_inst_state(mfc_ctx, INST_STATE_CREATE) < 0) {
			mfc_err("IOCTL_MFC_DEC_INIT invalid state: 0x%08x\n",
				 mfc_ctx->state);
			in_param.ret_code = MFC_STATE_INVALID;
			ret = -EINVAL;

			break;
		}

		mfc_clock_on();
		in_param.ret_code = mfc_init_decoding(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mfc_clock_off();

		mutex_unlock(&dev->lock);
		break;

	case IOCTL_MFC_ENC_INIT:
		mutex_lock(&dev->lock);

		if (mfc_chk_inst_state(mfc_ctx, INST_STATE_CREATE) < 0) {
			mfc_err("IOCTL_MFC_ENC_INIT invalid state: 0x%08x\n",
				 mfc_ctx->state);
			in_param.ret_code = MFC_STATE_INVALID;
			ret = -EINVAL;

			break;
		}

		mfc_clock_on();
		in_param.ret_code = mfc_init_encoding(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mfc_clock_off();

		mutex_unlock(&dev->lock);
		break;

	case IOCTL_MFC_DEC_EXE:
		mutex_lock(&dev->lock);

		mfc_clock_on();
		in_param.ret_code = mfc_exec_decoding(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mfc_clock_off();

		mutex_unlock(&dev->lock);
		break;

	case IOCTL_MFC_ENC_EXE:
		mutex_lock(&dev->lock);

		mfc_clock_on();
		in_param.ret_code = mfc_exec_encoding(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mfc_clock_off();

		mutex_unlock(&dev->lock);
		break;

	case IOCTL_MFC_GET_IN_BUF:
		if (in_param.args.mem_alloc.type == ENCODER) {
			buf_arg.type = ENCODER;
			port = 1;
		} else {
			buf_arg.type = DECODER;
			port = 0;
		}

		/* FIXME: consider the size */
		buf_arg.size = in_param.args.mem_alloc.buff_size;
		/*
		buf_arg.mapped = in_param.args.mem_alloc.mapped_addr;
		*/
		/* FIXME: encodeing linear: 2KB, tile: 8KB */
		buf_arg.align = ALIGN_2KB;

		if (buf_arg.type == ENCODER)
			in_param.ret_code = mfc_alloc_buf(mfc_ctx, &buf_arg, MBT_DPB | port);
		else
			in_param.ret_code = mfc_alloc_buf(mfc_ctx, &buf_arg, MBT_CPB | port);
#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
		in_param.args.mem_alloc.secure_id = buf_arg.secure_id;
#elif defined(CONFIG_S5P_VMEM)
		in_param.args.mem_alloc.cookie = buf_arg.cookie;
#else
		in_param.args.mem_alloc.offset = buf_arg.offset;
#endif
		ret = in_param.ret_code;

		break;

	case IOCTL_MFC_FREE_BUF:
		in_param.ret_code =
			mfc_free_buf(mfc_ctx, in_param.args.mem_free.key);
		ret = in_param.ret_code;

		break;

	case IOCTL_MFC_GET_REAL_ADDR:
		in_param.args.real_addr.addr =
			mfc_get_buf_real(mfc_ctx->id, in_param.args.real_addr.key);

		mfc_dbg("real addr: 0x%08x", in_param.args.real_addr.addr);

		if (in_param.args.real_addr.addr)
			in_param.ret_code = MFC_OK;
		else
			in_param.ret_code = MFC_MEM_INVALID_ADDR_FAIL;

		ret = in_param.ret_code;

		break;

	case IOCTL_MFC_GET_MMAP_SIZE:
		if (mfc_chk_inst_state(mfc_ctx, INST_STATE_CREATE) < 0) {
			mfc_err("IOCTL_MFC_GET_MMAP_SIZE invalid state: \
				0x%08x\n", mfc_ctx->state);
			in_param.ret_code = MFC_STATE_INVALID;
			ret = -EINVAL;

			break;
		}

		in_param.ret_code = MFC_OK;
		ret = 0;
		for (i = 0; i < dev->mem_ports; i++)
			ret += mfc_mem_data_size(i);

		break;

#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
	case IOCTL_MFC_SET_IN_BUF:
		if (in_param.args.mem_alloc.type == ENCODER) {
			buf_arg.secure_id = in_param.args.mem_alloc.secure_id;
			buf_arg.align = ALIGN_2KB;
			port = 1;
			ret = mfc_vcm_bind_from_others(mfc_ctx, &buf_arg, MBT_OTHER | port);
		}
		else {
		in_param.args.real_addr.addr =
			mfc_ump_get_virt(in_param.args.real_addr.key);

		mfc_dbg("real addr: 0x%08x", in_param.args.real_addr.addr);

		if (in_param.args.real_addr.addr)
			in_param.ret_code = MFC_OK;
		else
			in_param.ret_code = MFC_MEM_INVALID_ADDR_FAIL;

		ret = in_param.ret_code;
		}

		break;
#endif

	case IOCTL_MFC_SET_CONFIG:
		/* FIXME: mfc_chk_inst_state*/
		/* RMVME: need locking ? */
		mutex_lock(&dev->lock);

		/* in_param.ret_code = mfc_set_config(mfc_ctx, &(in_param.args)); */

		set_cnf_arg = (struct mfc_set_config_arg *)&in_param.args;

		in_param.ret_code = mfc_set_inst_cfg(mfc_ctx, set_cnf_arg->in_config_param, set_cnf_arg->in_config_value);
		ret = in_param.ret_code;

		mutex_unlock(&dev->lock);
		break;

	case IOCTL_MFC_GET_CONFIG:
		/* FIXME: */
		/* FIXME: mfc_chk_inst_state */
		/* RMVME: need locking ? */

		in_param.ret_code = MFC_OK;
		ret = MFC_OK;
		break;

	case IOCTL_MFC_SET_BUF_CACHE:
		mfc_ctx->buf_cache_type = in_param.args.mem_alloc.buf_cache_type;
		in_param.ret_code = MFC_OK;
		break;

	default:
		mfc_err("failed to execute ioctl cmd: 0x%08x\n", cmd);

		in_param.ret_code = MFC_INVALID_PARAM_FAIL;
		ret = -EINVAL;
	}
Esempio n. 6
0
unsigned int mfc_mem_hole_size(void)
{
	return mfc_mem_data_base(1) -
		(mfc_mem_data_base(0) + mfc_mem_data_size(0));
}