Exemplo n.º 1
0
static int mdfld_dpu_enter_dsr(struct drm_device * dev)
{
	struct drm_psb_private * dev_priv = dev->dev_private;
	struct mdfld_dbi_dpu_info * dpu_info = dev_priv->dbi_dpu_info;
	struct mdfld_dsi_dbi_output ** dbi_output;
	int i;
	
	PSB_DEBUG_ENTRY("\n");
	
	dbi_output = dpu_info->dbi_outputs;
	
	for(i=0; i<dpu_info->dbi_output_num; i++) {
		/*if output is off or already in DSR state, don't enter again*/
		if(dbi_output[i]->dbi_panel_on && 
		   !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
			mdfld_dsi_dbi_enter_dsr(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0);
		}
	}

	return 0;
}
Exemplo n.º 2
0
/* Periodically update dbi panel */
void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
	struct mdfld_dsi_dbi_output **dbi_outputs;
	struct mdfld_dsi_dbi_output *dbi_output;
	int i;
	int can_enter_dsr = 0;
	u32 damage_mask;

	dbi_outputs = dsr_info->dbi_outputs;
	dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0];

	if (!dbi_output)
		return;

	if (pipe == 0)
		damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_0;
	else if (pipe == 2)
		damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_2;
	else
		return;

	/* If FB is damaged and panel is on update on-panel FB */
	if (damage_mask && dbi_output->dbi_panel_on) {
		dbi_output->dsr_fb_update_done = false;

		if (dbi_output->p_funcs->update_fb)
			dbi_output->p_funcs->update_fb(dbi_output, pipe);

		if (dev_priv->dsr_enable && dbi_output->dsr_fb_update_done)
			dev_priv->dsr_fb_update &= ~damage_mask;

		/*clean IN_DSR flag*/
		dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;

		dbi_output->dsr_idle_count = 0;
	} else {
		dbi_output->dsr_idle_count++;
	}

	switch (dsr_info->dbi_output_num) {
	case 1:
		if (dbi_output->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT)
			can_enter_dsr = 1;
		break;
	case 2:
		if (dbi_outputs[0]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT
		   && dbi_outputs[1]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT)
			can_enter_dsr = 1;
		break;
	default:
		DRM_ERROR("Wrong DBI output number\n");
	}

	/* Try to enter DSR */
	if (can_enter_dsr) {
		for (i = 0; i < dsr_info->dbi_output_num; i++) {
			if (!mdfld_dbi_is_in_dsr(dev) && dbi_outputs[i] &&
			   !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) {
				mdfld_dsi_dbi_enter_dsr(dbi_outputs[i],
					dbi_outputs[i]->channel_num ? 2 : 0);
#if 0
				enter_dsr = 1;
				pr_err("%s: enter_dsr = 1\n", __func__);
#endif
			}
		}
	/*schedule rpm suspend after gfxrtdelay*/
#ifdef CONFIG_GFX_RTPM
		if (!dev_priv->rpm_enabled
			|| !enter_dsr
	/*		|| (REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN) */
			|| pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay))
			dev_warn(dev->dev,
				"Runtime PM schedule suspend failed, rpm %d\n",
					dev_priv->rpm_enabled);
#endif
	}
}