Exemplo n.º 1
0
static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf)
{
	unsigned long flag;
	int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC;

	pr_debug("mdp3_dmap_update\n");

	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
		cb_type |= MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
		wait_for_completion_killable(&dma->dma_comp);
	}

	spin_lock_irqsave(&dma->dma_lock, flag);
	MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)buf);
	dma->source_config.buf = buf;
	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD)
		MDP3_REG_WRITE(MDP3_REG_DMA_P_START, 1);

	wmb();
	init_completion(&dma->vsync_comp);
	spin_unlock_irqrestore(&dma->dma_lock, flag);

	mdp3_dma_callback_enable(dma, cb_type);
	pr_debug("mdp3_dmap_update wait for vsync_comp in\n");
	wait_for_completion_killable(&dma->vsync_comp);
	pr_debug("mdp3_dmap_update wait for vsync_comp out\n");
	return 0;
}
Exemplo n.º 2
0
static int mdp3_dma_start(struct mdp3_dma *dma, struct mdp3_intf *intf)
{
	unsigned long flag;
	int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC;
	u32 dma_start_offset = MDP3_REG_DMA_P_START;

	if (dma->dma_sel == MDP3_DMA_P)
		dma_start_offset = MDP3_REG_DMA_P_START;
	else if (dma->dma_sel == MDP3_DMA_S)
		dma_start_offset = MDP3_REG_DMA_S_START;
	else
		return -EINVAL;

	spin_lock_irqsave(&dma->dma_lock, flag);
	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
		cb_type |= MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
		MDP3_REG_WRITE(dma_start_offset, 1);
	}

	intf->start(intf);
	wmb();
	init_completion(&dma->vsync_comp);
	spin_unlock_irqrestore(&dma->dma_lock, flag);

	mdp3_dma_callback_enable(dma, cb_type);
	pr_debug("mdp3_dma_start wait for vsync_comp in\n");
	wait_for_completion_killable(&dma->vsync_comp);
	pr_debug("mdp3_dma_start wait for vsync_comp out\n");
	return 0;
}
Exemplo n.º 3
0
static void mdp3_dma_vsync_enable(struct mdp3_dma *dma,
				struct mdp3_vsync_notification *vsync_client)
{
	unsigned long flag;
	int updated = 0;
	int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC;

	pr_debug("mdp3_dma_vsync_enable\n");

	spin_lock_irqsave(&dma->dma_lock, flag);
	if (vsync_client) {
		if (dma->vsync_client.handler != vsync_client->handler) {
			dma->vsync_client = *vsync_client;
			updated = 1;
		}
	} else {
		if (dma->vsync_client.handler) {
			dma->vsync_client.handler = NULL;
			dma->vsync_client.arg = NULL;
			updated = 1;
		}
	}
	spin_unlock_irqrestore(&dma->dma_lock, flag);

