示例#1
0
static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
					MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct drm_device *dev = dbi_output->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct psb_drm_dpu_rect rect;

	mdfld_dsi_dbi_set_power(encoder, true);
	dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;

	rect.x = rect.y = 0;
	rect.width = 864;
	rect.height = 480;

	if (dbi_output->channel_num == 1) {
		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
		/*if dpu enabled report a fullscreen damage*/
		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
	} else {
		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
	}
	dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
}
示例#2
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;
}
void mdfld_panel_generic_dsi_dbi_commit(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder =
		MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct drm_device *dev = dbi_output->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	/*DSI DPU was still on debugging, will remove this option later*/
#ifdef CONFIG_MDFLD_DSI_DPU
	struct psb_drm_dpu_rect rect;
#endif

	PSB_DEBUG_ENTRY("\n");

	mdfld_panel_generic_dsi_dbi_set_power(encoder, true);
	gbdispstatus = true;
	dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;

#ifdef CONFIG_MDFLD_DSI_DPU
	rect.x = rect.y = 0;
	rect.width = 864;
	rect.height = 480;
#endif

	dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
}
static
bool mdfld_generic_dsi_dbi_mode_fixup(struct drm_encoder *encoder,
		const struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct drm_display_mode *fixed_mode = dbi_output->panel_fixed_mode;

	PSB_DEBUG_ENTRY("\n");

	if (fixed_mode) {
		adjusted_mode->hdisplay = fixed_mode->hdisplay;
		adjusted_mode->hsync_start = fixed_mode->hsync_start;
		adjusted_mode->hsync_end = fixed_mode->hsync_end;
		adjusted_mode->htotal = fixed_mode->htotal;
		adjusted_mode->vdisplay = fixed_mode->vdisplay;
		adjusted_mode->vsync_start = fixed_mode->vsync_start;
		adjusted_mode->vsync_end = fixed_mode->vsync_end;
		adjusted_mode->vtotal = fixed_mode->vtotal;
		adjusted_mode->clock = fixed_mode->clock;
		drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
	}

	return true;
}
示例#5
0
static void mdfld_dsi_dbi_prepare(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output
				= MDFLD_DSI_DBI_OUTPUT(dsi_encoder);

	dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
	dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;

	mdfld_dsi_dbi_set_power(encoder, false);
}
static
void mdfld_generic_dsi_dbi_prepare(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);

	PSB_DEBUG_ENTRY("\n");

	dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
	dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
}
void mdfld_panel_generic_dsi_dbi_prepare(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);

	PSB_DEBUG_ENTRY("\n");

	dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
	dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;

	mdfld_panel_generic_dsi_dbi_set_power(encoder, false);
	gbdispstatus = false;
}
int mdfld_panel_generic_dsi_dbi_power_on(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
		mdfld_dsi_encoder_get_config(dsi_encoder);
	struct panel_funcs *p_funcs = dbi_output->p_funcs;
	struct mdfld_dsi_hw_registers *regs = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	struct drm_device *dev = encoder->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	int err = 0;

	if (!dev_priv->dsi_init_done)
		return 0;

	if (!dsi_config)
		return -EINVAL;

	regs = &dsi_config->regs;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
					OSPM_UHB_FORCE_POWER_ON))
		return -EAGAIN;


	/*
	 * Different panel may have different ways to have
	 * panel turned on. Support it!
	 */
	if (p_funcs && p_funcs->power_on) {
		p_funcs->dsi_controller_init(dsi_config,
				dsi_config->pipe, true);

		if (p_funcs->power_on(dsi_config)) {
			DRM_ERROR("Failed to power on panel\n");
			err = -EAGAIN;
			goto power_on_err;
		}
	}

