Exemplo n.º 1
0
static int register_pmem(void)
{
	int result;
	unsigned long paddr;
	unsigned long kvaddr;
	unsigned long pmem_len;

	mutex_lock(&acdb_data.acdb_mutex);
	result = get_pmem_file(atomic_read(&acdb_data.pmem_fd),
				&paddr, &kvaddr, &pmem_len,
				&acdb_data.file);
	mutex_unlock(&acdb_data.acdb_mutex);
	if (result != 0) {
		atomic_set(&acdb_data.pmem_fd, 0);
		atomic64_set(&acdb_data.pmem_len, 0);
		pr_err("%s: Could not register PMEM!!!\n", __func__);
		goto done;
	}

	atomic64_set(&acdb_data.paddr, paddr);
	atomic64_set(&acdb_data.kvaddr, kvaddr);
	atomic64_set(&acdb_data.pmem_len, pmem_len);
	pr_debug("AUDIO_REGISTER_PMEM done! paddr = 0x%lx, "
		"kvaddr = 0x%lx, len = x%lx\n",
		(long)atomic64_read(&acdb_data.paddr),
		(long)atomic64_read(&acdb_data.kvaddr),
		(long)atomic64_read(&acdb_data.pmem_len));

done:
	return result;
}
Exemplo n.º 2
0
static int register_pmem(void)
{
	int result;
	struct audproc_buffer_data buffer;

	result = get_pmem_file(acdb_data.pmem_fd, &acdb_data.paddr,
				&acdb_data.kvaddr, &acdb_data.pmem_len,
				&acdb_data.file);
	if (result != 0) {
		acdb_data.pmem_fd = 0;
		pr_err("%s: Could not register PMEM!!!\n", __func__);
		goto done;
	}

	pr_debug("AUDIO_REGISTER_PMEM done! paddr = 0x%lx, "
		"kvaddr = 0x%lx, len = x%lx\n", acdb_data.paddr,
		acdb_data.kvaddr, acdb_data.pmem_len);
	get_audproc_buffer_data(&buffer);
	result = adm_memory_map_regions(buffer.phys_addr, 0,
			buffer.buf_size,
			NUM_AUDPROC_BUFFERS);
	if (result < 0)
		pr_err("Audcal mmap did not work!\n");
	goto done;

done:
	return result;
}
Exemplo n.º 3
0
static int get_buf_info(struct buf_info *buf_info, struct venc_buf *venc_buf)
{
	unsigned long len;
	unsigned long vaddr;
	unsigned long paddr;
	struct file *file;
	int ret;

	ret = get_pmem_file(venc_buf->fd, &paddr, &vaddr, &len, &file);
	if (ret) {
		pr_err("%s: get_pmem_file failed for fd=%d offset=%ld\n",
		       __func__, venc_buf->fd, venc_buf->offset);
		return ret;
	} else if (venc_buf->offset >= len) {
		/* XXX: we really should check venc_buf->size too, but userspace
		 * sometimes leaves this uninitialized (in encode ioctl) */
		pr_err("%s: invalid offset/size (%ld + %ld > %ld) for fd=%d\n",
		       __func__, venc_buf->offset, venc_buf->size, len,
		       venc_buf->fd);
		put_pmem_file(file);
		return -EINVAL;
	}

	buf_info->file = file;
	buf_info->paddr = paddr + venc_buf->offset;
	buf_info->vaddr = vaddr;
	memcpy(&buf_info->venc_buf, venc_buf, sizeof(struct venc_buf));
	return 0;
}
Exemplo n.º 4
0
/**
 * videobuf_pmem_contig_user_get() - setup user space memory pointer
 * @mem: per-buffer private videobuf-contig-pmem data
 * @vb: video buffer to map
 *
 * This function validates and sets up a pointer to user space memory.
 * Only physically contiguous pfn-mapped memory is accepted.
 *
 * Returns 0 if successful.
 */
