int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev,
		long clk_rate)
{
	int rc = 0;
	struct clk *jpeg_clk;

	jpeg_clk = clk_get(&pgmn_dev->pdev->dev, "core_clk");
	if (IS_ERR(jpeg_clk)) {
		JPEG_PR_ERR("%s get failed\n", "core_clk");
		rc = PTR_ERR(jpeg_clk);
		goto error;
	}

	clk_rate = clk_round_rate(jpeg_clk, clk_rate);
	if (clk_rate < 0) {
		JPEG_PR_ERR("%s:%d] round rate failed", __func__, __LINE__);
		rc = -EINVAL;
		goto error;
	}
	JPEG_DBG("%s:%d] jpeg clk rate %ld", __func__, __LINE__, clk_rate);

	rc = clk_set_rate(jpeg_clk, clk_rate);

error:
	return rc;
}
Esempio n. 2
0
int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, uint32_t m_cmds,
	uint32_t max_size, void *base)
{
	int is_copy_to_user = 0;
	uint32_t data;

	while (m_cmds--) {
		if (hw_cmd_p->offset >= max_size) {
			JPEG_PR_ERR("%s:%d] %d exceed hw region %d\n", __func__,
				__LINE__, hw_cmd_p->offset, max_size);
			return -EFAULT;
		}
		if (hw_cmd_p->offset & 0x3) {
			JPEG_PR_ERR("%s:%d] %d Invalid alignment\n", __func__,
					__LINE__, hw_cmd_p->offset);
			return -EFAULT;
		}

		switch (hw_cmd_p->type) {
		case MSM_JPEG_HW_CMD_TYPE_READ:
			hw_cmd_p->data = msm_jpeg_hw_read(hw_cmd_p, base);
			is_copy_to_user = 1;
			break;

		case MSM_JPEG_HW_CMD_TYPE_WRITE:
			msm_jpeg_hw_write(hw_cmd_p, base);
			break;

		case MSM_JPEG_HW_CMD_TYPE_WRITE_OR:
			data = msm_jpeg_hw_read(hw_cmd_p, base);
			hw_cmd_p->data = (hw_cmd_p->data & hw_cmd_p->mask) |
				data;
			msm_jpeg_hw_write(hw_cmd_p, base);
			break;

		case MSM_JPEG_HW_CMD_TYPE_UWAIT:
			msm_jpeg_hw_wait(hw_cmd_p, 1, base);
			break;

		case MSM_JPEG_HW_CMD_TYPE_MWAIT:
			msm_jpeg_hw_wait(hw_cmd_p, 1000, base);
			break;

		case MSM_JPEG_HW_CMD_TYPE_UDELAY:
			msm_jpeg_hw_delay(hw_cmd_p, 1);
			break;

		case MSM_JPEG_HW_CMD_TYPE_MDELAY:
			msm_jpeg_hw_delay(hw_cmd_p, 1000);
			break;

		default:
			JPEG_PR_ERR("wrong hw command type\n");
			break;
		}

		hw_cmd_p++;
	}
	return is_copy_to_user;
}
uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
	uint32_t len, int iommu_hdl)
{
	dma_addr_t paddr;
	size_t size;
	int rc;

	rc = cam_smmu_get_phy_addr(pgmn_dev->iommu_hdl, fd, CAM_SMMU_MAP_RW,
			&paddr, &size);
	JPEG_DBG("%s:%d] addr 0x%x size %zu", __func__, __LINE__,
		(uint32_t)paddr, size);

	if (rc < 0) {
		JPEG_PR_ERR("%s: fd %d got phy addr error %d\n", __func__, fd,
			rc);
		goto err_get_phy;
	}

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

	return paddr;
err_size:
	cam_smmu_put_phy_addr(pgmn_dev->iommu_hdl, fd);
err_get_phy:
	return 0;
}
Esempio n. 4
0
void msm_jpeg_io_dump(int size)
{
	char line_str[128], *p_str;
	void __iomem *addr = jpeg_region_base;
	int i;
	u32 *p = (u32 *) addr;
	u32 data;
	JPEG_PR_ERR("%s: %p %d reg_size %d\n", __func__, addr, size,
							jpeg_region_size);
	line_str[0] = '\0';
	p_str = line_str;
	for (i = 0; i < size/4; i++) {
		if (i % 4 == 0) {
			snprintf(p_str, 12, "%08x: ", (u32) p);
			p_str += 10;
		}
		data = readl_relaxed(p++);
		snprintf(p_str, 12, "%08x ", data);
		p_str += 9;
		if ((i + 1) % 4 == 0) {
			JPEG_PR_ERR("%s\n", line_str);
			line_str[0] = '\0';
			p_str = line_str;
		}
	}
	if (line_str[0] != '\0')
		JPEG_PR_ERR("%s\n", line_str);
}
Esempio n. 5
0
uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
	uint32_t len, struct file **file_p, struct ion_handle **ionhandle,
	int domain_num) {
	unsigned long paddr;
	unsigned long size;
	int rc;
	*ionhandle = ion_import_dma_buf(pgmn_dev->jpeg_client, fd);
	if (IS_ERR_OR_NULL(*ionhandle))
		return 0;

	rc = ion_map_iommu(pgmn_dev->jpeg_client, *ionhandle, domain_num, 0,
		SZ_4K, 0, &paddr, (unsigned long *)&size, 0, 0);
	JPEG_DBG("%s:%d] addr 0x%x size %ld", __func__, __LINE__,
		(uint32_t)paddr, size);

	if (rc < 0) {
		JPEG_PR_ERR("%s: ion_map_iommu fd %d error %d\n", __func__, fd,
			rc);
		goto error1;
	}

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

	return paddr;
error1:
	ion_free(pgmn_dev->jpeg_client, *ionhandle);
	return 0;
}
/*
 * msm_jpeg_set_init_dt_parms() - get device tree config and write to registers.
 * @pgmn_dev: Pointer to jpeg device.
 * @dt_prop_name: Device tree property name.
 * @base: Base address.
 *
 * This function reads register offsets and values from dtsi based on
 * device tree property name and writes to jpeg registers.
 *
 * Return: 0 on success and negative error on failure.
 */
