Пример #1
0
static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset,
		struct msm_smem *mem, enum hal_buffer buffer_type)
{
	struct ion_handle *hndl;
	unsigned long iova = 0;
	unsigned long buffer_size = 0;
	unsigned long ionflags = 0;
	int rc = 0;
	int align = SZ_4K;

	hndl = ion_import_dma_buf(client->clnt, fd);
	if (IS_ERR_OR_NULL(hndl)) {
		dprintk(VIDC_ERR, "Failed to get handle: %p, %d, %d, %p\n",
				client, fd, offset, hndl);
		rc = -ENOMEM;
		goto fail_import_fd;
	}
	mem->kvaddr = NULL;
	rc = ion_handle_get_flags(client->clnt, hndl, &ionflags);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to get ion flags: %d\n", rc);
		goto fail_device_address;
	}

	mem->flags = ionflags;
	mem->buffer_type = buffer_type;
	if (mem->flags & SMEM_SECURE)
		align = ALIGN(align, SZ_1M);

	rc = get_device_address(client, hndl, align, &iova, &buffer_size,
					mem->flags, buffer_type);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc);
		goto fail_device_address;
	}

	mem->mem_type = client->mem_type;
	mem->smem_priv = hndl;
	mem->device_addr = iova;
	mem->size = buffer_size;
	dprintk(VIDC_DBG,
		"%s: ion_handle = 0x%p, fd = %d, device_addr = 0x%x, size = %d, kvaddr = 0x%p, buffer_type = %d\n",
		__func__, mem->smem_priv, fd, (u32)mem->device_addr,
		mem->size, mem->kvaddr, mem->buffer_type);
	return rc;
fail_device_address:
	ion_free(client->clnt, hndl);
fail_import_fd:
	return rc;
}
static int ion_cache_operations(struct smem_client *client,
	struct msm_smem *mem, enum smem_cache_ops cache_op)
{
	unsigned long ionflag = 0;
	int rc = 0;
	int msm_cache_ops = 0;
	if (!mem || !client) {
		dprintk(VIDC_ERR, "Invalid params: %p, %p\n",
			mem, client);
		return -EINVAL;
	}
	rc = ion_handle_get_flags(client->clnt,	mem->smem_priv,
		&ionflag);
	if (rc) {
		dprintk(VIDC_ERR,
			"ion_handle_get_flags failed: %d\n", rc);
		goto cache_op_failed;
	}
	if (ION_IS_CACHED(ionflag)) {
		switch (cache_op) {
		case SMEM_CACHE_CLEAN:
			msm_cache_ops = ION_IOC_CLEAN_CACHES;
			break;
		case SMEM_CACHE_INVALIDATE:
			msm_cache_ops = ION_IOC_INV_CACHES;
			break;
		case SMEM_CACHE_CLEAN_INVALIDATE:
			msm_cache_ops = ION_IOC_CLEAN_INV_CACHES;
			break;
		default:
			dprintk(VIDC_ERR, "cache operation not supported\n");
			rc = -EINVAL;
			goto cache_op_failed;
		}
		rc = msm_ion_do_cache_op(client->clnt,
				(struct ion_handle *)mem->smem_priv,
				0, (unsigned long)mem->size,
				msm_cache_ops);
		if (rc) {
			dprintk(VIDC_ERR,
					"cache operation failed %d\n", rc);
			goto cache_op_failed;
		}
	}
cache_op_failed:
	return rc;
}
Пример #3
0
static int ion_user_to_kernel(struct smem_client *client,
			int fd, u32 offset, int domain, int partition,
			struct msm_smem *mem)
{
	struct ion_handle *hndl;
	unsigned long ionflag;
	unsigned long iova = 0;
	unsigned long buffer_size = 0;
	int rc = 0;
	hndl = ion_import_dma_buf(client->clnt, fd);
	if (IS_ERR_OR_NULL(hndl)) {
		dprintk(VIDC_ERR, "Failed to get handle: %p, %d, %d, %p\n",
				client, fd, offset, hndl);
		rc = -ENOMEM;
		goto fail_import_fd;
	}
	rc = ion_handle_get_flags(client->clnt, hndl, &ionflag);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to get ion flags: %d", rc);
		goto fail_map;
	}
	mem->kvaddr = NULL;
	mem->domain = domain;
	mem->partition_num = partition;
	rc = get_device_address(client->clnt, hndl, mem->domain,
		mem->partition_num, 4096, &iova, &buffer_size, ionflag);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc);
		goto fail_device_address;
	}

	mem->mem_type = client->mem_type;
	mem->smem_priv = hndl;
	mem->device_addr = iova;
	mem->size = buffer_size;
	dprintk(VIDC_DBG, "NOTE: Buffer device address: 0x%lx, size: %d\n",
		mem->device_addr, mem->size);
	return rc;
fail_device_address:
	ion_unmap_kernel(client->clnt, hndl);
fail_map:
	ion_free(client->clnt, hndl);