int videobuf2_pmem_contig_user_get(struct videobuf2_contig_pmem *mem,
                                   struct videobuf2_msm_offset *offset,
                                   enum videobuf2_buffer_type buffer_type,
                                   uint32_t addr_offset, int path,
                                   struct ion_client *client)
{
    unsigned long len;
    int rc = 0;
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
    unsigned long kvstart;
#endif
    unsigned int flags = 0;
    unsigned long paddr = 0;
    if (mem->phyaddr != 0)
        return 0;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
    mem->ion_handle = ion_import_fd(client, (int)mem->vaddr);
    if (IS_ERR_OR_NULL(mem->ion_handle)) {
        pr_err("%s ION import failed\n", __func__);
        return PTR_ERR(mem->ion_handle);
    }
    rc = ion_phys(client, mem->ion_handle, (ion_phys_addr_t *)&mem->phyaddr,
                  (size_t *)&len);
#elif CONFIG_ANDROID_PMEM
    rc = get_pmem_file((int)mem->vaddr, (unsigned long *)&mem->phyaddr,
                       &kvstart, &len, &mem->file);
    if (rc < 0) {
        pr_err("%s: get_pmem_file fd %d error %d\n",
               __func__, (int)mem->vaddr, rc);
        return rc;
    }
#else
    paddr = 0;
    kvstart = 0;
#endif
    if (offset)
        mem->offset = *offset;
    else
        memset(&mem->offset, 0, sizeof(struct videobuf2_msm_offset));
    mem->path = path;
    mem->buffer_type = buffer_type;
    paddr = mem->phyaddr;
    flags = MSM_SUBSYSTEM_MAP_IOVA;
    mem->subsys_id = MSM_SUBSYSTEM_CAMERA;
    mem->msm_buffer = msm_subsystem_map_buffer(mem->phyaddr, len,
                      flags, &(mem->subsys_id), 1);
    if (IS_ERR((void *)mem->msm_buffer)) {
        pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
        ion_free(client, mem->ion_handle);
#elif CONFIG_ANDROID_PMEM
        put_pmem_file(mem->file);
#endif
        return PTR_ERR((void *)mem->msm_buffer);
    }
    paddr = mem->msm_buffer->iova[0];
    mem->mapped_phyaddr = paddr + addr_offset;
    mem->addr_offset = addr_offset;
    return rc;
}
Exemplo n.º 5
0
static int get_img(struct mdp_img *img, struct fb_info *info,
		   unsigned long *start, unsigned long *len,
		   struct file** filep)
{
	int put_needed, ret = 0;
	struct file *file;
	unsigned long vstart;

	if (!get_pmem_file(img->memory_id, start, &vstart, len, filep))
		return 0;
	else if (!get_msm_hw3d_file(img->memory_id, &img->offset, start, len,
				    filep))
		return 0;

	file = fget_light(img->memory_id, &put_needed);
	if (file == NULL)
		return -1;

	if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
		*start = info->fix.smem_start;
		*len = info->fix.smem_len;
		ret = 0;
	} else
		ret = -1;
	fput_light(file, put_needed);

	return ret;
}
Exemplo n.º 6
0
uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file_p)
{
	unsigned long paddr;
	unsigned long size;
	int rc;

#ifdef CONFIG_ANDROID_PMEM
	unsigned long kvstart;
	rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
#else
	rc = 0;
	paddr = 0;
	size = 0;
#endif
	if (rc < 0) {
		GMN_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd,
			rc);
		return 0;
	}

	/* validate user input */
	if (len > size) {
		GMN_PR_ERR("%s: invalid offset + len\n", __func__);
		return 0;
	}

	return paddr;
}
static int msm_pmem_table_add(struct hlist_head *ptype,
	struct msm_pmem_info *info)
{
	struct file *file;
	unsigned long paddr;
#ifdef CONFIG_ANDROID_PMEM
	unsigned long kvstart;
	int rc;
#endif
	unsigned long len;
	struct msm_pmem_region *region;
#ifdef CONFIG_ANDROID_PMEM
	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
	if (rc < 0) {
		pr_err("%s: get_pmem_file fd %d error %d\n",
						__func__,
						info->fd, rc);
		return rc;
	}
	if (!info->len)
		info->len = len;

	rc = check_pmem_info(info, len);
	if (rc < 0)
		return rc;
#else
	paddr = 0;
	file = NULL;
#endif
	paddr += info->offset;
	len = info->len;