static int32_t msm_jpeg_set_init_dt_parms(struct msm_jpeg_device *pgmn_dev,
	const char *dt_prop_name,
	void *base)
{
	struct device_node *of_node;
	int32_t i = 0 , rc = 0;
	uint32_t *dt_reg_settings = NULL;
	uint32_t dt_count = 0;

	of_node = pgmn_dev->pdev->dev.of_node;
	JPEG_DBG("%s:%d E\n", __func__, __LINE__);

	if (!of_get_property(of_node, dt_prop_name,
				&dt_count)) {
		JPEG_DBG("%s: Error property does not exist\n",
				__func__);
		return -ENOENT;
	}
	if (dt_count % 8) {
		JPEG_PR_ERR("%s: Error invalid entries\n",
				__func__);
		return -EINVAL;
	}
	dt_count /= 4;
	if (dt_count != 0) {
		dt_reg_settings = kcalloc(dt_count, sizeof(uint32_t),
			GFP_KERNEL);
		if (!dt_reg_settings) {
			JPEG_PR_ERR("%s:%d No memory\n",
				__func__, __LINE__);
			return -ENOMEM;
		}
		rc = of_property_read_u32_array(of_node,
				dt_prop_name,
				dt_reg_settings,
				dt_count);
		if (rc < 0) {
			JPEG_PR_ERR("%s: No reg info\n",
				__func__);
			kfree(dt_reg_settings);
			return -EINVAL;
		}
		for (i = 0; i < dt_count; i = i + 2) {
			JPEG_DBG("%s:%d] %p %08x\n",
					__func__, __LINE__,
					base + dt_reg_settings[i],
					dt_reg_settings[i + 1]);
			msm_camera_io_w(dt_reg_settings[i + 1],
					base + dt_reg_settings[i]);
		}
		kfree(dt_reg_settings);
	}
	return 0;
}
static int msm_jpeg_release(struct inode *inode, struct file *filp)
{
	int rc;

	struct msm_jpeg_device *pgmn_dev = filp->private_data;

	JPEG_PR_ERR("%s:%d]\n", __func__, __LINE__);

	rc = __msm_jpeg_release(pgmn_dev);

	JPEG_PR_ERR("%s:%d] %s open_count = %d\n", __func__, __LINE__,
		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);
	return rc;
}
Esempio n. 8
0
int msm_jpeg_hw_pingpong_update(struct msm_jpeg_hw_pingpong *pingpong_hw,
	struct msm_jpeg_hw_buf *buf, void *base)
{
	int buf_free_index = -1;

	if (!pingpong_hw->buf_status[0]) {
		buf_free_index = 0;
	} else if (!pingpong_hw->buf_status[1]) {
		buf_free_index = 1;
	} else {
		JPEG_PR_ERR("%s:%d: pingpong buffer busy\n",
		__func__, __LINE__);
		return -EBUSY;
	}

	pingpong_hw->buf[buf_free_index] = *buf;
	pingpong_hw->buf_status[buf_free_index] = 1;

