void enable_HFPLL(struct drm_device *dev)
{
	uint32_t pll_select = 0, ctrl_reg5 = 0;
	struct drm_psb_private *dev_priv =
		(struct drm_psb_private *)dev->dev_private;

	/* Enable HFPLL for command mode panel */
	if (dev_priv->bUseHFPLL) {
			pll_select = intel_mid_msgbus_read32(CCK_PORT,
						DSI_PLL_CTRL_REG);
			ctrl_reg5 = intel_mid_msgbus_read32(CCK_PORT,
						FUSE_OVERRIDE_FREQ_CNTRL_REG5);

			pll_select &= ~(_DSI_MUX_SEL_CCK_DSI1 |
					_DSI_MUX_SEL_CCK_DSI0);

			intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG,
					pll_select | _DSI_CCK_PLL_SELECT);
			ctrl_reg5 |= (1 << 7) | 0xF;

			if (get_panel_type(dev, 0) == SHARP_10x19_CMD)
				ctrl_reg5 = 0x1f87;
			intel_mid_msgbus_write32(CCK_PORT,
					FUSE_OVERRIDE_FREQ_CNTRL_REG5,
					ctrl_reg5);
	}
}
Ejemplo n.º 2
0
void enable_HFPLL(struct drm_device *dev)
{
	uint32_t pll_select = 0, ctrl_reg5 = 0;
	struct drm_psb_private *dev_priv =
		(struct drm_psb_private *)dev->dev_private;

	/* Enable HFPLL for B0 command mode panel */
	if ((IS_TNG_B0(dev)) &&
		(dev_priv->mipi_encoder_type == MDFLD_DSI_ENCODER_DBI)) {
			pll_select = intel_mid_msgbus_read32(CCK_PORT,
						DSI_PLL_CTRL_REG);
			ctrl_reg5 = intel_mid_msgbus_read32(CCK_PORT,
						FUSE_OVERRIDE_FREQ_CNTRL_REG5);

			pll_select &= ~(_DSI_MUX_SEL_CCK_DSI1 |
					_DSI_MUX_SEL_CCK_DSI0);

			intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG,
					pll_select | _DSI_CCK_PLL_SELECT);
			ctrl_reg5 |= (1 << 7) | 0xF;
			intel_mid_msgbus_write32(CCK_PORT,
					FUSE_OVERRIDE_FREQ_CNTRL_REG5,
					ctrl_reg5);
	}
}
void power_on_pipe(u32 msg_port, u32 msg_reg,
							u32 val_comp, u32 val_write)
{
	u32 ret;
	int retry=0;

	ret = intel_mid_msgbus_read32(msg_port, msg_reg);

	if ((ret & val_comp) == 0) {
		DRM_ERROR("%s: pipe is already powered on\n", __func__);
		return;
	} else {
		intel_mid_msgbus_write32(msg_port, msg_reg, ret & val_write);
		ret = intel_mid_msgbus_read32(msg_port, msg_reg);
		while ((retry < 1000) && ((ret & val_comp) != 0)) {
			msleep(1);
			ret = intel_mid_msgbus_read32(msg_port, msg_reg);
			retry++;
		}
		if ((ret & val_comp) != 0)
			DRM_ERROR("%s: powering on pipe failed\n", __func__);
		if (msg_port == 0x4 && msg_reg == 0x3b) {
			DRM_ERROR("%s: skip powering up MIO AFE\n", __func__);
		}
	}
}
void power_off_pipe(u32 msg_port, u32 msg_reg, u32 val, u32 val_comp)
{
	u32 ret;
	int retry=0;

	ret = intel_mid_msgbus_read32(msg_port, msg_reg);

	intel_mid_msgbus_write32(msg_port, msg_reg, ret | val);

	ret = intel_mid_msgbus_read32(msg_port, msg_reg);
	if (((ret & val_comp) != val_comp) && (retry < 1000)) {
		retry++;
		ret = intel_mid_msgbus_read32(msg_port, msg_reg);
	}
}
static int wait_for_nc_pmcmd_complete(int verify_mask,
				int status_mask, int state_type , int reg)
{
	int pwr_sts;
	int count = 0;

	while (true) {
		pwr_sts = intel_mid_msgbus_read32(PUNIT_PORT, reg);
		pwr_sts = pwr_sts >> SSS_SHIFT;
		if (state_type == OSPM_ISLAND_DOWN ||
					state_type == OSPM_ISLAND_SR) {
			if ((pwr_sts & status_mask) ==
						(verify_mask & status_mask))
				break;
			else
				udelay(10);
		} else if (state_type == OSPM_ISLAND_UP) {
			if ((~pwr_sts & status_mask)  ==
						(~verify_mask & status_mask))
				break;
			else
				udelay(10);
		}

		count++;
		if (WARN_ONCE(count > 500000, "Timed out waiting for P-Unit"))
			return -EBUSY;
	}
	return 0;
}
static int punit_read_reg_gfxsspm1(int attempts, int interval_us, u32 *p_reg_value)
{
	int ui_count;

	*p_reg_value = 0;

	if(!p_reg_value)
		return -EINVAL;

	for (ui_count = 0; ; ui_count++) {

		*p_reg_value = intel_mid_msgbus_read32(PUNIT_PORT, GFX_SS_PM1);

		if(*p_reg_value) {
#if defined(RGX_POW_MON_DEBUG) && RGX_POW_MON_DEBUG
			printk(KERN_ALERT "punit_read_reg_gfxsspm1: read reg value: %0x\n", *p_reg_value);
#endif
			break;
		}
		if (ui_count >= attempts)
			return -EBUSY;

		udelay(interval_us);
	}

	return 0;
}
bool disable_DSIPLL(struct drm_device * dev)
{
	u32 val, guit_val;

	/* Disable PLL*/
	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0);

	val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
	val &= ~_CLK_EN_MASK;
	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, val);
	udelay(1);
	val &= ~DPLL_VCO_ENABLE;
	val |= _DSI_LDO_EN;
	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, val);
	udelay(1);

	guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
	if ((guit_val & _DSI_PLL_LOCK) == _DSI_PLL_LOCK ) {
		DRM_ERROR("DSI PLL fails to Unlock\n");
		return false;
	}
	return true;
}
/* This function checks north complex (NC) and
 * south complex (SC) device status in MRFLD.
 * returns TRUE if all NC and SC devices are in d0i3
 * else FALSE.
 */