	if (check_overlap(ptype, paddr, len) < 0)
		return -EINVAL;

	CDBG("%s: type %d, active flag %d, paddr 0x%lx, vaddr 0x%lx\n",
		__func__, info->type, info->active, paddr,
		(unsigned long)info->vaddr);

	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
	if (!region)
		return -ENOMEM;

	INIT_HLIST_NODE(&region->list);

	region->paddr = paddr;
	region->len = len;
	region->file = file;
	memcpy(&region->info, info, sizeof(region->info));
	D("%s Adding region to list with type %d\n", __func__,
						region->info.type);
	D("%s pmem_stats address is 0x%p\n", __func__, ptype);
	hlist_add_head(&(region->list), ptype);

	return 0;
}
Exemplo n.º 8
0
/**
 * videobuf_pmem_contig_user_get() - setup user space memory pointer
 * @mem: per-buffer private videobuf-contig-pmem data
 * @vb: video buffer to map
 *
 * This function validates and sets up a pointer to user space memory.
 * Only physically contiguous pfn-mapped memory is accepted.
 *
 * Returns 0 if successful.
 */
int videobuf2_pmem_contig_user_get(struct videobuf2_contig_pmem *mem,
					struct videobuf2_msm_offset *offset,
					enum videobuf2_buffer_type buffer_type,
					uint32_t addr_offset, int path,
					struct ion_client *client)
{
	unsigned long len;
	int rc = 0;
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
	unsigned long kvstart;
#endif
	unsigned long paddr = 0;
	if (mem->phyaddr != 0)
		return 0;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
	mem->ion_handle = ion_import_fd(client, (int)mem->vaddr);
	if (IS_ERR_OR_NULL(mem->ion_handle)) {
		pr_err("%s ION import failed\n", __func__);
		return PTR_ERR(mem->ion_handle);
	}
	rc = ion_map_iommu(client, mem->ion_handle, CAMERA_DOMAIN, GEN_POOL,
		SZ_4K, 0, (unsigned long *)&mem->phyaddr, &len, UNCACHED, 0);
	if (rc < 0)
		ion_free(client, mem->ion_handle);
	rc = ion_handle_get_flags(client, mem->ion_handle, &mem->ion_flags);
	mem->kernel_vaddr = ion_map_kernel(client,
		mem->ion_handle, mem->ion_flags);
#elif CONFIG_ANDROID_PMEM
	rc = get_pmem_file((int)mem->vaddr, (unsigned long *)&mem->phyaddr,
					&kvstart, &len, &mem->file);
	if (rc < 0) {
		pr_err("%s: get_pmem_file fd %d error %d\n",
					__func__, (int)mem->vaddr, rc);
		return rc;
	}
#else
	paddr = 0;
	kvstart = 0;
#endif
	if (offset)
		mem->offset = *offset;
	else
		memset(&mem->offset, 0, sizeof(struct videobuf2_msm_offset));
	mem->path = path;
	mem->buffer_type = buffer_type;
	paddr = mem->phyaddr;
	mem->mapped_phyaddr = paddr + addr_offset;
	mem->addr_offset = addr_offset;
	return rc;
}
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;
}
uint32_t msm_mercury_platform_v2p(int fd, uint32_t len,
	struct file **file_p,
	struct ion_handle **ionhandle)
{
	unsigned long paddr;
	unsigned long size;
	int rc;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
	*ionhandle = ion_import_dma_buf(mercury_client, fd);
	if (IS_ERR_OR_NULL(*ionhandle))
		return 0;

	rc = ion_map_iommu(mercury_client, *ionhandle, CAMERA_DOMAIN,
		GEN_POOL, SZ_4K, 0, &paddr,
		(unsigned long *)&size, 0, 0);
#elif CONFIG_ANDROID_PMEM
	unsigned long kvstart;
	rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
#else
	rc = 0;
	paddr = 0;
	size = 0;
#endif
	if (rc < 0) {
		MCR_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd,
			rc);
		goto error1;
	}

	/* validate user input */
	if (len > size) {
		MCR_PR_ERR("%s: invalid offset + len\n", __func__);
		goto error1;
	}

	return paddr;
