/* dsr lock and power island lock should be hold before calling this function */
int psb_dpst_diet_save(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = NULL;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	int dpst3_bin_count = 32;
	u32 i;

	if (!dev)
		return 0;

	dev_priv = psb_priv(dev);
	if (!dev_priv || !dev_priv->psb_dpst_state)
		return 0;

	ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
	ie_hist_cont_reg.bin_reg_func_select = 1;
	ie_hist_cont_reg.bin_reg_index = 0;
	PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
	for (i = 0; i <= dpst3_bin_count; i++)
		diet_saved[i] = PSB_RVDC32(iebdr_reg);
	dpst_print("diet saved\n");
		diet_saved[0] = 0x200;

	return 0;
}
/* SH TODO This doesn't work yet. */
int psb_diet_enable(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t *arg = data;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	int dpst3_bin_threshold_count = 1;
	int dpst_hsv_multiplier = 2;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	int dpst3_bin_count = 32;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON))
		return 0;

	mdfld_dsi_dsr_forbid(dsi_config);

	if (data) {
		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		ie_hist_cont_reg.bin_reg_func_select =
		    dpst3_bin_threshold_count;
		ie_hist_cont_reg.bin_reg_index = 0;

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);

		for (i = 0; i < dpst3_bin_count; i++)
			PSB_WVDC32(arg[i], iebdr_reg);
		ctx->aimg_enhance_bin = PSB_RVDC32(iebdr_reg);

		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		ie_hist_cont_reg.ie_mode_table_enabled = 1;
		ie_hist_cont_reg.alt_enhancement_mode = dpst_hsv_multiplier;

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
	} else {
		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		ie_hist_cont_reg.ie_mode_table_enabled = 0;

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
	}

	mdfld_dsi_dsr_allow(dsi_config);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
Esempio n. 3
0
static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
{
	struct drm_psb_private *dev_priv =
	    (struct drm_psb_private *)dev->dev_private;
	uint32_t pipestat;
	int wake = 0;
	int vsync_a = 0;
	int vsync_b = 0;
	static int pipe_a_on = 0;
	static int pipe_b_on = 0;
	int trigger_2d_blit = 0;

	pipestat = PSB_RVDC32(PSB_PIPEASTAT);
	if (pipestat & (1<<31)) {
		printk("buffer underrun 0x%x\n",underrun++);
		PSB_WVDC32(1<<31 | 1<<15, PSB_PIPEASTAT);
	}

	if ((!drm_psb_disable_vsync) && 
	    (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)) {
		atomic_inc(&dev->vbl_received);
		wake = 1;
		PSB_WVDC32(_PSB_VBLANK_INTERRUPT_ENABLE |
			   _PSB_VBLANK_CLEAR, PSB_PIPEASTAT);
	}

	if ((!drm_psb_disable_vsync) &&
	    (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)) {
		atomic_inc(&dev->vbl_received2);
		wake = 1;
		PSB_WVDC32(_PSB_VBLANK_INTERRUPT_ENABLE |
			   _PSB_VBLANK_CLEAR, PSB_PIPEBSTAT);
	}

	if (vdc_stat & _PSB_HOTPLUG_INTERRUPT_FLAG) {
		// Clear 2nd status register
		spin_lock(&dev_priv->irqmask_lock);
		uint32_t hotplugstat = PSB_RVDC32(PORT_HOTPLUG_STATUS_REG);
		PSB_WVDC32(hotplugstat, PORT_HOTPLUG_STATUS_REG);
		spin_unlock(&dev_priv->irqmask_lock);
		
		hotplug_env = '1';
		wake_up_interruptible(&hotplug_queue);
	}

	PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
	(void)PSB_RVDC32(PSB_INT_IDENTITY_R);
	DRM_READMEMORYBARRIER();

	if (wake) {
		DRM_WAKEUP(&dev->vbl_queue);
		drm_vbl_send_signals(dev);
	}
}
static int psb_hist_status(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct drm_psb_hist_status_arg *hist_status = data;
	uint32_t *arg = hist_status->buf;
	struct mdfld_dsi_config *dsi_config = NULL;
	u32 iedbr_reg_data = 0;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	int dpst3_bin_threshold_count = 0;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	uint32_t segvalue_max_22_bit = 0x3fffff;
	uint32_t iedbr_busy_bit = 0x80000000;
	int dpst3_bin_count = 32;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		return 0;
	}
	mdfld_dsi_dsr_forbid(dsi_config);

	ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
	ie_hist_cont_reg.bin_reg_func_select = dpst3_bin_threshold_count;
	ie_hist_cont_reg.bin_reg_index = 0;

	PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);

	for (i = 0; i < dpst3_bin_count; i++) {
		iedbr_reg_data = PSB_RVDC32(iebdr_reg);

		if (!(iedbr_reg_data & iedbr_busy_bit)) {
			arg[i] = iedbr_reg_data & segvalue_max_22_bit;
		} else {
			i = 0;
			ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
			ie_hist_cont_reg.bin_reg_index = 0;
			PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		}
	}
	mdfld_dsi_dsr_allow(dsi_config);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
