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; }
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; }
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; }