Beispiel #1
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);

}
Beispiel #2
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);
}
/* 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;
}
Beispiel #4
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;
}
 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;
}
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;
}
/* 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;
}
Beispiel #9
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);
	}
Beispiel #10
0
/* this function is only called by dpms on or late resume function */
void dpstmgr_reg_restore_locked(struct mdfld_dsi_config *dsi_config)
{
	struct mdfld_dsi_hw_context *ctx = NULL;
	struct drm_psb_private *dev_priv = NULL;
	struct mdfld_dsi_hw_registers *regs = NULL;

	if (!dsi_config || !dsi_config->dev)
		return;
	ctx = &dsi_config->dsi_hw_context;
	regs = &dsi_config->regs;
	dev_priv = dsi_config->dev->dev_private;

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

	PSB_WVDC32(ctx->histogram_intr_ctrl, regs->histogram_intr_ctrl_reg);
	PSB_WVDC32(ctx->histogram_logic_ctrl, regs->histogram_logic_ctrl_reg);
	PSB_WVDC32(ctx->aimg_enhance_bin, regs->aimg_enhance_bin_reg);
	PSB_WVDC32(ctx->lvds_port_ctrl, regs->lvds_port_ctrl_reg);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
/* this function is only called by dpms on or late resume function */
void dpstmgr_reg_restore_locked(struct drm_device *dev, struct mdfld_dsi_config *dsi_config)
{
	struct mdfld_dsi_hw_context *ctx = NULL;
	struct drm_psb_private *dev_priv = NULL;
	struct mdfld_dsi_hw_registers *regs = NULL;

	if (!dsi_config || !dsi_config->dev)
		return;

	ctx = &dsi_config->dsi_hw_context;
	regs = &dsi_config->regs;
	dev_priv = dsi_config->dev->dev_private;

	if (power_island_get(OSPM_DISPLAY_A))
	{

		PSB_WVDC32(ctx->histogram_intr_ctrl, regs->histogram_intr_ctrl_reg);
		PSB_WVDC32(ctx->histogram_logic_ctrl, regs->histogram_logic_ctrl_reg);
		PSB_WVDC32(ctx->aimg_enhance_bin, regs->aimg_enhance_bin_reg);
		PSB_WVDC32(ctx->lvds_port_ctrl, regs->lvds_port_ctrl_reg);

		power_island_put(OSPM_DISPLAY_A);
	}
}
Beispiel #12
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);
		}
	}
Beispiel #13
0
void psb_irq_preinstall(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv =
	    (struct drm_psb_private *)dev->dev_private;
	spin_lock(&dev_priv->irqmask_lock);
	PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
	PSB_WVDC32(0x00000000, PSB_INT_MASK_R);
	PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
	PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE);
	(void)PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);

	dev_priv->sgx_irq_mask = _PSB_CE_PIXELBE_END_RENDER |
	    _PSB_CE_DPM_3D_MEM_FREE |
	    _PSB_CE_TA_FINISHED |
	    _PSB_CE_DPM_REACHED_MEM_THRESH |
	    _PSB_CE_DPM_OUT_OF_MEMORY_GBL |
	    _PSB_CE_DPM_OUT_OF_MEMORY_MT |
	    _PSB_CE_TA_TERMINATE | _PSB_CE_SW_EVENT;

	dev_priv->sgx2_irq_mask = _PSB_CE2_BIF_REQUESTER_FAULT;

	dev_priv->vdc_irq_mask = _PSB_IRQ_SGX_FLAG | _PSB_IRQ_MSVDX_FLAG | _PSB_HOTPLUG_INTERRUPT_ENABLE;

	if (!drm_psb_disable_vsync || drm_psb_detear)
		dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG |
		    _PSB_VSYNC_PIPEB_FLAG;

	/*Clear MTX interrupt */
	{
		unsigned long mtx_int = 0;
		REGIO_WRITE_FIELD_LITE(mtx_int, MSVDX_INTERRUPT_STATUS,
				       CR_MTX_IRQ, 1);
		PSB_WMSVDX32(mtx_int, MSVDX_INTERRUPT_CLEAR);
	}
	spin_unlock(&dev_priv->irqmask_lock);
}
Beispiel #14
0
/**
 *	gma_resume_display	-	resume display side logic
 *
 *	Resume the display hardware restoring state and enabling
 *	as necessary.
 */