error1:
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
	ion_free(mercury_client, *ionhandle);
#endif
	return 0;
}
Exemplo n.º 11
0
/**
 * videobuf_pmem_contig_user_get() - setup user space memory pointer
 * @mem: per-buffer private videobuf-contig-pmem data
 * @vb: video buffer to map
 *
 * This function validates and sets up a pointer to user space memory.
 * Only physically contiguous pfn-mapped memory is accepted.
 *
 * Returns 0 if successful.
 */
static int videobuf_pmem_contig_user_get(struct videobuf_contig_pmem *mem,
					struct videobuf_buffer *vb)
{
	unsigned long kvstart;
	unsigned long len;
	int rc;

	mem->size = PAGE_ALIGN(vb->size);
	rc = get_pmem_file(vb->baddr, (unsigned long *)&mem->phyaddr,
					&kvstart, &len, &mem->file);
	if (rc < 0) {
		pr_err("%s: get_pmem_file fd %lu error %d\n",
					__func__, vb->baddr,
							rc);
		return rc;
	}
	mem->phyaddr += vb->boff;
	mem->y_off = 0;
	mem->cbcr_off = (vb->size)*2/3;
	mem->is_userptr = 1;
	return rc;
}
uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file_p,
					struct msm_mapped_buffer **msm_buffer,
					int *subsys_id)
{
	unsigned long paddr;
	unsigned long size;
	int rc;
	int flags;
#ifdef CONFIG_ANDROID_PMEM
	unsigned long kvstart;
	rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
#else
	rc = 0;
	paddr = 0;
	size = 0;
#endif
	if (rc < 0) {
		GMN_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd,
			rc);
		return 0;
	}

	/* validate user input */
	if (len > size) {
		GMN_PR_ERR("%s: invalid offset + len\n", __func__);
		return 0;
	}

	flags = MSM_SUBSYSTEM_MAP_IOVA;
	*subsys_id = MSM_SUBSYSTEM_CAMERA;
	*msm_buffer = msm_subsystem_map_buffer(paddr, size,
					flags, subsys_id, 1);
	if (IS_ERR((void *)*msm_buffer)) {
		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
		return 0;
	}
	paddr = ((struct msm_mapped_buffer *)*msm_buffer)->iova[0];
	return paddr;
}
Exemplo n.º 13
0
static int msm_pmem_table_add(struct hlist_head *ptype,
	struct msm_pmem_info *info, struct ion_client *client)
{
	unsigned long paddr;
#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
	unsigned long kvstart;
	struct file *file;
#endif
	int rc = -ENOMEM;

	unsigned long len;
	struct msm_pmem_region *region;

	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
	if (!region)
		goto out;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
	region->handle = ion_import_fd(client, info->fd);
	if (IS_ERR_OR_NULL(region->handle))
		goto out1;
	if (ion_map_iommu(client, region->handle, CAMERA_DOMAIN, GEN_POOL,
				  SZ_4K, 0, &paddr, &len, UNCACHED, 0) < 0)
		goto out2;
#elif CONFIG_ANDROID_PMEM
	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
	if (rc < 0) {
		pr_err("%s: get_pmem_file fd %d error %d\n",
				__func__, info->fd, rc);
		goto out1;
	}
	region->file = file;
#else
	paddr = 0;
	file = NULL;
	kvstart = 0;
#endif
	if (!info->len)
		info->len = len;
	rc = check_pmem_info(info, len);
	if (rc < 0)
		goto out3;
	paddr += info->offset;
	len = info->len;

	if (check_overlap(ptype, paddr, len) < 0) {
		rc = -EINVAL;
		goto out3;
	}

	CDBG("%s: type %d, active flag %d, paddr 0x%lx, vaddr 0x%lx\n",
		__func__, info->type, info->active, paddr,
		(unsigned long)info->vaddr);

	INIT_HLIST_NODE(&region->list);
	region->paddr = paddr;
	region->len = len;
	memcpy(&region->info, info, sizeof(region->info));
	D("%s Adding region to list with type %d\n", __func__,
						region->info.type);
	D("%s pmem_stats address is 0x%p\n", __func__, ptype);
	hlist_add_head(&(region->list), ptype);

