Пример #1
0
int s5p_tvout_vcm_create_unified(void)
{
	s5p_vcm = vcm_create_unified((SZ_64M), VCM_DEV_TV,
						&s5ptv_vcm_driver);

	if (IS_ERR(s5p_vcm))
		return PTR_ERR(s5p_vcm);

	return 0;
}
Пример #2
0
int s3cfb_map_default_video_memory(struct s3cfb_global *fbdev,
					struct fb_info *fb, int fimd_id)
{
	struct fb_fix_screeninfo *fix = &fb->fix;
	struct s3cfb_window *win = fb->par;

#ifdef CONFIG_VCM
	struct cma_info mem_info;
	unsigned int reserved_size;
	int err;
	struct vcm_phys *phys = NULL;
	ump_dd_physical_block ump_memory_description;
	unsigned int device_virt_start = 0;
	int frame_size = fix->smem_len / CONFIG_FB_S3C_NR_BUFFERS;
	struct  vcm_res *fb_dev_vcm_res[CONFIG_FB_S3C_NR_BUFFERS];

	enum vcm_dev_id id;
#else
#ifdef CONFIG_S5P_MEM_CMA
	struct cma_info mem_info;
	unsigned int reserved_size;
	int err;
#endif
#endif

#ifdef MALI_USE_UNIFIED_MEMORY_PROVIDER
#ifdef CONFIG_VCM
	int i;
	unsigned int arg = 0;
#ifdef CONFIG_UMP_VCM_ALLOC
	struct ump_vcm ump_vcm;
#endif
	unsigned int arg = 0;
#endif
#endif

	if (win->owner == DMA_MEM_OTHER)
		return 0;

#ifdef CONFIG_VCM
	phys = kmalloc(sizeof(*phys) + sizeof(*phys->parts), GFP_KERNEL);
	memset(phys, 0, sizeof(*phys) + sizeof(*phys->parts));

	if (fimd_id == 0)
		id = VCM_DEV_FIMD0;
	else
		id = VCM_DEV_FIMD1;

	err = cma_info(&mem_info, fbdev->dev, 0);
	if (ERR_PTR(err))
		return -ENOMEM;
	reserved_size = fix->smem_len;
	fix->smem_start = (dma_addr_t)cma_alloc
		(fbdev->dev, "fimd", (size_t)reserved_size, 0);
	fb->screen_base = cma_get_virt(fix->smem_start, reserved_size, 1);

	fbdev->s5p_vcm = vcm_create_unified((SZ_64M), id, &s3cfb_vcm_driver);
	if (IS_ERR(fbdev->s5p_vcm))
		return PTR_ERR(fbdev->s5p_vcm);
	if (vcm_activate(fbdev->s5p_vcm))
		dev_info(fbdev->dev, "[fb%d] : VCM activated", win->id);

	phys->count = 1;
	phys->size = fix->smem_len;
	phys->free = NULL;
	phys->parts[0].size = fix->smem_len;
	phys->parts[0].start = fix->smem_start;

	win->s5p_vcm_res = vcm_map(fbdev->s5p_vcm, phys, 0);
	device_virt_start = win->s5p_vcm_res->start;