static void gma_resume_display(struct pci_dev *pdev)
{
	struct drm_device *dev = pci_get_drvdata(pdev);
	struct drm_psb_private *dev_priv = dev->dev_private;

	/* turn on the display power island */
	dev_priv->ops->power_up(dev);
	dev_priv->suspended = false;
	dev_priv->display_power = true;

	PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
	pci_write_config_word(pdev, PSB_GMCH_CTRL,
			dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);

	psb_gtt_restore(dev); /* Rebuild our GTT mappings */
	dev_priv->ops->restore_regs(dev);
}
Beispiel #15
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_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;
}
/* 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;
}
Beispiel #18
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;
}
 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;
}
Beispiel #22
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;
}
/* dbi interface power on*/
int __dbi_power_on(struct mdfld_dsi_config *dsi_config)
{
	u32 val = 0;
	struct mdfld_dsi_hw_registers *regs;
	struct mdfld_dsi_hw_context *ctx;
	struct drm_psb_private *dev_priv;
	struct drm_device *dev;
	int retry;
	int err = 0;
	u32 guit_val = 0;
	u32 power_island = 0;
	u32 sprite_reg_offset = 0;
	int i = 0;
	int offset = 0;

	PSB_DEBUG_ENTRY("\n");

	if (!dsi_config)
		return -EINVAL;

	regs = &dsi_config->regs;
	ctx = &dsi_config->dsi_hw_context;
	dev = dsi_config->dev;
	dev_priv = dev->dev_private;

	power_island = pipe_to_island(dsi_config->pipe);

	if (power_island & (OSPM_DISPLAY_A | OSPM_DISPLAY_C))
		power_island |= OSPM_DISPLAY_MIO;

	if (is_dual_dsi(dev))
	power_island |= OSPM_DISPLAY_C;

	if (!power_island_get(power_island))
		return -EAGAIN;

	/*
	 * Wait for DSI PLL locked on pipe, and only need to poll status of pipe
	 * A as both MIPI pipes share the same DSI PLL.
	 */
	if (dsi_config->pipe == 0) {
		retry = 20000;
		while (!(REG_READ(regs->pipeconf_reg) & PIPECONF_DSIPLL_LOCK) &&
				--retry)
			udelay(150);
		if (!retry) {
			DRM_ERROR("PLL failed to lock on pipe\n");
			err = -EAGAIN;
			goto power_on_err;
		}
	}

	if (IS_ANN_A0(dev)) {
		/* FIXME: reset the DC registers for ANN A0 */
		power_island_get(OSPM_DISPLAY_B | OSPM_DISPLAY_C);

		REG_WRITE(DSPCLK_GATE_D, 0xFFFFFFFF); /* 0x10000000 */
		REG_WRITE(RAMCLK_GATE_D, 0xFFFFFFFF); /* 0x0 */
		REG_WRITE(PFIT_CONTROL, 0x20000000);
		REG_WRITE(DSPIEDCFGSHDW, 0x0);
		REG_WRITE(DSPARB2, 0x000A0200);
		REG_WRITE(DSPARB, 0x18040080);
		REG_WRITE(DSPFW1, 0x0F0F3F3F);
		REG_WRITE(DSPFW2, 0x5F2F0F3F);
		REG_WRITE(DSPFW3, 0x0);
		REG_WRITE(DSPFW4, 0x07071F1F);
		REG_WRITE(DSPFW5, 0x2F17071F);
		REG_WRITE(DSPFW6, 0x00001F3F);
		REG_WRITE(DSPFW7, 0x1F3F1F3F);
		REG_WRITE(DSPSRCTRL, 0x00080100);
		REG_WRITE(DSPCHICKENBIT, 0x0);
		REG_WRITE(FBDC_CHICKEN, 0x0C0C0C0C);
		REG_WRITE(CURACNTR, 0x0);
		REG_WRITE(CURBCNTR, 0x0);
		REG_WRITE(CURCCNTR, 0x0);
		REG_WRITE(IEP_OVA_CTRL, 0x0);
		REG_WRITE(IEP_OVA_CTRL, 0x0);
		REG_WRITE(DSPACNTR, 0x0);
		REG_WRITE(DSPBCNTR, 0x0);
		REG_WRITE(DSPCCNTR, 0x0);
		REG_WRITE(DSPDCNTR, 0x0);
		REG_WRITE(DSPECNTR, 0x0);
		REG_WRITE(DSPFCNTR, 0x0);

		power_island_put(OSPM_DISPLAY_B | OSPM_DISPLAY_C);
	}

	/*exit ULPS*/
	if (__dbi_exit_ulps_locked(dsi_config, 0)) {
		DRM_ERROR("Failed to exit ULPS\n");
		goto power_on_err;
	}
	/*update MIPI port config*/
	REG_WRITE(regs->mipi_reg, ctx->mipi |
			 REG_READ(regs->mipi_reg));

	/*unready dsi adapter for re-programming*/
	REG_WRITE(regs->device_ready_reg,
		REG_READ(regs->device_ready_reg) & ~(DSI_DEVICE_READY));

	if (is_dual_dsi(dev)) {
		if (__dbi_exit_ulps_locked(dsi_config, 0x800)) {
			DRM_ERROR("Failed to exit ULPS\n");
			goto power_on_err;
		}
		offset = 0x1000;
		REG_WRITE(regs->mipi_reg + offset, ctx->mipi |
				 REG_READ(regs->mipi_reg + offset));
		/*unready dsi adapter for re-programming*/
		offset = 0x800;
		REG_WRITE(regs->device_ready_reg + offset,
			REG_READ(regs->device_ready_reg + offset) & ~(DSI_DEVICE_READY));
	}

	/*
	 * According to MIPI D-PHY spec, if clock stop feature is enabled (EOT
	 * Disable), un-ready MIPI adapter needs to wait for 20 cycles from HS
	 * to LP mode. Per calculation 1us is enough.
	 */
	if (ctx->eot_disable & CLOCK_STOP)
		udelay(1);

	__dbi_set_properties(dsi_config, PORT_A);

	/*Setup pipe timing*/
	REG_WRITE(regs->htotal_reg, ctx->htotal);
	REG_WRITE(regs->hblank_reg, ctx->hblank);
	REG_WRITE(regs->hsync_reg, ctx->hsync);
	REG_WRITE(regs->vtotal_reg, ctx->vtotal);
	REG_WRITE(regs->vblank_reg, ctx->vblank);
	REG_WRITE(regs->vsync_reg, ctx->vsync);
	REG_WRITE(regs->pipesrc_reg, ctx->pipesrc);
	REG_WRITE(regs->dsppos_reg, ctx->dsppos);
	REG_WRITE(regs->dspstride_reg, ctx->dspstride);

	if (!IS_ANN_A0(dev)) {
		/*restore color_coef (chrome) */
		for (i = 0; i < 6; i++)
			REG_WRITE(regs->color_coef_reg + (i<<2), ctx->color_coef[i]);


		/* restore palette (gamma) */
		for (i = 0; i < 256; i++)
			REG_WRITE(regs->palette_reg + (i<<2), ctx->palette[i]);

		/* restore dpst setting */
		if (dev_priv->psb_dpst_state) {
			dpstmgr_reg_restore_locked(dev, dsi_config);
			psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
		}
	}

	/*Setup plane*/
	REG_WRITE(regs->dspsize_reg, ctx->dspsize);
	REG_WRITE(regs->dspsurf_reg, ctx->dspsurf);
	REG_WRITE(regs->dsplinoff_reg, ctx->dsplinoff);
	REG_WRITE(regs->vgacntr_reg, ctx->vgacntr);

	if (is_dual_dsi(dev))
		__dbi_set_properties(dsi_config, PORT_C);

	/*enable plane*/
	val = ctx->dspcntr | BIT31;
	REG_WRITE(regs->dspcntr_reg, val);

	if (ctx->sprite_dspcntr & BIT31) {
		if (dsi_config->pipe == 0)
			sprite_reg_offset = 0x3000;
		else if (dsi_config->pipe == 2)
			sprite_reg_offset = 0x1000;

		/* Set up Sprite Plane */
		REG_WRITE(regs->dspsize_reg + sprite_reg_offset,
				ctx->sprite_dspsize);
		REG_WRITE(regs->dspsurf_reg + sprite_reg_offset,
				ctx->sprite_dspsurf);
		REG_WRITE(regs->dsplinoff_reg + sprite_reg_offset,
				ctx->sprite_dsplinoff);
		REG_WRITE(regs->dsppos_reg + sprite_reg_offset,
				ctx->sprite_dsppos);
		REG_WRITE(regs->dspstride_reg + sprite_reg_offset,
				ctx->sprite_dspstride);

		/* enable plane */
		REG_WRITE(regs->dspcntr_reg + sprite_reg_offset,
				ctx->sprite_dspcntr);
	}

	/* Set up Overlay Plane */
	if (ctx->ovaadd)
		PSB_WVDC32(ctx->ovaadd, OV_OVADD);

	if (ctx->ovcadd)
		PSB_WVDC32(ctx->ovcadd, OVC_OVADD);

	/*ready dsi adapter*/
	REG_WRITE(regs->device_ready_reg,
		REG_READ(regs->device_ready_reg) | DSI_DEVICE_READY);
	mdelay(1);
	if (is_dual_dsi(dev)) {
		REG_WRITE(regs->device_ready_reg + offset,
			REG_READ(regs->device_ready_reg + offset) | DSI_DEVICE_READY);
	}

	if (IS_ANN_A0(dev)) {
		REG_WRITE(regs->ddl1_reg, ctx->ddl1);
		REG_WRITE(regs->ddl2_reg, ctx->ddl2);
		REG_WRITE(regs->ddl3_reg, ctx->ddl3);
		REG_WRITE(regs->ddl4_reg, ctx->ddl4);
	}

	/*Enable pipe*/
	val = ctx->pipeconf;
	val &= ~0x000c0000;
	val |= BIT31 | PIPEACONF_DSR;
	REG_WRITE(regs->pipeconf_reg, val);

	/*Wait for pipe enabling,when timing generator is working */
	retry = 10000;
	while (--retry && !(REG_READ(regs->pipeconf_reg) & BIT30))
		udelay(3);

	if (!retry) {
		DRM_ERROR("Failed to enable pipe\n");
		err = -EAGAIN;
		goto power_on_err;
	}

	/*
	 * Enable TE to trigger "write_mem_start" issuing
	 * in non-normal boot modes.
	 */
	mdfld_enable_te(dev, dsi_config->pipe);
	return err;

power_on_err:
	power_island_put(power_island);
	return err;
}
Beispiel #24
0
/**
 * mdfld_restore_cursor_overlay_registers	-	restore cursor
 * @dev: our device
 *
 * Restore the cursor and overlay state that was saved earlier
 */
static int mdfld_restore_cursor_overlay_registers(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;

	/* Enable Cursor A */
	PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
	PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
	PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);

	PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
	PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
	PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);

	PSB_WVDC32(dev_priv->saveDSPCCURSOR_CTRL, CURCCNTR);
	PSB_WVDC32(dev_priv->saveDSPCCURSOR_POS, CURCPOS);
	PSB_WVDC32(dev_priv->saveDSPCCURSOR_BASE, CURCBASE);

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

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

	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;
}
/* 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;
}
Beispiel #27
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;
}