	if (pingpong_hw->is_fe) {
		/* it is fe */
		msm_jpeg_hw_fe_buffer_update(
			&pingpong_hw->buf[buf_free_index], buf_free_index,
			base);
	} else {
		/* it is we */
		msm_jpeg_hw_we_buffer_update(
			&pingpong_hw->buf[buf_free_index], buf_free_index,
			base);
	}
	return 0;
}
static int msm_jpeg_open(struct inode *inode, struct file *filp)
{
	int rc = 0;

	struct msm_jpeg_device *pgmn_dev = container_of(inode->i_cdev,
		struct msm_jpeg_device, cdev);
	filp->private_data = pgmn_dev;

	JPEG_PR_ERR("%s:%d]\n", __func__, __LINE__);

	rc = __msm_jpeg_open(pgmn_dev);

	JPEG_PR_ERR("%s:%d] %s open_count = %d\n", __func__, __LINE__,
		filp->f_path.dentry->d_name.name, pgmn_dev->open_count);

	return rc;
}
static int msm_jpeg_attach_iommu(struct msm_jpeg_device *pgmn_dev)
{
	int rc;
	rc = cam_smmu_ops(pgmn_dev->iommu_hdl, CAM_SMMU_ATTACH);
	if (rc < 0) {
		JPEG_PR_ERR("%s: Device attach failed\n", __func__);
		return -ENODEV;
	}
	JPEG_DBG("%s:%d] handle %d attach\n",
			__func__, __LINE__, pgmn_dev->iommu_hdl);
	return 0;
}
void msm_jpeg_hw_we_buffer_update(struct msm_jpeg_hw_buf *p_input,
	uint8_t pingpong_index, void *base)
{
	struct msm_jpeg_hw_cmd *hw_cmd_p;

	if (pingpong_index == 0) {
		hw_cmd_p = &hw_cmd_we_ping_update[0];
		hw_cmd_p->data = p_input->y_buffer_addr;
		JPEG_PR_ERR("%s Output pln0 buffer address is %x\n", __func__,
			p_input->y_buffer_addr);
		msm_jpeg_hw_write(hw_cmd_p++, base);
		hw_cmd_p->data = p_input->cbcr_buffer_addr;
		JPEG_PR_ERR("%s Output pln1 buffer address is %x\n", __func__,
			p_input->cbcr_buffer_addr);
		msm_jpeg_hw_write(hw_cmd_p++, base);
		hw_cmd_p->data = p_input->pln2_addr;
		JPEG_PR_ERR("%s Output pln2 buffer address is %x\n", __func__,
			p_input->pln2_addr);
		msm_jpeg_hw_write(hw_cmd_p++, base);
	}
	return;
}
static int msm_jpeg_attach_iommu(struct msm_jpeg_device *pgmn_dev)
{
	int i;

	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
		int rc = iommu_attach_device(pgmn_dev->domain,
				pgmn_dev->iommu_ctx_arr[i]);
		if (rc < 0) {
			JPEG_PR_ERR("%s: Device attach failed\n", __func__);
			return -ENODEV;
		}
		JPEG_DBG("%s:%d] dom 0x%lx ctx 0x%lx", __func__, __LINE__,
				(unsigned long)pgmn_dev->domain,
				(unsigned long)pgmn_dev->iommu_ctx_arr[i]);
	}
	return 0;
}
int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev,
		long clk_rate)
{
	int rc = 0;
	struct clk *jpeg_clk;

	jpeg_clk = clk_get(&pgmn_dev->pdev->dev, "core_clk");
	if (IS_ERR(jpeg_clk)) {
		JPEG_PR_ERR("%s get failed\n", "core_clk");
		rc = PTR_ERR(jpeg_clk);
		return rc;
	}

	rc = clk_set_rate(jpeg_clk, clk_rate);

	return rc;
}
Esempio n. 14
0
int msm_jpeg_platform_release(struct resource *mem, void *base, int irq,
	void *context)
{
	int result = 0;
	int i = 0;
	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *) context;

	free_irq(irq, context);

#ifdef CONFIG_MSM_IOMMU
	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
		iommu_detach_device(pgmn_dev->domain,
				pgmn_dev->iommu_ctx_arr[i]);
		JPEG_DBG("%s:%d]", __func__, __LINE__);
	}
#endif
	if (pgmn_dev->jpeg_bus_client) {
		msm_bus_scale_client_update_request(
			pgmn_dev->jpeg_bus_client, 0);
		msm_bus_scale_unregister_client(pgmn_dev->jpeg_bus_client);
	}

	msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
	pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 0);
	JPEG_DBG("%s:%d] clock disbale done", __func__, __LINE__);

	if (pgmn_dev->jpeg_fs) {
		result = regulator_disable(pgmn_dev->jpeg_fs);
		if (!result)
			regulator_put(pgmn_dev->jpeg_fs);
		else
			JPEG_PR_ERR("%s:%d] regulator disable failed %d",
				__func__, __LINE__, result);
		pgmn_dev->jpeg_fs = NULL;
	}
	iounmap(pgmn_dev->jpeg_vbif);
	iounmap(base);
	release_mem_region(mem->start, resource_size(mem));
	ion_client_destroy(pgmn_dev->jpeg_client);
	pgmn_dev->state = MSM_JPEG_IDLE;
	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
	return result;
}
int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev,
		long clk_rate)
{
	int rc = 0;
	uint32_t msm_jpeg_idx;

	/* retrieve clock index from list of clocks */
	msm_jpeg_idx = msm_jpeg_get_clock_index(pgmn_dev,
		"core_clk");
	if (msm_jpeg_idx < 0)  {
		JPEG_PR_ERR("%s:Fail to get clock index\n", __func__);
		return -EINVAL;
	}

	/* set the rate */
	msm_camera_clk_set_rate(&pgmn_dev->pdev->dev,
		pgmn_dev->jpeg_clk[msm_jpeg_idx], clk_rate);

	return rc;
}
int msm_jpeg_platform_release(struct resource *mem, void *base, int irq,
	void *context)
{
	int result = 0;

	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *) context;

	free_irq(irq, context);

	msm_jpeg_detach_iommu(pgmn_dev);

	if (pgmn_dev->jpeg_bus_client) {
		msm_bus_scale_client_update_request(
			pgmn_dev->jpeg_bus_client, 0);
		msm_bus_scale_unregister_client(pgmn_dev->jpeg_bus_client);
	}

	msm_cam_clk_enable(&pgmn_dev->pdev->dev, pgmn_dev->jpeg_clk_info,
	pgmn_dev->jpeg_clk, pgmn_dev->num_clk, 0);
	JPEG_DBG("%s:%d] clock disbale done", __func__, __LINE__);

	if (pgmn_dev->jpeg_fs) {
		result = regulator_disable(pgmn_dev->jpeg_fs);
		if (!result)
			regulator_put(pgmn_dev->jpeg_fs);
		else
			JPEG_PR_ERR("%s:%d] regulator disable failed %d",
				__func__, __LINE__, result);
		pgmn_dev->jpeg_fs = NULL;
	}
	iounmap(pgmn_dev->jpeg_vbif);
	iounmap(base);
	release_mem_region(mem->start, resource_size(mem));
	ion_client_destroy(pgmn_dev->jpeg_client);
	pgmn_dev->state = MSM_JPEG_IDLE;
	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);
	return result;
}
/*
 * msm_jpeg_platform_set_dt_config() - set jpeg device tree configuration.
 * @pgmn_dev: Pointer to jpeg device.
 *
 * This function holds an array of device tree property names and calls
 * msm_jpeg_set_init_dt_parms() for each property.
 *
 * Return: 0 on success and negative error on failure.
 */
