int alloc_ion_mem(unsigned int size) { if (!overlay_supported) return -EINVAL; int result; struct ion_fd_data fd_data; struct ion_allocation_data ionAllocData; mem_info.ion_fd = open("/dev/ion", O_RDWR|O_DSYNC); if (mem_info.ion_fd < 0) { perror("ERROR: Can't open ion "); return -errno; } ionAllocData.flags = 0; ionAllocData.len = size; ionAllocData.align = sysconf(_SC_PAGESIZE); #ifdef NEW_ION_HEAP ionAllocData.heap_id_mask = #else ionAllocData.heap_mask = #endif ION_HEAP(ION_IOMMU_HEAP_ID) | ION_HEAP(ION_SYSTEM_CONTIG_HEAP_ID); result = ioctl(mem_info.ion_fd, ION_IOC_ALLOC, &ionAllocData); if(result){ perror("ION_IOC_ALLOC Failed "); close(mem_info.ion_fd); return result; } fd_data.handle = ionAllocData.handle; mem_info.handle_data.handle = ionAllocData.handle; result = ioctl(mem_info.ion_fd, ION_IOC_MAP, &fd_data); if (result) { perror("ION_IOC_MAP Failed "); free_ion_mem(); return result; } mem_info.mem_buf = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_data.fd, 0); mem_info.mem_fd = fd_data.fd; if (!mem_info.mem_buf) { perror("ERROR: mem_buf MAP_FAILED "); free_ion_mem(); return -ENOMEM; } return 0; }
static int alloc_ion_mem(struct fb_qcom_overlay_data *data, unsigned int size) { int result; struct ion_fd_data fd_data; struct ion_allocation_data ionAllocData; data->ion_fd = open("/dev/ion", O_RDWR|O_DSYNC); if (data->ion_fd < 0) { ERROR("ERROR: Can't open ion "); return -errno; } ionAllocData.flags = 0; ionAllocData.len = size; ionAllocData.align = sysconf(_SC_PAGESIZE); ionAllocData.heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID) | ION_HEAP(21); // ION_SYSTEM_CONTIG_HEAP_ID result = ioctl(data->ion_fd, ION_IOC_ALLOC, &ionAllocData); if(result) { ERROR("ION_IOC_ALLOC Failed "); close(data->ion_fd); return result; } fd_data.handle = ionAllocData.handle; data->handle_data.handle = ionAllocData.handle; result = ioctl(data->ion_fd, ION_IOC_MAP, &fd_data); if (result) { ERROR("ION_IOC_MAP Failed "); free_ion_mem(data); return result; } data->mem_buf = (uint8_t*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_data.fd, 0); data->mem_fd = fd_data.fd; if (!data->mem_buf) { ERROR("ERROR: mem_buf MAP_FAILED "); free_ion_mem(data); return -ENOMEM; } return 0; }
static void impl_close(struct framebuffer *fb) { struct fb_qcom_overlay_data *data = fb->impl_data; free_overlay(data, fb->fd); free_ion_mem(data); free(data); fb->impl_data = NULL; }
int gr_init(void) { gglInit(&gr_context); GGLContext *gl = gr_context; gr_init_font(); gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC); if (gr_vt_fd < 0) { // This is non-fatal; post-Cupcake kernels don't have tty0. perror("can't open /dev/tty0"); } else if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) { // However, if we do open tty0, we expect the ioctl to work. perror("failed KDSETMODE to KD_GRAPHICS on tty0"); gr_exit(); return -1; } gr_fb_fd = get_framebuffer(gr_framebuffer); if (gr_fb_fd < 0) { gr_exit(); return -1; } get_memory_surface(&gr_mem_surface); fprintf(stderr, "framebuffer: fd %d (%d x %d)\n", gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height); /* start with 0 as front (displayed) and 1 as back (drawing) */ gr_active_fb = 0; if (!has_overlay) set_active_framebuffer(0); gl->colorBuffer(gl, &gr_mem_surface); gl->activeTexture(gl, 0); gl->enable(gl, GGL_BLEND); gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA); gr_fb_blank(true); gr_fb_blank(false); if (has_overlay) { if (alloc_ion_mem(fi.line_length * vi.yres) || allocate_overlay(gr_fb_fd, gr_framebuffer)) { free_ion_mem(); } } return 0; }
void gr_exit(void) { free_overlay(gr_fb_fd); free_ion_mem(); close(gr_fb_fd); gr_fb_fd = -1; free(gr_mem_surface.data); ioctl(gr_vt_fd, KDSETMODE, (void*) KD_TEXT); close(gr_vt_fd); gr_vt_fd = -1; }
void msm_smem_free(void *clt, struct msm_smem *mem) { struct smem_client *client = clt; if (!client || !mem) { pr_err("Invalid client/handle passed\n"); return; } switch (client->mem_type) { case SMEM_ION: free_ion_mem(client, mem); break; default: pr_err("Mem type not supported\n"); break; } kfree(mem); };
static int impl_open(struct framebuffer *fb) { struct fb_qcom_overlay_data *data = mzalloc(sizeof(struct fb_qcom_overlay_data)); data->overlay_id = MSMFB_NEW_REQUEST; if (alloc_ion_mem(data, fb->fi.line_length * fb->vi.yres) < 0) goto fail; if(allocate_overlay(data, fb->fd, fb->vi.xres, fb->vi.yres) < 0) { free_ion_mem(data); goto fail; } fb->impl_data = data; return 0; fail: free(data); return -1; }