static bool mrfld_nc_sc_status_check(void)
{
	int i;
	u32 val, nc_pwr_sts;
	struct pmu_ss_states cur_pmsss;
	bool nc_status, sc_status;

	/* assuming nc and sc are good */
	nc_status = true;
	sc_status = true;

	/* Check south complex device status */
	pmu_read_sss(&cur_pmsss);

	if (!(((cur_pmsss.pmu2_states[0] & S0IX_TARGET_SSS0_MASK) ==
					 S0IX_TARGET_SSS0) &&
		((cur_pmsss.pmu2_states[1] & S0IX_TARGET_SSS1_MASK) ==
					 S0IX_TARGET_SSS1) &&
		((cur_pmsss.pmu2_states[2] & S0IX_TARGET_SSS2_MASK) ==
					 S0IX_TARGET_SSS2) &&
		((cur_pmsss.pmu2_states[3] & S0IX_TARGET_SSS3_MASK) ==
					 (S0IX_TARGET_SSS3)))) {
		sc_status = false;
		pr_warn("SC device/devices not in d0i3!!\n");
	}

	if (sc_status) {
		/* Check north complex status */
		nc_pwr_sts =
			 intel_mid_msgbus_read32(PUNIT_PORT, NC_PM_SSS);
		/* loop through the status to see if any of nc power island
		 * is not in D0i3 state
		 */
		for (i = 0; i < mrfl_no_of_nc_devices; i++) {
			val = nc_pwr_sts & 3;
			if (val != 3) {
				nc_status = false;
				pr_warn("NC device/devices is not in D0i3!!\n");
				break;
			}
			nc_pwr_sts >>= BITS_PER_LSS;
		}
	}

	return nc_status & sc_status;
}
static int mrfld_nc_set_power_state(int islands, int state_type,
							int reg, int *change)
{
	u32 pwr_sts = 0;
	u32 pwr_mask = 0;
	int i, lss, mask;
	int ret = 0;
	int status_mask = 0;

	*change = 0;
	pwr_sts = intel_mid_msgbus_read32(PUNIT_PORT, reg);
	pwr_mask = pwr_sts;

	for (i = 0; i < OSPM_MAX_POWER_ISLANDS; i++) {
		lss = islands & (0x1 << i);
		if (lss) {
			mask = D0I3_MASK << (BITS_PER_LSS * i);
			status_mask = status_mask | mask;
			if (state_type == OSPM_ISLAND_DOWN)
				pwr_mask |= mask;
			else if (state_type == OSPM_ISLAND_UP)
				pwr_mask &= ~mask;
			/* Soft reset case */
			else if (state_type == OSPM_ISLAND_SR) {
				pwr_mask &= ~mask;
				mask = SR_MASK << (BITS_PER_LSS * i);
				pwr_mask |= mask;
			}
		}
	}

	if (pwr_mask != pwr_sts) {
		intel_mid_msgbus_write32(PUNIT_PORT, reg, pwr_mask);
		ret = wait_for_nc_pmcmd_complete(pwr_mask,
					status_mask, state_type, reg);
		if (!ret)
			*change = 1;
		if (nc_report_power_state)
			nc_report_power_state(pwr_mask, reg);
	}

	return ret;
}
Ejemplo n.º 10
0
static int atomisp_save_iunit_reg(struct atomisp_device *isp)
{
	struct pci_dev *dev = isp->pdev;

	dev_dbg(isp->dev, "%s\n", __func__);

	pci_read_config_word(dev, PCI_COMMAND, &isp->saved_regs.pcicmdsts);
	/* isp->saved_regs.ispmmadr is set from the atomisp_pci_probe() */
	pci_read_config_dword(dev, PCI_MSI_CAPID, &isp->saved_regs.msicap);
	pci_read_config_dword(dev, PCI_MSI_ADDR, &isp->saved_regs.msi_addr);
	pci_read_config_word(dev, PCI_MSI_DATA,  &isp->saved_regs.msi_data);
	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &isp->saved_regs.intr);
	pci_read_config_dword(dev, PCI_INTERRUPT_CTRL,
			      &isp->saved_regs.interrupt_control);

	if (IS_ISP2400) {
		pci_read_config_dword(dev, MRFLD_PCI_PMCS,
				      &isp->saved_regs.pmcs);
		/* Ensure read/write combining is enabled. */
		pci_read_config_dword(dev, PCI_I_CONTROL,
				&isp->saved_regs.i_control);
		isp->saved_regs.i_control |=
				MRFLD_PCI_I_CONTROL_ENABLE_READ_COMBINING |
				MRFLD_PCI_I_CONTROL_ENABLE_WRITE_COMBINING;
		pci_read_config_dword(dev, MRFLD_PCI_CSI_ACCESS_CTRL_VIOL,
				      &isp->saved_regs.csi_access_viol);
		pci_read_config_dword(dev, MRFLD_PCI_CSI_RCOMP_CONTROL,
				      &isp->saved_regs.csi_rcomp_config);
		pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL,
				      &isp->saved_regs.csi_afe_dly);
		pci_read_config_dword(dev, MRFLD_PCI_CSI_CONTROL,
				      &isp->saved_regs.csi_control);
		pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_RCOMP_CONTROL,
				      &isp->saved_regs.csi_afe_rcomp_config);
		pci_read_config_dword(dev, MRFLD_PCI_CSI_AFE_HS_CONTROL,
				      &isp->saved_regs.csi_afe_hs_control);
		pci_read_config_dword(dev, MRFLD_PCI_CSI_DEADLINE_CONTROL,
				      &isp->saved_regs.csi_deadline_control);
	} else {
		pci_read_config_dword(dev, MFLD_PCI_PMCS,
				      &isp->saved_regs.pmcs);

		/* Ensure clock gating for ISPCLK, PERF and NOA monitoring. */
		pci_read_config_dword(dev, MFLD_PCI_CG_DIS,
				      &isp->saved_regs.cg_dis);
		isp->saved_regs.cg_dis &= ~(MFLD_PCI_CG_DIS_DISABLED_ISPCLK |
				MFLD_PCI_CG_DIS_DISABLED_PERF_MON |
				MFLD_PCI_CG_DIS_DISABLED_NOA_MON);

		/* Ensure read/write combining is enabled. */
		pci_read_config_dword(dev, PCI_I_CONTROL,
				&isp->saved_regs.i_control);
		isp->saved_regs.i_control |=
				MFLD_PCI_I_CONTROL_ENABLE_READ_COMBINING |
				MFLD_PCI_I_CONTROL_ENABLE_WRITE_COMBINING;

		isp->saved_regs.csi_rcomp_config = intel_mid_msgbus_read32(
				MFLD_IUNITPHY_PORT, MFLD_CSI_RCOMP);
		isp->saved_regs.csi_afe_dly = intel_mid_msgbus_read32(
				MFLD_IUNITPHY_PORT, MFLD_CSI_AFE);

		/* Ensure mipi1 and mipi4 configurations are enabled */
		isp->saved_regs.csi_control = intel_mid_msgbus_read32(
				MFLD_IUNITPHY_PORT, MFLD_CSI_CONTROL);
		isp->saved_regs.csi_control &= ~(MFLD_CSI_CONTROL_DIS_MIPI4_IF |
				MFLD_CSI_CONTROL_DIS_MIPI1_IF);
		isp->saved_regs.csi_control |= MFLD_CSI_CONTROL_EN_MIPI4_LANE |
				MFLD_CSI_CONTROL_EN_MIPI1_LANE;
	}

	return 0;
}
static inline u32 read_soc_reg(unsigned int addr)
{
	return intel_mid_msgbus_read32(PUNIT_PORT, addr);
}
/**
 * Power off sequence for video mode MIPI panel.
 * NOTE: do NOT modify this function
 */