int msm_jpeg_platform_set_dt_config(struct msm_jpeg_device *pgmn_dev)
{
	int rc = 0;
	uint8_t dt_prop_cnt = JPEG_DT_PROP_CNT;
	char *dt_prop_name[JPEG_DT_PROP_CNT] = {"qcom,qos-reg-settings",
		"qcom,prefetch-reg-settings"};

	while (dt_prop_cnt) {
		dt_prop_cnt--;
		rc = msm_jpeg_set_init_dt_parms(pgmn_dev,
			dt_prop_name[dt_prop_cnt],
			pgmn_dev->base);
		if (rc == -ENOENT) {
			JPEG_DBG("%s: No %s property\n", __func__,
				dt_prop_name[dt_prop_cnt]);
		} else if (rc < 0) {
			JPEG_PR_ERR("%s: %s params set fail\n", __func__,
				dt_prop_name[dt_prop_cnt]);
			return rc;
		}
	}
	return rc;
}
int msm_jpeg_platform_init(irqreturn_t (*handler)(int, void *),
	void *context)
{
	int rc = -1;
	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *) context;
	struct platform_device *pdev = pgmn_dev->pdev;

	pgmn_dev->state = MSM_JPEG_IDLE;

	/* enable all regulators */
	rc = msm_camera_regulator_enable(pgmn_dev->jpeg_vdd,
		pgmn_dev->num_reg, true);
	if (rc < 0) {
		JPEG_PR_ERR("%s: failed to enable regulators\n", __func__);
		goto err_reg_enable;
	}

	/* enable all clocks */
	rc = msm_camera_clk_enable(&pgmn_dev->pdev->dev,
			pgmn_dev->jpeg_clk_info, pgmn_dev->jpeg_clk,
			pgmn_dev->num_clk, true);
	if (rc < 0) {
		JPEG_PR_ERR("%s: clk enable failed\n", __func__);
		goto err_clk_enable;
	}

	/* attach the smmu context banks */
	rc = msm_jpeg_attach_iommu(pgmn_dev);
	if (rc < 0) {
		JPEG_PR_ERR("%s: iommu attach failed\n", __func__);
		goto err_fail_iommu;
	}
	rc = msm_jpeg_set_init_dt_parms(pgmn_dev, "qcom,vbif-reg-settings",
		pgmn_dev->vbif_base);
	if (rc == -ENOENT) {
		JPEG_DBG("%s: No qcom,vbif-reg-settings property\n", __func__);
		set_vbif_params(pgmn_dev, pgmn_dev->vbif_base);
	} else if (rc < 0) {
		JPEG_PR_ERR("%s: vbif params set fail\n", __func__);
		goto err_fail_set_vbif;
	}

	/* register the interrupt handler */
	rc = msm_camera_register_irq(pgmn_dev->pdev,
		pgmn_dev->jpeg_irq_res, handler, IRQF_TRIGGER_RISING,
		"jpeg", context);
	if (rc < 0) {
		JPEG_PR_ERR("%s: irq request fail\n", __func__);
		goto err_reg_irq_fail;
	}

	pgmn_dev->hw_version = msm_camera_io_r(pgmn_dev->base +
		JPEG_HW_VERSION);
	JPEG_DBG_HIGH("%s:%d] jpeg HW version 0x%x", __func__, __LINE__,
		pgmn_dev->hw_version);
	pgmn_dev->state = MSM_JPEG_INIT;

	return 0;
