Пример #1
0
static struct panel_funcs *dsi_config_to_p_func(
	struct mdfld_dsi_config *dsi_config)
{
	struct mdfld_dsi_encoder *encoder;
	struct mdfld_dsi_dpi_output *dpi_output;
	struct mdfld_dsi_dbi_output *dbi_output;
	struct panel_funcs *p_funcs = NULL;

	if (!dsi_config)
		return NULL;

	encoder = dsi_config->encoders[dsi_config->type];
	if (!encoder)
		return NULL;

	if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
		dbi_output = MDFLD_DSI_DBI_OUTPUT(encoder);
		p_funcs = dbi_output ? dbi_output->p_funcs : NULL;
	} else if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
		dpi_output = MDFLD_DSI_DPI_OUTPUT(encoder);
		p_funcs = dpi_output ? dpi_output->p_funcs : NULL;
	}

	return p_funcs;
}
Пример #2
0
static void mdfld_dsi_configure_up(struct mdfld_dsi_encoder *dsi_encoder,
								int pipe)
{
	struct mdfld_dsi_dpi_output *dpi_output =
				MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
				mdfld_dsi_encoder_get_config(dsi_encoder);
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;

	if (dev_priv->dpi_panel_on[pipe]) {
		dev_err(dev->dev, "DPI panel is already on\n");
		return;
	}

	/* For resume path sequence */
	mdfld_dsi_dpi_shut_down(dpi_output, pipe);
	dsi_set_device_ready_state(dev, 0, pipe);

	dsi_set_device_ready_state(dev, 1, pipe);
	tc35876x_set_bridge_reset_state(dev, 0);
	tc35876x_configure_lvds_bridge(dev);
	mdfld_dsi_dpi_turn_on(dpi_output, pipe);  /* Send turn on command */
	dsi_set_pipe_plane_enable_state(dev, 1, pipe);
}
static
void mdfld_dsi_dpi_commit(struct drm_encoder *encoder)
{
    struct mdfld_dsi_encoder *dsi_encoder;
    struct mdfld_dsi_dpi_output *dpi_output;
    struct mdfld_dsi_hw_context *ctx;
    struct mdfld_dsi_config *dsi_config;
    struct drm_device *dev;
    u32 temp_val = 0;

    PSB_DEBUG_ENTRY("\n");

    dsi_encoder = MDFLD_DSI_ENCODER(encoder);
    dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
    dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
    dev = dsi_config->dev;
    ctx = &dsi_config->dsi_hw_context;

    if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON))
        return;
    temp_val = REG_READ(PIPEACONF);
    temp_val &= ~(BIT27 | BIT28);
    /* Setup pipe configuration for different panels*/
    REG_WRITE(PIPEACONF, temp_val | (ctx->pipeconf & (BIT27 | BIT28)));
    ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

    /*Everything is ready, commit DSI hw context to HW*/
    __mdfld_dsi_dpi_set_power(encoder, true);
    dpi_output->first_boot = 0;
}
Пример #4
0
void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
	int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	u32 mipi_reg = MIPI;
	u32 pipeconf_reg = PIPEACONF;
	
	if(pipe) {
		mipi_reg = MIPI_C;
		pipeconf_reg = PIPECCONF;
	}
	
	/* Start up display island if it was shutdown */
	if (!gma_power_begin(dev, true))
		return;

	if(on) {
		if (mdfld_get_panel_type(dev, pipe) == TMD_VID){
 			mdfld_dsi_dpi_turn_on(dpi_output, pipe);
 		} else {
			/* Enable mipi port */
			REG_WRITE(mipi_reg, (REG_READ(mipi_reg) | (1 << 31)));
			REG_READ(mipi_reg);

			mdfld_dsi_dpi_turn_on(dpi_output, pipe);
			mdfld_dsi_tpo_ic_init(dsi_config, pipe);
		}

		if(pipe == 2) {
			dev_priv->dpi_panel_on2 = true;
		}
		else {
			dev_priv->dpi_panel_on  = true;
		}

	} else {
 		if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
 			mdfld_dsi_dpi_shut_down(dpi_output, pipe);
 		} else {
			mdfld_dsi_dpi_shut_down(dpi_output, pipe);
			/* Disable mipi port */
			REG_WRITE(mipi_reg, (REG_READ(mipi_reg) & ~(1<<31)));
			REG_READ(mipi_reg);
		}

		if(pipe == 2)
			dev_priv->dpi_panel_on2 = false;
		else
			dev_priv->dpi_panel_on  = false;
	}
	gma_power_end(dev);
}
static
void mdfld_dsi_dpi_commit(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder;
	struct mdfld_dsi_dpi_output *dpi_output;

	PSB_DEBUG_ENTRY("\n");

	dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);

	/*Everything is ready, commit DSI hw context to HW*/
	__mdfld_dsi_dpi_set_power(encoder, true);
	dpi_output->first_boot = 0;
}
Пример #6
0
static void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
{
	struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder);
	struct mdfld_dsi_dpi_output *dpi_output =
				MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
				mdfld_dsi_encoder_get_config(dsi_encoder);
	int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;

	/*start up display island if it was shutdown*/
	if (!gma_power_begin(dev, true))
		return;

	if (on) {
		if (mdfld_get_panel_type(dev, pipe) == TMD_VID)
			mdfld_dsi_dpi_turn_on(dpi_output, pipe);
		else if (mdfld_get_panel_type(dev, pipe) == TC35876X)
			mdfld_dsi_configure_up(dsi_encoder, pipe);
		else {
			/*enable mipi port*/
			REG_WRITE(MIPI_PORT_CONTROL(pipe),
				REG_READ(MIPI_PORT_CONTROL(pipe)) | BIT(31));
			REG_READ(MIPI_PORT_CONTROL(pipe));

			mdfld_dsi_dpi_turn_on(dpi_output, pipe);
			mdfld_dsi_tpo_ic_init(dsi_config, pipe);
		}
		dev_priv->dpi_panel_on[pipe] = true;
	} else {
		if (mdfld_get_panel_type(dev, pipe) == TMD_VID)
			mdfld_dsi_dpi_shut_down(dpi_output, pipe);
		else if (mdfld_get_panel_type(dev, pipe) == TC35876X)
			mdfld_dsi_configure_down(dsi_encoder, pipe);
		else {
			mdfld_dsi_dpi_shut_down(dpi_output, pipe);

			/*disable mipi port*/
			REG_WRITE(MIPI_PORT_CONTROL(pipe),
				REG_READ(MIPI_PORT_CONTROL(pipe)) & ~BIT(31));
			REG_READ(MIPI_PORT_CONTROL(pipe));
		}
		dev_priv->dpi_panel_on[pipe] = false;
	}
	gma_power_end(dev);
}
Пример #7
0
static void mdfld_dsi_configure_down(struct mdfld_dsi_encoder *dsi_encoder,
								int pipe)
{
	struct mdfld_dsi_dpi_output *dpi_output =
				MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
				mdfld_dsi_encoder_get_config(dsi_encoder);
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;

	if (!dev_priv->dpi_panel_on[pipe]) {
		dev_err(dev->dev, "DPI panel is already off\n");
		return;
	}
	tc35876x_toshiba_bridge_panel_off(dev);
	tc35876x_set_bridge_reset_state(dev, 1);
	dsi_set_pipe_plane_enable_state(dev, 0, pipe);
	mdfld_dsi_dpi_shut_down(dpi_output, pipe);
	dsi_set_device_ready_state(dev, 0, pipe);
}
Пример #8
0
void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_config *dsi_config =
		mdfld_dsi_encoder_get_config(dsi_encoder);
	struct drm_device *dev;
	struct drm_psb_private *dev_priv;
	struct mdfld_dsi_dpi_output *dpi_output = NULL;
	u32 mipi_reg = MIPI;
	u32 pipeconf_reg = PIPEACONF;
	int pipe;

	if (!dsi_config) {
		DRM_ERROR("dsi_config is NULL\n");
		return;
	}

	pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
	dev = dsi_config->dev;
	dev_priv = dev->dev_private;

	PSB_DEBUG_ENTRY("set power %s on pipe %d\n", on ? "On" : "Off", pipe);

	dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);

	if (pipe)
		if (!(dev_priv->panel_desc & DISPLAY_B) ||
				!(dev_priv->panel_desc & DISPLAY_C))
			return;

	if (pipe) {
		mipi_reg = MIPI_C;
		pipeconf_reg = PIPECCONF;
	}

	/**
	 * if TMD panel call new power on/off sequences instead.
	 * NOTE: refine TOSHIBA panel code later
	 */
	__mdfld_dsi_dpi_set_power(encoder, on);
}
void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
{
    struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
    struct mdfld_dsi_config *dsi_config =
        mdfld_dsi_encoder_get_config(dsi_encoder);
    int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
    struct drm_device *dev = dsi_config->dev;
    struct drm_psb_private *dev_priv = dev->dev_private;
    struct mdfld_dsi_dpi_output *dpi_output = NULL;
    u32 mipi_reg = MIPI;
    u32 pipeconf_reg = PIPEACONF;

    PSB_DEBUG_ENTRY("set power %s on pipe %d\n", on ? "On" : "Off", pipe);

    dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);

    if (pipe)
        if (!(dev_priv->panel_desc & DISPLAY_B) ||
                !(dev_priv->panel_desc & DISPLAY_C))
            return;

    if (pipe) {
        mipi_reg = MIPI_C;
        pipeconf_reg = PIPECCONF;
    }

    /*start up display island if it was shutdown*/
    if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
                                   OSPM_UHB_FORCE_POWER_ON))
        return;

    /**
     * if TMD panel call new power on/off sequences instead.
     * NOTE: refine TOSHIBA panel code later
     */
    __mdfld_dsi_dpi_set_power(encoder, on);

    ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