	for (i = 0; i < CONFIG_FB_S3C_NR_BUFFERS; i++) {
		fb_dev_vcm_res[i] = kzalloc(sizeof(struct vcm_res), GFP_KERNEL);
		win->s3cfb_vcm[i].dev_vcm_res = fb_dev_vcm_res[i];

		win->s3cfb_vcm[i].dev_vcm_res->start = device_virt_start
							+ frame_size * i;
		win->s3cfb_vcm[i].dev_vcm_res->bound_size = frame_size;
		win->s3cfb_vcm[i].dev_vcm_res->res_size = frame_size;
		win->s3cfb_vcm[i].dev_vcm = fbdev->s5p_vcm;
		win->s3cfb_vcm[i].dev_vcm_res->vcm = fbdev->s5p_vcm;
		if (IS_ERR(win->s3cfb_vcm[i].dev_vcm_res))
			return -ENOMEM;
	}
#else
#ifdef CONFIG_S5P_MEM_CMA
	err = cma_info(&mem_info, fbdev->dev, 0);
	if (ERR_PTR(err))
		return -ENOMEM;
	reserved_size = mem_info.total_size;
	fix->smem_start = (dma_addr_t)cma_alloc
		(fbdev->dev, "fimd", (size_t)reserved_size, 0);
	fb->screen_base = cma_get_virt(fix->smem_start, reserved_size, 1);
#elif defined(CONFIG_S5P_MEM_BOOTMEM)
	fix->smem_start = s5p_get_media_memory_bank(S5P_MDEV_FIMD, 1);
	fix->smem_len = s5p_get_media_memsize_bank(S5P_MDEV_FIMD, 1);
	fb->screen_base = ioremap_wc(fix->smem_start, fix->smem_len);
#endif
#endif

	memset(fb->screen_base, 0, fix->smem_len);
	win->owner = DMA_MEM_FIMD;

#if MALI_USE_UNIFIED_MEMORY_PROVIDER
#ifdef CONFIG_VCM
#ifdef CONFIG_UMP_VCM_ALLOC
	for (i = 0; i < CONFIG_FB_S3C_NR_BUFFERS; i++) {
		ump_vcm.vcm = win->s3cfb_vcm[i].dev_vcm;
		ump_vcm.vcm_res = win->s3cfb_vcm[i].dev_vcm_res;
		ump_vcm.dev_id = id;
		arg = (unsigned int)&ump_vcm;
		ump_memory_description.addr = fix->smem_start + ((fix->smem_len / CONFIG_FB_S3C_NR_BUFFERS) * i);
		ump_memory_description.size = fix->smem_len / CONFIG_FB_S3C_NR_BUFFERS;

		win->ump_wrapped_buffer[i] =
			ump_dd_handle_create_from_phys_blocks
			(&ump_memory_description, 1);

		if (ump_dd_vcm_attribute_set(win->ump_wrapped_buffer[i], arg))
			return -ENOMEM;
	}
#else
	if (s3cfb_ump_wrapper(fix, arg, 0, win)) {
		dev_info(fbdev->dev, "[fb%d] : Wrapped UMP memory : %x\n"
				, win->id, (unsigned int)ump_wrapped_buffer);
		s3cfb_unmap_video_memory(fbdev, fb);
		return -ENOMEM;
	}
#endif
#endif
#endif