fail_import_fd:
	return rc;
}
Пример #4
0
static int ion_user_to_kernel(struct smem_client *client,
			int fd, u32 offset, struct msm_smem *mem)
{
	struct ion_handle *hndl;
	unsigned long ionflag;
	size_t len;
	int rc = 0;
	hndl = ion_import_dma_buf(client->clnt, fd);
	if (IS_ERR_OR_NULL(hndl)) {
		pr_err("Failed to get handle: %p, %d, %d, %p\n",
				client, fd, offset, hndl);
		rc = -ENOMEM;
		goto fail_import_fd;
	}
	rc = ion_handle_get_flags(client->clnt, hndl, &ionflag);
	if (rc) {
		pr_err("Failed to get ion flags: %d", rc);
		goto fail_map;
	}
	rc = ion_phys(client->clnt, hndl, &mem->paddr, &len);
	if (rc) {
		pr_err("Failed to get physical address\n");
		goto fail_map;
	}
	mem->kvaddr = ion_map_kernel(client->clnt, hndl);
	if (!mem->kvaddr) {
		pr_err("Failed to map shared mem in kernel\n");
		rc = -EIO;
		goto fail_map;
	}

	mem->kvaddr += offset;
	mem->paddr += offset;
	mem->mem_type = client->mem_type;
	mem->smem_priv = hndl;
	mem->device_addr = mem->paddr;
	mem->size = len;
	return rc;
fail_map:
	ion_free(client->clnt, hndl);
fail_import_fd:
	return rc;
}
/*
 * make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile
 * has enough space h * w * 3 * 2
 */
static void mdp4_dsi_video_do_blt(struct msm_fb_data_type *mfd, int enable)
{
    unsigned long flag;
    int cndx = 0;
    struct vsycn_ctrl *vctrl;
    struct mdp4_overlay_pipe *pipe;
    long long vtime;

    vctrl = &vsync_ctrl_db[cndx];
    pipe = vctrl->base_pipe;

    mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);

    if (mfd->ov0_wb_buf->write_addr == 0) {
        pr_info("%s: no blt_base assigned\n", __func__);
        return;
    }

    spin_lock_irqsave(&vctrl->spin_lock, flag);
    if (enable && pipe->ov_blt_addr == 0) {
        pipe->ov_blt_addr = mfd->ov0_wb_buf->write_addr;
        pipe->dma_blt_addr = mfd->ov0_wb_buf->read_addr;
        pipe->ov_cnt = 0;
        pipe->dmap_cnt = 0;
        vctrl->ov_koff = 0;
        vctrl->ov_done = 0;
        vctrl->blt_free = 0;
        mdp4_stat.blt_dsi_video++;
        vctrl->blt_change++;
    } else if (enable == 0 && pipe->ov_blt_addr) {
        pipe->ov_blt_addr = 0;
        pipe->dma_blt_addr =  0;
        vctrl->blt_free = 4;	/* 4 commits to free wb buf */
        vctrl->blt_change++;
    }

    pr_info("%s: changed=%d enable=%d ov_blt_addr=%x\n", __func__,
            vctrl->blt_change, enable, (int)pipe->ov_blt_addr);

    if (!vctrl->blt_change) {
        spin_unlock_irqrestore(&vctrl->spin_lock, flag);
        return;
    }

    if (vctrl->blt_ctrl == BLT_SWITCH_TG_OFF) // QC_1204
        vctrl->blt_change = 0; // QC_1204

    spin_unlock_irqrestore(&vctrl->spin_lock, flag);

    // QC_1206 - start
    if (enable && pipe->ov_blt_addr) {
        size_t blt_vm_size;
        char *blt_vm_addr;
        unsigned long ionflag = 0;
        int rc = -1;

        blt_vm_size = roundup(mfd->panel_info.xres * \
                              mfd->panel_info.yres * 3 * 2, SZ_4K);

        if (!IS_ERR_OR_NULL(mfd->iclient)) {
            rc = ion_handle_get_flags(mfd->iclient,
                                      mfd->ov0_wb_buf->ihdl,
                                      &ionflag);
            pr_err("*** %s: rc=%x\n", __func__, rc); // QC_1207

            if (!rc) {
                blt_vm_addr = (char *) ion_map_kernel(
                                  mfd->iclient,
                                  mfd->ov0_wb_buf->ihdl,
                                  ionflag);
                pr_err("*** %s: blt_vm_addr=%x\n", __func__, (unsigned int)blt_vm_addr); // QC_1207
                if (blt_vm_addr) {
                    pr_err("*** %s: Calling memset() with blt_vm_size=%d\n", __func__, blt_vm_size); // QC_1207
                    memset(blt_vm_addr, 0, blt_vm_size);
                    ion_unmap_kernel(mfd->iclient,
                                     mfd->ov0_wb_buf->ihdl);
                }
            }
        }
    }
    // QC_1206 - end

    if (vctrl->blt_ctrl == BLT_SWITCH_TG_OFF) {
        int tg_enabled;

        vctrl->blt_change = 0;
        tg_enabled = inpdw(MDP_BASE + DSI_VIDEO_BASE) & 0x01;
        if (tg_enabled) {
            vsync_irq_enable(INTR_PRIMARY_VSYNC, MDP_PRIM_VSYNC_TERM);
            mdp4_dsi_video_wait4vsync(0, &vtime);
            MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0);
            mdp4_dsi_video_wait4dmap_done(0);
        }
        mdp4_overlayproc_cfg(pipe);
        mdp4_overlay_dmap_xy(pipe);
        if (tg_enabled) {
            /*
            * need wait for more than 1 ms to
            * make sure dsi lanes' fifo is empty and
            * lanes in stop state befroe reset
            * controller
            */
            usleep(2000);
            mipi_dsi_sw_reset();
            MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1);
        }
    }
}
Пример #6
0
static int audpcm_in_open(struct inode *inode, struct file *file)
{
	struct audio_in *audio = &the_audio_in;
	int rc;
	int len = 0;
	unsigned long ionflag = 0;
	ion_phys_addr_t addr = 0;
	struct ion_handle *handle = NULL;
	struct ion_client *client = NULL;

	int encid;
	mutex_lock(&audio->lock);
	if (audio->opened) {
		rc = -EBUSY;
		goto done;
	}

	/* Settings will be re-config at AUDIO_SET_CONFIG,
	 * but at least we need to have initial config
	 */
	audio->mode = MSM_AUD_ENC_MODE_TUNNEL;
	audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025;
	audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025;
	audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO;
	audio->buffer_size = MONO_DATA_SIZE;
	audio->enc_type = AUDREC_CMD_TYPE_0_INDEX_WAV | audio->mode;

	rc = audmgr_open(&audio->audmgr);
	if (rc)
		goto done;
	encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name,
			&audio->queue_ids);
	if (encid < 0) {
		MM_ERR("No free encoder available\n");
		rc = -ENODEV;
		goto done;
	}
	audio->enc_id = encid;

	rc = msm_adsp_get(audio->module_name, &audio->audrec,
			   &audrec_adsp_ops, audio);
	if (rc) {
		audpreproc_aenc_free(audio->enc_id);
		goto done;
	}

	rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
				&audpre_adsp_ops, audio);
	if (rc) {
		msm_adsp_put(audio->audrec);
		audpreproc_aenc_free(audio->enc_id);
		goto done;
	}

	audio->dsp_cnt = 0;
	audio->stopped = 0;

	audpcm_in_flush(audio);

	client = msm_ion_client_create(UINT_MAX, "Audio_PCM_in_client");
	if (IS_ERR_OR_NULL(client)) {
		MM_ERR("Unable to create ION client\n");
		rc = -ENOMEM;
		goto client_create_error;
	}
	audio->client = client;

	MM_DBG("allocating mem sz = %d\n", DMASZ);
	handle = ion_alloc(client, DMASZ, SZ_4K,
		ION_HEAP(ION_AUDIO_HEAP_ID), 0);
	if (IS_ERR_OR_NULL(handle)) {
		MM_ERR("Unable to create allocate O/P buffers\n");
		rc = -ENOMEM;
		goto output_buff_alloc_error;
	}

	audio->output_buff_handle = handle;

	rc = ion_phys(client , handle, &addr, &len);
	if (rc) {
		MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n",
			(unsigned int) addr, (unsigned int) len);
		rc = -ENOMEM;
		goto output_buff_get_phys_error;
	} else {
		MM_INFO("O/P buffers:valid phy: %x sz: %x\n",
			(unsigned int) addr, (unsigned int) len);
	}
	audio->phys = (int32_t)addr;

	rc = ion_handle_get_flags(client, handle, &ionflag);
	if (rc) {
		MM_ERR("could not get flags for the handle\n");
		rc = -ENOMEM;
		goto output_buff_get_flags_error;
	}

	audio->data = ion_map_kernel(client, handle);
	if (IS_ERR(audio->data)) {
		MM_ERR("could not map read buffers,freeing instance 0x%08x\n",
				(int)audio);
		rc = -ENOMEM;
		goto output_buff_map_error;
	}
	MM_DBG("read buf: phy addr 0x%08x kernel addr 0x%08x\n",
		audio->phys, (int)audio->data);

	file->private_data = audio;
	audio->opened = 1;
	rc = 0;