static int __dpi_panel_power_off(struct mdfld_dsi_config *dsi_config,
		struct panel_funcs *p_funcs)
{
	u32 val = 0;
	u32 tmp = 0;
	struct mdfld_dsi_hw_registers *regs;
	struct mdfld_dsi_hw_context *ctx;
	struct drm_device *dev;
	struct drm_psb_private *dev_priv;
	int retry;
	int i;
	int err = 0;
	u32 guit_val = 0;
	u32 power_island = 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;

	/* Don't reset brightness to 0.*/
	ctx->lastbrightnesslevel = psb_brightness;

	tmp = REG_READ(regs->pipeconf_reg);

	/*save color_coef (chrome) */
	for (i = 0; i < 6; i++)
		ctx->color_coef[i] = REG_READ(regs->color_coef_reg + (i<<2));

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

	/*
	 * Couldn't disable the pipe until DRM_WAIT_ON signaled by last
	 * vblank event when playing video, otherwise the last vblank event
	 * will lost when pipe disabled before vblank interrupt coming
	 * sometimes.
	 */

	/*Disable panel*/
	val = ctx->dspcntr;
	REG_WRITE(regs->dspcntr_reg, (val & ~BIT31));
	/*Disable overlay & cursor panel assigned to this pipe*/
	REG_WRITE(regs->pipeconf_reg, (tmp | (0x000c0000)));