err_reg_irq_fail:
err_fail_set_vbif:
	msm_jpeg_detach_iommu(pgmn_dev);
err_fail_iommu:
	msm_camera_clk_enable(&pdev->dev, pgmn_dev->jpeg_clk_info,
		pgmn_dev->jpeg_clk, pgmn_dev->num_clk, false);
err_clk_enable:
	msm_camera_regulator_enable(pgmn_dev->jpeg_vdd,
		pgmn_dev->num_reg, false);
err_reg_enable:
	return rc;
}
Esempio n. 19
0
int msm_jpeg_platform_init(struct platform_device *pdev,
	struct resource **mem,
	void **base,
	int *irq,
	irqreturn_t (*handler) (int, void *),
	void *context)
{
	int rc = -1;
	int i = 0;
	int jpeg_irq;
	struct resource *jpeg_mem, *jpeg_io, *jpeg_irq_res;
	void *jpeg_base;
	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *) context;

	pgmn_dev->state = MSM_JPEG_IDLE;

	jpeg_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!jpeg_mem) {
		JPEG_PR_ERR("%s: no mem resource?\n", __func__);
		return -ENODEV;
	}

	jpeg_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!jpeg_irq_res) {
		JPEG_PR_ERR("no irq resource?\n");
		return -ENODEV;
	}
	jpeg_irq = jpeg_irq_res->start;
	JPEG_DBG("%s base address: 0x%x, jpeg irq number: %d\n", __func__,
		jpeg_mem->start, jpeg_irq);

	pgmn_dev->jpeg_bus_client =
		msm_bus_scale_register_client(&msm_jpeg_bus_client_pdata);
	if (!pgmn_dev->jpeg_bus_client) {
		JPEG_PR_ERR("%s: Registration Failed!\n", __func__);
		pgmn_dev->jpeg_bus_client = 0;
		return -EINVAL;
	}
	msm_bus_scale_client_update_request(
		pgmn_dev->jpeg_bus_client, 1);

	jpeg_io = request_mem_region(jpeg_mem->start,
		resource_size(jpeg_mem), pdev->name);
	if (!jpeg_io) {
		JPEG_PR_ERR("%s: region already claimed\n", __func__);
		return -EBUSY;
	}

	jpeg_base = ioremap(jpeg_mem->start, resource_size(jpeg_mem));
	if (!jpeg_base) {
		rc = -ENOMEM;
		JPEG_PR_ERR("%s: ioremap failed\n", __func__);
		goto fail_remap;
	}

	pgmn_dev->jpeg_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd");
	rc = regulator_enable(pgmn_dev->jpeg_fs);
	if (rc) {
		JPEG_PR_ERR("%s:%d]jpeg regulator get failed\n",
				__func__, __LINE__);
		goto fail_fs;
	}

	rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
	 pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 1);
	if (rc < 0) {
		JPEG_PR_ERR("%s: clk failed rc = %d\n", __func__, rc);
		goto fail_clk;
	}

	pgmn_dev->hw_version = readl_relaxed(jpeg_base +
		JPEG_HW_VERSION);
	JPEG_DBG_HIGH("%s:%d] jpeg HW version 0x%x", __func__, __LINE__,
		pgmn_dev->hw_version);

	pgmn_dev->jpeg_vbif = ioremap(VBIF_BASE_ADDRESS, VBIF_REGION_SIZE);
	if (!pgmn_dev->jpeg_vbif) {
		rc = -ENOMEM;
		JPEG_PR_ERR("%s:%d] ioremap failed\n", __func__, __LINE__);
		goto fail_vbif;
	}
	JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__,
		(uint32_t)pgmn_dev->jpeg_vbif);

#ifdef CONFIG_MSM_IOMMU
	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
		rc = iommu_attach_device(pgmn_dev->domain,
				pgmn_dev->iommu_ctx_arr[i]);
		if (rc < 0) {
			rc = -ENODEV;
			JPEG_PR_ERR("%s: Device attach failed\n", __func__);
			goto fail_iommu;
		}
		JPEG_DBG("%s:%d] dom 0x%x ctx 0x%x", __func__, __LINE__,
					(uint32_t)pgmn_dev->domain,
					(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
	}
#endif
	set_vbif_params(pgmn_dev, pgmn_dev->jpeg_vbif);

#ifdef CONFIG_MACH_LGE
	*mem  = jpeg_mem;
	*base = jpeg_base;
#endif

	rc = request_irq(jpeg_irq, handler, IRQF_TRIGGER_RISING, "jpeg",
		context);
	if (rc) {
		JPEG_PR_ERR("%s: request_irq failed, %d\n", __func__,
			jpeg_irq);
		goto fail_request_irq;
	}

#ifndef CONFIG_MACH_LGE /* QCT origin */
	*mem  = jpeg_mem;
	*base = jpeg_base;
#endif
	*irq  = jpeg_irq;

	pgmn_dev->jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);

	pgmn_dev->state = MSM_JPEG_INIT;
	return rc;