	return 0;
out3:
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
	ion_unmap_iommu(client, region->handle, CAMERA_DOMAIN, GEN_POOL);
#endif
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
out2:
	ion_free(client, region->handle);
#elif CONFIG_ANDROID_PMEM
	put_pmem_file(region->file);
#endif
out1:
	kfree(region);
out:
	return rc;
}
Exemplo n.º 14
0
static u32 vid_dec_set_buffer(struct video_client_ctx *client_ctx,
			      struct vdec_setbuffer_cmd *buffer_info)
{
	enum vcd_buffer_type buffer_type;
	enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
	u32 vcd_status = VCD_ERR_FAIL;
	unsigned long user_vaddr, kernel_vaddr, phy_addr, len;
	int pmem_fd;
	struct file *file;
	struct buf_addr_table *buf_addr_table;
	s32 buffer_index = -1;

	if (!client_ctx || !buffer_info)
		return FALSE;

	user_vaddr = (unsigned long)buffer_info->buffer.bufferaddr;

	if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT)
		dir_buffer = BUFFER_TYPE_OUTPUT;

	/*If buffer already set, ignore */
	if (vid_c_lookup_addr_table(client_ctx, dir_buffer,
				      TRUE, &user_vaddr, &kernel_vaddr,
				      &phy_addr, &pmem_fd, &file,
				      &buffer_index)) {
		DBG("%s() : user_virt_addr = 0x%08lx is alreday set.",
		    __func__, user_vaddr);
		return TRUE;
	}

	if (get_pmem_file(buffer_info->buffer.pmem_fd,
			  &phy_addr, &kernel_vaddr, &len, &file)) {
		ERR("%s(): get_pmem_file failed\n", __func__);
		return FALSE;
	}
	put_pmem_file(file);
	if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
		buffer_type = VCD_BUFFER_INPUT;
		client_ctx->num_of_input_buffers++;
		if (client_ctx->num_of_input_buffers >
				MAX_VIDEO_NUM_OF_BUFF) {
			ERR("%s(): num_of_input_buffers reached max value"
			    " MAX_VIDEO_NUM_OF_BUFF \n", __func__);
			client_ctx->num_of_input_buffers--;
			return FALSE;
		}
		buffer_index = client_ctx->num_of_input_buffers - 1;
		buf_addr_table =
		    &client_ctx->input_buf_addr_table[buffer_index];
		buf_addr_table->user_vaddr =
		    (unsigned long)buffer_info->buffer.bufferaddr;
		buf_addr_table->kernel_vaddr = kernel_vaddr;
		buf_addr_table->phy_addr = phy_addr;
		buf_addr_table->pmem_fd = buffer_info->buffer.pmem_fd;
		buf_addr_table->file = file;
	} else {
		buffer_type = VCD_BUFFER_OUTPUT;
		client_ctx->num_of_output_buffers++;
		if (client_ctx->num_of_output_buffers >
				MAX_VIDEO_NUM_OF_BUFF) {
			ERR("%s(): num_of_outut_buffers reached max value"
			    " MAX_VIDEO_NUM_OF_BUFF \n", __func__);
			client_ctx->num_of_output_buffers--;
			return FALSE;
		}
		buffer_index = client_ctx->num_of_output_buffers - 1;
		buf_addr_table =
		    &client_ctx->output_buf_addr_table[buffer_index];
		kernel_vaddr += (unsigned long)buffer_info->buffer.offset;
		phy_addr += (unsigned long)buffer_info->buffer.offset;
		buf_addr_table->user_vaddr =
		    (unsigned long)buffer_info->buffer.bufferaddr;
		buf_addr_table->kernel_vaddr = kernel_vaddr;
		buf_addr_table->phy_addr = phy_addr;
		buf_addr_table->pmem_fd = buffer_info->buffer.pmem_fd;
		buf_addr_table->file = file;
	}

	vcd_status = vcd_set_buffer(client_ctx->vcd_handle,
				    buffer_type, (u8 *) kernel_vaddr,
				    buffer_info->buffer.buffer_len);

	if (!vcd_status)
		return TRUE;
	else
		return FALSE;
}