done:
	mutex_unlock(&audio->lock);
	return rc;
output_buff_map_error:
output_buff_get_phys_error:
output_buff_get_flags_error:
	ion_free(client, audio->output_buff_handle);
output_buff_alloc_error:
	ion_client_destroy(client);
client_create_error:
	msm_adsp_put(audio->audrec);
	msm_adsp_put(audio->audpre);
	audpreproc_aenc_free(audio->enc_id);
	mutex_unlock(&audio->lock);
	return rc;
}
Пример #7
0
static int audpcm_in_open(struct inode *inode, struct file *file)
{
	struct audio_in *audio = &the_audio_in;
	int rc;
	int len = 0;
	unsigned long ionflag = 0;
	ion_phys_addr_t addr = 0;
	struct ion_handle *handle = NULL;
	struct ion_client *client = NULL;

	int encid;
	struct timespec ts;
	struct rtc_time tm;

	mutex_lock(&audio->lock);
	if (audio->opened) {
		rc = -EBUSY;
		goto done;
	}

	audio->mode = MSM_AUD_ENC_MODE_TUNNEL;
	audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025;
	audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025;
	audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO;
	audio->buffer_size = MONO_DATA_SIZE;
	audio->enc_type = AUDREC_CMD_TYPE_0_INDEX_WAV | audio->mode;

	rc = audmgr_open(&audio->audmgr);
	if (rc)
		goto done;
	encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name,
			&audio->queue_ids);
	if (encid < 0) {
		MM_AUD_ERR("No free encoder available\n");
		rc = -ENODEV;
		goto done;
	}
	audio->enc_id = encid;

	rc = msm_adsp_get(audio->module_name, &audio->audrec,
			   &audrec_adsp_ops, audio);
	if (rc) {
		audpreproc_aenc_free(audio->enc_id);
		goto done;
	}

	audio->dsp_cnt = 0;
	audio->stopped = 0;

	audpcm_in_flush(audio);

	client = msm_ion_client_create(UINT_MAX, "Audio_PCM_in_client");
	if (IS_ERR_OR_NULL(client)) {
		MM_ERR("Unable to create ION client\n");
		rc = -ENOMEM;
		goto client_create_error;
	}
	audio->client = client;

	MM_DBG("allocating mem sz = %d\n", DMASZ);
	handle = ion_alloc(client, DMASZ, SZ_4K,
		ION_HEAP(ION_AUDIO_HEAP_ID));
	if (IS_ERR_OR_NULL(handle)) {
		MM_ERR("Unable to create allocate O/P buffers\n");
		rc = -ENOMEM;
		goto output_buff_alloc_error;
	}

	audio->output_buff_handle = handle;

	rc = ion_phys(client , handle, &addr, &len);
	if (rc) {
		MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n",
			(unsigned int) addr, (unsigned int) len);
		rc = -ENOMEM;
		goto output_buff_get_phys_error;
	} else {
		MM_INFO("O/P buffers:valid phy: %x sz: %x\n",
			(unsigned int) addr, (unsigned int) len);
	}
	audio->phys = (int32_t)addr;

	rc = ion_handle_get_flags(client, handle, &ionflag);
	if (rc) {
		MM_ERR("could not get flags for the handle\n");
		rc = -ENOMEM;
		goto output_buff_get_flags_error;
	}

	audio->data = ion_map_kernel(client, handle, ionflag);
	if (IS_ERR(audio->data)) {
		MM_ERR("could not map read buffers,freeing instance 0x%08x\n",
				(int)audio);
		rc = -ENOMEM;
		goto output_buff_map_error;
	}
	MM_DBG("read buf: phy addr 0x%08x kernel addr 0x%08x\n",
		audio->phys, (int)audio->data);

	file->private_data = audio;
	audio->opened = 1;
	rc = 0;