Пример #10
0
void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
				   struct drm_display_mode *mode,
				   struct drm_display_mode *adjusted_mode)
{
	struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder);
	struct mdfld_dsi_dpi_output *dpi_output =
					MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
				mdfld_dsi_encoder_get_config(dsi_encoder);
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);

	u32 pipeconf_reg = PIPEACONF;
	u32 dspcntr_reg = DSPACNTR;

	u32 pipeconf;
	u32 dspcntr;
	u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;

	if (pipe == -1)
		return;

	pipeconf = dev_priv->pipeconf[pipe];
	dspcntr = dev_priv->dspcntr[pipe];

	if (pipe) {
		pipeconf_reg = PIPECCONF;
		dspcntr_reg = DSPCCNTR;
	} else {
		if (mdfld_get_panel_type(dev, pipe) == TC35876X)
			mipi &= (~0x03); /* Use all four lanes */
		else
			mipi |= 2;
	}

	/*start up display island if it was shutdown*/
	if (!gma_power_begin(dev, true))
		return;

	if (mdfld_get_panel_type(dev, pipe) == TC35876X) {
		/*
		 * The following logic is required to reset the bridge and
		 * configure. This also starts the DSI clock at 200MHz.
		 */
		tc35876x_set_bridge_reset_state(dev, 0);  /*Pull High Reset */
		tc35876x_toshiba_bridge_panel_on(dev);
		udelay(100);
		/* Now start the DSI clock */
		REG_WRITE(MRST_DPLL_A, 0x00);
		REG_WRITE(MRST_FPA0, 0xC1);
		REG_WRITE(MRST_DPLL_A, 0x00800000);
		udelay(500);
		REG_WRITE(MRST_DPLL_A, 0x80800000);

		if (REG_BIT_WAIT(pipeconf_reg, 1, 29))
			dev_err(&dev->pdev->dev, "%s: DSI PLL lock timeout\n",
				__func__);

		REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008);

		mipi_set_properties(dsi_config, pipe);
		mdfld_mipi_config(dsi_config, pipe);
		mdfld_set_pipe_timing(dsi_config, pipe);

		REG_WRITE(DSPABASE, 0x00);
		REG_WRITE(DSPASIZE,
			((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));

		REG_WRITE(DSPACNTR, 0x98000000);
		REG_WRITE(DSPASURF, 0x00);

		REG_WRITE(VGACNTRL, 0x80000000);
		REG_WRITE(DEVICE_READY_REG, 0x00000001);

		REG_WRITE(MIPI_PORT_CONTROL(pipe), 0x80810000);
	} else {
		/*set up mipi port FIXME: do at init time */
		REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi);
	}
	REG_READ(MIPI_PORT_CONTROL(pipe));

	if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
		/* NOP */
	} else if (mdfld_get_panel_type(dev, pipe) == TC35876X) {
		/* set up DSI controller DPI interface */
		mdfld_dsi_dpi_controller_init(dsi_config, pipe);

		/* Configure MIPI Bridge and Panel */
		tc35876x_configure_lvds_bridge(dev);
		dev_priv->dpi_panel_on[pipe] = true;
	} else {
		/*turn on DPI interface*/
		mdfld_dsi_dpi_turn_on(dpi_output, pipe);
	}

	/*set up pipe*/
	REG_WRITE(pipeconf_reg, pipeconf);
	REG_READ(pipeconf_reg);

	/*set up display plane*/
	REG_WRITE(dspcntr_reg, dspcntr);
	REG_READ(dspcntr_reg);

	msleep(20); /* FIXME: this should wait for vblank */

	if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
		/* NOP */
	} else if (mdfld_get_panel_type(dev, pipe) == TC35876X) {
		mdfld_dsi_dpi_turn_on(dpi_output, pipe);
	} else {
		/* init driver ic */
		mdfld_dsi_tpo_ic_init(dsi_config, pipe);
		/*init backlight*/
		mdfld_dsi_brightness_init(dsi_config, pipe);
	}

	gma_power_end(dev);
}
/**
 * Setup Display Controller to turn on/off a video mode panel.
 * Most of the video mode MIPI panel should follow the power on/off
 * sequence in this function.
 * NOTE: do NOT modify this function for new panel Enabling. Register
 * new panel function callbacks to make this function available for a
 * new video mode panel
 */
