Exemplo n.º 1
0
static int mdp3_dmap_histo_get(struct mdp3_dma *dma,
			struct mdp3_dma_histogram_data *data)
{
	int i;
	u32 addr, extra;

	addr = MDP3_REG_DMA_P_HIST_R_DATA;
	for (i = 0; i < 32; i++) {
		data->r_data[i] = MDP3_REG_READ(addr);
		addr += 4;
	}

	addr = MDP3_REG_DMA_P_HIST_G_DATA;
	for (i = 0; i < 32; i++) {
		data->g_data[i] = MDP3_REG_READ(addr);
		addr += 4;
	}

	addr = MDP3_REG_DMA_P_HIST_B_DATA;
	for (i = 0; i < 32; i++) {
		data->b_data[i] = MDP3_REG_READ(addr);
		addr += 4;
	}

	extra = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_EXTRA_INFO_0);
	data->r_min_value = (extra & 0x1F0000) >> 16;
	data->r_max_value = (extra & 0x1F000000) >> 24;
	extra = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_EXTRA_INFO_1);
	data->g_min_value = extra & 0x1F;
	data->g_max_value = (extra & 0x1F00) >> 8;
	data->b_min_value = (extra & 0x1F0000) >> 16;
	data->b_max_value = (extra & 0x1F000000) >> 24;
	return 0;
}
static void mdp3_hist_done_intr_handler(int type, void *arg)
{
	struct mdp3_dma *dma = (struct mdp3_dma *)arg;
	u32 isr, mask;

	isr = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_INTR_STATUS);
	mask = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_INTR_ENABLE);
	MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_INTR_CLEAR, isr);

	isr &= mask;
	if (isr == 0)
		return;

	if (isr & MDP3_DMA_P_HIST_INTR_HIST_DONE_BIT) {
		spin_lock(&dma->histo_lock);
		dma->histo_state = MDP3_DMA_HISTO_STATE_READY;
		complete(&dma->histo_comp);
		spin_unlock(&dma->histo_lock);
	}
	if (isr & MDP3_DMA_P_HIST_INTR_RESET_DONE_BIT) {
		spin_lock(&dma->histo_lock);
		dma->histo_state = MDP3_DMA_HISTO_STATE_IDLE;
		complete(&dma->histo_comp);
		spin_unlock(&dma->histo_lock);
	}
}
Exemplo n.º 3
0
void mdp3_dump_dma(void *data)
{
	struct mdp3_dma *dma = (struct mdp3_dma *)data;
	u32 isr, mask;

	mdp3_clk_prepare();
	mdp3_clk_enable(1, 0);

	isr = MDP3_REG_READ(MDP3_REG_INTR_STATUS);
	mask = MDP3_REG_READ(MDP3_REG_INTR_ENABLE);
	MDSS_TIMEOUT_LOG("-------- MDP3 INTERRUPT DATA ---------\n");
	MDSS_TIMEOUT_LOG("MDP3_REG_INTR_STATUS: 0x%08X\n", isr);
	MDSS_TIMEOUT_LOG("MDP3_REG_INTR_ENABLE: 0x%08X\n", mask);
	MDSS_TIMEOUT_LOG("global irqs disabled: %d\n", irqs_disabled());
	MDSS_TIMEOUT_LOG("------ MDP3 INTERRUPT DATA DONE ------\n");

	if (dma) {
		MDSS_TIMEOUT_LOG("-------- MDP3 DMA DATA ---------\n");
		MDSS_TIMEOUT_LOG("vsync_cnt=%u\n", dma->vsync_cnt);
		MDSS_TIMEOUT_LOG("------ MDP3 DMA DATA DONE ------\n");
	}

	mdp3_clk_enable(0, 0);
	mdp3_clk_unprepare();
}
Exemplo n.º 4
0
static int mdp3_dmap_lut_config(struct mdp3_dma *dma,
			struct mdp3_dma_lut_config *config,
			struct mdp3_dma_lut *lut)
{
	u32 cc_config, addr, color;
	int i;