done:
	mutex_unlock(&audio->lock);
	getnstimeofday(&ts);
	rtc_time_to_tm(ts.tv_sec, &tm);
	pr_aud_info1("[ATS][start_recording][successful] at %lld \
		(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n",
		ktime_to_ns(ktime_get()),
		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
		tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
	return rc;
output_buff_map_error:
output_buff_get_phys_error:
output_buff_get_flags_error:
	ion_free(client, audio->output_buff_handle);
output_buff_alloc_error:
	ion_client_destroy(client);
client_create_error:
	msm_adsp_put(audio->audrec);
	audpreproc_aenc_free(audio->enc_id);
	mutex_unlock(&audio->lock);
	return rc;
}
Пример #8
0
static int audamrnb_in_open(struct inode *inode, struct file *file)
{
	struct audio_in *audio = &the_audio_amrnb_in;
	int rc;
	int encid;
	int len = 0;
	unsigned long ionflag = 0;
	ion_phys_addr_t addr = 0;
	struct ion_handle *handle = NULL;
	struct ion_client *client = NULL;

	mutex_lock(&audio->lock);
	if (audio->opened) {
		rc = -EBUSY;
		goto done;
	}

	client = msm_ion_client_create(UINT_MAX, "Audio_AMR_In_Client");
	if (IS_ERR_OR_NULL(client)) {
		MM_ERR("Unable to create ION client\n");
		rc = -ENOMEM;
		goto client_create_error;
	}
	audio->client = client;

	handle = ion_alloc(client, DMASZ, SZ_4K,
		ION_HEAP(ION_AUDIO_HEAP_ID),0);
	if (IS_ERR_OR_NULL(handle)) {
		MM_ERR("Unable to create allocate O/P buffers\n");
		rc = -ENOMEM;
		goto buff_alloc_error;
	}
	audio->buff_handle = handle;

	rc = ion_phys(client, handle, &addr, &len);
	if (rc) {
		MM_ERR("O/P buffers:Invalid phy: %x sz: %x\n",
			(unsigned int) addr, (unsigned int) len);
		goto buff_get_phys_error;
	} else {
		MM_INFO("O/P buffers:valid phy: %x sz: %x\n",
			(unsigned int) addr, (unsigned int) len);
	}
	audio->phys = (int32_t)addr;

	rc = ion_handle_get_flags(client, handle, &ionflag);
	if (rc) {
		MM_ERR("could not get flags for the handle\n");
		goto buff_get_flags_error;
	}

	audio->map_v_read = ion_map_kernel(client, handle);
	if (IS_ERR(audio->map_v_read)) {
		MM_ERR("could not map write buffers\n");
		rc = -ENOMEM;
		goto buff_map_error;
	}
	audio->data = audio->map_v_read;
	MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
		audio->phys, (int)audio->data);

	MM_DBG("Memory addr = 0x%8x  phy addr = 0x%8x\n",\
		(int) audio->data, (int) audio->phys);
	if ((file->f_mode & FMODE_WRITE) &&
			(file->f_mode & FMODE_READ)) {
		rc = -EACCES;
		MM_ERR("Non tunnel encoding is not supported\n");
		goto buff_map_error;
	} else if (!(file->f_mode & FMODE_WRITE) &&
					(file->f_mode & FMODE_READ)) {
		audio->mode = MSM_AUD_ENC_MODE_TUNNEL;
		MM_DBG("Opened for tunnel mode encoding\n");
	} else {
		rc = -EACCES;
		goto buff_map_error;
	}


	/* Settings will be re-config at AUDIO_SET_CONFIG,
	 * but at least we need to have initial config
	 */
	audio->buffer_size = (FRAME_SIZE - 8);
	audio->enc_type = ENC_TYPE_AMRNB | audio->mode;
	audio->dtx_mode = -1;
	audio->frame_format = 0;
	audio->used_mode = 7; /* Bit Rate 12.2 kbps MR122 */

	encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name,
			&audio->queue_ids);
	if (encid < 0) {
		MM_ERR("No free encoder available\n");
		rc = -ENODEV;
		goto aenc_alloc_error;
	}
	audio->enc_id = encid;

	rc = msm_adsp_get(audio->module_name, &audio->audrec,
			   &audrec_amrnb_adsp_ops, audio);

	if (rc) {
		audpreproc_aenc_free(audio->enc_id);
		goto aenc_alloc_error;
	}

	audio->stopped = 0;
	audio->source = 0;

	audamrnb_in_flush(audio);

	audio->device_events = AUDDEV_EVT_DEV_RDY | AUDDEV_EVT_DEV_RLS |
				AUDDEV_EVT_VOICE_STATE_CHG;

	audio->voice_state = msm_get_voice_state();
	rc = auddev_register_evt_listner(audio->device_events,
					AUDDEV_CLNT_ENC, audio->enc_id,
					amrnb_in_listener, (void *) audio);
	if (rc) {
		MM_ERR("failed to register device event listener\n");
		goto evt_error;
	}
	audio->build_id = socinfo_get_build_id();
	MM_DBG("Modem build id = %s\n", audio->build_id);

	file->private_data = audio;
	audio->opened = 1;
	mutex_unlock(&audio->lock);
	return rc;