	if (updated) {
		if (vsync_client && vsync_client->handler)
			mdp3_dma_callback_enable(dma, cb_type);
		else
			mdp3_dma_callback_disable(dma, cb_type);
	}
}
static int mdp3_dmap_histo_reset(struct mdp3_dma *dma)
{
	unsigned long flag;
	int ret;

	spin_lock_irqsave(&dma->histo_lock, flag);

	init_completion(&dma->histo_comp);

	mdp3_dma_clk_auto_gating(dma, 0);

	MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_INTR_ENABLE, BIT(0)|BIT(1));
	MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_RESET_SEQ_START, 1);
	wmb();
	dma->histo_state = MDP3_DMA_HISTO_STATE_RESET;

	spin_unlock_irqrestore(&dma->histo_lock, flag);

	mdp3_dma_callback_enable(dma, MDP3_DMA_CALLBACK_TYPE_HIST_RESET_DONE);
	ret = wait_for_completion_killable_timeout(&dma->histo_comp,
				msecs_to_jiffies(DMA_HISTO_RESET_TIMEOUT_MS));

	if (ret == 0) {
		pr_err("mdp3_dmap_histo_reset time out\n");
		ret = -ETIMEDOUT;
	} else if (ret < 0) {
		pr_err("mdp3_dmap_histo_reset interrupted\n");
	} else {
		ret = 0;
	}
	mdp3_dma_callback_disable(dma, MDP3_DMA_CALLBACK_TYPE_HIST_RESET_DONE);
	mdp3_dma_clk_auto_gating(dma, 1);

	return ret;
}
static int mdp3_dmas_update(struct mdp3_dma *dma, void *buf,
				struct mdp3_intf *intf)
{
	unsigned long flag;
	int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC;

	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
		cb_type = MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
		if (intf->active)
			wait_for_completion_killable(&dma->dma_comp);
	}

	spin_lock_irqsave(&dma->dma_lock, flag);
	MDP3_REG_WRITE(MDP3_REG_DMA_S_IBUF_ADDR, (u32)buf);
	dma->source_config.buf = buf;
	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD)
		MDP3_REG_WRITE(MDP3_REG_DMA_S_START, 1);

	if (!intf->active) {
		pr_debug("mdp3_dmap_update start interface\n");
		intf->start(intf);
	}

	wmb();
	init_completion(&dma->vsync_comp);
	spin_unlock_irqrestore(&dma->dma_lock, flag);

	mdp3_dma_callback_enable(dma, cb_type);
	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO)
		wait_for_completion_killable(&dma->vsync_comp);
	return 0;
}
static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf,
				struct mdp3_intf *intf)
{
	unsigned long flag;
	int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC;
	int rc = 0;

	pr_debug("mdp3_dmap_update\n");

	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
		cb_type = MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
		if (intf->active) {
			rc = wait_for_completion_timeout(&dma->dma_comp,
				KOFF_TIMEOUT);
			if (rc <= 0) {
				WARN(1, "cmd kickoff timed out (%d)\n", rc);
				rc = -1;
			}
		}
	}
	if (dma->update_src_cfg) {
		if (dma->output_config.out_sel ==
				 MDP3_DMA_OUTPUT_SEL_DSI_VIDEO && intf->active)
			pr_err("configuring dma source while dma is active\n");
		dma->dma_config_source(dma);
		dma->update_src_cfg = false;
	}
	spin_lock_irqsave(&dma->dma_lock, flag);
	MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)buf);
	dma->source_config.buf = buf;
	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
		mdp3_ccs_update(dma);
		MDP3_REG_WRITE(MDP3_REG_DMA_P_START, 1);
	}

	if (!intf->active) {
		pr_debug("mdp3_dmap_update start interface\n");
		intf->start(intf);
	}

	mb();
	dma->vsync_status = MDP3_REG_READ(MDP3_REG_INTR_STATUS) &
		(1 << MDP3_INTR_LCDC_START_OF_FRAME);
	init_completion(&dma->vsync_comp);
	spin_unlock_irqrestore(&dma->dma_lock, flag);

	mdp3_dma_callback_enable(dma, cb_type);
	pr_debug("mdp3_dmap_update wait for vsync_comp in\n");
	if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) {
		rc = wait_for_completion_timeout(&dma->vsync_comp,
			KOFF_TIMEOUT);
		if (rc <= 0)
			rc = -1;
	}
	pr_debug("mdp3_dmap_update wait for vsync_comp out\n");
	return rc;
}
static int mdp3_dmap_histo_start(struct mdp3_dma *dma)
{
	unsigned long flag;

	if (dma->histo_state != MDP3_DMA_HISTO_STATE_IDLE)
		return -EINVAL;

	spin_lock_irqsave(&dma->histo_lock, flag);

	init_completion(&dma->histo_comp);
	MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_START, 1);
	wmb();
	dma->histo_state = MDP3_DMA_HISTO_STATE_START;

	spin_unlock_irqrestore(&dma->histo_lock, flag);

	mdp3_dma_callback_enable(dma, MDP3_DMA_CALLBACK_TYPE_HIST_DONE);
	return 0;

}