	/*Disable pipe*/
	val = REG_READ(regs->pipeconf_reg);
	ctx->pipeconf = val;
	REG_WRITE(regs->pipeconf_reg, (val & ~BIT31));

	/*wait for pipe disabling,
	  pipe synchronization plus , only avaiable when
	  timer generator is working*/
	if (REG_READ(regs->mipi_reg) & BIT31) {
		retry = 100000;
		while (--retry && (REG_READ(regs->pipeconf_reg) & BIT30))
			udelay(5);

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

	/**
	 * Different panel may have different ways to have
	 * panel turned off. Support it!
	 */
	if (p_funcs && p_funcs->power_off) {
		if (p_funcs->power_off(dsi_config)) {
			DRM_ERROR("Failed to power off panel\n");
			err = -EAGAIN;
			goto power_off_err;
		}
	}

	/*Disable MIPI port*/
	REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT31));

	/*clear Low power output hold*/
	REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT16));

	/*Disable DSI controller*/
	REG_WRITE(regs->device_ready_reg, (ctx->device_ready & ~BIT0));

	/*enter ULPS*/
	__dpi_enter_ulps_locked(dsi_config, offset);

	if (is_dual_dsi(dev)) {
		offset = 0x1000;
		/*Disable MIPI port*/
		REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT31));

		/*clear Low power output hold*/
		REG_WRITE(regs->mipi_reg, (REG_READ(regs->mipi_reg) & ~BIT16));
		offset = 0x800;
		/*Disable DSI controller*/
		REG_WRITE(regs->device_ready_reg, (ctx->device_ready & ~BIT0));

		/*enter ULPS*/
		__dpi_enter_ulps_locked(dsi_config, offset);
		offset = 0x0;
	}

	/* Disable DSI PLL */
	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0);
	guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, _DSI_LDO_EN);