evt_error:
	msm_adsp_put(audio->audrec);
	audpreproc_aenc_free(audio->enc_id);
	ion_unmap_kernel(client, audio->buff_handle);
aenc_alloc_error:
buff_map_error:
buff_get_phys_error:
buff_get_flags_error:
	ion_free(client, audio->buff_handle);
buff_alloc_error:
	ion_client_destroy(client);
client_create_error:
done:
	mutex_unlock(&audio->lock);
	return rc;
}
Пример #9
0
static long msm_ion_custom_ioctl(struct ion_client *client,
				unsigned int cmd,
				unsigned long arg)
{
	switch (cmd) {
	case ION_IOC_CLEAN_CACHES:
	case ION_IOC_INV_CACHES:
	case ION_IOC_CLEAN_INV_CACHES:
	{
		struct ion_flush_data data;
		unsigned long start, end;
		struct ion_handle *handle = NULL;
		int ret;

		if (copy_from_user(&data, (void __user *)arg,
					sizeof(struct ion_flush_data)))
			return -EFAULT;

		start = (unsigned long) data.vaddr;
		end = (unsigned long) data.vaddr + data.length;

		if (start && check_vaddr_bounds(start, end)) {
			pr_err("%s: virtual address %p is out of bounds\n",
				__func__, data.vaddr);
			return -EINVAL;
		}

		if (!data.handle) {
			handle = ion_import_dma_buf(client, data.fd);
			if (IS_ERR(handle)) {
				pr_info("%s: Could not import handle: %d\n",
					__func__, (int)handle);
				return -EINVAL;
			}
		}

		ret = ion_do_cache_op(client,
				data.handle ? data.handle : handle,
				data.vaddr, data.offset, data.length,
				cmd);

		if (!data.handle)
			ion_free(client, handle);

		if (ret < 0)
			return ret;
		break;

	}
	case ION_IOC_GET_FLAGS:
	{
		struct ion_flag_data data;
		int ret;
		if (copy_from_user(&data, (void __user *)arg,
					sizeof(struct ion_flag_data)))
			return -EFAULT;

		ret = ion_handle_get_flags(client, data.handle, &data.flags);
		if (ret < 0)
			return ret;
		if (copy_to_user((void __user *)arg, &data,
					sizeof(struct ion_flag_data)))
			return -EFAULT;
		break;
	}
	default:
		return -ENOTTY;
	}
	return 0;
}
Пример #10
0
static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct ion_client *client = filp->private_data;

	switch (cmd) {
	case ION_IOC_ALLOC:
	{
		struct ion_allocation_data data;

		if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
			return -EFAULT;
		data.handle = ion_alloc(client, data.len, data.align,
					     data.flags);

		if (IS_ERR(data.handle))
			return PTR_ERR(data.handle);

		if (copy_to_user((void __user *)arg, &data, sizeof(data))) {
			ion_free(client, data.handle);
			return -EFAULT;
		}
		break;
	}
	case ION_IOC_FREE:
	{
		struct ion_handle_data data;
		bool valid;

		if (copy_from_user(&data, (void __user *)arg,
				   sizeof(struct ion_handle_data)))
			return -EFAULT;
		mutex_lock(&client->lock);
		valid = ion_handle_validate(client, data.handle);
		mutex_unlock(&client->lock);
		if (!valid)
			return -EINVAL;
		ion_free(client, data.handle);
		break;
	}
	case ION_IOC_MAP:
	case ION_IOC_SHARE:
	{
		struct ion_fd_data data;
		int ret;
		if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
			return -EFAULT;

		ret = ion_share_set_flags(client, data.handle, filp->f_flags);
		if (ret)
			return ret;

		data.fd = ion_share_dma_buf(client, data.handle);
		if (copy_to_user((void __user *)arg, &data, sizeof(data)))
			return -EFAULT;
		if (data.fd < 0)
			return data.fd;
		break;
	}
	case ION_IOC_IMPORT:
	{
		struct ion_fd_data data;
		int ret = 0;
		if (copy_from_user(&data, (void __user *)arg,
				   sizeof(struct ion_fd_data)))
			return -EFAULT;
		data.handle = ion_import_dma_buf(client, data.fd);
		if (IS_ERR(data.handle))
			data.handle = NULL;
		if (copy_to_user((void __user *)arg, &data,
				 sizeof(struct ion_fd_data)))
			return -EFAULT;
		if (ret < 0)
			return ret;
		break;
	}
	case ION_IOC_CUSTOM:
	{
		struct ion_device *dev = client->dev;
		struct ion_custom_data data;

		if (!dev->custom_ioctl)
			return -ENOTTY;
		if (copy_from_user(&data, (void __user *)arg,
				sizeof(struct ion_custom_data)))
			return -EFAULT;
		return dev->custom_ioctl(client, data.cmd, data.arg);
	}
	case ION_IOC_CLEAN_CACHES:
	case ION_IOC_INV_CACHES:
	case ION_IOC_CLEAN_INV_CACHES:
	{
		struct ion_flush_data data;
		unsigned long start, end;
		struct ion_handle *handle = NULL;
		int ret;

		if (copy_from_user(&data, (void __user *)arg,
				sizeof(struct ion_flush_data)))
			return -EFAULT;

		start = (unsigned long) data.vaddr;
		end = (unsigned long) data.vaddr + data.length;

		if (check_vaddr_bounds(start, end)) {
			pr_err("%s: virtual address %p is out of bounds\n",
				__func__, data.vaddr);
			return -EINVAL;
		}

		if (!data.handle) {
			handle = ion_import_dma_buf(client, data.fd);
			if (IS_ERR(handle)) {
				pr_info("%s: Could not import handle: %d\n",
					__func__, (int)handle);
				return -EINVAL;
			}
		}

		ret = ion_do_cache_op(client,
					data.handle ? data.handle : handle,
					data.vaddr, data.offset, data.length,
					cmd);

		if (!data.handle)
			ion_free(client, handle);

		if (ret < 0)
			return ret;
		break;

	}
	case ION_IOC_GET_FLAGS:
	{
		struct ion_flag_data data;
		int ret;
		if (copy_from_user(&data, (void __user *)arg,
				   sizeof(struct ion_flag_data)))
			return -EFAULT;

		ret = ion_handle_get_flags(client, data.handle, &data.flags);
		if (ret < 0)
			return ret;
		if (copy_to_user((void __user *)arg, &data,
				 sizeof(struct ion_flag_data)))
			return -EFAULT;
		break;
	}
	default:
		return -ENOTTY;
	}
	return 0;
}
Пример #11
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;
	unsigned long ionflag;
	void *vaddr;

	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
	if (!region)
		goto out;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
	region->handle = ion_import_dma_buf(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, 0 /* UNCACHED */, 0) < 0)
		goto out2;

	rc = ion_handle_get_flags(client, region->handle, &ionflag);
	if (rc) {
		pr_err("%s: could not get flags for the handle\n", __func__);
		return 0;
	}
	D("ionflag=%ld\n", ionflag);
	vaddr = ion_map_kernel(client, region->handle);
	if (IS_ERR_OR_NULL(vaddr)) {
		pr_err("%s: could not get virtual address\n", __func__);
		return 0;
	}
	region->vaddr = (unsigned long) vaddr;

