/**
 * Power off sequence for DBI interface
*/
int __dbi_power_off(struct mdfld_dsi_config *dsi_config)
{
	struct mdfld_dsi_hw_registers *regs;
	struct mdfld_dsi_hw_context *ctx;
	struct drm_device *dev;
	struct drm_psb_private *dev_priv;
	int pipe0_enabled;
	int pipe2_enabled;
	int err = 0;
	u32 guit_val = 0;
	u32 power_island = 0;
	int retry;
	int offset = 0;

	if (!dsi_config)
		return -EINVAL;

	PSB_DEBUG_ENTRY("\n");

	regs = &dsi_config->regs;
	ctx = &dsi_config->dsi_hw_context;
	dev = dsi_config->dev;
	dev_priv = dev->dev_private;
	/*Disable plane*/
	REG_WRITE(regs->dspcntr_reg, 0);

	/*Disable pipe*/
	/* Don't disable DSR mode. */
	REG_WRITE(regs->pipeconf_reg, (REG_READ(regs->pipeconf_reg) & ~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;
		}
	}
	if (!is_dual_dsi(dev)) {
		/*enter ULPS*/
		__dbi_enter_ulps_locked(dsi_config, offset);
	} else {
		/*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*/
		__dbi_enter_ulps_locked(dsi_config, offset);

		offset = 0x1000;
		/*Disable MIPI port*/
		REG_WRITE(regs->mipi_reg +offset,
		(REG_READ(regs->mipi_reg + offset) & ~BIT31));
		/*clear Low power output hold*/
		REG_WRITE(regs->mipi_reg + offset,
		(REG_READ(regs->mipi_reg + offset) & ~BIT16));

		offset = 0x800;
		/*Disable DSI controller*/
		REG_WRITE(regs->device_ready_reg + offset, (ctx->device_ready & ~BIT0));
		/*enter ULPS*/
		__dbi_enter_ulps_locked(dsi_config, offset);
		offset = 0x0;

	}
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;
}
Beispiel #2
0
/**
 * Power off sequence for DBI interface
*/
int __dbi_power_off(struct mdfld_dsi_config *dsi_config)
{
    struct mdfld_dsi_hw_registers *regs;
    struct mdfld_dsi_hw_context *ctx;
    struct drm_device *dev;
    struct drm_psb_private *dev_priv;
    int err = 0;
    u32 power_island = 0;
    int retry,i;
    int offset = 0;
    u32 val;

    if (!dsi_config)
        return -EINVAL;

    PSB_DEBUG_ENTRY("\n");

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

    ctx->dspcntr    = REG_READ(regs->dspcntr_reg);
    ctx->pipeconf   = REG_READ(regs->pipeconf_reg);

    ctx->dsparb = REG_READ(DSPARB);
    ctx->dsparb2 = REG_READ(DSPARB2);

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

    /*Disable plane*/
    val = ctx->dspcntr;
    REG_WRITE(regs->dspcntr_reg, (val & ~BIT31));

    /*Disable pipe*/
    /* Don't disable DSR mode. */
    REG_WRITE(regs->pipeconf_reg, (REG_READ(regs->pipeconf_reg) & ~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");
            if (IS_MOFD(dev)) {
                /*
                 * FIXME: turn off the power island directly
                 * although failed to disable pipe.
                 */
                err = 0;
            } else
                err = -EAGAIN;
            goto power_off_err;
        }
    }
    if (!is_dual_dsi(dev)) {
        /*enter ULPS*/
        __dbi_enter_ulps_locked(dsi_config, offset);
    } else {
        /*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*/
        __dbi_enter_ulps_locked(dsi_config, offset);

        offset = 0x1000;
        /*Disable MIPI port*/
        REG_WRITE(regs->mipi_reg +offset,
                  (REG_READ(regs->mipi_reg + offset) & ~BIT31));
        /*clear Low power output hold*/
        REG_WRITE(regs->mipi_reg + offset,
                  (REG_READ(regs->mipi_reg + offset) & ~BIT16));

        offset = 0x800;
        /*Disable DSI controller*/
        REG_WRITE(regs->device_ready_reg + offset, (ctx->device_ready & ~BIT0));
        /*enter ULPS*/
        __dbi_enter_ulps_locked(dsi_config, offset);
        offset = 0x0;

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