Esempio n. 5
0
void
psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
{
	if ((dev_priv->pipestat[pipe] & mask) != mask) {
		u32 reg = psb_pipestat(pipe);
		u32 writeVal = PSB_RVDC32(reg);

		dev_priv->pipestat[pipe] |= mask;
		/* Enable the interrupt, clear any pending status */
		writeVal |= (mask | (mask >> 16));
		PSB_WVDC32(writeVal, reg);
		(void) PSB_RVDC32(reg);
	}
 static int psb_hist_status(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct drm_psb_hist_status_arg *hist_status = data;
	uint32_t * arg = hist_status->buf;
	struct mdfld_dsi_config *dsi_config = NULL;
	u32 iedbr_reg_data = 0;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	int dpst3_bin_threshold_count = 0;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	uint32_t segvalue_max_22_bit = 0x3fffff;
	uint32_t iedbr_busy_bit = 0x80000000;
	int dpst3_bin_count = 32; //Different DPST Algs has different Values?

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;

	/*
        * FIXME: We need to force the Display to
        * turn on but on TNG OSPM how we can force PIPEA to do it?
        */
        if (power_island_get(OSPM_DISPLAY_A))
	{
		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		ie_hist_cont_reg.bin_reg_func_select = dpst3_bin_threshold_count;
		ie_hist_cont_reg.bin_reg_index = 0;

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		for (i = 0; i < dpst3_bin_count; i++) {
			iedbr_reg_data = PSB_RVDC32(iebdr_reg);
			if (!(iedbr_reg_data & iedbr_busy_bit)) {
				arg[i] = iedbr_reg_data & segvalue_max_22_bit;
			} else {
				i = 0;
				ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
				ie_hist_cont_reg.bin_reg_index = 0;
				PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
			}
		}

		power_island_put(OSPM_DISPLAY_A);
	}

	return 0;
}
Esempio n. 7
0
void psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
{
	if ((dev_priv->pipestat[pipe] & mask) != mask) {
		u32 reg = psb_pipestat(pipe);
		dev_priv->pipestat[pipe] |= mask;
		/* Enable the interrupt, clear any pending status */
		if (ospm_power_using_hw_begin
		    (OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON)) {
			u32 writeVal = PSB_RVDC32(reg);
			writeVal |= (mask | (mask >> 16));
			PSB_WVDC32(writeVal, reg);
			(void)PSB_RVDC32(reg);
			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
		}
	}
Esempio n. 8
0
void psb_irq_postinstall(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv =
	    (struct drm_psb_private *)dev->dev_private;
	unsigned long irqflags;

	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
	PSB_WSGX32(dev_priv->sgx2_irq_mask, PSB_CR_EVENT_HOST_ENABLE2);
	PSB_WSGX32(dev_priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE);
	(void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);
	/****MSVDX IRQ Setup...*****/
	/* Enable Mtx Interupt to host */
	{
		unsigned long enables = 0;
		PSB_DEBUG_GENERAL("Setting up MSVDX IRQs.....\n");
		REGIO_WRITE_FIELD_LITE(enables, MSVDX_INTERRUPT_STATUS,
				       CR_MTX_IRQ, 1);
		PSB_WMSVDX32(enables, MSVDX_HOST_INTERRUPT_ENABLE);
	}
	dev_priv->irq_enabled = 1;
 
	uint32_t hotplug_stat = PSB_RVDC32(PORT_HOTPLUG_ENABLE_REG);
	PSB_WVDC32(hotplug_stat | SDVOB_HOTPLUG_DETECT_ENABLE, PORT_HOTPLUG_ENABLE_REG);

	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
}
int psb_update_guard(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct dpst_guardband *input = (struct dpst_guardband *)data;
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	struct dpst_guardband reg_data;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON))
		return 0;

	mdfld_dsi_dsr_forbid(dsi_config);

	reg_data.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
	reg_data.guardband = input->guardband;
	reg_data.guardband_interrupt_delay = input->guardband_interrupt_delay;

	PSB_WVDC32(reg_data.data, HISTOGRAM_INT_CONTROL);
	ctx->histogram_intr_ctrl = reg_data.data;

	mdfld_dsi_dsr_allow(dsi_config);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
Esempio n. 10
0
void psb_irq_uninstall(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv =
	    (struct drm_psb_private *)dev->dev_private;
	unsigned long irqflags;

	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

	dev_priv->sgx_irq_mask = 0x00000000;
	dev_priv->sgx2_irq_mask = 0x00000000;
	dev_priv->vdc_irq_mask = 0x00000000;

	PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
	PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
	PSB_WSGX32(dev_priv->sgx_irq_mask, PSB_CR_EVENT_HOST_ENABLE);
	PSB_WSGX32(dev_priv->sgx2_irq_mask, PSB_CR_EVENT_HOST_ENABLE2);
	wmb();
	PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
	PSB_WSGX32(PSB_RSGX32(PSB_CR_EVENT_STATUS), PSB_CR_EVENT_HOST_CLEAR);
	PSB_WSGX32(PSB_RSGX32(PSB_CR_EVENT_STATUS2), PSB_CR_EVENT_HOST_CLEAR2);

	/****MSVDX IRQ Setup...*****/
	/* Clear interrupt enabled flag */
	PSB_WMSVDX32(0, MSVDX_HOST_INTERRUPT_ENABLE);

	dev_priv->irq_enabled = 0;
	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);

}
Esempio n. 11
0
irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
{
	struct drm_device *dev = (struct drm_device *)arg;
	struct drm_psb_private *dev_priv =
	    (struct drm_psb_private *)dev->dev_private;

	uint32_t vdc_stat;
	uint32_t sgx_stat;
	uint32_t sgx_stat2;
	uint32_t msvdx_stat;
	int handled = 0;

	spin_lock(&dev_priv->irqmask_lock);

	vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
	sgx_stat = PSB_RSGX32(PSB_CR_EVENT_STATUS);
	sgx_stat2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2);
	msvdx_stat = PSB_RMSVDX32(MSVDX_INTERRUPT_STATUS);

	sgx_stat2 &= dev_priv->sgx2_irq_mask;
	sgx_stat &= dev_priv->sgx_irq_mask;
	PSB_WSGX32(sgx_stat2, PSB_CR_EVENT_HOST_CLEAR2);
	PSB_WSGX32(sgx_stat, PSB_CR_EVENT_HOST_CLEAR);
	(void)PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR);

	vdc_stat &= dev_priv->vdc_irq_mask;
	spin_unlock(&dev_priv->irqmask_lock);

	if (msvdx_stat) {
		psb_msvdx_interrupt(dev, msvdx_stat);
		handled = 1;
	}

	if (vdc_stat) {
#ifdef PSB_DETEAR
		if(psb_blit_info.cmd_ready) {
			psb_blit_info.cmd_ready = 0;
			psb_blit_2d_reg_write(dev_priv, psb_blit_info.cmdbuf);
			/* to resume the blocked psb_cmdbuf_2d() */
			set_bit(0, &psb_blit_info.vdc_bit);
		}
#endif	/* PSB_DETEAR */

		/* MSVDX IRQ status is part of vdc_irq_mask */
		psb_vdc_interrupt(dev, vdc_stat);
		handled = 1;
	}

	if (sgx_stat || sgx_stat2) {
		psb_sgx_interrupt(dev, sgx_stat, sgx_stat2);
		handled = 1;
	}

	if (!handled) {
		return IRQ_NONE;
	}

	return IRQ_HANDLED;
}
Esempio n. 12
0
static int get_data(void *data)
{
	struct intel_i2c_chan *chan = data;
	struct drm_psb_private *dev_priv = chan->drm_dev->dev_private;
	uint32_t val;

	val = PSB_RVDC32(chan->reg);
	return ((val & GPIO_DATA_VAL_IN) != 0);
}
Esempio n. 13
0
static void set_clock(void *data, int state_high)
{
	struct intel_i2c_chan *chan = data;
	struct drm_psb_private *dev_priv = chan->drm_dev->dev_private;
	uint32_t reserved = 0, clock_bits;

	/* On most chips, these bits must be preserved in software. */
	reserved = PSB_RVDC32(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
					    GPIO_CLOCK_PULLUP_DISABLE);

	if (state_high)
		clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
	else
		clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
		    GPIO_CLOCK_VAL_MASK;
	PSB_WVDC32(reserved | clock_bits, chan->reg);
	udelay(I2C_RISEFALL_TIME);	/* wait for the line to change state */
}
 int psb_dpst_mode(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct mdfld_dsi_config *dsi_config = NULL;
	uint32_t * arg = data;
	uint32_t x = 0;
	uint32_t y = 0;
	uint32_t reg;

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;

	if (!power_island_get(OSPM_DISPLAY_A))
		return 0;

	reg = PSB_RVDC32(PIPEASRC);

	power_island_put(OSPM_DISPLAY_A);

	/* horizontal is the left 16 bits */
	x = reg >> 16;

	/* vertical is the right 16 bits */
	y = reg & 0x0000ffff;

	/* the values are the image size minus one */
	x += 1;
	y += 1;
	*arg = (x << 16) | y;

	if (x*y <= 1280*800)
		dpst_hist_fake = dpst_hist_720p;
	else if (x*y <= 1920*1200)
		dpst_hist_fake = dpst_hist_1080p;
	else
		dpst_hist_fake = dpst_hist_25x16;

	return 0;
}
int psb_dpst_mode(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct mdfld_dsi_config *dsi_config = NULL;
	uint32_t *arg = data;
	uint32_t x = 0;
	uint32_t y = 0;
	uint32_t reg;

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	mdfld_dsi_dsr_forbid(dsi_config);

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_ONLY_IF_ON))
		return 0;

	reg = PSB_RVDC32(PIPEASRC);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	mdfld_dsi_dsr_allow(dsi_config);
	/* horizontal is the left 16 bits */
	x = reg >> 16;
	/* vertical is the right 16 bits */
	y = reg & 0x0000ffff;

	/* the values are the image size minus one */
	x += 1;
	y += 1;

	*arg = (x << 16) | y;

	return 0;
}
 int psb_update_guard(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct dpst_guardband *input = (struct dpst_guardband *)data;
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	struct dpst_guardband reg_data;

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	/*
        * FIXME: We need to force the Display to
        * turn on but on TNG OSPM how we can force PIPEA to do it?
        */
        if (!power_island_get(OSPM_DISPLAY_A))
        {
		return 0;
	}

	reg_data.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
	reg_data.guardband = input->guardband;
	reg_data.guardband_interrupt_delay = input->guardband_interrupt_delay;

	/* printk(KERN_ALERT "guardband = %u\ninterrupt delay = %u\n",
		reg_data.guardband, reg_data.guardband_interrupt_delay); */
	PSB_WVDC32(reg_data.data, HISTOGRAM_INT_CONTROL);
	ctx->histogram_intr_ctrl = reg_data.data;
	dpst_print("guardband 0x%x\n", reg_data.data);

	power_island_put(OSPM_DISPLAY_A);

	return 0;
}
Esempio n. 17
0
/**
 * mdfld_save_cursor_overlay_registers	-	save cursor overlay info
 * @dev: our device
 *
 * Save the cursor and overlay register state
 */