#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;
}
static long ion_test_ioctl(struct file *file, unsigned cmd, unsigned long arg)
{
	int ret;
	ion_phys_addr_t phys_addr;
	void *addr;
	size_t len;
	unsigned long flags, size;
	struct msm_ion_test *ion_test = file->private_data;
	struct ion_test_data *test_data = &ion_test->test_data;

	switch (cmd) {
	case IOC_ION_KCLIENT_CREATE:
	{
		ret = create_ion_client(ion_test);
		break;
	}
	case IOC_ION_KCLIENT_DESTROY:
	{
		free_ion_client(ion_test);
		ret = 0;
		break;
	}
	case IOC_ION_KALLOC:
	{
		if (copy_from_user(test_data, (void __user *)arg,
						sizeof(struct ion_test_data)))
			return -EFAULT;
		ret = alloc_ion_buf(ion_test, test_data);
		if (ret)
			pr_info("allocating ion buffer failed\n");
		break;
	}
	case IOC_ION_KFREE:
	{
		free_ion_buf(ion_test);
		ret = 0;
		break;
	}
	case IOC_ION_KPHYS:
	{
		ret = ion_phys(ion_test->ion_client, ion_test->ion_handle,
							&phys_addr, &len);
		if (!ret)
			pr_info("size is 0x%x\n phys addr 0x%x", len,
						(unsigned int)phys_addr);
		break;
	}
	case IOC_ION_KMAP:
	{
		addr = ion_map_kernel(ion_test->ion_client,
					ion_test->ion_handle);
		if (IS_ERR_OR_NULL(addr)) {
			ret = -EIO;
			pr_info("mapping kernel buffer failed\n");
		} else {
			ret = 0;
			test_data->vaddr = (unsigned long)addr;
		}
		break;
	}
	case IOC_ION_KUMAP:
	{
		ion_unmap_kernel(ion_test->ion_client, ion_test->ion_handle);
		ret = 0;
		break;
	}
	case IOC_ION_UIMPORT:
	{
		if (copy_from_user(test_data, (void __user *)arg,
						sizeof(struct ion_test_data)))
			return -EFAULT;
		ion_test->ion_handle = ion_import_dma_buf(ion_test->ion_client,
							test_data->shared_fd);
		if (IS_ERR_OR_NULL(ion_test->ion_handle)) {
			ret = -EIO;
			pr_info("import of user buf failed\n");
		} else
			ret = 0;
		break;
	}
	case IOC_ION_UBUF_FLAGS:
	{
		ret = ion_handle_get_flags(ion_test->ion_client,
						ion_test->ion_handle, &flags);
		if (ret)
			pr_info("user flags cannot be retrieved\n");
		else
			if (copy_to_user((void __user *)arg, &flags,
						sizeof(unsigned long)))
				ret = -EFAULT;
		break;
	}
	case IOC_ION_UBUF_SIZE:
	{
		ret = ion_handle_get_size(ion_test->ion_client,
						ion_test->ion_handle, &size);
		if (ret)
			pr_info("buffer size cannot be retrieved\n");
		else
			if (copy_to_user((void __user *)arg, &size,
							sizeof(unsigned long)))
				ret = -EFAULT;
		break;
	}
	case IOC_ION_WRITE_VERIFY:
	{
		write_pattern(test_data->vaddr, test_data->size);
		if (verify_pattern(test_data->vaddr, test_data->size)) {
			pr_info("verify of mapped buf failed\n");
			ret = -EIO;
		} else
			ret = 0;
		break;
	}
	case IOC_ION_VERIFY:
	{
		if (verify_pattern(test_data->vaddr, test_data->size)) {
			pr_info("fail in verifying imported buffer\n");
			ret = -EIO;
		} else
			ret = 0;
		break;
	}
	case IOC_ION_SEC:
	{
		ret = msm_ion_secure_heap(ION_CP_MM_HEAP_ID);
		if (ret)
			pr_info("unable to secure heap\n");
		else
			pr_info("able to secure heap\n");
		break;
	}
	case IOC_ION_UNSEC:
	{
		ret = msm_ion_unsecure_heap(ION_CP_MM_HEAP_ID);
		if (ret)
			pr_info("unable to unsecure heap\n");
		else
			pr_info("able to unsecure heap\n");
		break;
	}
	default:
	{
		pr_info("command not supproted\n");
		ret = -EINVAL;
	}
	};
	return ret;
}
Пример #13
0
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;
	unsigned long ionflag;
	void *vaddr;
	if (mem->phyaddr != 0)
		return 0;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
	mem->ion_handle = ion_import_dma_buf(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, 0 , 0);
	if (rc < 0)
		ion_free(client, mem->ion_handle);

	rc = ion_handle_get_flags(client, mem->ion_handle, &ionflag);
	if (rc) {
		pr_err("%s: could not get flags for the handle\n", __func__);
		return 0;
	}
	D("ionflag=%ld\n", ionflag);
	vaddr = ion_map_kernel(client, mem->ion_handle);
	if (IS_ERR_OR_NULL(vaddr)) {
		pr_err("%s: could not get virtual address\n", __func__);
		return 0;
	}
	mem->arm_vaddr = vaddr;
	D("arm_vaddr=0x%lx\n", (unsigned long) mem->arm_vaddr);