static int __mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
{
	struct mdfld_dsi_encoder *dsi_encoder;
	struct mdfld_dsi_connector *dsi_connector;
	struct mdfld_dsi_dpi_output *dpi_output;
	struct mdfld_dsi_config *dsi_config;
	struct panel_funcs *p_funcs;
	int pipe;
	struct drm_device *dev;
	struct drm_psb_private *dev_priv;

	if (!encoder) {
		DRM_ERROR("Invalid encoder\n");
		return -EINVAL;
	}

	dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
	p_funcs = dpi_output->p_funcs;
	pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
	dsi_connector = mdfld_dsi_encoder_get_connector(dsi_encoder);
	if (!dsi_connector) {
		DRM_ERROR("dsi_connector is NULL\n");
		return -EINVAL;
	}

	dev = dsi_config->dev;
	dev_priv = dev->dev_private;

	if (dsi_connector->status != connector_status_connected)
		return 0;

	mutex_lock(&dsi_config->context_lock);

	if (dpi_output->first_boot && dsi_config->dsi_hw_context.panel_on) {
		printk(KERN_ALERT "skip panle power setting for first boot!" \
				"panel is already powered on\n");
		goto fun_exit;
	}

	switch (on) {
	case true:
		/* panel is already on */
		if (dsi_config->dsi_hw_context.panel_on)
			goto fun_exit;
		if (__dpi_panel_power_on(dsi_config, p_funcs)) {
			DRM_ERROR("Faild to turn on panel\n");
			goto set_power_err;
		}
		dsi_config->dsi_hw_context.panel_on = 1;
		break;
	case false:
		if (__dpi_panel_power_off(dsi_config, p_funcs)) {
			DRM_ERROR("Faild to turn off panel\n");
			goto set_power_err;
		}
		dsi_config->dsi_hw_context.panel_on = 0;
		break;
	default:
		break;
	}

fun_exit:
	mutex_unlock(&dsi_config->context_lock);
	PSB_DEBUG_ENTRY("successfully\n");
	return 0;
set_power_err:
	mutex_unlock(&dsi_config->context_lock);
	PSB_DEBUG_ENTRY("unsuccessfully!!!!\n");
	return -EAGAIN;
}
Пример #12
0
static
void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
{
	struct mdfld_dsi_encoder *dsi_encoder;
	struct mdfld_dsi_config *dsi_config;
	struct drm_device *dev;
	struct drm_psb_private *dev_priv;
	struct mdfld_dsi_dpi_output *dpi_output;
	struct panel_funcs *p_funcs;

	dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
	if (!dsi_config) {
		DRM_ERROR("dsi_config is NULL\n");
		return;
	}
	dev = dsi_config->dev;
	dev_priv = dev->dev_private;

	dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	p_funcs = dpi_output->p_funcs;

	PSB_DEBUG_ENTRY("%s\n", (mode == DRM_MODE_DPMS_ON ? "on" :
		DRM_MODE_DPMS_STANDBY == mode ? "standby" : "off"));

	mutex_lock(&dev_priv->dpms_mutex);
	DCLockMutex();

	if (mode == DRM_MODE_DPMS_ON) {
		mdfld_dsi_dpi_set_power(encoder, true);
		DCAttachPipe(dsi_config->pipe);
		DC_MRFLD_onPowerOn(dsi_config->pipe);

#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
		{
			struct mdfld_dsi_hw_context *ctx =
				&dsi_config->dsi_hw_context;
			struct backlight_device bd;
			bd.props.brightness = ctx->lastbrightnesslevel;
			psb_set_brightness(&bd);
		}
#endif
	} else if (mode == DRM_MODE_DPMS_STANDBY) {
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
		struct mdfld_dsi_hw_context *ctx = &dsi_config->dsi_hw_context;
		struct backlight_device bd;
		ctx->lastbrightnesslevel = psb_get_brightness(&bd);
		bd.props.brightness = 0;
		psb_set_brightness(&bd);
#endif
		/* Make the pending flip request as completed. */
		DCUnAttachPipe(dsi_config->pipe);
		msleep(50);
		DC_MRFLD_onPowerOff(dsi_config->pipe);
		msleep(50);
	} else {
		mdfld_dsi_dpi_set_power(encoder, false);

		drm_handle_vblank(dev, dsi_config->pipe);

		/* Turn off TE interrupt. */
		drm_vblank_off(dev, dsi_config->pipe);

		/* Make the pending flip request as completed. */
		DCUnAttachPipe(dsi_config->pipe);
		DC_MRFLD_onPowerOff(dsi_config->pipe);
	}

	DCUnLockMutex();
	mutex_unlock(&dev_priv->dpms_mutex);
}
Пример #13
0
/**
 * Setup Display Controller to turn on/off a video mode panel.
 * Most of the video mode MIPI panel should follow the power on/off
 * sequence in this function.
 * NOTE: do NOT modify this function for new panel Enabling. Register
 * new panel function callbacks to make this function available for a
 * new video mode panel
 */