static int mdfld_save_cursor_overlay_registers(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;

	/* Save cursor regs */
	dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
	dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
	dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);

	dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
	dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
	dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);

	dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR);
	dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE);
	dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS);

	/* HW overlay */
	dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
	dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
	dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
	dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
	dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
	dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
	dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);

	dev_priv->saveOV_OVADD_C = PSB_RVDC32(OV_OVADD + OV_C_OFFSET);
	dev_priv->saveOV_OGAMC0_C = PSB_RVDC32(OV_OGAMC0 + OV_C_OFFSET);
	dev_priv->saveOV_OGAMC1_C = PSB_RVDC32(OV_OGAMC1 + OV_C_OFFSET);
	dev_priv->saveOV_OGAMC2_C = PSB_RVDC32(OV_OGAMC2 + OV_C_OFFSET);
	dev_priv->saveOV_OGAMC3_C = PSB_RVDC32(OV_OGAMC3 + OV_C_OFFSET);
	dev_priv->saveOV_OGAMC4_C = PSB_RVDC32(OV_OGAMC4 + OV_C_OFFSET);
	dev_priv->saveOV_OGAMC5_C = PSB_RVDC32(OV_OGAMC5 + OV_C_OFFSET);

	return 0;
}
/* dsr lock and power island lock should be hold before calling this function */
int psb_dpst_diet_restore(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = NULL;
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	int dpst3_bin_count = 32;
	u32 temp =0;

	if (!dev)
		return 0;

	dev_priv = psb_priv(dev);
	if (!dev_priv || !dev_priv->psb_dpst_state)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	PSB_WVDC32(ctx->histogram_intr_ctrl, HISTOGRAM_INT_CONTROL);
	ie_hist_cont_reg.data = ctx->histogram_logic_ctrl;
	dpst_print("hist_ctl: 0x%x\n", ie_hist_cont_reg.data);
	ie_hist_cont_reg.bin_reg_func_select = 1;
	ie_hist_cont_reg.bin_reg_index = 0;
	ie_hist_cont_reg.ie_histogram_enable = 1;
	ie_hist_cont_reg.ie_mode_table_enabled = 1;
	ie_hist_cont_reg.ie_pipe_assignment = 0;
#ifdef HSV
	ie_hist_cont_reg.histogram_mode_select = 1;//HSV
	ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier;
#else
	ie_hist_cont_reg.histogram_mode_select = 0;//YUV
	ie_hist_cont_reg.alt_enhancement_mode = 1; //additive
#endif
	PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
	if (drm_psb_debug & PSB_D_DPST) {
		printk("before restore: ");
		for (i = 0; i <= dpst3_bin_count; i++)
		{
			printk(" 0x%x ", PSB_RVDC32(iebdr_reg));
		}
		printk("\n");
	}
	for (i = 0; i <= dpst3_bin_count; i++)
	{
		PSB_WVDC32(diet_saved[i], iebdr_reg);
	}
	ctx->aimg_enhance_bin = PSB_RVDC32(iebdr_reg);

	ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);

	temp = ie_hist_cont_reg.data;
	temp|=(1<<27);
	temp&=~0x7f;
	ie_hist_cont_reg.data = temp;
	PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);

	ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;

	return 0;
}
Esempio n. 19
0
IMG_BOOL  MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo,
		unsigned long uiAddr)
{
    int dspbase = (psDevInfo->ui32MainPipe == 0 ? DSPABASE : DSPBBASE);
    int dspsurf = (psDevInfo->ui32MainPipe == 0 ? DSPASURF : DSPBSURF);
    struct drm_device * dev = psDevInfo->psDrmDevice;
    struct drm_psb_private *dev_priv =
        (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
    MRSTLFB_SWAPCHAIN *psCurrentSwapChain = psDevInfo->psCurrentSwapChain;
	struct mdfld_dsi_config *dsi_config;
	struct mdfld_dsi_hw_context *ctx;
	unsigned int tmp;

    if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false))
    {
        if (IS_MRST(dev)) {
            MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
        } else if (IS_MDFLD(dev)) {
		if (psCurrentSwapChain != NULL) {
			if (psCurrentSwapChain->ui32SwapChainPropertyFlag
					& PVRSRV_SWAPCHAIN_ATTACHED_PLANE_A) {
				dspsurf = DSPASURF;
				tmp = PSB_RVDC32(DSPACNTR);
				if (!(tmp & DISPLAY_PLANE_ENABLE))
					PSB_WVDC32(tmp | DISPLAY_PLANE_ENABLE,
							DSPACNTR);
				MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);

				dsi_config = dev_priv->dsi_configs[0];
				if (dsi_config) {
					ctx = &dsi_config->dsi_hw_context;
					ctx->dspsurf = uiAddr;
				}

				if (mdfld_dsi_dsr_update_panel_fb(dsi_config)) {
					ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
					return IMG_FALSE;
				}
			}
#if defined(CONFIG_MDFD_DUAL_MIPI)
			if (psCurrentSwapChain->ui32SwapChainPropertyFlag
					& PVRSRV_SWAPCHAIN_ATTACHED_PLANE_C) {
				dspsurf = DSPCSURF;
				tmp = PSB_RVDC32(DSPACNTR + 0x2000);
				if (!(tmp & DISPLAY_PLANE_ENABLE))
					PSB_WVDC32(tmp | DISPLAY_PLANE_ENABLE,
							DSPACNTR + 0x2000);
				MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);

				dsi_config = dev_priv->dsi_configs[1];
				if (dsi_config) {
					ctx = &dsi_config->dsi_hw_context;
					ctx->dspsurf = uiAddr;
				}

				if (mdfld_dsi_dsr_update_panel_fb(dsi_config)) {
					ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
					return IMG_FALSE;
				}
			}
#endif
#ifdef CONFIG_SUPPORT_HDMI
			/* To avoid Plane B still fetches data from original frame
			 * buffer. */
			if (psCurrentSwapChain->ui32SwapChainPropertyFlag
					& PVRSRV_SWAPCHAIN_ATTACHED_PLANE_B) {
				dspsurf = DSPBSURF;
				tmp = PSB_RVDC32(DSPACNTR + 0x1000);
				if (!(tmp & DISPLAY_PLANE_ENABLE))
					PSB_WVDC32(tmp | DISPLAY_PLANE_ENABLE,
							DSPACNTR + 0x1000);
				MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
			}
#endif
		} else {
			printk(KERN_WARNING "Current Swapchain is null, no attached plane info\
				 available, omit address update\n");
			if (drm_psb_debug & PSB_D_GENERAL)
				dump_stack();
		}
        } else {
            MRSTLFBVSyncWriteReg(psDevInfo, dspbase, uiAddr);
        }
        ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
    }
