int mdss_mdp_get_img(struct ion_client *iclient, struct msmfb_data *img, struct mdss_mdp_img_data *data) { struct file *file; int ret = -EINVAL; int fb_num; unsigned long *start, *len; start = (unsigned long *) &data->addr; len = (unsigned long *) &data->len; data->flags = img->flags; data->p_need = 0; if (img->flags & MDP_BLIT_SRC_GEM) { data->srcp_file = NULL; ret = kgsl_gem_obj_addr(img->memory_id, (int) img->priv, start, len); } else if (img->flags & MDP_MEMORY_ID_TYPE_FB) { file = fget_light(img->memory_id, &data->p_need); if (file && FB_MAJOR == MAJOR(file->f_dentry->d_inode->i_rdev)) { data->srcp_file = file; fb_num = MINOR(file->f_dentry->d_inode->i_rdev); ret = mdss_fb_get_phys_info(start, len, fb_num); } } else if (iclient) { data->iclient = iclient; data->srcp_ihdl = ion_import_dma_buf(iclient, img->memory_id); if (IS_ERR_OR_NULL(data->srcp_ihdl)) return PTR_ERR(data->srcp_ihdl); ret = ion_phys(iclient, data->srcp_ihdl, start, (size_t *) len); } else { unsigned long vstart; ret = get_pmem_file(img->memory_id, start, &vstart, len, &data->srcp_file); } if (!ret && (img->offset < data->len)) { data->addr += img->offset; data->len -= img->offset; } else { mdss_mdp_put_img(data); ret = -EINVAL; } return ret; }
int mdss_mdp_get_img(struct msmfb_data *img, struct mdss_mdp_img_data *data) { struct file *file; int ret = -EINVAL; int fb_num; unsigned long *start, *len; struct ion_client *iclient = mdss_get_ionclient(); start = (unsigned long *) &data->addr; len = (unsigned long *) &data->len; data->flags |= img->flags; data->p_need = 0; if (img->flags & MDP_BLIT_SRC_GEM) { data->srcp_file = NULL; ret = kgsl_gem_obj_addr(img->memory_id, (int) img->priv, start, len); } else if (img->flags & MDP_MEMORY_ID_TYPE_FB) { file = fget_light(img->memory_id, &data->p_need); if (file == NULL) { pr_err("invalid framebuffer file (%d)\n", img->memory_id); return -EINVAL; } data->srcp_file = file; if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) { fb_num = MINOR(file->f_dentry->d_inode->i_rdev); ret = mdss_fb_get_phys_info(start, len, fb_num); if (ret) pr_err("mdss_fb_get_phys_info() failed\n"); } else { pr_err("invalid FB_MAJOR\n"); ret = -1; } } else if (iclient) { data->srcp_ihdl = ion_import_dma_buf(iclient, img->memory_id); if (IS_ERR_OR_NULL(data->srcp_ihdl)) { pr_err("error on ion_import_fd\n"); ret = PTR_ERR(data->srcp_ihdl); data->srcp_ihdl = NULL; return ret; } if (is_mdss_iommu_attached()) { int domain; if (data->flags & MDP_SECURE_OVERLAY_SESSION) { domain = MDSS_IOMMU_DOMAIN_SECURE; mdss_mdp_secure_vote(1); ret = msm_ion_secure_buffer(iclient, data->srcp_ihdl, 0x2, 0); if (IS_ERR_VALUE(ret)) { ion_free(iclient, data->srcp_ihdl); pr_err("failed to secure handle (%d)\n", ret); return ret; } } else { domain = MDSS_IOMMU_DOMAIN_UNSECURE; } ret = ion_map_iommu(iclient, data->srcp_ihdl, mdss_get_iommu_domain(domain), 0, SZ_4K, 0, start, len, 0, 0); } else { ret = ion_phys(iclient, data->srcp_ihdl, start, (size_t *) len); } if (IS_ERR_VALUE(ret)) { ion_free(iclient, data->srcp_ihdl); pr_err("failed to map ion handle (%d)\n", ret); return ret; } } if (!*start) { pr_err("start address is zero!\n"); return -ENOMEM; } if (!ret && (img->offset < data->len)) { data->addr += img->offset; data->len -= img->offset; pr_debug("mem=%d ihdl=%p buf=0x%x len=0x%x\n", img->memory_id, data->srcp_ihdl, data->addr, data->len); } else { return -EINVAL; } return ret; }