power_on_err:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	return err;
}
示例#9
0
static void pyr_dsi_dbi_commit(struct drm_encoder * encoder) 
{
	struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct drm_device * dev = dbi_output->dev;
	struct drm_psb_private * dev_priv = dev->dev_private;
	
/*DSI DPU was still on debugging, will remove this option later*/
#ifdef CONFIG_MDFLD_DSI_DPU		
	struct psb_drm_dpu_rect rect;
#endif
	
	PSB_DEBUG_ENTRY("\n");

	pyr_dsi_dbi_set_power(encoder, true);
	
	dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;

#ifdef CONFIG_MDFLD_DSI_DPU
	rect.x = rect.y = 0;
	rect.width = 864;
	rect.height = 480;
#endif	
	
	if(dbi_output->channel_num == 1) {
		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
#ifdef CONFIG_MDFLD_DSI_DPU
		/*if dpu enabled report a fullscreen damage*/
		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
#endif
	} else {
		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
		
#ifdef CONFIG_MDFLD_DSI_DPU		
		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
		/*start dpu timer*/
		if (dev_priv->platform_rev_id == MDFLD_PNW_A0)
			mdfld_dbi_dpu_timer_start(dev_priv->dbi_dpu_info);
#else 
		if (dev_priv->platform_rev_id == MDFLD_PNW_A0)
			mdfld_dbi_dsr_timer_start(dev_priv->dbi_dsr_info);
#endif
	}

	dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
}
static
void mdfld_generic_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
{
	struct mdfld_dsi_encoder *dsi_encoder;
	struct mdfld_dsi_dbi_output *dbi_output;
	struct drm_device *dev;
	struct mdfld_dsi_config *dsi_config;
	struct drm_psb_private *dev_priv;

	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;
	}
	dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	dev = dsi_config->dev;
	dev_priv = dev->dev_private;

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

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

	if (mode == DRM_MODE_DPMS_ON) {
		mdfld_generic_dsi_dbi_set_power(encoder, true);
		DCAttachPipe(dsi_config->pipe);
		DC_MRFLD_onPowerOn(dsi_config->pipe);
	} else {
		mdfld_generic_dsi_dbi_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);
}
int mdfld_panel_generic_dsi_dbi_power_off(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
		mdfld_dsi_encoder_get_config(dsi_encoder);
	struct panel_funcs *p_funcs = dbi_output->p_funcs;
	struct mdfld_dsi_hw_context *ctx;
	struct drm_device *dev = encoder->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	int err = 0;

	if (!dev_priv->dsi_init_done)
		return 0;

	if (!dsi_config)
		return -EINVAL;

	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
					OSPM_UHB_FORCE_POWER_ON))
		return -EAGAIN;

	ctx->lastbrightnesslevel = psb_brightness;

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