power_off_err:
	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_put(power_island))
		return -EINVAL;

	return err;
}
/**
 * Power on sequence for video mode MIPI panel.
 * NOTE: do NOT modify this function
 */
static int __dpi_panel_power_on(struct mdfld_dsi_config *dsi_config,
		struct panel_funcs *p_funcs)
{
	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, reset_count = 10;
	int i;
	int err = 0;
	u32 guit_val = 0;
	u32 power_island = 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;

reset_recovery:
	--reset_count;
	/*HW-Reset*/
	if (p_funcs && p_funcs->reset)
		p_funcs->reset(dsi_config);

	if (!is_dual_dsi(dev)) {
		/* Disable PLL*/
		intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0);
		guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
		intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, _DSI_LDO_EN);

		/* Program PLL */
		intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, ctx->fp);

		guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
		intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG,
		                ((guit_val & ~_P1_POST_DIV_MASK) |
		                 (ctx->dpll & _P1_POST_DIV_MASK)));
		ctx->dpll |= DPLL_VCO_ENABLE;
		ctx->dpll &= ~_DSI_LDO_EN;
		intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, ctx->dpll);
	} else {
		intel_mid_msgbus_write32(CCK_PORT, 0x68, 0x682);
		/* Disable PLL*/
		intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0);
		guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
		intel_mid_msgbus_write32(CCK_PORT,
					DSI_PLL_CTRL_REG,
					_DSI_LDO_EN);
		/* Program PLL */
		intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, ctx->fp);
		guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
		intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG,
				((guit_val & ~_P1_POST_DIV_MASK) |
				 (ctx->dpll & _P1_POST_DIV_MASK)));
		guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
		ctx->dpll |= DPLL_VCO_ENABLE;
		ctx->dpll &= ~(_DSI_LDO_EN |
			       _CLK_EN_CCK_DSI0 | _CLK_EN_CCK_DSI1 |
			       _DSI_MUX_SEL_CCK_DSI1 | _DSI_MUX_SEL_CCK_DSI0);
		ctx->dpll |= _CLK_EN_PLL_DSI0 | _CLK_EN_PLL_DSI1;
		intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, ctx->dpll);
	}
	/* Wait for DSI PLL lock */
	retry = 10000;
	guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
	while (((guit_val & _DSI_PLL_LOCK) != _DSI_PLL_LOCK) && (--retry)) {
		udelay(3);
		guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
		if (retry == 0) {
			DRM_ERROR("DSI PLL fails to lock\n");
			err = -EAGAIN;
			goto power_on_err;
		}
	}

	/*
	 * 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;
		}
	}
	__dpi_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)) {
		/*reset registers*/
		REG_WRITE(0x7002C, 0x000A0200);
		REG_WRITE(0x70508, 0x0c0c0c0c);
		REG_WRITE(0x70504, 0xffffffff);
		REG_WRITE(0x70500, 0xffffffff);
		DRM_DEBUG("LOADING: 0x70504 %#x\n", REG_READ(0x70504));
	}

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

	/*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);
	}

	if (__dpi_config_port(dsi_config, p_funcs, PORT_A) != 0) {
		if (!reset_count) {
				err = -EAGAIN;
				goto power_on_err;
			}
			DRM_ERROR("Failed to init dsi controller, reset it!\n");
			goto reset_recovery;
	}
	if (is_dual_dsi(dev)) {
		__dpi_set_properties(dsi_config, PORT_C);
		__dpi_config_port(dsi_config, p_funcs, PORT_C);
	}

	/**
	 * Different panel may have different ways to have
	 * drvIC initialized. Support it!
	 */
	if (p_funcs && p_funcs->drv_ic_init) {
		if (p_funcs->drv_ic_init(dsi_config)) {
			if (!reset_count) {
				err = -EAGAIN;
				goto power_on_err;
			}

			DRM_ERROR("Failed to init dsi controller, reset it!\n");
			goto reset_recovery;
		}
	}

	/*Enable MIPI Port A*/
	offset = 0x0;
	REG_WRITE(regs->mipi_reg + offset, (ctx->mipi | BIT31));

	REG_WRITE(regs->dpi_control_reg + offset, BIT1);
	if (is_dual_dsi(dev)) {
		/*Enable MIPI Port C*/
		offset = 0x1000;
		REG_WRITE(regs->mipi_reg + offset, (ctx->mipi | BIT31));
		offset = 0x800;
		REG_WRITE(regs->dpi_control_reg + offset, BIT1);
	}
	/**
	 * Different panel may have different ways to have
	 * panel turned on. Support it!
	 */
	if (p_funcs && p_funcs->power_on)
		if (p_funcs->power_on(dsi_config)) {
			DRM_ERROR("Failed to power on panel\n");
			err = -EAGAIN;
			goto power_on_err;
		}
	/*Enable pipe*/
	val = ctx->pipeconf;
	val &= ~0x000c0000;
	val |= BIT31;
	REG_WRITE(regs->pipeconf_reg, val);
	/*Wait for pipe enabling,when timing generator
	  is wroking */
	if (REG_READ(regs->mipi_reg) & BIT31) {
		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 plane*/
	val = ctx->dspcntr | BIT31;
	REG_WRITE(regs->dspcntr_reg, val);

	if (p_funcs && p_funcs->set_brightness) {
		if (p_funcs->set_brightness(dsi_config,
				ctx->lastbrightnesslevel))
			DRM_ERROR("Failed to set panel brightness\n");
	} else {
		DRM_ERROR("Failed to set panel brightness\n");
	}
	if (p_funcs && p_funcs->drv_set_panel_mode)
		p_funcs->drv_set_panel_mode(dsi_config);

	psb_enable_vblank(dev, dsi_config->pipe);
	return err;

power_on_err:
	power_island_put(power_island);
	return err;
}
bool enable_DSIPLL(struct drm_device *dev)
{
	DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	u32 guit_val = 0x0;
	u32 retry;

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

	if (IS_ANN(dev)) {
		int dspfreq;

		if ((get_panel_type(dev, 0) == JDI_7x12_CMD) ||
			(get_panel_type(dev, 0) == JDI_7x12_VID))
			dspfreq = DISPLAY_FREQ_FOR_200;
		else
			dspfreq = DISPLAY_FREQ_FOR_333;

		intel_mid_msgbus_write32(CCK_PORT,
			FUSE_OVERRIDE_FREQ_CNTRL_REG5,
			CKESC_GATE_EN | CKDP1X_GATE_EN | DISPLAY_FRE_EN
			| dspfreq);
	}

	/* Prepare DSI  PLL register before enabling */
	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, 0);
	guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
	guit_val &= ~(DPLL_VCO_ENABLE | _DSI_LDO_EN
			|_CLK_EN_MASK | _DSI_MUX_SEL_CCK_DSI0 | _DSI_MUX_SEL_CCK_DSI1);
	intel_mid_msgbus_write32(CCK_PORT,
					DSI_PLL_CTRL_REG, guit_val);
	udelay(1);
	/* Program PLL */

	/*first set up the dpll and fp variables
	 * dpll - will contain the following information
	 *      - the clock source - DSI vs HFH vs LFH PLL
	 * 	- what clocks should be running DSI0, DSI1
	 *      - and the divisor.
	 *
	 */

	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_DIV_REG, ctx->fp);
	guit_val &= ~_P1_POST_DIV_MASK;	/*clear the divisor bit*/
	/* the ctx->dpll contains the divisor that we need to use as well as which clocks
	 * need to start up */
	guit_val |= ctx->dpll;
	guit_val &= ~_DSI_LDO_EN;	/* We want to clear the LDO enable when programming*/
	guit_val |=  DPLL_VCO_ENABLE;	/* Enable the DSI PLL */

	/* For the CD clock (clock used by Display controller), we need to set
	 * the DSI_CCK_PLL_SELECT bit (bit 11). This should already be set. But
	 * setting it just in case
	 */
	if (dev_priv->bUseHFPLL)
		guit_val |= _DSI_CCK_PLL_SELECT;

	intel_mid_msgbus_write32(CCK_PORT, DSI_PLL_CTRL_REG, guit_val);

	/* Wait for DSI PLL lock */
	retry = 10000;
	guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
	while (((guit_val & _DSI_PLL_LOCK) != _DSI_PLL_LOCK) && (--retry)) {
		udelay(3);
		guit_val = intel_mid_msgbus_read32(CCK_PORT, DSI_PLL_CTRL_REG);
		if (!retry%1000)
			DRM_ERROR("DSI PLL taking too long to lock"
				"- retry count=%d\n", 10000-retry);
	}
	if (retry == 0) {
		DRM_ERROR("DSI PLL fails to lock\n");
		return false;
	}

	return true;