// SH START DIET
int psb_diet_enable(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t * arg = data;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	int dpst3_bin_count = 32;
	 u32 temp =0;

	if (!dev_priv)
		return 0;

	if(dev_priv->early_suspended)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	mutex_lock(&dpst_mutex);

	if (power_island_get(OSPM_DISPLAY_A))
	{
		mdfld_dsi_dsr_forbid(dsi_config);
		if (data) {
			ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
			dpst_print("hist_ctl: 0x%x\n", ie_hist_cont_reg.data);
			ie_hist_cont_reg.bin_reg_func_select = 1;
			ie_hist_cont_reg.bin_reg_index = 0;
			ie_hist_cont_reg.ie_histogram_enable = 1;
			ie_hist_cont_reg.ie_mode_table_enabled = 1;
			ie_hist_cont_reg.ie_pipe_assignment = 0;
#ifdef HSV
			ie_hist_cont_reg.histogram_mode_select = 1;//HSV
			ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier;
#else
			ie_hist_cont_reg.histogram_mode_select = 0;//YUV
			ie_hist_cont_reg.alt_enhancement_mode = 1; //additive
#endif
			PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
			if (drm_psb_debug & PSB_D_DPST) {
				printk("previous corr: ");
				for (i = 0; i <= dpst3_bin_count; i++)
				{
					printk(" 0x%x ", PSB_RVDC32(iebdr_reg));
				}
				printk("\n");
			}
			PSB_WVDC32(0x200, iebdr_reg);
			for (i = 1; i <= dpst3_bin_count; i++)
			{
				PSB_WVDC32(arg[i], iebdr_reg);
			}
			ctx->aimg_enhance_bin = PSB_RVDC32(iebdr_reg);

			ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);

			temp = ie_hist_cont_reg.data;
			temp|=(1<<27);
			temp&=~0x7f;
			ie_hist_cont_reg.data = temp;
			PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);

			ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
		} else {
			ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
			ie_hist_cont_reg.ie_mode_table_enabled = 0;
			PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
			ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
		}

		mdfld_dsi_dsr_allow(dsi_config);
		power_island_put(OSPM_DISPLAY_A);
	}

	mutex_unlock(&dpst_mutex);

	return 0;
}
int psb_hist_enable(struct drm_device *dev, void *data)
{
	u32 irqCtrl = 0;
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct dpst_guardband guardband_reg;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t *enable = data;
	struct mdfld_dsi_config *dsi_config = NULL;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		return 0;
	}
	mdfld_dsi_dsr_forbid(dsi_config);

	if (*enable == 1) {
		ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
		ie_hist_cont_reg.ie_pipe_assignment = 0;
		ie_hist_cont_reg.histogram_mode_select = DPST_YUV_LUMA_MODE;
		ie_hist_cont_reg.ie_histogram_enable = 1;
		PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;

		guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
		guardband_reg.interrupt_enable = 1;
		guardband_reg.interrupt_status = 1;
		PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
		ctx->histogram_intr_ctrl = guardband_reg.data;

		irqCtrl = PSB_RVDC32(PIPEASTAT);
		ctx->pipestat = (irqCtrl | PIPE_DPST_EVENT_ENABLE);
		PSB_WVDC32(ctx->pipestat, PIPEASTAT);
	} else {
		guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
		guardband_reg.interrupt_enable = 0;
		guardband_reg.interrupt_status = 1;
		PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
		ctx->histogram_intr_ctrl = guardband_reg.data;

		ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
		ie_hist_cont_reg.ie_histogram_enable = 0;
		PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;

		irqCtrl = PSB_RVDC32(PIPEASTAT);
		irqCtrl &= ~PIPE_DPST_EVENT_ENABLE;
		PSB_WVDC32(irqCtrl, PIPEASTAT);
		ctx->pipestat = irqCtrl;
		dpst_disable_post_process(g_dev);
	}

	mdfld_dsi_dsr_allow(dsi_config);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
 static int psb_hist_status(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct drm_psb_hist_status_arg *hist_status = data;
	uint32_t * arg = hist_status->buf;
	struct mdfld_dsi_config *dsi_config = NULL;
	u32 iedbr_reg_data = 0;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	uint32_t segvalue_max_22_bit = 0x3fffff;
	uint32_t iedbr_busy_bit = 0x80000000;
	int dpst3_bin_count = 32; //Different DPST Algs has different Values?

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;

	/* Use a fake hist status to avoid enhancement is adapted to black
	 * content during suspend, while make content too bright on resume.
	*/
	if(dev_priv->early_suspended) {
		memcpy(arg, dpst_hist_fake, 32*sizeof(uint32_t));
		return 0;
	}

	mutex_lock(&dpst_mutex);
	/*
	 * FIXME: We need to force the Display to
	 * turn on but on TNG OSPM how we can force PIPEA to do it?
	 */
	if (power_island_get(OSPM_DISPLAY_A))
	{
		mdfld_dsi_dsr_forbid(dsi_config);

		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		dpst_print("hist_ctl: 0x%x\n", ie_hist_cont_reg.data);
		ie_hist_cont_reg.bin_reg_func_select = 0;
		ie_hist_cont_reg.bin_reg_index = 0;
		ie_hist_cont_reg.ie_histogram_enable = 1;
		ie_hist_cont_reg.ie_mode_table_enabled = 1;
		ie_hist_cont_reg.ie_pipe_assignment = 0;
#ifdef HSV
		ie_hist_cont_reg.histogram_mode_select = 1;//HSV
		ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier;
#else
		ie_hist_cont_reg.histogram_mode_select = 0;//YUV
		ie_hist_cont_reg.alt_enhancement_mode = 1; //additive
#endif

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		dpst_print("hist static: \n");
		for (i = 0; i < dpst3_bin_count; i++) {
			iedbr_reg_data = PSB_RVDC32(iebdr_reg);
			if (!(iedbr_reg_data & iedbr_busy_bit)) {
				arg[i] = iedbr_reg_data & segvalue_max_22_bit;
				dpst_print("hist_ctl 0x%d 0x%x\n", 0x3ff & PSB_RVDC32(blm_hist_ctl), arg[i]);
			} else {
				i = -1;
				ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
				ie_hist_cont_reg.bin_reg_index = 0;
				PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
			}
		}
		mdfld_dsi_dsr_allow(dsi_config);
		power_island_put(OSPM_DISPLAY_A);
	}

	mutex_unlock(&dpst_mutex);

	return 0;
}
/* IOCTL - moved to standard calls for Kernel Integration */
int psb_hist_enable(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct dpst_guardband guardband_reg;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t * enable = data;
	struct mdfld_dsi_config *dsi_config = NULL;

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if(!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	mutex_lock(&dpst_mutex);
	/*
	* FIXME: We need to force the Display to
	* turn on but on TNG OSPM how we can force PIPEA to do it?
	*/
	if (power_island_get(OSPM_DISPLAY_A)) {

		mdfld_dsi_dsr_forbid(dsi_config);

		if (*enable == 1) {
			ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
			ie_hist_cont_reg.ie_pipe_assignment = 0;
			ie_hist_cont_reg.bin_reg_func_select = 1;
			ie_hist_cont_reg.bin_reg_index = 0;
			ie_hist_cont_reg.ie_histogram_enable = 1;
			ie_hist_cont_reg.ie_mode_table_enabled = 1;
#ifdef HSV
			ie_hist_cont_reg.histogram_mode_select = 1;//HSV
			ie_hist_cont_reg.alt_enhancement_mode = 2;//dpst_hsv_multiplier;
#else
			ie_hist_cont_reg.histogram_mode_select = 0;//YUV
			ie_hist_cont_reg.alt_enhancement_mode = 1; //additive
#endif
			PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
			ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
			dpst_print("hist_ctl 0x%x\n", ie_hist_cont_reg.data);

			guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
			guardband_reg.interrupt_enable = 1;
			guardband_reg.interrupt_status = 1;

			PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
			ctx->histogram_intr_ctrl = guardband_reg.data;
			dpst_print("guardband 0x%x\n", guardband_reg.data);

			/* Wait for two vblanks */
		} else {
			guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
			guardband_reg.interrupt_enable = 0;
			guardband_reg.interrupt_status = 1;
			PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
			ctx->histogram_intr_ctrl = guardband_reg.data;
			dpst_print("guardband 0x%x\n", guardband_reg.data);

			ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
			ie_hist_cont_reg.ie_histogram_enable = 0;
			PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
			ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
			dpst_print("disabled: hist_ctl 0x%x\n", ie_hist_cont_reg.data);

			dpst_disable_post_process(g_dev);
		}

		mdfld_dsi_dsr_allow(dsi_config);
		power_island_put(OSPM_DISPLAY_A);
	}

	mutex_unlock(&dpst_mutex);

	return 0;
}
Esempio n. 24
0
/**
 * mdfld_save_display_registers	-	save registers for pipe
 * @dev: our device
 * @pipe: pipe to save
 *
 * Save the pipe state of the device before we power it off. Keep everything
 * we need to put it back again
 */
static int mdfld_save_display_registers(struct drm_device *dev, int pipe)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	int i;

	/* register */
	u32 dpll_reg = MRST_DPLL_A;
	u32 fp_reg = MRST_FPA0;
	u32 pipeconf_reg = PIPEACONF;
	u32 htot_reg = HTOTAL_A;
	u32 hblank_reg = HBLANK_A;
	u32 hsync_reg = HSYNC_A;
	u32 vtot_reg = VTOTAL_A;
	u32 vblank_reg = VBLANK_A;
	u32 vsync_reg = VSYNC_A;
	u32 pipesrc_reg = PIPEASRC;
	u32 dspstride_reg = DSPASTRIDE;
	u32 dsplinoff_reg = DSPALINOFF;
	u32 dsptileoff_reg = DSPATILEOFF;
	u32 dspsize_reg = DSPASIZE;
	u32 dsppos_reg = DSPAPOS;
	u32 dspsurf_reg = DSPASURF;
	u32 mipi_reg = MIPI;
	u32 dspcntr_reg = DSPACNTR;
	u32 dspstatus_reg = PIPEASTAT;
	u32 palette_reg = PALETTE_A;

	/* pointer to values */
	u32 *dpll_val = &dev_priv->saveDPLL_A;
	u32 *fp_val = &dev_priv->saveFPA0;
	u32 *pipeconf_val = &dev_priv->savePIPEACONF;
	u32 *htot_val = &dev_priv->saveHTOTAL_A;
	u32 *hblank_val = &dev_priv->saveHBLANK_A;
	u32 *hsync_val = &dev_priv->saveHSYNC_A;
	u32 *vtot_val = &dev_priv->saveVTOTAL_A;
	u32 *vblank_val = &dev_priv->saveVBLANK_A;
	u32 *vsync_val = &dev_priv->saveVSYNC_A;
	u32 *pipesrc_val = &dev_priv->savePIPEASRC;
	u32 *dspstride_val = &dev_priv->saveDSPASTRIDE;
	u32 *dsplinoff_val = &dev_priv->saveDSPALINOFF;
	u32 *dsptileoff_val = &dev_priv->saveDSPATILEOFF;
	u32 *dspsize_val = &dev_priv->saveDSPASIZE;
	u32 *dsppos_val = &dev_priv->saveDSPAPOS;
	u32 *dspsurf_val = &dev_priv->saveDSPASURF;
	u32 *mipi_val = &dev_priv->saveMIPI;
	u32 *dspcntr_val = &dev_priv->saveDSPACNTR;
	u32 *dspstatus_val = &dev_priv->saveDSPASTATUS;
	u32 *palette_val = dev_priv->save_palette_a;

	switch (pipe) {
	case 0:
		break;
	case 1:
		/* register */
		dpll_reg = MDFLD_DPLL_B;
		fp_reg = MDFLD_DPLL_DIV0;
		pipeconf_reg = PIPEBCONF;
		htot_reg = HTOTAL_B;
		hblank_reg = HBLANK_B;
		hsync_reg = HSYNC_B;
		vtot_reg = VTOTAL_B;
		vblank_reg = VBLANK_B;
		vsync_reg = VSYNC_B;
		pipesrc_reg = PIPEBSRC;
		dspstride_reg = DSPBSTRIDE;
		dsplinoff_reg = DSPBLINOFF;
		dsptileoff_reg = DSPBTILEOFF;
		dspsize_reg = DSPBSIZE;
		dsppos_reg = DSPBPOS;
		dspsurf_reg = DSPBSURF;
		dspcntr_reg = DSPBCNTR;
		dspstatus_reg = PIPEBSTAT;
		palette_reg = PALETTE_B;

		/* values */
		dpll_val = &dev_priv->saveDPLL_B;
		fp_val = &dev_priv->saveFPB0;
		pipeconf_val = &dev_priv->savePIPEBCONF;
		htot_val = &dev_priv->saveHTOTAL_B;
		hblank_val = &dev_priv->saveHBLANK_B;
		hsync_val = &dev_priv->saveHSYNC_B;
		vtot_val = &dev_priv->saveVTOTAL_B;
		vblank_val = &dev_priv->saveVBLANK_B;
		vsync_val = &dev_priv->saveVSYNC_B;
		pipesrc_val = &dev_priv->savePIPEBSRC;
		dspstride_val = &dev_priv->saveDSPBSTRIDE;
		dsplinoff_val = &dev_priv->saveDSPBLINOFF;
		dsptileoff_val = &dev_priv->saveDSPBTILEOFF;
		dspsize_val = &dev_priv->saveDSPBSIZE;
		dsppos_val = &dev_priv->saveDSPBPOS;
		dspsurf_val = &dev_priv->saveDSPBSURF;
		dspcntr_val = &dev_priv->saveDSPBCNTR;
		dspstatus_val = &dev_priv->saveDSPBSTATUS;
		palette_val = dev_priv->save_palette_b;
		break;
	case 2:
		/* register */
		pipeconf_reg = PIPECCONF;
		htot_reg = HTOTAL_C;
		hblank_reg = HBLANK_C;
		hsync_reg = HSYNC_C;
		vtot_reg = VTOTAL_C;
		vblank_reg = VBLANK_C;
		vsync_reg = VSYNC_C;
		pipesrc_reg = PIPECSRC;
		dspstride_reg = DSPCSTRIDE;
		dsplinoff_reg = DSPCLINOFF;
		dsptileoff_reg = DSPCTILEOFF;
		dspsize_reg = DSPCSIZE;
		dsppos_reg = DSPCPOS;
		dspsurf_reg = DSPCSURF;
		mipi_reg = MIPI_C;
		dspcntr_reg = DSPCCNTR;
		dspstatus_reg = PIPECSTAT;
		palette_reg = PALETTE_C;

		/* pointer to values */
		pipeconf_val = &dev_priv->savePIPECCONF;
		htot_val = &dev_priv->saveHTOTAL_C;
		hblank_val = &dev_priv->saveHBLANK_C;
		hsync_val = &dev_priv->saveHSYNC_C;
		vtot_val = &dev_priv->saveVTOTAL_C;
		vblank_val = &dev_priv->saveVBLANK_C;
		vsync_val = &dev_priv->saveVSYNC_C;
		pipesrc_val = &dev_priv->savePIPECSRC;
		dspstride_val = &dev_priv->saveDSPCSTRIDE;
		dsplinoff_val = &dev_priv->saveDSPCLINOFF;
		dsptileoff_val = &dev_priv->saveDSPCTILEOFF;
		dspsize_val = &dev_priv->saveDSPCSIZE;
		dsppos_val = &dev_priv->saveDSPCPOS;
		dspsurf_val = &dev_priv->saveDSPCSURF;
		mipi_val = &dev_priv->saveMIPI_C;
		dspcntr_val = &dev_priv->saveDSPCCNTR;
		dspstatus_val = &dev_priv->saveDSPCSTATUS;
		palette_val = dev_priv->save_palette_c;
		break;
	default:
		DRM_ERROR("%s, invalid pipe number.\n", __func__);
		return -EINVAL;
	}

	/* Pipe & plane A info */
	*dpll_val = PSB_RVDC32(dpll_reg);
	*fp_val = PSB_RVDC32(fp_reg);
	*pipeconf_val = PSB_RVDC32(pipeconf_reg);
	*htot_val = PSB_RVDC32(htot_reg);
	*hblank_val = PSB_RVDC32(hblank_reg);
	*hsync_val = PSB_RVDC32(hsync_reg);
	*vtot_val = PSB_RVDC32(vtot_reg);
	*vblank_val = PSB_RVDC32(vblank_reg);
	*vsync_val = PSB_RVDC32(vsync_reg);
	*pipesrc_val = PSB_RVDC32(pipesrc_reg);
	*dspstride_val = PSB_RVDC32(dspstride_reg);
	*dsplinoff_val = PSB_RVDC32(dsplinoff_reg);
	*dsptileoff_val = PSB_RVDC32(dsptileoff_reg);
	*dspsize_val = PSB_RVDC32(dspsize_reg);
	*dsppos_val = PSB_RVDC32(dsppos_reg);
	*dspsurf_val = PSB_RVDC32(dspsurf_reg);
	*dspcntr_val = PSB_RVDC32(dspcntr_reg);
	*dspstatus_val = PSB_RVDC32(dspstatus_reg);

	/*save palette (gamma) */
	for (i = 0; i < 256; i++)
		palette_val[i] = PSB_RVDC32(palette_reg + (i<<2));

	if (pipe == 1) {
		dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
		dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
		dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
		dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
		return 0;
	}
	*mipi_val = PSB_RVDC32(mipi_reg);
	return 0;
}
Esempio n. 25
0
/*
 * mdfld_save_display_registers
 *
 * Description: We are going to suspend so save current display
 * register state.
 *
 * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio
 */