power_off_err:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	return err;
}
示例#12
0
static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output
				= MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct drm_device *dev = dbi_output->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	static bool bdispoff;

	dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));

	if (mode == DRM_MODE_DPMS_ON) {
		/*
		 * FIXME: in case I am wrong!
		 * we don't need to exit dsr here to wake up plane/pipe/pll
		 * if everything goes right, hw_begin will resume them all
		 * during set_power.
		 */
		if (bdispoff /* FIXME && gbgfxsuspended */) {
			mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D);
			bdispoff = false;
			dev_priv->dispstatus = true;
		}

		mdfld_dsi_dbi_set_power(encoder, true);
		/* FIXME if (gbgfxsuspended)
			gbgfxsuspended = false; */
	} else {
		/*
		 * I am not sure whether this is the perfect place to
		 * turn rpm on since we still have a lot of CRTC turnning
		 * on work to do.
		 */
		bdispoff = true;
		dev_priv->dispstatus = false;
		mdfld_dsi_dbi_set_power(encoder, false);
	}
}
static
void mdfld_generic_dsi_dbi_commit(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder =
		MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct drm_device *dev = dbi_output->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;

	PSB_DEBUG_ENTRY("\n");

	mdfld_generic_dsi_dbi_set_power(encoder, true);

	dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
	if (dbi_output->channel_num == 1)
		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
	else
		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
	dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;

	dbi_output->first_boot = false;
}
示例#14
0
static void pyr_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
{
	struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder);
        struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
        struct drm_device * dev = dbi_output->dev;
        static bool bdispoff = false;

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

	if (mode == DRM_MODE_DPMS_ON){
		 if(gbgfxsuspended && bdispoff){
                        bdispoff = false;
                        gbdispstatus = true;
                        gbgfxsuspended = false;
                        mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_2D_3D, 0, 0);
                }
		pyr_dsi_dbi_set_power(encoder, true);
		
	} else {
		bdispoff = true;
		gbdispstatus = false;
		pyr_dsi_dbi_set_power(encoder, false);
	}
}
int mdfld_panel_generic_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
{
	int ret = 0;
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct panel_funcs *p_funcs = dbi_output->p_funcs;
	struct mdfld_dsi_connector *dsi_connector =
		mdfld_dsi_encoder_get_connector(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
		mdfld_dsi_encoder_get_config(dsi_encoder);
	struct drm_device *dev = encoder->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	u32 reg_offset = 0;
	int pipe = (dbi_output->channel_num == 0) ? 0 : 2;

	PSB_DEBUG_ENTRY("pipe %d : %s, panel on: %s\n", pipe, on ? "On" : "Off",
			dbi_output->dbi_panel_on ? "True" : "False");

	if (pipe == 2) {
		if (on)
			dev_priv->dual_mipi = true;
		else
			dev_priv->dual_mipi = false;

		reg_offset = MIPIC_REG_OFFSET;
	} else {
		if (!on)
			dev_priv->dual_mipi = false;
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("hw begin failed\n");
		return -EAGAIN;
	}

	mutex_lock(&dsi_config->context_lock);

	if (on) {
		if (dbi_output->dbi_panel_on)
			goto out_err;

		ret = mdfld_panel_generic_dsi_dbi_power_on(encoder);
		if (ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}

		dbi_output->dbi_panel_on = true;

		if (pipe == 2)
			dev_priv->dbi_panel_on2 = true;
		else
			dev_priv->dbi_panel_on = true;

		if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
			mdfld_enable_te(dev, pipe);

		/* wake up error detector if ESD enabled */
		if (p_funcs->esd_detection)
			mdfld_dsi_error_detector_wakeup(dsi_connector);
		else
			PSB_DEBUG_ENTRY("ESD detection disabled\n");

		dsi_config->dsi_hw_context.panel_on = 1;
	} else {
		if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
			goto out_err;

		dbi_output->dbi_panel_on = false;
		dbi_output->first_boot = false;

		if (pipe == 2)
			dev_priv->dbi_panel_on2 = false;
		else
			dev_priv->dbi_panel_on = false;

		if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
			mdfld_disable_te(dev, pipe);

		ret = mdfld_panel_generic_dsi_dbi_power_off(encoder);
		if (ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}

		dsi_config->dsi_hw_context.panel_on = 0;
	}

out_err:
	mutex_unlock(&dsi_config->context_lock);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	if (ret)
		DRM_ERROR("failed\n");
	else
		PSB_DEBUG_ENTRY("successfully\n");

	return ret;
}
示例#16
0
static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
{
	int ret = 0;
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
				MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
		mdfld_dsi_encoder_get_config(dsi_encoder);
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_encoder_get_pkg_sender(dsi_encoder);
	struct drm_device *dev = encoder->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	u32 reg_offset = 0;
	int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
	u32 data = 0;

	dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n",
			pipe, on ? "On" : "Off",
			dbi_output->dbi_panel_on ? "True" : "False");

	if (pipe == 2) {
		if (on)
			dev_priv->dual_mipi = true;
		else
			dev_priv->dual_mipi = false;
		reg_offset = MIPIC_REG_OFFSET;
	} else {
		if (!on)
			dev_priv->dual_mipi = false;
	}

	if (!gma_power_begin(dev, true)) {
		dev_err(dev->dev, "hw begin failed\n");
		return;
	}

	if (on) {
		if (dbi_output->dbi_panel_on)
			goto out_err;

		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
		if (ret) {
			dev_err(dev->dev, "power on error\n");
			goto out_err;
		}

		dbi_output->dbi_panel_on = true;

		if (pipe == 2)
			dev_priv->dbi_panel_on2 = true;
		else
			dev_priv->dbi_panel_on = true;
		mdfld_enable_te(dev, pipe);
	} else {
		if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
			goto out_err;

		dbi_output->dbi_panel_on = false;
		dbi_output->first_boot = false;

		if (pipe == 2)
			dev_priv->dbi_panel_on2 = false;
		else
			dev_priv->dbi_panel_on = false;

		mdfld_disable_te(dev, pipe);

		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
		if (ret) {
			dev_err(dev->dev, "power on error\n");
			goto out_err;
		}
	}

	/*
	 * FIXME: this is a WA for TPO panel crash on DPMS on & off around
	 * 83 times. the root cause of this issue is that Booster in
	 * drvIC crashed. Add this WA so that we can resume the driver IC
	 * once we found that booster has a fault
	 */
	mdfld_dsi_get_power_mode(dsi_config,
				&data,
				MDFLD_DSI_HS_TRANSMISSION);

	if (on && data && !(data & (1 << 7))) {
		/* Soft reset */
		mdfld_dsi_send_dcs(sender,
				   DCS_SOFT_RESET,
				   NULL,
				   0,
				   CMD_DATA_SRC_PIPE,
				   MDFLD_DSI_SEND_PACKAGE);

		/* Init drvIC */
		if (dbi_output->p_funcs->drv_ic_init)
			dbi_output->p_funcs->drv_ic_init(dsi_config,
							 pipe);
	}
 
out_err:
	gma_power_end(dev);
	if (ret)
		dev_err(dev->dev, "failed\n");
}
/* generic dbi function */
static
int mdfld_generic_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
{
	struct mdfld_dsi_encoder *dsi_encoder;
	struct mdfld_dsi_dbi_output *dbi_output;
	struct mdfld_dsi_connector *dsi_connector;
	struct mdfld_dsi_config *dsi_config;
	struct panel_funcs *p_funcs;
	struct drm_device *dev;
	struct drm_psb_private *dev_priv;
	int pipe = 0;

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

	PSB_DEBUG_ENTRY("%s\n", (on ? "on" : "off"));

	dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
	dsi_connector = mdfld_dsi_encoder_get_connector(dsi_encoder);
	if (!dsi_connector) {
		DRM_ERROR("dsi_connector is NULL\n");
		return -EINVAL;
	}

	p_funcs = dbi_output->p_funcs;
	dev = encoder->dev;
	dev_priv = dev->dev_private;
	pipe = dsi_config->pipe;

	mutex_lock(&dsi_config->context_lock);

	if (dsi_connector->status != connector_status_connected)
		goto set_power_err;

	if (dbi_output->first_boot &&
	    dsi_config->dsi_hw_context.panel_on) {
		if (on) {
			/* When using smooth transition,
			 * wake up ESD detection thread.
			 */
			mdfld_dsi_error_detector_wakeup(dsi_connector);
		}
		DRM_INFO("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 (__dbi_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;
		dbi_output->dbi_panel_on = 1;
		mdfld_dsi_error_detector_wakeup(dsi_connector);

		break;
	case false:
		if (!dsi_config->dsi_hw_context.panel_on &&
		    !dbi_output->first_boot)
			goto fun_exit;
		if (__dbi_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;
		dbi_output->dbi_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;
}
示例#18
0
static void mdfld_dsi_dbi_mode_set(struct drm_encoder *encoder,
				   struct drm_display_mode *mode,
				   struct drm_display_mode *adjusted_mode)
{
	int ret = 0;
	struct drm_device *dev = encoder->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dsi_output =
					MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
				mdfld_dsi_encoder_get_config(dsi_encoder);
	struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
	int pipe = dsi_connector->pipe;
	u8 param = 0;

	/* Regs */
	u32 mipi_reg = MIPI;
	u32 dspcntr_reg = DSPACNTR;
	u32 pipeconf_reg = PIPEACONF;
	u32 reg_offset = 0;

	/* Values */
	u32 dspcntr_val = dev_priv->dspcntr;
	u32 pipeconf_val = dev_priv->pipeconf;
	u32 h_active_area = mode->hdisplay;
	u32 v_active_area = mode->vdisplay;
	u32 mipi_val;

	mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
						TE_TRIGGER_GPIO_PIN);

	dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);

	dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
	dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);

	if (pipe == 2) {
		mipi_reg = MIPI_C;
		dspcntr_reg = DSPCCNTR;
		pipeconf_reg = PIPECCONF;

		reg_offset = MIPIC_REG_OFFSET;

		dspcntr_val = dev_priv->dspcntr2;
		pipeconf_val = dev_priv->pipeconf2;
	} else {
		mipi_val |= 0x2; /*two lanes for port A and C respectively*/
	}

	if (!gma_power_begin(dev, true)) {
		dev_err(dev->dev, "hw begin failed\n");
		return;
	}

	REG_WRITE(dspcntr_reg, dspcntr_val);
	REG_READ(dspcntr_reg);

	/* 20ms delay before sending exit_sleep_mode */
	msleep(20);

	/* Send exit_sleep_mode DCS */
	ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_EXIT_SLEEP_MODE,
					NULL, 0, CMD_DATA_SRC_SYSTEM_MEM);
	if (ret) {
		dev_err(dev->dev, "sent exit_sleep_mode faild\n");
		goto out_err;
	}

	/* Send set_tear_on DCS */
	ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_SET_TEAR_ON,
					&param, 1, CMD_DATA_SRC_SYSTEM_MEM);
	if (ret) {
		dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
		goto out_err;
	}

	/* Do some init stuff */
	REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
	REG_READ(pipeconf_reg);

	/* TODO: this looks ugly, try to move it to CRTC mode setting*/
	if (pipe == 2)
		dev_priv->pipeconf2 |= PIPEACONF_DSR;
	else
		dev_priv->pipeconf |= PIPEACONF_DSR;

	dev_dbg(dev->dev, "pipeconf %x\n",  REG_READ(pipeconf_reg));

	ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
				h_active_area - 1, v_active_area - 1);
	if (ret) {
		dev_err(dev->dev, "update area failed\n");
		goto out_err;
	}