fail_request_irq:
#ifdef CONFIG_MACH_LGE
	*mem  = NULL;
	*base = NULL;
#endif

#ifdef CONFIG_MSM_IOMMU
	for (i = 0; i < pgmn_dev->iommu_cnt; i++) {
		JPEG_PR_ERR("%s:%d] dom 0x%x ctx 0x%x", __func__, __LINE__,
					(uint32_t)pgmn_dev->domain,
					(uint32_t)pgmn_dev->iommu_ctx_arr[i]);
		iommu_detach_device(pgmn_dev->domain,
					pgmn_dev->iommu_ctx_arr[i]);
	}
#endif

fail_iommu:
	iounmap(pgmn_dev->jpeg_vbif);

fail_vbif:
	msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
	pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_8x_clk_info), 0);

fail_clk:
	rc = regulator_disable(pgmn_dev->jpeg_fs);
	if (!rc)
		regulator_put(pgmn_dev->jpeg_fs);
	else
		JPEG_PR_ERR("%s:%d] regulator disable failed %d",
			__func__, __LINE__, rc);
	pgmn_dev->jpeg_fs = NULL;

fail_fs:
	iounmap(jpeg_base);

fail_remap:
	release_mem_region(jpeg_mem->start, resource_size(jpeg_mem));
	JPEG_DBG("%s:%d] fail\n", __func__, __LINE__);
	return rc;
}
Esempio n. 20
0
static int msm_jpeg_init_dev(struct platform_device *pdev)
{
	int rc = -1;
	struct device *dev;
	struct msm_jpeg_device *msm_jpeg_device_p;
	char devname[10];

	msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC);
	if (!msm_jpeg_device_p) {
		JPEG_PR_ERR("%s: no mem\n", __func__);
		return -EFAULT;
	}

	msm_jpeg_device_p->pdev = pdev;

	if (pdev->dev.of_node)
		of_property_read_u32((&pdev->dev)->of_node, "cell-index",
								&pdev->id);

	snprintf(devname, sizeof(devname), "%s%d", MSM_JPEG_NAME, pdev->id);

	rc = __msm_jpeg_init(msm_jpeg_device_p);
	if (rc < -1) {
		JPEG_PR_ERR("%s: initialization failed\n", __func__);
		goto fail;
	}

	v4l2_subdev_init(&msm_jpeg_device_p->subdev, &msm_jpeg_subdev_ops);
	v4l2_set_subdev_hostdata(&msm_jpeg_device_p->subdev, msm_jpeg_device_p);
	JPEG_DBG("%s: msm_jpeg_device_p 0x%x", __func__,
			(uint32_t)msm_jpeg_device_p);

	rc = alloc_chrdev_region(&msm_jpeg_device_p->msm_jpeg_devno, 0, 1,
				devname);
	if (rc < 0) {
		JPEG_PR_ERR("%s: failed to allocate chrdev\n", __func__);
		goto fail_1;
	}

	if (!msm_jpeg_device_p->msm_jpeg_class) {
		msm_jpeg_device_p->msm_jpeg_class =
				class_create(THIS_MODULE, devname);
		if (IS_ERR(msm_jpeg_device_p->msm_jpeg_class)) {
			rc = PTR_ERR(msm_jpeg_device_p->msm_jpeg_class);
			JPEG_PR_ERR("%s: create device class failed\n",
				__func__);
			goto fail_2;
		}
	}

	dev = device_create(msm_jpeg_device_p->msm_jpeg_class, NULL,
		MKDEV(MAJOR(msm_jpeg_device_p->msm_jpeg_devno),
		MINOR(msm_jpeg_device_p->msm_jpeg_devno)), NULL,
		"%s%d", MSM_JPEG_NAME, pdev->id);
	if (IS_ERR(dev)) {
		JPEG_PR_ERR("%s: error creating device\n", __func__);
		rc = -ENODEV;
		goto fail_3;
	}

	cdev_init(&msm_jpeg_device_p->cdev, &msm_jpeg_fops);
	msm_jpeg_device_p->cdev.owner = THIS_MODULE;
	msm_jpeg_device_p->cdev.ops	 =
		(const struct file_operations *) &msm_jpeg_fops;
	rc = cdev_add(&msm_jpeg_device_p->cdev,
			msm_jpeg_device_p->msm_jpeg_devno, 1);
	if (rc < 0) {
		JPEG_PR_ERR("%s: error adding cdev\n", __func__);
		rc = -ENODEV;
		goto fail_4;
	}

	platform_set_drvdata(pdev, &msm_jpeg_device_p);

	JPEG_DBG("%s %s%d: success\n", __func__, MSM_JPEG_NAME, pdev->id);

	return rc;

fail_4:
	device_destroy(msm_jpeg_device_p->msm_jpeg_class,
			msm_jpeg_device_p->msm_jpeg_devno);

fail_3:
	class_destroy(msm_jpeg_device_p->msm_jpeg_class);

fail_2:
	unregister_chrdev_region(msm_jpeg_device_p->msm_jpeg_devno, 1);

fail_1:
	__msm_jpeg_exit(msm_jpeg_device_p);