static int mdfld_save_display_registers(struct drm_device *dev, int pipenum)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct medfield_state *regs = &dev_priv->regs.mdfld;
	struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum];
	const struct psb_offset *map = &dev_priv->regmap[pipenum];
	int i;
	u32 *mipi_val;

	/* register */
	u32 mipi_reg = MIPI;

	switch (pipenum) {
	case 0:
		mipi_val = &regs->saveMIPI;
		break;
	case 1:
		mipi_val = &regs->saveMIPI;
		break;
	case 2:
		/* register */
		mipi_reg = MIPI_C;
		/* pointer to values */
		mipi_val = &regs->saveMIPI_C;
		break;
	default:
		DRM_ERROR("%s, invalid pipe number.\n", __func__);
		return -EINVAL;
	}

	/* Pipe & plane A info */
	pipe->dpll = PSB_RVDC32(map->dpll);
	pipe->fp0 = PSB_RVDC32(map->fp0);
	pipe->conf = PSB_RVDC32(map->conf);
	pipe->htotal = PSB_RVDC32(map->htotal);
	pipe->hblank = PSB_RVDC32(map->hblank);
	pipe->hsync = PSB_RVDC32(map->hsync);
	pipe->vtotal = PSB_RVDC32(map->vtotal);
	pipe->vblank = PSB_RVDC32(map->vblank);
	pipe->vsync = PSB_RVDC32(map->vsync);
	pipe->src = PSB_RVDC32(map->src);
	pipe->stride = PSB_RVDC32(map->stride);
	pipe->linoff = PSB_RVDC32(map->linoff);
	pipe->tileoff = PSB_RVDC32(map->tileoff);
	pipe->size = PSB_RVDC32(map->size);
	pipe->pos = PSB_RVDC32(map->pos);
	pipe->surf = PSB_RVDC32(map->surf);
	pipe->cntr = PSB_RVDC32(map->cntr);
	pipe->status = PSB_RVDC32(map->status);

	/*save palette (gamma) */
	for (i = 0; i < 256; i++)
		pipe->palette[i] = PSB_RVDC32(map->palette + (i << 2));

	if (pipenum == 1) {
		regs->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
		regs->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);

		regs->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
		regs->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
		return 0;
	}

	*mipi_val = PSB_RVDC32(mipi_reg);
	return 0;
}
Esempio n. 26
0
/*
 * mdfld_restore_display_registers
 *
 * Description: We are going to resume so restore display register state.
 *
 * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio
 */