#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;
}
Пример #14
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,
					int domain_num)
{
	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_dma_buf(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);
	}
#if !defined(CONFIG_MSM_IOMMU)
	rc = ion_phys(client, mem->ion_handle, (ion_phys_addr_t *)&mem->phyaddr,
			 (size_t *)&len);
#else
	rc = ion_map_iommu(client, mem->ion_handle, CAMERA_DOMAIN, GEN_POOL,
		SZ_4K, 0, (unsigned long *)&mem->phyaddr, &len, 0, 0);
	if (rc < 0)
		ion_free(client, mem->ion_handle);
#endif

#if !defined(CONFIG_MSM_IOMMU)
#if defined(CACHABLE_MEMORY)
	rc = ion_handle_get_flags(client, mem->ion_handle, &mem->ion_flags);
	mem->kernel_vaddr = ion_map_kernel(client,
		mem->ion_handle);
#endif
#endif

#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;
}
Пример #15
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);
	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;
	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_unmap_kernel(client, mem->ion_handle);
		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;
}
void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
{
	u32 alloc_size, offset = 0 ;
	u32 index = 0;
	struct ddl_context *ddl_context;
	struct msm_mapped_buffer *mapped_buffer = NULL;
	unsigned long iova = 0;
	unsigned long buffer_size = 0;
	unsigned long *kernel_vaddr = NULL;
	unsigned long ionflag = 0;
	unsigned long flags = 0;
	int ret = 0;
	DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz);
	if (!addr) {
		DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__);
		goto bail_out;
	}
	ddl_context = ddl_get_context();
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
	res_trk_set_mem_type(addr->mem_type);