out_err:
	gma_power_end(dev);

	if (ret)
		dev_err(dev->dev, "mode set failed\n");
}
示例#19
0
static
void mdfld_generic_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
{
    struct mdfld_dsi_encoder *dsi_encoder;
    struct mdfld_dsi_dbi_output *dbi_output;
    struct drm_device *dev;
    struct mdfld_dsi_config *dsi_config;
    struct drm_psb_private *dev_priv;
    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;
    }
    dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
    dev = dsi_config->dev;
    dev_priv = dev->dev_private;

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

    p_funcs = dbi_output->p_funcs;
    if (mode == DRM_MODE_DPMS_ON) {
        mdfld_generic_dsi_dbi_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);
        DC_MRFLD_onPowerOff(dsi_config->pipe);
    } else {
        mdfld_generic_dsi_dbi_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);
}
示例#20
0
static void pyr_dsi_dbi_mode_set(struct drm_encoder * encoder,
				   struct drm_display_mode * mode,
				   struct drm_display_mode * adjusted_mode)
{
	int ret = 0;
	struct drm_device * dev = encoder->dev;
	struct drm_psb_private * dev_priv = (struct drm_psb_private*)dev->dev_private;
	struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output * dsi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config * dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
	struct mdfld_dsi_connector * dsi_connector = dsi_config->connector;
	int pipe = dsi_connector->pipe;
	u8 param = 0;
	