static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum)
{
	/* To get  panel out of ULPS mode. */
	u32 temp = 0;
	u32 device_ready_reg = DEVICE_READY_REG;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dsi_config *dsi_config = NULL;
	struct medfield_state *regs = &dev_priv->regs.mdfld;
	struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum];
	const struct psb_offset *map = &dev_priv->regmap[pipenum];
	u32 i;
	u32 dpll;
	u32 timeout = 0;

	/* register */
	u32 mipi_reg = MIPI;

	/* values */
	u32 dpll_val = pipe->dpll;
	u32 mipi_val = regs->saveMIPI;

	switch (pipenum) {
	case 0:
		dpll_val &= ~DPLL_VCO_ENABLE;
		dsi_config = dev_priv->dsi_configs[0];
		break;
	case 1:
		dpll_val &= ~DPLL_VCO_ENABLE;
		break;
	case 2:
		mipi_reg = MIPI_C;
		mipi_val = regs->saveMIPI_C;
		dsi_config = dev_priv->dsi_configs[1];
		break;
	default:
		DRM_ERROR("%s, invalid pipe number.\n", __func__);
		return -EINVAL;
	}

	/*make sure VGA plane is off. it initializes to on after reset!*/
	PSB_WVDC32(0x80000000, VGACNTRL);

	if (pipenum == 1) {
		PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, map->dpll);
		PSB_RVDC32(map->dpll);

		PSB_WVDC32(pipe->fp0, map->fp0);
	} else {

		dpll = PSB_RVDC32(map->dpll);

		if (!(dpll & DPLL_VCO_ENABLE)) {

			/* When ungating power of DPLL, needs to wait 0.5us
			   before enable the VCO */
			if (dpll & MDFLD_PWR_GATE_EN) {
				dpll &= ~MDFLD_PWR_GATE_EN;
				PSB_WVDC32(dpll, map->dpll);
				/* FIXME_MDFLD PO - change 500 to 1 after PO */
				udelay(500);
			}

			PSB_WVDC32(pipe->fp0, map->fp0);
			PSB_WVDC32(dpll_val, map->dpll);
			/* FIXME_MDFLD PO - change 500 to 1 after PO */
			udelay(500);

			dpll_val |= DPLL_VCO_ENABLE;
			PSB_WVDC32(dpll_val, map->dpll);
			PSB_RVDC32(map->dpll);

			/* wait for DSI PLL to lock */
			while (timeout < 20000 &&
			  !(PSB_RVDC32(map->conf) & PIPECONF_DSIPLL_LOCK)) {
				udelay(150);
				timeout++;
			}

			if (timeout == 20000) {
				DRM_ERROR("%s, can't lock DSIPLL.\n",
								__func__);
				return -EINVAL;
			}
		}
	}
	/* Restore mode */
	PSB_WVDC32(pipe->htotal, map->htotal);
	PSB_WVDC32(pipe->hblank, map->hblank);
	PSB_WVDC32(pipe->hsync, map->hsync);
	PSB_WVDC32(pipe->vtotal, map->vtotal);
	PSB_WVDC32(pipe->vblank, map->vblank);
	PSB_WVDC32(pipe->vsync, map->vsync);
	PSB_WVDC32(pipe->src, map->src);
	PSB_WVDC32(pipe->status, map->status);

	/*set up the plane*/
	PSB_WVDC32(pipe->stride, map->stride);
	PSB_WVDC32(pipe->linoff, map->linoff);
	PSB_WVDC32(pipe->tileoff, map->tileoff);
	PSB_WVDC32(pipe->size, map->size);
	PSB_WVDC32(pipe->pos, map->pos);
	PSB_WVDC32(pipe->surf, map->surf);

	if (pipenum == 1) {
		/* restore palette (gamma) */
		/*DRM_UDELAY(50000); */
		for (i = 0; i < 256; i++)
			PSB_WVDC32(pipe->palette[i], map->palette + (i << 2));

		PSB_WVDC32(regs->savePFIT_CONTROL, PFIT_CONTROL);
		PSB_WVDC32(regs->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);

		/*TODO: resume HDMI port */

		/*TODO: resume pipe*/

		/*enable the plane*/
		PSB_WVDC32(pipe->cntr & ~DISPLAY_PLANE_ENABLE, map->cntr);

		return 0;
	}

	/*set up pipe related registers*/
	PSB_WVDC32(mipi_val, mipi_reg);

	/*setup MIPI adapter + MIPI IP registers*/
	if (dsi_config)
		mdfld_dsi_controller_init(dsi_config, pipenum);

	if (in_atomic() || in_interrupt())
		mdelay(20);
	else
		msleep(20);

	/*enable the plane*/
	PSB_WVDC32(pipe->cntr, map->cntr);

	if (in_atomic() || in_interrupt())
		mdelay(20);
	else
		msleep(20);

	/* LP Hold Release */
	temp = REG_READ(mipi_reg);
	temp |= LP_OUTPUT_HOLD_RELEASE;
	REG_WRITE(mipi_reg, temp);
	mdelay(1);


	/* Set DSI host to exit from Utra Low Power State */
	temp = REG_READ(device_ready_reg);
	temp &= ~ULPS_MASK;
	temp |= 0x3;
	temp |= EXIT_ULPS_DEV_READY;
	REG_WRITE(device_ready_reg, temp);
	mdelay(1);

	temp = REG_READ(device_ready_reg);
	temp &= ~ULPS_MASK;
	temp |= EXITING_ULPS;
	REG_WRITE(device_ready_reg, temp);
	mdelay(1);

	/*enable the pipe*/
	PSB_WVDC32(pipe->conf, map->conf);

	/* restore palette (gamma) */
	/*DRM_UDELAY(50000); */
	for (i = 0; i < 256; i++)
		PSB_WVDC32(pipe->palette[i], map->palette + (i << 2));

	return 0;
}
/* IOCTL - moved to standard calls for Kernel Integration */
int psb_hist_enable(struct drm_device *dev, void *data)
{
	u32 irqCtrl = 0;
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct dpst_guardband guardband_reg;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t * enable = data;
	struct mdfld_dsi_config *dsi_config = NULL;

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if(!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	/*
	* FIXME: We need to force the Display to
	* turn on but on TNG OSPM how we can force PIPEA to do it?
	*/
	if (power_island_get(OSPM_DISPLAY_A)) {

		if (*enable == 1) {
			ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
			ie_hist_cont_reg.ie_pipe_assignment = 0;
			ie_hist_cont_reg.histogram_mode_select = DPST_YUV_LUMA_MODE;
			ie_hist_cont_reg.ie_histogram_enable = 1;
			PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
			ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;

			guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
			guardband_reg.interrupt_enable = 1;
			guardband_reg.interrupt_status = 1;
			PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
			ctx->histogram_intr_ctrl = guardband_reg.data;

			irqCtrl = PSB_RVDC32(PIPEASTAT);
			ctx->pipestat = (irqCtrl | PIPE_DPST_EVENT_ENABLE);
			PSB_WVDC32(ctx->pipestat, PIPEASTAT);

			/* Wait for two vblanks */
		} else {
			guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
			guardband_reg.interrupt_enable = 0;
			guardband_reg.interrupt_status = 1;
			PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
			ctx->histogram_intr_ctrl = guardband_reg.data;

			ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
			ie_hist_cont_reg.ie_histogram_enable = 0;
			PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
			ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;

			irqCtrl = PSB_RVDC32(PIPEASTAT);
			irqCtrl &= ~PIPE_DPST_EVENT_ENABLE;
			PSB_WVDC32(irqCtrl, PIPEASTAT);
			ctx->pipestat = irqCtrl;
			dpst_disable_post_process(g_dev);
		}

		power_island_put(OSPM_DISPLAY_A);
	}

	return 0;
}
Esempio n. 28
0
/*
 * mdfld_restore_display_registers	-	restore the state of a pipe
 * @dev: our device
 * @pipe: the pipe to restore
 *
 * Restore the state of a pipe to that which was saved by the register save
 * functions.
 */
static int mdfld_restore_display_registers(struct drm_device *dev, int pipe)
{
	/* To get  panel out of ULPS mode */
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dsi_config *dsi_config = NULL;
	u32 i = 0;
	u32 dpll = 0;
	u32 timeout = 0;
	u32 reg_offset = 0;

	/* register */
	u32 dpll_reg = MRST_DPLL_A;
	u32 fp_reg = MRST_FPA0;
	u32 pipeconf_reg = PIPEACONF;
	u32 htot_reg = HTOTAL_A;
	u32 hblank_reg = HBLANK_A;
	u32 hsync_reg = HSYNC_A;
	u32 vtot_reg = VTOTAL_A;
	u32 vblank_reg = VBLANK_A;
	u32 vsync_reg = VSYNC_A;
	u32 pipesrc_reg = PIPEASRC;
	u32 dspstride_reg = DSPASTRIDE;
	u32 dsplinoff_reg = DSPALINOFF;
	u32 dsptileoff_reg = DSPATILEOFF;
	u32 dspsize_reg = DSPASIZE;
	u32 dsppos_reg = DSPAPOS;
	u32 dspsurf_reg = DSPASURF;
	u32 dspstatus_reg = PIPEASTAT;
	u32 mipi_reg = MIPI;
	u32 dspcntr_reg = DSPACNTR;
	u32 palette_reg = PALETTE_A;

	/* values */
	u32 dpll_val = dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE;
	u32 fp_val = dev_priv->saveFPA0;
	u32 pipeconf_val = dev_priv->savePIPEACONF;
	u32 htot_val = dev_priv->saveHTOTAL_A;
	u32 hblank_val = dev_priv->saveHBLANK_A;
	u32 hsync_val = dev_priv->saveHSYNC_A;
	u32 vtot_val = dev_priv->saveVTOTAL_A;
	u32 vblank_val = dev_priv->saveVBLANK_A;
	u32 vsync_val = dev_priv->saveVSYNC_A;
	u32 pipesrc_val = dev_priv->savePIPEASRC;
	u32 dspstride_val = dev_priv->saveDSPASTRIDE;
	u32 dsplinoff_val = dev_priv->saveDSPALINOFF;
	u32 dsptileoff_val = dev_priv->saveDSPATILEOFF;
	u32 dspsize_val = dev_priv->saveDSPASIZE;
	u32 dsppos_val = dev_priv->saveDSPAPOS;
	u32 dspsurf_val = dev_priv->saveDSPASURF;
	u32 dspstatus_val = dev_priv->saveDSPASTATUS;
	u32 mipi_val = dev_priv->saveMIPI;
	u32 dspcntr_val = dev_priv->saveDSPACNTR;
	u32 *palette_val = dev_priv->save_palette_a;

	switch (pipe) {
	case 0:
		dsi_config = dev_priv->dsi_configs[0];
		break;
	case 1:
		/* register */
		dpll_reg = MDFLD_DPLL_B;
		fp_reg = MDFLD_DPLL_DIV0;
		pipeconf_reg = PIPEBCONF;
		htot_reg = HTOTAL_B;
		hblank_reg = HBLANK_B;
		hsync_reg = HSYNC_B;
		vtot_reg = VTOTAL_B;
		vblank_reg = VBLANK_B;
		vsync_reg = VSYNC_B;
		pipesrc_reg = PIPEBSRC;
		dspstride_reg = DSPBSTRIDE;
		dsplinoff_reg = DSPBLINOFF;
		dsptileoff_reg = DSPBTILEOFF;
		dspsize_reg = DSPBSIZE;
		dsppos_reg = DSPBPOS;
		dspsurf_reg = DSPBSURF;
		dspcntr_reg = DSPBCNTR;
		palette_reg = PALETTE_B;
		dspstatus_reg = PIPEBSTAT;

		/* values */
		dpll_val = dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE;
		fp_val = dev_priv->saveFPB0;
		pipeconf_val = dev_priv->savePIPEBCONF;
		htot_val = dev_priv->saveHTOTAL_B;
		hblank_val = dev_priv->saveHBLANK_B;
		hsync_val = dev_priv->saveHSYNC_B;
		vtot_val = dev_priv->saveVTOTAL_B;
		vblank_val = dev_priv->saveVBLANK_B;
		vsync_val = dev_priv->saveVSYNC_B;
		pipesrc_val = dev_priv->savePIPEBSRC;
		dspstride_val = dev_priv->saveDSPBSTRIDE;
		dsplinoff_val = dev_priv->saveDSPBLINOFF;
		dsptileoff_val = dev_priv->saveDSPBTILEOFF;
		dspsize_val = dev_priv->saveDSPBSIZE;
		dsppos_val = dev_priv->saveDSPBPOS;
		dspsurf_val = dev_priv->saveDSPBSURF;
		dspcntr_val = dev_priv->saveDSPBCNTR;
		dspstatus_val = dev_priv->saveDSPBSTATUS;
		palette_val = dev_priv->save_palette_b;
		break;
	case 2:
		reg_offset = MIPIC_REG_OFFSET;

		/* register */
		pipeconf_reg = PIPECCONF;
		htot_reg = HTOTAL_C;
		hblank_reg = HBLANK_C;
		hsync_reg = HSYNC_C;
		vtot_reg = VTOTAL_C;
		vblank_reg = VBLANK_C;
		vsync_reg = VSYNC_C;
		pipesrc_reg = PIPECSRC;
		dspstride_reg = DSPCSTRIDE;
		dsplinoff_reg = DSPCLINOFF;
		dsptileoff_reg = DSPCTILEOFF;
		dspsize_reg = DSPCSIZE;
		dsppos_reg = DSPCPOS;
		dspsurf_reg = DSPCSURF;
		mipi_reg = MIPI_C;
		dspcntr_reg = DSPCCNTR;
		palette_reg = PALETTE_C;
		dspstatus_reg = PIPECSTAT;

		/* values */
		pipeconf_val = dev_priv->savePIPECCONF;
		htot_val = dev_priv->saveHTOTAL_C;
		hblank_val = dev_priv->saveHBLANK_C;
		hsync_val = dev_priv->saveHSYNC_C;
		vtot_val = dev_priv->saveVTOTAL_C;
		vblank_val = dev_priv->saveVBLANK_C;
		vsync_val = dev_priv->saveVSYNC_C;
		pipesrc_val = dev_priv->savePIPECSRC;
		dspstride_val = dev_priv->saveDSPCSTRIDE;
		dsplinoff_val = dev_priv->saveDSPCLINOFF;
		dsptileoff_val = dev_priv->saveDSPCTILEOFF;
		dspsize_val = dev_priv->saveDSPCSIZE;
		dsppos_val = dev_priv->saveDSPCPOS;
		dspsurf_val = dev_priv->saveDSPCSURF;
		dspstatus_val = dev_priv->saveDSPCSTATUS;
		mipi_val = dev_priv->saveMIPI_C;
		dspcntr_val = dev_priv->saveDSPCCNTR;
		palette_val = dev_priv->save_palette_c;

		dsi_config = dev_priv->dsi_configs[1];
		break;
	default:
		DRM_ERROR("%s, invalid pipe number.\n", __func__);
		return -EINVAL;
	}

	/* Make sure VGA plane is off. it initializes to on after reset!*/
	PSB_WVDC32(0x80000000, VGACNTRL);
	if (pipe == 1) {
		PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg);
		PSB_RVDC32(dpll_reg);

		PSB_WVDC32(fp_val, fp_reg);
	} else {
		dpll = PSB_RVDC32(dpll_reg);

		if (!(dpll & DPLL_VCO_ENABLE)) {

			/* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
			if (dpll & MDFLD_PWR_GATE_EN) {
				dpll &= ~MDFLD_PWR_GATE_EN;
				PSB_WVDC32(dpll, dpll_reg);
				udelay(500);	/* FIXME: 1 ? */
			}

			PSB_WVDC32(fp_val, fp_reg);
			PSB_WVDC32(dpll_val, dpll_reg);
			/* FIXME_MDFLD PO - change 500 to 1 after PO */
			udelay(500);

			dpll_val |= DPLL_VCO_ENABLE;
			PSB_WVDC32(dpll_val, dpll_reg);
			PSB_RVDC32(dpll_reg);

			/* wait for DSI PLL to lock */
			while ((timeout < 20000) && !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
				udelay(150);
				timeout++;
			}

			if (timeout == 20000) {
				DRM_ERROR("%s, can't lock DSIPLL.\n",
							__func__);
				return -EINVAL;
			}
		}
	}
	/* Restore mode */
	PSB_WVDC32(htot_val, htot_reg);
	PSB_WVDC32(hblank_val, hblank_reg);
	PSB_WVDC32(hsync_val, hsync_reg);
	PSB_WVDC32(vtot_val, vtot_reg);
	PSB_WVDC32(vblank_val, vblank_reg);
	PSB_WVDC32(vsync_val, vsync_reg);
	PSB_WVDC32(pipesrc_val, pipesrc_reg);
	PSB_WVDC32(dspstatus_val, dspstatus_reg);

	/* Set up the plane */
	PSB_WVDC32(dspstride_val, dspstride_reg);
	PSB_WVDC32(dsplinoff_val, dsplinoff_reg);
	PSB_WVDC32(dsptileoff_val, dsptileoff_reg);
	PSB_WVDC32(dspsize_val, dspsize_reg);
	PSB_WVDC32(dsppos_val, dsppos_reg);
	PSB_WVDC32(dspsurf_val, dspsurf_reg);

	if (pipe == 1) {
		PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
		PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
		PSB_WVDC32(dev_priv->saveHDMIPHYMISCCTL, HDMIPHYMISCCTL);
		PSB_WVDC32(dev_priv->saveHDMIB_CONTROL, HDMIB_CONTROL);

	} else {
		/* Set up pipe related registers */
		PSB_WVDC32(mipi_val, mipi_reg);
		/* Setup MIPI adapter + MIPI IP registers */
		mdfld_dsi_controller_init(dsi_config, pipe);
		msleep(20);
	}
	/* Enable the plane */
	PSB_WVDC32(dspcntr_val, dspcntr_reg);
	msleep(20);
	/* Enable the pipe */
	PSB_WVDC32(pipeconf_val, pipeconf_reg);

	for (i = 0; i < 256; i++)
		PSB_WVDC32(palette_val[i], palette_reg + (i<<2));
	if (pipe == 1)
		return 0;
	if (!mdfld_panel_dpi(dev))
		mdfld_enable_te(dev, pipe);
	return 0;
}