Ejemplo n.º 1
0
int msm_gemini_core_reset(uint8_t op_mode, void *base, int size)
{
	unsigned long flags;
	int rc = 0;
	int tm = 500; /*500ms*/
	memset(&fe_pingpong_buf, 0, sizeof(fe_pingpong_buf));
	fe_pingpong_buf.is_fe = 1;
	we_pingpong_index = 0;
	memset(&we_pingpong_buf, 0, sizeof(we_pingpong_buf));
	spin_lock_irqsave(&reset_lock, flags);
	reset_done_ack = 0;
	msm_gemini_hw_reset(base, size);
	spin_unlock_irqrestore(&reset_lock, flags);
	rc = wait_event_interruptible_timeout(
			reset_wait,
			reset_done_ack,
			msecs_to_jiffies(tm));

	if (!reset_done_ack) {
		GMN_DBG("%s: reset ACK failed %d", __func__, rc);
		return -EBUSY;
	}

	GMN_DBG("%s: reset_done_ack rc %d", __func__, rc);
	spin_lock_irqsave(&reset_lock, flags);
	reset_done_ack = 0;
	spin_unlock_irqrestore(&reset_lock, flags);

	if (op_mode == MSM_GEMINI_MODE_REALTIME_ENCODE) {
		/* Nothing needed for fe buffer cfg, config we only */
		msm_gemini_hw_we_buffer_cfg(1);
	} else {
		/* Nothing needed for fe buffer cfg, config we only */
		msm_gemini_hw_we_buffer_cfg(0);
	}

	/* @todo wait for reset done irq */

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

	free_irq(irq, context);
	result = msm_camio_jpeg_clk_disable();
	iounmap(base);
	release_mem_region(mem->start, resource_size(mem));

	GMN_DBG("%s:%d] success\n", __func__, __LINE__);
	return result;
}
Ejemplo n.º 3
0
inline void *msm_gemini_q_out(struct msm_gemini_q *q_p)
{
	unsigned long flags;
	struct msm_gemini_q_entry *q_entry_p = NULL;
	void *data = NULL;

	GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
	spin_lock_irqsave(&q_p->lck, flags);
	if (!list_empty(&q_p->q)) {
		q_entry_p = list_first_entry(&q_p->q, struct msm_gemini_q_entry,
			list);
		list_del_init(&q_entry_p->list);
	}
Ejemplo n.º 4
0
int msm_gemini_platform_release(struct resource *mem, void *base, int irq,
	void *context)
{
	int result;
	free_irq(irq, context);
	result = msm_camio_jpeg_clk_disable();
	iounmap(base);
	release_mem_region(mem->start, resource_size(mem));
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
	ion_client_destroy(gemini_client);
#endif
	GMN_DBG("%s:%d] success\n", __func__, __LINE__);
	return result;
}
Ejemplo n.º 5
0
void msm_gemini_hw_region_dump(int size)
{
	uint32_t *p;
	uint8_t *p8;

	if (size > gemini_region_size)
		GMN_PR_ERR("%s:%d] wrong region dump size\n",
			__func__, __LINE__);

	p = (uint32_t *) gemini_region_base;
	while (size >= 16) {
		GMN_DBG("0x%08X] %08X %08X %08X %08X\n",
			gemini_region_size - size,
			readl(p), readl(p+1), readl(p+2), readl(p+3));
		p += 4;
		size -= 16;
	}

	if (size > 0) {
		uint32_t d;
		GMN_DBG("0x%08X] ", gemini_region_size - size);
		while (size >= 4) {
			GMN_DBG("%08X ", readl(p++));
			size -= 4;
		}

		d = readl(p);
		p8 = (uint8_t *) &d;
		while (size) {
			GMN_DBG("%02X", *p8++);
			size--;
		}

		GMN_DBG("\n");
	}
}
Ejemplo n.º 6
0
uint32_t msm_gemini_hw_read(struct msm_gemini_hw_cmd *hw_cmd_p)
{
	uint32_t *paddr;
	uint32_t data;

	paddr = gemini_region_base + hw_cmd_p->offset;

	data = readl(paddr);
	data &= hw_cmd_p->mask;

	GMN_DBG("%s:%d] type-%d n-%d offset-0x%4x mask-0x%8x data-0x%8x\n",
		__func__, __LINE__, hw_cmd_p->type, hw_cmd_p->n,
		hw_cmd_p->offset, hw_cmd_p->mask, data);
	return data;
}
void *msm_gemini_core_framedone_irq(int gemini_irq_status, void *context)
{
	struct msm_gemini_hw_buf *buf_p;

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

	buf_p = msm_gemini_hw_pingpong_active_buffer(&we_pingpong_buf);
	if (buf_p) {
		buf_p->framedone_len = msm_gemini_hw_encode_output_size();
		pr_err("%s:%d] framedone_len %d\n", __func__, __LINE__,
			buf_p->framedone_len);
	}

	return buf_p;
}
void msm_gemini_hw_we_buffer_update(struct msm_gemini_hw_buf *p_input,
	uint8_t pingpong_index)
{
	uint32_t n_reg_val = 0;

	struct msm_gemini_hw_cmd *hw_cmd_p;

	GMN_DBG("%s:%d] pingpong index %d", __func__, __LINE__,
		pingpong_index);
	if (pingpong_index == 0) {
		hw_cmd_p = &hw_cmd_we_ping_update[0];

		n_reg_val = ((p_input->y_len <<
			HWIO_JPEG_WE_Y_PING_BUFFER_CFG_WE_BUFFER_LENGTH_SHFT) &
			HWIO_JPEG_WE_Y_PING_BUFFER_CFG_WE_BUFFER_LENGTH_BMSK);
		hw_cmd_p->data = n_reg_val;
		msm_gemini_hw_write(hw_cmd_p++);

		n_reg_val = p_input->y_buffer_addr;
		hw_cmd_p->data = n_reg_val;
		msm_gemini_hw_write(hw_cmd_p++);
	} else if (pingpong_index == 1) {
		hw_cmd_p = &hw_cmd_we_pong_update[0];

		n_reg_val = ((p_input->y_len <<
			HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_WE_BUFFER_LENGTH_SHFT) &
			HWIO_JPEG_WE_Y_PONG_BUFFER_CFG_WE_BUFFER_LENGTH_BMSK);
		hw_cmd_p->data = n_reg_val;
		msm_gemini_hw_write(hw_cmd_p++);

		n_reg_val = p_input->y_buffer_addr;
		hw_cmd_p->data = n_reg_val;
		msm_gemini_hw_write(hw_cmd_p++);
	} else {
		
	}

	return;
}
Ejemplo n.º 9
0
void msm_gemini_hw_write(struct msm_gemini_hw_cmd *hw_cmd_p)
{
	uint32_t *paddr;
	uint32_t old_data, new_data;

	/* type, repeat n times, offset, mask, data or pdata */
	GMN_DBG("%s:%d] type-%d n-%d offset-0x%4x mask-0x%8x data-0x%8x\n",
		__func__, __LINE__, hw_cmd_p->type, hw_cmd_p->n,
		hw_cmd_p->offset, hw_cmd_p->mask, hw_cmd_p->data);

	paddr = gemini_region_base + hw_cmd_p->offset;

	if (hw_cmd_p->mask == 0xffffffff) {
		old_data = 0;
	} else {
		old_data = readl(paddr);
		old_data &= ~hw_cmd_p->mask;
	}

	new_data = hw_cmd_p->data & hw_cmd_p->mask;
	new_data |= old_data;
	writel(new_data, paddr);
}
int msm_gemini_platform_init(struct platform_device *pdev,
	struct resource **mem,
	void **base,
	int *irq,
	irqreturn_t (*handler) (int, void *),
	void *context)
{
	int rc = -1;
	int gemini_irq;
	struct resource *gemini_mem, *gemini_io, *gemini_irq_res;
	void *gemini_base;

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

	gemini_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!gemini_irq_res) {
		GMN_PR_ERR("no irq resource?\n");
		return -ENODEV;
	}
	gemini_irq = gemini_irq_res->start;

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

	gemini_base = ioremap(gemini_mem->start, resource_size(gemini_mem));
	if (!gemini_base) {
		rc = -ENOMEM;
		GMN_PR_ERR("%s: ioremap failed\n", __func__);
		goto fail1;
	}

	rc = msm_camio_jpeg_clk_enable();
	if (rc) {
		GMN_PR_ERR("%s: clk failed rc = %d\n", __func__, rc);
		goto fail2;
	}

	msm_gemini_hw_init(gemini_base, resource_size(gemini_mem));
	rc = request_irq(gemini_irq, handler, IRQF_TRIGGER_RISING, "gemini",
		context);
	if (rc) {
		GMN_PR_ERR("%s: request_irq failed, %d, JPEG = %d\n", __func__,
			gemini_irq, INT_JPEG);
		goto fail3;
	}

	*mem  = gemini_mem;
	*base = gemini_base;
	*irq  = gemini_irq;
	GMN_DBG("%s:%d] success\n", __func__, __LINE__);

	return rc;

fail3:
	msm_camio_jpeg_clk_disable();
fail2:
	iounmap(gemini_base);
fail1:
	release_mem_region(gemini_mem->start, resource_size(gemini_mem));
	GMN_DBG("%s:%d] fail\n", __func__, __LINE__);
	return rc;
}
static int msm_gemini_init(struct platform_device *pdev)
{
	int rc = -1;
	struct device *dev;

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

	msm_gemini_device_p = __msm_gemini_init(pdev);
	if (msm_gemini_device_p == NULL) {
		GMN_PR_ERR("%s: initialization failed\n", __func__);
		goto fail;
	}

	rc = alloc_chrdev_region(&msm_gemini_devno, 0, 1, MSM_GEMINI_NAME);
	if (rc < 0) {
		GMN_PR_ERR("%s: failed to allocate chrdev\n", __func__);
		goto fail_1;
	}

	if (!msm_gemini_class) {
		msm_gemini_class = class_create(THIS_MODULE, MSM_GEMINI_NAME);
		if (IS_ERR(msm_gemini_class)) {
			rc = PTR_ERR(msm_gemini_class);
			GMN_PR_ERR("%s: create device class failed\n",
				__func__);
			goto fail_2;
		}
	}

	dev = device_create(msm_gemini_class, NULL,
		MKDEV(MAJOR(msm_gemini_devno), MINOR(msm_gemini_devno)), NULL,
		"%s%d", MSM_GEMINI_NAME, 0);

	if (IS_ERR(dev)) {
		GMN_PR_ERR("%s: error creating device\n", __func__);
		rc = -ENODEV;
		goto fail_3;
	}

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

	pr_info("[CAM] %s %s: success\n", __func__, MSM_GEMINI_NAME);

	return rc;

fail_4:
	device_destroy(msm_gemini_class, msm_gemini_devno);

fail_3:
	class_destroy(msm_gemini_class);

fail_2:
	unregister_chrdev_region(msm_gemini_devno, 1);

fail_1:
	__msm_gemini_exit(msm_gemini_device_p);

fail:
	return rc;
}
Ejemplo n.º 12
0
int msm_gemini_platform_init(struct platform_device *pdev,
	struct resource **mem,
	void **base,
	int *irq,
	irqreturn_t (*handler) (int, void *),
	void *context)
{
	int rc = -1;
	int gemini_irq;
	struct resource *gemini_mem, *gemini_io, *gemini_irq_res;
	void *gemini_base;
	struct msm_gemini_device *pgmn_dev =
		(struct msm_gemini_device *) context;

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

	gemini_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!gemini_irq_res) {
		GMN_PR_ERR("no irq resource?\n");
		return -ENODEV;
	}
	gemini_irq = gemini_irq_res->start;

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

	gemini_base = ioremap(gemini_mem->start, resource_size(gemini_mem));
	if (!gemini_base) {
		rc = -ENOMEM;
		GMN_PR_ERR("%s: ioremap failed\n", __func__);
		goto fail1;
	}

	pgmn_dev->hw_version = GEMINI_8X60;
	rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_8x_clk_info,
	 pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_8x_clk_info), 1);
	if (rc < 0) {
		pgmn_dev->hw_version = GEMINI_7X;
		rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev,
			gemini_7x_clk_info, pgmn_dev->gemini_clk,
			ARRAY_SIZE(gemini_7x_clk_info), 1);
		if (rc < 0) {
			GMN_PR_ERR("%s: clk failed rc = %d\n", __func__, rc);
			goto fail2;
		}
	} else {
		rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev,
				gemini_imem_clk_info, &pgmn_dev->gemini_clk[2],
				ARRAY_SIZE(gemini_imem_clk_info), 1);
		if (!rc)
			pgmn_dev->hw_version = GEMINI_8960;
	}

	if (pgmn_dev->hw_version != GEMINI_7X) {
		if (pgmn_dev->gemini_fs == NULL) {
			pgmn_dev->gemini_fs =
				regulator_get(&pgmn_dev->pdev->dev, "vdd");
			if (IS_ERR(pgmn_dev->gemini_fs)) {
				pr_err("%s: Regulator FS_ijpeg get failed %ld\n",
					__func__, PTR_ERR(pgmn_dev->gemini_fs));
				pgmn_dev->gemini_fs = NULL;
				goto gemini_fs_failed;
			} else if (regulator_enable(pgmn_dev->gemini_fs)) {
				pr_err("%s: Regulator FS_ijpeg enable failed\n",
								__func__);
				regulator_put(pgmn_dev->gemini_fs);
				pgmn_dev->gemini_fs = NULL;
				goto gemini_fs_failed;
			}
		}
	}

	msm_gemini_hw_init(gemini_base, resource_size(gemini_mem));
	rc = request_irq(gemini_irq, handler, IRQF_TRIGGER_RISING, "gemini",
		context);
	if (rc) {
		GMN_PR_ERR("%s: request_irq failed, %d\n", __func__,
			gemini_irq);
		goto fail3;
	}

	*mem  = gemini_mem;
	*base = gemini_base;
	*irq  = gemini_irq;