	/*regs*/
	u32 mipi_reg = MIPI;
	u32 dspcntr_reg = DSPACNTR;
	u32 pipeconf_reg = PIPEACONF;
	u32 reg_offset = 0;
	
	/*values*/
	u32 dspcntr_val = dev_priv->dspcntr;
	u32 pipeconf_val = dev_priv->pipeconf;
	u32 h_active_area = mode->hdisplay; 
	u32 v_active_area = mode->vdisplay; 
	u32 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX);

	if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
		mipi_val = (PASS_FROM_SPHY_TO_AFE | TE_TRIGGER_GPIO_PIN);

	PSB_DEBUG_ENTRY("mipi_val =0x%x\n", mipi_val);

	PSB_DEBUG_ENTRY("type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
	PSB_DEBUG_ENTRY("h %d v %d\n", mode->hdisplay, mode->vdisplay);

	if(pipe == 2) {
		mipi_reg = MIPI_C;
		dspcntr_reg = DSPCCNTR;
		pipeconf_reg = PIPECCONF;
		
		reg_offset = MIPIC_REG_OFFSET;
		
		dspcntr_val = dev_priv->dspcntr2;
		pipeconf_val = dev_priv->pipeconf2;
	} else {
		mipi_val |= 0x2; /*two lanes for port A and C respectively*/
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("hw begin failed\n");
		return;
	}
	
	/*set up pipe related registers*/
	REG_WRITE(mipi_reg, mipi_val);
	REG_READ(mipi_reg);
	
	pyr_dsi_controller_dbi_init(dsi_config, pipe);
	
	msleep(20);
	
	REG_WRITE(dspcntr_reg, dspcntr_val);
	REG_READ(dspcntr_reg);
    
	/*20ms delay before sending exit_sleep_mode*/
	msleep(20);
    
	/*send exit_sleep_mode DCS*/
	ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM);
	if(ret) {
		DRM_ERROR("sent exit_sleep_mode faild\n");
		goto out_err;
	}

	if (dev_priv->platform_rev_id != MDFLD_PNW_A0) {
		/*send set_tear_on DCS*/
		ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on, &param, 1, CMD_DATA_SRC_SYSTEM_MEM);

		if(ret) {
			DRM_ERROR("%s - sent set_tear_on faild\n", __func__);
			goto out_err;
		}
	}

	/*do some init stuff*/
	mdfld_dsi_brightness_init(dsi_config, pipe);
	
	mdfld_dsi_gen_fifo_ready (dev, (MIPIA_GEN_FIFO_STAT_REG + reg_offset), HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);

	REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
	REG_READ(pipeconf_reg);
	
	/*TODO: this looks ugly, try to move it to CRTC mode setting*/
	if(pipe == 2) {
		dev_priv->pipeconf2 |= PIPEACONF_DSR;
	} else {
		dev_priv->pipeconf |= PIPEACONF_DSR;
	}
	
	PSB_DEBUG_ENTRY("pipeconf %x\n",  REG_READ(pipeconf_reg));
	
	ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0, h_active_area - 1, v_active_area - 1);
	if(ret) {
		DRM_ERROR("update area failed\n");
		goto out_err;
	}