err_out:
	return false;

}
int vsp_init_fw(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct vsp_private *vsp_priv = dev_priv->vsp_private;
	int ret = 0;
	const struct firmware *raw;
	unsigned char *ptr, *ma_ptr;
	struct vsp_secure_boot_header *boot_header;
	struct vsp_multi_app_blob_data *ma_header;
	unsigned long imr_addr;
	int imr_size;
	unsigned char *imr_ptr;
	unsigned int vrl_header_size = 736;
	const unsigned long vsp_magic_num = 0x50535624;
	const int FW_NAME_LEN = 30;
	char fw_name[FW_NAME_LEN];
	int name_ret;

	PSB_DEBUG_GENERAL("read firmware into buffer\n");

	name_ret = snprintf(fw_name, FW_NAME_LEN, "vsp.bin.%04x.%04x",
		 (int)spid.platform_family_id, (int)spid.hardware_id);
	if (name_ret > FW_NAME_LEN) {
		DRM_ERROR("failed to get fw name, ret %d vs expect %d\n",
			  name_ret, FW_NAME_LEN);
		/* no way */
		return -1;
	}

	/* try load with spid first */
	ret = request_firmware(&raw, fw_name, &dev->pdev->dev);
	if (ret < 0 || raw == NULL) {
		VSP_DEBUG("failed to load fw: %s, try to load different fw\n",
			fw_name);

		/* read firmware img */
		VSP_DEBUG("load vsp fw\n");
		if (IS_ANN_A0(dev))
			ret = request_firmware(&raw, FW_NAME_ANN,
					       &dev->pdev->dev);
		else if (IS_TNG_B0(dev))
			ret = request_firmware(&raw, FW_NAME_B0,
					       &dev->pdev->dev);
		else {
			DRM_ERROR("VSP secure fw: bad platform\n");
			raw = NULL;
		}
	}

	if (ret < 0 || raw == NULL) {
		DRM_ERROR("VSP: request_firmware failed: reason %d\n", ret);
		return -1;
	}

	if (raw->size < sizeof(struct vsp_secure_boot_header)) {
		DRM_ERROR("VSP: %s is not a correct firmware (size %d)\n",
				FW_NAME, raw->size);
		ret = -1;
		goto out;
	}

	ptr = (void *)raw->data;
	ma_ptr = (void *) raw->data + vrl_header_size;
	boot_header = (struct vsp_secure_boot_header *)
		(ptr + vrl_header_size);
	ma_header = (struct vsp_multi_app_blob_data *)
		(ma_ptr + boot_header->ma_header_offset);

	/* get firmware header */
	memcpy(&vsp_priv->boot_header, boot_header, sizeof(vsp_priv->boot_header));

	if (vsp_priv->boot_header.magic_number != VSP_SECURE_BOOT_MAGIC_NR) {
		DRM_ERROR("VSP: failed to load correct vsp firmware\n"
			  "FW magic number is wrong %x (should be %x)\n",
			  vsp_priv->boot_header.magic_number,
			  VSP_SECURE_BOOT_MAGIC_NR);
		ret = -1;
		goto out;
	}

	/* read application firmware image data (for state-buffer size, etc) */
	/* load the multi-app blob header */
	memcpy(&vsp_priv->ma_header, ma_header, sizeof(vsp_priv->ma_header));
	if (vsp_priv->ma_header.magic_number != VSP_MULTI_APP_MAGIC_NR) {
		DRM_ERROR("VSP: failed to load correct vsp firmware\n"
			  "FW magic number is wrong %x (should be %x)\n",
			  vsp_priv->ma_header.magic_number,
			  VSP_MULTI_APP_MAGIC_NR);
		ret = -1;
		goto out;
	}

	VSP_DEBUG("firmware secure header:\n");
	VSP_DEBUG("boot_header magic number %x\n", boot_header->magic_number);
	VSP_DEBUG("boot_text_offset %x\n", boot_header->boot_text_offset);
	VSP_DEBUG("boot_text_reg %x\n", boot_header->boot_text_reg);
	VSP_DEBUG("boot_icache_value %x\n", boot_header->boot_icache_value);
	VSP_DEBUG("boot_icache_reg %x\n", boot_header->boot_icache_reg);
	VSP_DEBUG("boot_pc_value %x\n", boot_header->boot_pc_value);
	VSP_DEBUG("boot_pc_reg %x\n", boot_header->boot_pc_reg);
	VSP_DEBUG("ma_header_offset %x\n", boot_header->ma_header_offset);
	VSP_DEBUG("ma_header_reg %x\n", boot_header->ma_header_reg);
	VSP_DEBUG("boot_start_value %x\n", boot_header->boot_start_value);
	VSP_DEBUG("boot_start_reg %x\n", boot_header->boot_start_reg);
	VSP_DEBUG("firmware ma_blob header:\n");
	VSP_DEBUG("ma_header magic number %x\n", ma_header->magic_number);
	VSP_DEBUG("offset_from_start %x\n", ma_header->offset_from_start);
	VSP_DEBUG("imr_state_buffer_addr %x\n", ma_header->imr_state_buffer_addr);
	VSP_DEBUG("imr_state_buffer_size %x\n", ma_header->imr_state_buffer_size);
	VSP_DEBUG("apps_default_context_buffer_size %x\n",
			ma_header->apps_default_context_buffer_size);

	/* get imr 11 region start address and size */
	imr_addr = intel_mid_msgbus_read32(PNW_IMR_MSG_PORT,
					   TNG_IMR11L_MSG_REGADDR);
	imr_addr <<= 10;
	VSP_DEBUG("IMR11 base address %p\n", imr_addr);

	imr_size = raw->size;

	/* map imr 11 */
	/* check if raw size is smaller than */
	/* ioremap the region */
	imr_ptr = ioremap(imr_addr, imr_size);
	if (!imr_ptr) {
		DRM_ERROR("failed to map imr_addr\n");
		ret = -1;
		goto out;
	}

	/* copy the firmware to imr 11 */
	memcpy(imr_ptr, ptr, raw->size);

	/* unmap the region */
	iounmap(imr_ptr);
#ifdef CONFIG_DX_SEP54
	ret = sepapp_image_verify(imr_addr, imr_size, 15, vsp_magic_num);
	if (ret) {
		DRM_ERROR("failed to verify vsp firmware, ret %x\n", ret);
		ret = -1;
		goto out;
	}
#endif

	vsp_priv->fw_loaded = VSP_FW_LOADED;
	vsp_priv->vsp_state = VSP_STATE_DOWN;

	vsp_priv->ctrl = (struct vsp_ctrl_reg *) (dev_priv->vsp_reg +
						  VSP_CONFIG_REG_SDRAM_BASE +
						  VSP_CONFIG_REG_START);
out:
	release_firmware(raw);

	return ret;
}