#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
	gemini_client = msm_ion_client_create(-1, "camera/gemini");
#endif
	GMN_DBG("%s:%d] success\n", __func__, __LINE__);

	return rc;

fail3:
	if (pgmn_dev->hw_version != GEMINI_7X) {
		regulator_disable(pgmn_dev->gemini_fs);
		regulator_put(pgmn_dev->gemini_fs);
		pgmn_dev->gemini_fs = NULL;
	}
gemini_fs_failed:
	if (pgmn_dev->hw_version == GEMINI_8960)
		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_imem_clk_info,
		 &pgmn_dev->gemini_clk[2], ARRAY_SIZE(gemini_imem_clk_info), 0);
	if (pgmn_dev->hw_version != GEMINI_7X)
		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_8x_clk_info,
		pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_8x_clk_info), 0);
	else
		msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_7x_clk_info,
		pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_7x_clk_info), 0);
fail2:
	iounmap(gemini_base);
fail1:
	release_mem_region(gemini_mem->start, resource_size(gemini_mem));
	GMN_DBG("%s:%d] fail\n", __func__, __LINE__);
	return rc;
}
Ejemplo n.º 13
0
irqreturn_t msm_gemini_core_irq(int irq_num, void *context)
{
	void *data = NULL;
	unsigned long flags;
	int gemini_irq_status;

	GMN_DBG("%s:%d] irq_num = %d\n", __func__, __LINE__, irq_num);

	spin_lock_irqsave(&reset_lock, flags);
	reset_done_ack = 1;
	spin_unlock_irqrestore(&reset_lock, flags);
	gemini_irq_status = msm_gemini_hw_irq_get_status();

	GMN_DBG("%s:%d] gemini_irq_status = %0x\n", __func__, __LINE__,
		gemini_irq_status);

	/*For reset and framedone IRQs, clear all bits*/
	if (gemini_irq_status & 0x400) {
		wake_up(&reset_wait);
		msm_gemini_hw_irq_clear(HWIO_JPEG_IRQ_CLEAR_RMSK,
			JPEG_IRQ_CLEAR_ALL);
	} else if (gemini_irq_status & 0x1) {
		msm_gemini_hw_irq_clear(HWIO_JPEG_IRQ_CLEAR_RMSK,
			JPEG_IRQ_CLEAR_ALL);
	} else {
		msm_gemini_hw_irq_clear(HWIO_JPEG_IRQ_CLEAR_RMSK,
			gemini_irq_status);
	}

	if (msm_gemini_hw_irq_is_frame_done(gemini_irq_status)) {
		data = msm_gemini_core_framedone_irq(gemini_irq_status,
			context);
		if (msm_gemini_irq_handler)
			msm_gemini_irq_handler(
				MSM_GEMINI_HW_MASK_COMP_FRAMEDONE,
				context, data);
	}

	if (msm_gemini_hw_irq_is_fe_pingpong(gemini_irq_status)) {
		data = msm_gemini_core_fe_pingpong_irq(gemini_irq_status,
			context);
		if (msm_gemini_irq_handler)
			msm_gemini_irq_handler(MSM_GEMINI_HW_MASK_COMP_FE,
				context, data);
	}

	if (msm_gemini_hw_irq_is_we_pingpong(gemini_irq_status) &&
	    !msm_gemini_hw_irq_is_frame_done(gemini_irq_status)) {
		data = msm_gemini_core_we_pingpong_irq(gemini_irq_status,
			context);
		if (msm_gemini_irq_handler)
			msm_gemini_irq_handler(MSM_GEMINI_HW_MASK_COMP_WE,
				context, data);
	}

	if (msm_gemini_hw_irq_is_reset_ack(gemini_irq_status)) {
		data = msm_gemini_core_reset_ack_irq(gemini_irq_status,
			context);
		if (msm_gemini_irq_handler)
			msm_gemini_irq_handler(
				MSM_GEMINI_HW_MASK_COMP_RESET_ACK,
				context, data);
	}

	/* Unexpected/unintended HW interrupt */
	if (msm_gemini_hw_irq_is_err(gemini_irq_status)) {
		data = msm_gemini_core_err_irq(gemini_irq_status, context);
		if (msm_gemini_irq_handler)
			msm_gemini_irq_handler(MSM_GEMINI_HW_MASK_COMP_ERR,
				context, data);
	}

	return IRQ_HANDLED;
}
Ejemplo n.º 14
0
void *msm_gemini_core_reset_ack_irq(int gemini_irq_status, void *context)
{
	/* @todo return the status back to msm_gemini_core_reset */
	GMN_DBG("%s:%d]\n", __func__, __LINE__);
	return NULL;
}
Ejemplo n.º 15
0
void *msm_gemini_core_we_pingpong_irq(int gemini_irq_status, void *context)
{
	GMN_DBG("%s:%d]\n", __func__, __LINE__);

	return msm_gemini_hw_pingpong_irq(&we_pingpong_buf);
}
int msm_gemini_platform_clk_enable(void)
{
	/* MP*fps*(1 + %blanking)
	   2MP: 24MHz  ------ 2 x 10 x 1.2
	   3MP: 36MHz  ------ 3 x 10 x 1.2
	   5MP: 60MHz  ------ 5 x 10 x 1.2
	   8MP: 96MHz  ------ 8 x 10 x 1.2
	  12MP: 144MHz ------12 x 10 x 1.2
	 */
	int rc = -1;
	u32 rate = 144000000;

	if (jpeg_clk  == NULL) {
		jpeg_clk  = clk_get(NULL, "jpeg_clk");
		if (jpeg_clk  == NULL) {
			GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__,
				rc);
			goto fail;
		}
	}

	rc = clk_set_min_rate(jpeg_clk, rate);
	if (rc) {
		GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc);
		goto fail;
	}

	rc = clk_enable(jpeg_clk);
	if (rc) {
		GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc);
		goto fail;
	}

	if (jpeg_pclk == NULL) {
		jpeg_pclk = clk_get(NULL, "jpeg_pclk");
		if (jpeg_pclk == NULL) {
			GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__,
				rc);
			goto fail;
		}
	}

	rc = clk_enable(jpeg_pclk);
	if (rc) {
		GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc);
		goto fail;
	}

	rc = pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ,
		"msm_gemini", MSM_SYSTEM_BUS_RATE);
	if (rc) {
		GMN_PR_ERR("request AXI bus QOS fails. rc = %d\n", rc);
		goto fail;
	}

GMN_DBG("%s:%d]\n", __func__, __LINE__);
	return rc;

fail:
	GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc);
	return rc;
}