	return 0;
}
Пример #3
0
int mfc_init_mem_mgr(struct mfc_dev *dev)
{
	int i;
#if !defined(CONFIG_VIDEO_MFC_VCM_UMP)
	dma_addr_t base[MAX_ALLOCATION];
#else
	/* FIXME: for support user-side allocation. it's temporary solution */
	struct vcm_res	*hole;
#endif
#ifndef SYSMMU_MFC_ON
	size_t size;
#endif
#ifdef CONFIG_S5P_MEM_CMA
	struct cma_info cma_infos[2];
#ifdef CONFIG_EXYNOS4_CONTENT_PATH_PROTECTION
	size_t bound_size;
	size_t available_size;
	size_t hole_size;
#else
	int cma_index = 0;
#endif
#else
	unsigned int align_margin;
#endif

	dev->mem_ports = MFC_MAX_MEM_PORT_NUM;
	memset(dev->mem_infos, 0, sizeof(dev->mem_infos));

#ifdef SYSMMU_MFC_ON
#if defined(CONFIG_VIDEO_MFC_VCM_UMP)
	dev->vcm_info.sysmmu_vcm = vcm_create_unified(
		SZ_256M * dev->mem_ports,
			VCM_DEV_MFC,
			&mfc_vcm_driver);

	memcpy(&vcm_info, &dev->vcm_info, sizeof(struct mfc_vcm));

	dev->mem_infos[0].vcm_s = vcm_reserve(dev->vcm_info.sysmmu_vcm,
		MFC_MEMSIZE_PORT_A, 0);

	if (IS_ERR(dev->mem_infos[0].vcm_s))
		return PTR_ERR(dev->mem_infos[0].vcm_s);

	dev->mem_infos[0].base = ALIGN(dev->mem_infos[0].vcm_s->start,
		ALIGN_128KB);
	align_margin = dev->mem_infos[0].base - dev->mem_infos[0].vcm_s->start;
	/* FIXME: for offset operation. it's temporary solution */
	/*
	dev->mem_infos[0].size = MFC_MEMSIZE_PORT_A - align_margin;
	*/
	dev->mem_infos[0].size = SZ_256M - align_margin;
	dev->mem_infos[0].addr = NULL;

	/* FIXME: for support user-side allocation. it's temporary solution */
	if (MFC_MEMSIZE_PORT_A < SZ_256M)
		hole = vcm_reserve(dev->vcm_info.sysmmu_vcm,
			SZ_256M - MFC_MEMSIZE_PORT_A, 0);

	if (dev->mem_ports == 2) {
		dev->mem_infos[1].vcm_s = vcm_reserve(dev->vcm_info.sysmmu_vcm,
			MFC_MEMSIZE_PORT_B, 0);

		if (IS_ERR(dev->mem_infos[1].vcm_s)) {
			vcm_unreserve(dev->mem_infos[0].vcm_s);
			return PTR_ERR(dev->mem_infos[1].vcm_s);
		}

		dev->mem_infos[1].base = ALIGN(dev->mem_infos[1].vcm_s->start,
			ALIGN_128KB);
		align_margin = dev->mem_infos[1].base - dev->mem_infos[1].vcm_s->start;
		dev->mem_infos[1].size = MFC_MEMSIZE_PORT_B - align_margin;
		dev->mem_infos[1].addr = NULL;
	}

	/* FIXME: for support user-side allocation. it's temporary solution */
	vcm_unreserve(hole);

	dev->fw.vcm_s = mfc_vcm_bind(dev->mem_infos[0].base, MFC_FW_SYSTEM_SIZE);
	if (IS_ERR(dev->fw.vcm_s))
		return PTR_ERR(dev->fw.vcm_s);

	dev->fw.vcm_k = mfc_vcm_map(dev->fw.vcm_s->res.phys);
	if (IS_ERR(dev->fw.vcm_k)) {
		mfc_vcm_unbind(dev->fw.vcm_s, 0);
		return PTR_ERR(dev->fw.vcm_k);
	}

	/* FIXME: it's very tricky! MUST BE FIX */
	dev->mem_infos[0].addr = (unsigned char *)dev->fw.vcm_k->start;
#elif defined(CONFIG_S5P_VMEM)
	base[0] = MFC_FREEBASE;

	dev->mem_infos[0].base = ALIGN(base[0], ALIGN_128KB);
	align_margin = dev->mem_infos[0].base - base[0];
	dev->mem_infos[0].size = MFC_MEMSIZE_PORT_A - align_margin;
	dev->mem_infos[0].addr = (unsigned char *)dev->mem_infos[0].base;

	if (dev->mem_ports == 2) {
		base[1] = dev->mem_infos[0].base + dev->mem_infos[0].size;
		dev->mem_infos[1].base = ALIGN(base[1], ALIGN_128KB);
		align_margin = dev->mem_infos[1].base - base[1];
		dev->mem_infos[1].size = MFC_MEMSIZE_PORT_B - align_margin;
		dev->mem_infos[1].addr = (unsigned char *)dev->mem_infos[1].base;
	}

	dev->fw.vmem_cookie = s5p_vmem_vmemmap(MFC_FW_SYSTEM_SIZE,
		dev->mem_infos[0].base,
		dev->mem_infos[0].base + MFC_FW_SYSTEM_SIZE);

	if (!dev->fw.vmem_cookie)
		return -ENOMEM;
#else	/* not CONFIG_VIDEO_MFC_VCM_UMP && not CONFIG_S5P_VMEM */
	/* kernel virtual memory allocator */

	dev->mem_infos[0].vmalloc_addr = vmalloc(MFC_MEMSIZE_PORT_A);
	if (dev->mem_infos[0].vmalloc_addr == NULL)
		return -ENOMEM;

	base[0] = (unsigned long)dev->mem_infos[0].vmalloc_addr;
	dev->mem_infos[0].base = ALIGN(base[0], ALIGN_128KB);
	align_margin = dev->mem_infos[0].base - base[0];
	dev->mem_infos[0].size = MFC_MEMSIZE_PORT_A - align_margin;
	dev->mem_infos[0].addr = (unsigned char *)dev->mem_infos[0].base;

	if (dev->mem_ports == 2) {
		dev->mem_infos[1].vmalloc_addr = vmalloc(MFC_MEMSIZE_PORT_B);
		if (dev->mem_infos[1].vmalloc_addr == NULL) {
			vfree(dev->mem_infos[0].vmalloc_addr);
			return -ENOMEM;
		}

		base[1] = (unsigned long)dev->mem_infos[1].vmalloc_addr;
		dev->mem_infos[1].base = ALIGN(base[1], ALIGN_128KB);
		align_margin = dev->mem_infos[1].base - base[1];
		dev->mem_infos[1].size = MFC_MEMSIZE_PORT_B - align_margin;
		dev->mem_infos[1].addr = (unsigned char *)dev->mem_infos[1].base;
	}
#endif	/* end of CONFIG_VIDEO_MFC_VCM_UMP */
#else	/* not SYSMMU_MFC_ON */
	/* early allocator */
#if defined(CONFIG_S5P_MEM_CMA)
#ifdef  CONFIG_EXYNOS4_CONTENT_PATH_PROTECTION
	if (cma_info(&cma_infos[0], dev->device, "A")) {
		mfc_info("failed to get CMA info of 'mfc-secure'\n");
		return -ENOMEM;
	}

	if (cma_info(&cma_infos[1], dev->device, "B")) {
		mfc_info("failed to get CMA info of 'mfc-normal'\n");
		return -ENOMEM;
	}

	if (cma_infos[0].lower_bound > cma_infos[1].lower_bound) {
		mfc_info("'mfc-secure' region must be lower than 'mfc-normal' region\n");
		return -ENOMEM;
	}

	/*
	 * available = secure + normal
	 * bound = secure + hole + normal
	 * hole = bound - available
	 */
	available_size = cma_infos[0].free_size + cma_infos[1].free_size;
	bound_size = cma_infos[1].upper_bound - cma_infos[0].lower_bound;
	hole_size = bound_size - available_size;
	mfc_dbg("avail: 0x%08x, bound: 0x%08x offset: 0x%08x, hole: 0x%08x\n",
		available_size, bound_size, MAX_MEM_OFFSET, hole_size);

	/* re-assign actually available size */
	if (bound_size > MAX_MEM_OFFSET) {
		if (cma_infos[0].free_size > MAX_MEM_OFFSET)
			/* it will be return error */
			available_size = MAX_MEM_OFFSET;
		else if ((cma_infos[0].free_size + hole_size) >= MAX_MEM_OFFSET)
			/* it will be return error */
			available_size = cma_infos[0].free_size;
		else
			available_size -= (bound_size - MAX_MEM_OFFSET);
	}
	mfc_dbg("avail: 0x%08x\n", available_size);

	size = cma_infos[0].free_size;
	if (size > available_size) {
		mfc_info("'mfc-secure' region is too large (%d:%d)",
			size >> 10,
			MAX_MEM_OFFSET >> 10);
		return -ENOMEM;
	}