	if (config->lut_enable && lut) {
		addr = MDP3_REG_DMA_P_CSC_LUT1;
		if (config->lut_sel)
			addr = MDP3_REG_DMA_P_CSC_LUT2;

		for (i = 0; i < MDP_LUT_SIZE; i++) {
			color = lut->color0_lut[i] & 0xff;
			color |= (lut->color1_lut[i] & 0xff) << 8;
			color |= (lut->color2_lut[i] & 0xff) << 16;
			MDP3_REG_WRITE(addr, color);
			addr += 4;
		}
	}

	cc_config = MDP3_REG_READ(MDP3_REG_DMA_P_COLOR_CORRECT_CONFIG);
	cc_config &= DMA_LUT_CONFIG_MASK;
	cc_config |= config->lut_enable;
	cc_config |= config->lut_position << 4;
	cc_config |= config->lut_sel << 10;
	MDP3_REG_WRITE(MDP3_REG_DMA_P_COLOR_CORRECT_CONFIG, cc_config);
	wmb();

	dma->lut_config = *config;
	return 0;
}
static void mdp3_dma_clk_auto_gating(struct mdp3_dma *dma, int enable)
{
	u32 cgc;
	int clock_bit = 10;

	clock_bit += dma->dma_sel;

	if (enable) {
		cgc = MDP3_REG_READ(MDP3_REG_CGC_EN);
		cgc |= BIT(clock_bit);
		MDP3_REG_WRITE(MDP3_REG_CGC_EN, cgc);

	} else {
		cgc = MDP3_REG_READ(MDP3_REG_CGC_EN);
		cgc &= ~BIT(clock_bit);
		MDP3_REG_WRITE(MDP3_REG_CGC_EN, cgc);
	}
}
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 void mdp3_dmas_config_source(struct mdp3_dma *dma)
{
	struct mdp3_dma_source *source_config = &dma->source_config;
	u32 dma_s_cfg_reg, dma_s_size;

	dma_s_cfg_reg = MDP3_REG_READ(MDP3_REG_DMA_S_CONFIG);
	dma_s_cfg_reg &= ~MDP3_DMA_IBUF_FORMAT_MASK;
	dma_s_cfg_reg |= source_config->format << 25;

	dma_s_size = source_config->width | (source_config->height << 16);

	MDP3_REG_WRITE(MDP3_REG_DMA_S_CONFIG, dma_s_cfg_reg);
	MDP3_REG_WRITE(MDP3_REG_DMA_S_SIZE, dma_s_size);
	MDP3_REG_WRITE(MDP3_REG_DMA_S_IBUF_Y_STRIDE, source_config->stride);
}
Exemplo n.º 8
0
static void mdp3_dmap_config_source(struct mdp3_dma *dma)
{
	struct mdp3_dma_source *source_config = &dma->source_config;
	u32 dma_p_cfg_reg, dma_p_size;

	dma_p_cfg_reg = MDP3_REG_READ(MDP3_REG_DMA_P_CONFIG);
	dma_p_cfg_reg &= ~MDP3_DMA_IBUF_FORMAT_MASK;
	dma_p_cfg_reg |= source_config->format << 25;
	dma_p_cfg_reg &= ~MDP3_DMA_PACK_PATTERN_MASK;
	dma_p_cfg_reg |= dma->output_config.pack_pattern << 8;

	dma_p_size = source_config->width | (source_config->height << 16);

	MDP3_REG_WRITE(MDP3_REG_DMA_P_CONFIG, dma_p_cfg_reg);
	MDP3_REG_WRITE(MDP3_REG_DMA_P_SIZE, dma_p_size);
	MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_Y_STRIDE, source_config->stride);
}
Exemplo n.º 9
0
static int mdp3_dmap_histo_reset(struct mdp3_dma *dma)
{
	unsigned long flag;
	int ret;
	u32 cgc;

	if (dma->histo_state == MDP3_DMA_HISTO_STATE_START)
		return -EINVAL;

	spin_lock_irqsave(&dma->histo_lock, flag);

	init_completion(&dma->histo_comp);
	cgc = MDP3_REG_READ(MDP3_REG_CGC_EN);
	cgc &= ~BIT(10);
	MDP3_REG_WRITE(MDP3_REG_CGC_EN, cgc);

	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);
	cgc |= BIT(10);
	MDP3_REG_WRITE(MDP3_REG_CGC_EN, cgc);

	return ret;
}
static void mdp3_ccs_update(struct mdp3_dma *dma)
{
	u32 cc_config;
	int updated = 0;

	cc_config = MDP3_REG_READ(MDP3_REG_DMA_P_COLOR_CORRECT_CONFIG);

	if (dma->ccs_config.ccs_dirty) {
		cc_config &= DMA_CCS_CONFIG_MASK;
		if (dma->ccs_config.ccs_enable)
			cc_config |= BIT(3);
		else
			cc_config &= ~BIT(3);
		cc_config |= dma->ccs_config.ccs_sel << 5;
		cc_config |= dma->ccs_config.pre_bias_sel << 6;
		cc_config |= dma->ccs_config.post_bias_sel << 7;
		cc_config |= dma->ccs_config.pre_limit_sel << 8;
		cc_config |= dma->ccs_config.post_limit_sel << 9;
		dma->ccs_config.ccs_dirty = false;
		updated = 1;
	}

	if (dma->lut_config.lut_dirty) {
		cc_config &= DMA_LUT_CONFIG_MASK;
		cc_config |= dma->lut_config.lut_enable;
		cc_config |= dma->lut_config.lut_position << 4;
		cc_config |= dma->lut_config.lut_sel << 10;
		dma->lut_config.lut_dirty = false;
		updated = 1;
	}
	if (updated) {
		MDP3_REG_WRITE(MDP3_REG_DMA_P_COLOR_CORRECT_CONFIG, cc_config);

		/* Make sure ccs configuration update is done before continuing
		with the DMA transfer */
		wmb();
	}
}
Exemplo n.º 11
0
static int mdp3_dmap_histo_intr_status(struct mdp3_dma *dma, int *status)
{
	*status = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_INTR_STATUS);
	return 0;
}
Exemplo n.º 12
0
static int mdp3_dmap_histo_get(struct mdp3_dma *dma)
{
	int i, state, timeout, ret;
	u32 addr;
	unsigned long flag;

	spin_lock_irqsave(&dma->histo_lock, flag);
	state = dma->histo_state;
	spin_unlock_irqrestore(&dma->histo_lock, flag);

	if (state != MDP3_DMA_HISTO_STATE_START &&
		state != MDP3_DMA_HISTO_STATE_READY) {
		pr_err("mdp3_dmap_histo_get invalid state %d\n", state);
		return -EINVAL;
	}

	timeout = HIST_WAIT_TIMEOUT(dma->histogram_config.frame_count);
	ret = wait_for_completion_killable_timeout(&dma->histo_comp, timeout);

	if (ret == 0) {
		pr_debug("mdp3_dmap_histo_get time out\n");
		ret = -ETIMEDOUT;
	} else if (ret < 0) {
		pr_err("mdp3_dmap_histo_get interrupted\n");
	}

	if (ret < 0)
		return ret;

	if (dma->histo_state != MDP3_DMA_HISTO_STATE_READY) {
		pr_debug("mdp3_dmap_histo_get after dma shut down\n");
		return -EPERM;
	}

	addr = MDP3_REG_DMA_P_HIST_R_DATA;
	for (i = 0; i < MDP_HISTOGRAM_BIN_NUM; i++) {
		dma->histo_data.r_data[i] = MDP3_REG_READ(addr);
		addr += 4;
	}

	addr = MDP3_REG_DMA_P_HIST_G_DATA;
	for (i = 0; i < MDP_HISTOGRAM_BIN_NUM; i++) {
		dma->histo_data.g_data[i] = MDP3_REG_READ(addr);
		addr += 4;
	}

	addr = MDP3_REG_DMA_P_HIST_B_DATA;
	for (i = 0; i < MDP_HISTOGRAM_BIN_NUM; i++) {
		dma->histo_data.b_data[i] = MDP3_REG_READ(addr);
		addr += 4;
	}

	dma->histo_data.extra[0] =
			MDP3_REG_READ(MDP3_REG_DMA_P_HIST_EXTRA_INFO_0);
	dma->histo_data.extra[1] =
			MDP3_REG_READ(MDP3_REG_DMA_P_HIST_EXTRA_INFO_1);

	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);

	return 0;
}
Exemplo n.º 13
0
static int mdp3_dmap_ccs_config(struct mdp3_dma *dma,
			struct mdp3_dma_color_correct_config *config,
			struct mdp3_dma_ccs *ccs)
{
	int i;
	u32 cc_config, addr;