#endif
	alloc_size = (sz + alignment);
	alloc_size = (alloc_size+4095) & ~4095;
	if (res_trk_get_enable_ion()) {
		if (!ddl_context->video_ion_client)
			ddl_context->video_ion_client =
				res_trk_get_ion_client();
		if (!ddl_context->video_ion_client) {
			DDL_MSG_ERROR("%s() :DDL ION Client Invalid handle\n",
						 __func__);
			goto bail_out;
		}
		addr->alloc_handle = ion_alloc(
		ddl_context->video_ion_client, alloc_size, SZ_4K,
			res_trk_get_mem_type());
		if (IS_ERR_OR_NULL(addr->alloc_handle)) {
			DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
						 __func__);
			goto bail_out;
		}
		if (res_trk_check_for_sec_session() ||
			addr->mem_type == DDL_FW_MEM)
			ionflag = UNCACHED;
		else
			ionflag = CACHED;
		kernel_vaddr = (unsigned long *) ion_map_kernel(
					ddl_context->video_ion_client,
					addr->alloc_handle, ionflag);
		if (!kernel_vaddr) {
				DDL_MSG_ERROR("%s() :DDL ION map failed\n",
							 __func__);
				goto free_acm_ion_alloc;
		}
		addr->virtual_base_addr = (u8 *) kernel_vaddr;
		if (ion_handle_get_flags(ddl_context->video_ion_client,
					addr->alloc_handle,
					&ionflag)) {
				DDL_MSG_ERROR("%s():DDL ION get flag failed\n",
							 __func__);
				goto free_acm_ion_alloc;
		}
		ret = ion_map_iommu(ddl_context->video_ion_client,
				addr->alloc_handle,
				VIDEO_DOMAIN,
				VIDEO_MAIN_POOL,
				SZ_4K,
				0,
				&iova,
				&buffer_size,
				UNCACHED, 0);
		if (ret) {
			DDL_MSG_ERROR("%s():DDL ION ion map iommu failed\n",
						 __func__);
			goto free_acm_ion_alloc;
		}
		addr->alloced_phys_addr = (phys_addr_t) iova;
		if (!addr->alloced_phys_addr) {
			DDL_MSG_ERROR("%s():DDL ION client physical failed\n",
						 __func__);
			goto free_acm_ion_alloc;
		}
		addr->mapped_buffer = 0;
		addr->physical_base_addr = (u8 *) iova;
		addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
			addr->physical_base_addr, alignment);
		offset = (u32)(addr->align_physical_addr -
				addr->physical_base_addr);
		addr->align_virtual_addr = addr->virtual_base_addr + offset;
		addr->buffer_size = alloc_size;
	} else {
		addr->alloced_phys_addr = (phys_addr_t)
		allocate_contiguous_memory_nomap(alloc_size,
			res_trk_get_mem_type(), SZ_4K);
		if (!addr->alloced_phys_addr) {
			DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n",
					 __func__, alloc_size);
			goto bail_out;
		}
		flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR;
		if (alignment == DDL_KILO_BYTE(128))
				index = 1;
		else if (alignment > SZ_4K)
			flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K;

		addr->mapped_buffer =
		msm_subsystem_map_buffer((unsigned long)addr->alloced_phys_addr,
			alloc_size, flags, &vidc_mmu_subsystem[index],
			sizeof(vidc_mmu_subsystem[index])/sizeof(unsigned int));
		if (IS_ERR(addr->mapped_buffer)) {
			pr_err(" %s() buffer map failed", __func__);
			goto free_acm_ion_alloc;
		}
		mapped_buffer = addr->mapped_buffer;
		if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
			pr_err("%s() map buffers failed\n", __func__);
			goto free_map_buffers;
		}
		addr->physical_base_addr = (u8 *)mapped_buffer->iova[0];
		addr->virtual_base_addr = mapped_buffer->vaddr;
		addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
			addr->physical_base_addr, alignment);
		offset = (u32)(addr->align_physical_addr -
				addr->physical_base_addr);
		addr->align_virtual_addr = addr->virtual_base_addr + offset;
		addr->buffer_size = sz;
	}
	return addr->virtual_base_addr;
free_map_buffers:
	msm_subsystem_unmap_buffer(addr->mapped_buffer);
	addr->mapped_buffer = NULL;
free_acm_ion_alloc:
	if (ddl_context->video_ion_client) {
		if (addr->alloc_handle) {
			if (addr->virtual_base_addr) {
				ion_unmap_kernel(ddl_context->video_ion_client,
					addr->alloc_handle);
				addr->virtual_base_addr = 0;
			}
			if (addr->alloced_phys_addr) {
				ion_unmap_iommu(ddl_context->video_ion_client,
						addr->alloc_handle,
						VIDEO_DOMAIN,
						VIDEO_MAIN_POOL);
				addr->alloced_phys_addr = 0;
			}
			ion_free(ddl_context->video_ion_client,
				addr->alloc_handle);
			addr->alloc_handle = NULL;
		}
	} else {
		free_contiguous_memory_by_paddr(
			(unsigned long)addr->alloced_phys_addr);
		addr->alloced_phys_addr = (phys_addr_t)NULL;
	}
bail_out:
	return NULL;
}