fail:
	kfree(msm_jpeg_device_p);
	return rc;

}
int msm_jpeg_platform_init(struct platform_device *pdev,
	struct resource **mem,
	void **base,
	int *irq,
	irqreturn_t (*handler) (int, void *),
	void *context)
{
	int rc = -1;
	int jpeg_irq;
	struct resource *jpeg_mem, *vbif_mem, *jpeg_io, *jpeg_irq_res;
	void *jpeg_base;
	struct msm_jpeg_device *pgmn_dev =
		(struct msm_jpeg_device *) context;

	pgmn_dev->state = MSM_JPEG_IDLE;

	jpeg_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!jpeg_mem) {
		JPEG_PR_ERR("%s: jpeg no mem resource?\n", __func__);
		return -ENODEV;
	}

	vbif_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!vbif_mem) {
		JPEG_PR_ERR("%s: vbif no mem resource?\n", __func__);
		return -ENODEV;
	}

	jpeg_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!jpeg_irq_res) {
		JPEG_PR_ERR("no irq resource?\n");
		return -ENODEV;
	}
	jpeg_irq = jpeg_irq_res->start;
	JPEG_DBG("%s base address: 0x%x, jpeg irq number: %d\n", __func__,
		jpeg_mem->start, jpeg_irq);

	pgmn_dev->jpeg_bus_client =
		msm_bus_scale_register_client(&msm_jpeg_bus_client_pdata);
	if (!pgmn_dev->jpeg_bus_client) {
		JPEG_PR_ERR("%s: Registration Failed!\n", __func__);
		pgmn_dev->jpeg_bus_client = 0;
		return -EINVAL;
	}
	msm_bus_scale_client_update_request(
		pgmn_dev->jpeg_bus_client, 1);

	jpeg_io = request_mem_region(jpeg_mem->start,
		resource_size(jpeg_mem), pdev->name);
	if (!jpeg_io) {
		JPEG_PR_ERR("%s: region already claimed\n", __func__);
		return -EBUSY;
	}

	jpeg_base = ioremap(jpeg_mem->start, resource_size(jpeg_mem));
	if (!jpeg_base) {
		rc = -ENOMEM;
		JPEG_PR_ERR("%s: ioremap failed\n", __func__);
		goto fail_remap;
	}

	pgmn_dev->jpeg_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd");
	rc = regulator_enable(pgmn_dev->jpeg_fs);
	if (rc) {
		JPEG_PR_ERR("%s:%d]jpeg regulator get failed\n",
				__func__, __LINE__);
		goto fail_fs;
	}

	if (msm_jpeg_get_clk_info(pgmn_dev, pgmn_dev->pdev) < 0) {
		JPEG_PR_ERR("%s:%d]jpeg clock get failed\n",
				__func__, __LINE__);
		goto fail_fs;
	}

	rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
	 pgmn_dev->jpeg_clk, pgmn_dev->num_clk, 1);
	if (rc < 0) {
		JPEG_PR_ERR("%s: clk failed rc = %d\n", __func__, rc);
		goto fail_clk;
	}

	pgmn_dev->hw_version = readl_relaxed(jpeg_base +
		JPEG_HW_VERSION);
	JPEG_DBG_HIGH("%s:%d] jpeg HW version 0x%x", __func__, __LINE__,
		pgmn_dev->hw_version);

	pgmn_dev->jpeg_vbif = ioremap(vbif_mem->start, resource_size(vbif_mem));
	if (!pgmn_dev->jpeg_vbif) {
		rc = -ENOMEM;
		JPEG_PR_ERR("%s: ioremap failed\n", __func__);
		goto fail_vbif;
	}

	JPEG_DBG("%s:%d] jpeg_vbif 0x%x", __func__, __LINE__,
		(uint32_t)pgmn_dev->jpeg_vbif);

	rc = msm_jpeg_attach_iommu(pgmn_dev);
	if (rc < 0)
		goto fail_iommu;

	set_vbif_params(pgmn_dev, pgmn_dev->jpeg_vbif);

	if (pgmn_dev->hw_version == JPEG_8939) {
		writel_relaxed(0x0000550e,
				jpeg_base + JPEG_FE_QOS_CFG);
		writel_relaxed(0x00005555,
				jpeg_base + JPEG_WE_QOS_CFG);
	}

	rc = request_irq(jpeg_irq, handler, IRQF_TRIGGER_RISING, "jpeg",
		context);
	if (rc) {
		JPEG_PR_ERR("%s: request_irq failed, %d\n", __func__,
			jpeg_irq);
		goto fail_request_irq;
	}

	*mem  = jpeg_mem;
	*base = jpeg_base;
	*irq  = jpeg_irq;

	pgmn_dev->jpeg_client = msm_ion_client_create(-1, "camera/jpeg");
	JPEG_DBG("%s:%d] success\n", __func__, __LINE__);

	pgmn_dev->state = MSM_JPEG_INIT;
	return rc;

fail_request_irq:
	msm_jpeg_detach_iommu(pgmn_dev);