static int __mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
{
	struct mdfld_dsi_encoder *dsi_encoder;
	struct mdfld_dsi_connector *dsi_connector;
	struct mdfld_dsi_dpi_output *dpi_output;
	struct mdfld_dsi_config *dsi_config;
	struct panel_funcs *p_funcs;
	int pipe;
	struct drm_device *dev;
	struct drm_psb_private *dev_priv;

	if (!encoder) {
		DRM_ERROR("Invalid encoder\n");
		return -EINVAL;
	}

	dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
	p_funcs = dpi_output->p_funcs;
	pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
	dsi_connector = mdfld_dsi_encoder_get_connector(dsi_encoder);
	if (!dsi_connector) {
		DRM_ERROR("dsi_connector is NULL\n");
		return -EINVAL;
	}

	dev = dsi_config->dev;
	dev_priv = dev->dev_private;

	if (dsi_connector->status != connector_status_connected)
		return 0;

	mutex_lock(&dsi_config->context_lock);

	if (dpi_output->first_boot && on) {
		if (dsi_config->dsi_hw_context.panel_on) {
			if (IS_ANN(dev))
				ann_dc_setup(dsi_config);

			psb_enable_vblank(dev, dsi_config->pipe);

			/* don't need ISLAND c for non dual-dsi panel */
			if (!is_dual_dsi(dev))
				power_island_put(OSPM_DISPLAY_C);

			DRM_INFO("skip panle power setting for first boot! "
				 "panel is already powered on\n");
			goto fun_exit;
		}
		if (android_hdmi_is_connected(dev))
			otm_hdmi_power_islands_off();
		/* power down islands turned on by firmware */
		power_island_put(OSPM_DISPLAY_A | OSPM_DISPLAY_C |
				 OSPM_DISPLAY_MIO);
	}

	switch (on) {
	case true:
		/* panel is already on */
		if (dsi_config->dsi_hw_context.panel_on)
			goto fun_exit;
		if (__dpi_panel_power_on(dsi_config, p_funcs, dpi_output->first_boot)) {
			DRM_ERROR("Faild to turn on panel\n");
			goto set_power_err;
		}
		dsi_config->dsi_hw_context.panel_on = 1;

		/* for every dpi panel power on, clear the dpi underrun count */
		dev_priv->pipea_dpi_underrun_count = 0;
		dev_priv->pipec_dpi_underrun_count = 0;

		break;
	case false:
		if (!dsi_config->dsi_hw_context.panel_on &&
			!dpi_output->first_boot)
			goto fun_exit;
		if (__dpi_panel_power_off(dsi_config, p_funcs)) {
			DRM_ERROR("Faild to turn off panel\n");
			goto set_power_err;
		}
		dsi_config->dsi_hw_context.panel_on = 0;
		break;
	default:
		break;
	}

fun_exit:
	mutex_unlock(&dsi_config->context_lock);
	PSB_DEBUG_ENTRY("successfully\n");
	return 0;
set_power_err:
	mutex_unlock(&dsi_config->context_lock);
	PSB_DEBUG_ENTRY("unsuccessfully!!!!\n");
	return -EAGAIN;
}
Пример #14
0
void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
				   struct drm_display_mode *mode,
				   struct drm_display_mode *adjusted_mode)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
	
	u32 pipeconf_reg = PIPEACONF;
	u32 dspcntr_reg = DSPACNTR;
	u32 mipi_reg = MIPI;
	u32 reg_offset = 0;
	
	u32 pipeconf = dev_priv->pipeconf;
	u32 dspcntr = dev_priv->dspcntr;
	u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
	
	dev_dbg(dev->dev, "set mode %dx%d on pipe %d\n",
				mode->hdisplay, mode->vdisplay, pipe);

	if(pipe) {
		pipeconf_reg = PIPECCONF;
		dspcntr_reg = DSPCCNTR;
		mipi_reg = MIPI_C;
		reg_offset = MIPIC_REG_OFFSET;
	} else {
		mipi |= 2;
	}
	
	if (!gma_power_begin(dev, true))
		return;

	/* Set up mipi port FIXME: do at init time */
	REG_WRITE(mipi_reg, mipi);
	REG_READ(mipi_reg);

	/* Set up DSI controller DPI interface */
	mdfld_dsi_dpi_controller_init(dsi_config, pipe);

	if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
		/* Turn on DPI interface */
		mdfld_dsi_dpi_turn_on(dpi_output, pipe);
	}
	
	/* Set up pipe */
	REG_WRITE(pipeconf_reg, pipeconf);
	REG_READ(pipeconf_reg);
	
	/* Set up display plane */
	REG_WRITE(dspcntr_reg, dspcntr);
	REG_READ(dspcntr_reg);
	
	msleep(20); /* FIXME: this should wait for vblank */
	
	dev_dbg(dev->dev, "State %x, power %d\n",
		REG_READ(MIPIA_INTR_STAT_REG + reg_offset),
		dpi_output->panel_on);

	if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
		/* Init driver ic */
		mdfld_dsi_tpo_ic_init(dsi_config, pipe);
		/* Init backlight */
		mdfld_dsi_brightness_init(dsi_config, pipe);
	}
	gma_power_end(dev);
}
Пример #15
0
/**
 * Setup Display Controller to turn on/off a video mode panel.
 * Most of the video mode MIPI panel should follow the power on/off
 * sequence in this function.
 * NOTE: do NOT modify this function for new panel Enabling. Register
 * new panel function callbacks to make this function available for a
 * new video mode panel
 */
