Example #1
0
/**
 * 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, bool first_boot)
{
	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 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;
	if (android_hdmi_is_connected(dev) && first_boot)
			otm_hdmi_power_islands_on();

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

	/*
	 * 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(dev)) {
		/* FIXME: reset the DC registers for ANN A0 */
		ann_dc_setup(dsi_config);
	}

	__dpi_set_properties(dsi_config, PORT_A);

	/* update 0x650c[0] = 1 to fixed arbitration pattern
	 * it is found display TLB request be blocked by display plane
	 * memory requests, never goes out. This causes display controller
	 * uses stale TLB data to do memory translation, getting wrong
	 * memory address for data, and causing the flickering issue.
	 */
	REG_WRITE(GCI_CTRL, REG_READ(GCI_CTRL) | 1);

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

	/*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), csc_setting_save[i]);

	/* restore palette (gamma) */
	for (i = 0; i < 256; i++)
		REG_WRITE(regs->palette_reg + (i<<2), gamma_setting_save[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;
		}

	if (IS_ANN(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);

		REG_WRITE(DSPARB2, ctx->dsparb2);
		REG_WRITE(DSPARB, ctx->dsparb);
	}

	/*Enable pipe*/
	val = ctx->pipeconf;
	val &= ~0x000c0000;
	/**
	 * Frame Start occurs on third HBLANK
	 * after the start of VBLANK
	 */
	val |= BIT31 | BIT28;
	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;
}
/**
 * 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;
}
/**
 * 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);

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

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

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

	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;
	/**
	 * Frame Start occurs on third HBLANK
	 * after the start of VBLANK
	 */
	val |= BIT31 | BIT28;
	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;
}