	cc_config = MDP3_REG_READ(MDP3_REG_DMA_P_COLOR_CORRECT_CONFIG);
	cc_config &= DMA_CCS_CONFIG_MASK;
	cc_config |= BIT(3);
	cc_config |= config->ccs_sel << 5;
	cc_config |= config->pre_bias_sel << 6;
	cc_config |= config->post_bias_sel << 7;
	cc_config |= config->pre_limit_sel << 8;
	cc_config |= config->post_limit_sel << 9;

	MDP3_REG_WRITE(MDP3_REG_DMA_P_COLOR_CORRECT_CONFIG, cc_config);

	if (config->ccs_enable && ccs) {
		if (ccs->mv1) {
			addr = MDP3_REG_DMA_P_CSC_MV1;
			for (i = 0; i < 9; i++) {
				MDP3_REG_WRITE(addr, ccs->mv1[i]);
				addr += 4;
			}
		}

		if (ccs->mv2) {
			addr = MDP3_REG_DMA_P_CSC_MV2;
			for (i = 0; i < 9; i++) {
				MDP3_REG_WRITE(addr, ccs->mv2[i]);
				addr += 4;
			}
		}

		if (ccs->pre_bv1) {
			addr = MDP3_REG_DMA_P_CSC_PRE_BV1;
			for (i = 0; i < 3; i++) {
				MDP3_REG_WRITE(addr, ccs->pre_bv1[i]);
				addr += 4;
			}
		}

		if (ccs->pre_bv2) {
			addr = MDP3_REG_DMA_P_CSC_PRE_BV2;
			for (i = 0; i < 3; i++) {
				MDP3_REG_WRITE(addr, ccs->pre_bv2[i]);
				addr += 4;
			}
		}

		if (ccs->post_bv1) {
			addr = MDP3_REG_DMA_P_CSC_POST_BV1;
			for (i = 0; i < 3; i++) {
				MDP3_REG_WRITE(addr, ccs->post_bv1[i]);
				addr += 4;
			}
		}

		if (ccs->post_bv2) {
			addr = MDP3_REG_DMA_P_CSC_POST_BV2;
			for (i = 0; i < 3; i++) {
				MDP3_REG_WRITE(addr, ccs->post_bv2[i]);
				addr += 4;
			}
		}

		if (ccs->pre_lv1) {
			addr = MDP3_REG_DMA_P_CSC_PRE_LV1;
			for (i = 0; i < 6; i++) {
				MDP3_REG_WRITE(addr, ccs->pre_lv1[i]);
				addr += 4;
			}
		}

		if (ccs->pre_lv2) {
			addr = MDP3_REG_DMA_P_CSC_PRE_LV2;
			for (i = 0; i < 6; i++) {
				MDP3_REG_WRITE(addr, ccs->pre_lv2[i]);
				addr += 4;
			}
		}

		if (ccs->post_lv1) {
			addr = MDP3_REG_DMA_P_CSC_POST_LV1;
			for (i = 0; i < 6; i++) {
				MDP3_REG_WRITE(addr, ccs->post_lv1[i]);
				addr += 4;
			}
		}

		if (ccs->post_lv2) {
			addr = MDP3_REG_DMA_P_CSC_POST_LV2;
			for (i = 0; i < 6; i++) {
				MDP3_REG_WRITE(addr, ccs->post_lv2[i]);
				addr += 4;
			}
		}
	}

	dma->ccs_config = *config;
	return 0;
}