static int __mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
{
    struct mdfld_dsi_encoder *dsi_encoder;
    struct mdfld_dsi_connector *dsi_connector;
    struct mdfld_dsi_dpi_output *dpi_output;
    struct mdfld_dsi_config *dsi_config;
    struct panel_funcs *p_funcs;
    int pipe;
    struct drm_device *dev;
    struct drm_psb_private *dev_priv;
    static int last_ospm_suspend = -1;

    if (!encoder) {
        DRM_ERROR("Invalid encoder\n");
        return -EINVAL;
    }

    PSB_DEBUG_ENTRY("%s, last_ospm_suspend = %s\n", (on ? "on" : "off"),
                    (last_ospm_suspend ? "true" : "false"));

    dsi_encoder = MDFLD_DSI_ENCODER(encoder);
    dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
    dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
    p_funcs = dpi_output->p_funcs;
    pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
    dsi_connector = mdfld_dsi_encoder_get_connector(dsi_encoder);
    if (!dsi_connector) {
        DRM_ERROR("Invalid connector\n");
        return -EINVAL;
    }
    dev = dsi_config->dev;
    dev_priv = dev->dev_private;

    if (dsi_connector->status != connector_status_connected)
        return 0;

    mutex_lock(&dsi_config->context_lock);

    if (last_ospm_suspend == -1)
        last_ospm_suspend = false;

    if (dpi_output->first_boot && dsi_config->dsi_hw_context.panel_on) {

        if (Check_fw_initilized_reusable(dsi_config, p_funcs)) {
            DRM_INFO("skip panle power setting for first boot!"
                     " panel is already powered on\n");
            goto fun_exit;
        } else
            dsi_config->dsi_hw_context.panel_on = 0;
    }
    /*	ASUS_BSP: Louis	+++*/
    else if (dpi_output->first_boot && !dsi_config->dsi_hw_context.panel_on) {
        DRM_INFO("No display in ifwi, initialize panel in kernel\n");
        psbfb_memclear();
    }
    /*	ASUS_BSP: Louis	---*/

    /**
     * if ospm has turned panel off, but dpms tries to turn panel on, skip
     */
    if (dev_priv->dpms_on_off && on && last_ospm_suspend)
        goto fun_exit;

    switch (on) {
    case true:
        /* panel is already on */
        if (dsi_config->dsi_hw_context.panel_on)
            goto fun_exit;
        /* For DPMS case, just turn on/off panel */
        if (dev_priv->dpms_on_off) {
            if (mdfld_dsi_dpi_panel_turn_on(dsi_config, p_funcs)) {
                DRM_ERROR("Faild to turn on panel\n");
                goto set_power_err;
            }
        } else {
            if (__dpi_panel_power_on(dsi_config, p_funcs)) {
                DRM_ERROR("Faild to turn on panel\n");
                goto set_power_err;
            }
        }
        /**
         * If power on, turn off color mode by default,
         * let panel in full color mode
         */
        mdfld_dsi_dpi_set_color_mode(dsi_config, false);

        dsi_config->dsi_hw_context.panel_on = 1;
        last_ospm_suspend = false;
        break;
    case false:
        if (dev_priv->dpms_on_off &&
                dsi_config->dsi_hw_context.panel_on) {
            if (mdfld_dsi_dpi_panel_shut_down(dsi_config, p_funcs))
                DRM_ERROR("Faild to shutdown panel\n");

            last_ospm_suspend = false;
        } else if (!dev_priv->dpms_on_off && !last_ospm_suspend) {
            if (__dpi_panel_power_off(dsi_config, p_funcs)) {
                DRM_ERROR("Faild to turn off panel\n");
                goto set_power_err;
            }
            /* ospm suspend called? */
            last_ospm_suspend = true;
        }
        dsi_config->dsi_hw_context.panel_on = 0;
        SetDisplayFrameUpdate(5);	/*	ASUS_BSP: Louis ++	*/
        break;
    default:
        break;
    }

fun_exit:
    mutex_unlock(&dsi_config->context_lock);
    /*To optimize dpms with context lock, move panel sleep out of mutex*/
    if (dev_priv->dpms_on_off)
        msleep(100);
    PSB_DEBUG_ENTRY("successfully\n");
    return 0;
set_power_err:
    mutex_unlock(&dsi_config->context_lock);
    PSB_DEBUG_ENTRY("unsuccessfully!!!!\n");
    return -EAGAIN;
}