out_err:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	if(ret) {
		DRM_ERROR("mode set failed\n");
	} else {
		PSB_DEBUG_ENTRY("mode set done successfully\n");
	}
}
示例#21
0
static void pyr_dsi_dbi_set_power(struct drm_encoder * encoder, bool on)
{
	int ret = 0;
	struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	/*struct drm_device * dev = dbi_output->dev;*/
	struct drm_device* dev = encoder->dev;
	struct drm_psb_private * dev_priv = dev->dev_private;
	u32 reg_offset = 0;
	int pipe = (dbi_output->channel_num == 0) ? 0 : 2;

	PSB_DEBUG_ENTRY("pipe %d : %s, panel on: %s\n",pipe, on ? "On" : "Off", dbi_output->dbi_panel_on ? "True" : "False");
        
	if(pipe == 2) {
		if(on)
			dev_priv->dual_mipi = true;
		else
			dev_priv->dual_mipi = false;

		reg_offset = MIPIC_REG_OFFSET;
	} else {
		if (!on)
			dev_priv->dual_mipi = false;
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("hw begin failed\n");
		return;
	}


	if(on) {
		if(dbi_output->dbi_panel_on)
			goto out_err;
					
		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
		if(ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}

		dbi_output->dbi_panel_on = true;

		if(pipe == 2) {
			dev_priv->dbi_panel_on2 = true;
		} else {
			dev_priv->dbi_panel_on = true;

			if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
				mdfld_enable_te(dev, 0);
		}
		
	} else {
		if(!dbi_output->dbi_panel_on && !dbi_output->first_boot) 
			goto out_err;
					
		dbi_output->dbi_panel_on = false;
		dbi_output->first_boot = false;

		if(pipe == 2) {
			dev_priv->dbi_panel_on2 = false;

			if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
				mdfld_disable_te(dev, 2);
		} else {
			dev_priv->dbi_panel_on = false;

			if (dev_priv->platform_rev_id != MDFLD_PNW_A0) {
				mdfld_disable_te(dev, 0);

				if (dev_priv->dbi_panel_on2)
					mdfld_enable_te(dev, 2);
			}
		}

		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
		if(ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}
	}

out_err:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	if(ret)
		DRM_ERROR("failed\n");
	else
		PSB_DEBUG_ENTRY("successfully\n");
}