fail_iommu:
	iounmap(pgmn_dev->jpeg_vbif);


fail_vbif:
	msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_8x_clk_info,
	pgmn_dev->jpeg_clk, pgmn_dev->num_clk, 0);

fail_clk:
	rc = regulator_disable(pgmn_dev->jpeg_fs);
	if (!rc)
		regulator_put(pgmn_dev->jpeg_fs);
	else
		JPEG_PR_ERR("%s:%d] regulator disable failed %d",
			__func__, __LINE__, rc);
	pgmn_dev->jpeg_fs = NULL;

fail_fs:
	iounmap(jpeg_base);

fail_remap:
	release_mem_region(jpeg_mem->start, resource_size(jpeg_mem));
	JPEG_DBG("%s:%d] fail\n", __func__, __LINE__);
	return rc;
}
int msm_jpeg_platform_setup(struct msm_jpeg_device *pgmn_dev)
{
	int rc = -1;
	struct resource *jpeg_irq_res;
	void *jpeg_base, *vbif_base;
	struct platform_device *pdev = pgmn_dev->pdev;

	/* get the jpeg hardware device address */
	jpeg_base = msm_camera_get_reg_base(pdev, "jpeg_hw", true);
	if (!jpeg_base) {
		JPEG_PR_ERR("%s: jpeg no mem resource?\n", __func__);
		rc = -ENXIO;
		goto out;
	}

	/* get the jpeg vbif device address */
	vbif_base = msm_camera_get_reg_base(pdev, "jpeg_vbif", false);
	if (!vbif_base) {
		JPEG_PR_ERR("%s: vbif no mem resource?\n", __func__);
		rc = -ENXIO;
		goto err_vbif_base;
	}

	/* get the irq resource for the jpeg hardware */
	jpeg_irq_res = msm_camera_get_irq(pdev, "jpeg");
	if (!jpeg_irq_res) {
		JPEG_PR_ERR("%s: no irq resource?\n", __func__);
		rc = -ENXIO;
		goto err_jpeg_irq_res;
	}

	/* get all the clocks information */
	rc = msm_camera_get_clk_info(pdev, &pgmn_dev->jpeg_clk_info,
		&pgmn_dev->jpeg_clk, &pgmn_dev->num_clk);
	if (rc < 0) {
		JPEG_PR_ERR("%s: failed to get the clocks\n", __func__);
		rc = -ENXIO;
		goto err_jpeg_clk;
	}

	/* get all the regulators information */
	rc = msm_camera_get_regulator_info(pdev, &pgmn_dev->jpeg_vdd,
		&pgmn_dev->num_reg);
	if (rc < 0) {
		JPEG_PR_ERR("%s: failed to get the regulators\n", __func__);
		rc = -ENXIO;
		goto err_jpeg_get_reg;
	}

	/* map the dtsi cell id to bus client id */
	switch (pgmn_dev->pdev->id) {
	case 0:
		pgmn_dev->bus_client = CAM_BUS_CLIENT_JPEG_ENC0;
		break;
	case 1:
		pgmn_dev->bus_client = CAM_BUS_CLIENT_JPEG_ENC1;
		break;
	case 2:
		pgmn_dev->bus_client = CAM_BUS_CLIENT_JPEG_DEC;
		break;
	case 3:
		pgmn_dev->bus_client = CAM_BUS_CLIENT_JPEG_DMA;
		break;
	default:
		JPEG_PR_ERR("%s: invalid cell id :%d\n",
			__func__, pgmn_dev->pdev->id);
		goto err_jpeg_get_reg;
	}

	/* register the bus client */
	rc = msm_camera_register_bus_client(pgmn_dev->pdev,
			pgmn_dev->bus_client);
	if (rc < 0) {
		JPEG_PR_ERR("Fail to register bus client\n");
		rc = -EINVAL;
		goto err_reg_bus;
	}

	/* get the resource size of jpeg hardware */
	pgmn_dev->res_size = msm_camera_get_res_size(pdev, "jpeg_hw");
	if (!pgmn_dev->res_size) {
		JPEG_PR_ERR("Fail to resource size\n");
		rc = -EINVAL;
		goto err_res_size;
	}

	pgmn_dev->base = jpeg_base;
	pgmn_dev->vbif_base = vbif_base;
	pgmn_dev->jpeg_irq_res = jpeg_irq_res;

	return 0;

err_res_size:
	msm_camera_unregister_bus_client(pgmn_dev->bus_client);
err_reg_bus:
	msm_camera_put_regulators(pdev, &pgmn_dev->jpeg_vdd,
		pgmn_dev->num_reg);
err_jpeg_get_reg:
	msm_camera_put_clk_info(pdev, &pgmn_dev->jpeg_clk_info,
		&pgmn_dev->jpeg_clk, pgmn_dev->num_clk);
err_jpeg_clk:
err_jpeg_irq_res:
	msm_camera_put_reg_base(pdev, vbif_base, "jpeg_vbif", false);
err_vbif_base:
	msm_camera_put_reg_base(pdev, jpeg_base, "jpeg_hw", true);
out:
	return rc;
}