Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3caa89e9 authored by Alan Cox's avatar Alan Cox Committed by Greg Kroah-Hartman
Browse files

gma500: resync with Medfield progress

parent f75c7538
Loading
Loading
Loading
Loading
+134 −235
Original line number Original line Diff line number Diff line
@@ -39,29 +39,10 @@ extern int gfxrtdelay;
int enter_dsr;
int enter_dsr;
struct mdfld_dsi_dbi_output *gdbi_output;
struct mdfld_dsi_dbi_output *gdbi_output;
extern bool gbgfxsuspended;
extern bool gbgfxsuspended;
extern int enable_gfx_rtpm;
extern int gfxrtdelay;
extern int gfxrtdelay;


#ifdef CONFIG_GFX_RTPM
#define MDFLD_DSR_MAX_IDLE_COUNT	2
static void psb_runtimepm_wq_handler(struct work_struct *work);
DECLARE_DELAYED_WORK(rtpm_work, psb_runtimepm_wq_handler);

void psb_runtimepm_wq_handler(struct work_struct *work)
{
	struct drm_psb_private *dev_priv =  gpDrmDevice->dev_private;

	if (drm_psb_ospm && !enable_gfx_rtpm) {
		pr_info("Enable GFX runtime_pm\n");
		dev_priv->rpm_enabled = 1;
		enable_gfx_rtpm = 1;

		pm_runtime_enable(&gpDrmDevice->pdev->dev);
		pm_runtime_set_active(&gpDrmDevice->pdev->dev);

		pm_runtime_allow(&gpDrmDevice->pdev->dev);
	}
}
#endif



/*
/*
 * set refreshing area
 * set refreshing area
@@ -80,8 +61,8 @@ int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
		return -EINVAL;
		return -EINVAL;
	}
	}


	/*set column*/
	/* Set column */
	cmd = set_column_address;
	cmd = DCS_SET_COLUMN_ADDRESS;
	param[0] = x1 >> 8;
	param[0] = x1 >> 8;
	param[1] = x1;
	param[1] = x1;
	param[2] = x2 >> 8;
	param[2] = x2 >> 8;
@@ -98,8 +79,8 @@ int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
		goto err_out;
		goto err_out;
	}
	}


	/*set page*/
	/* Set page */
	cmd = set_page_addr;
	cmd = DCS_SET_PAGE_ADDRESS;
	param[0] = y1 >> 8;
	param[0] = y1 >> 8;
	param[1] = y1;
	param[1] = y1;
	param[2] = y2 >> 8;
	param[2] = y2 >> 8;
@@ -139,56 +120,46 @@ int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
								int mode)
								int mode)
{
{
	struct drm_device *dev = dbi_output->dev;
	struct drm_device *dev = dbi_output->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dsi_pkg_sender *sender =
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	u8 param = 0;
	u8 param = 0;
	u32 err = 0;
	u32 err = 0;


	if (!dev_priv->dispstatus && mode != DRM_MODE_DPMS_ON) {
		dev_err(dev->dev, "%s: already OFF ignoring\n", __func__);
		return 0;
	}
	if (dev_priv->dispstatus && mode == DRM_MODE_DPMS_ON) {
		dev_err(dev->dev, "%s: already ON ignoring\n", __func__);
		return 0;
	}

	if (!sender) {
	if (!sender) {
		WARN_ON(1);
		WARN_ON(1);
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (mode == DRM_MODE_DPMS_ON) {
	if (mode == DRM_MODE_DPMS_ON) {
		/*exit sleep mode*/
		/* Exit sleep mode */
		err = mdfld_dsi_send_dcs(sender,
		err = mdfld_dsi_send_dcs(sender,
					 exit_sleep_mode,
					 DCS_EXIT_SLEEP_MODE,
					 NULL,
					 NULL,
					 0,
					 0,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
						exit_sleep_mode);
						DCS_EXIT_SLEEP_MODE);
			goto power_err;
			goto power_err;
		}
		}


		/*set display on*/
		/* Set display on */
		err = mdfld_dsi_send_dcs(sender,
		err = mdfld_dsi_send_dcs(sender,
					 set_display_on,
					 DCS_SET_DISPLAY_ON,
					 NULL,
					 NULL,
					 0,
					 0,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
							set_display_on);
							DCS_SET_DISPLAY_ON);
			goto power_err;
			goto power_err;
		}
		}


		/* set tear effect on */
		/* set tear effect on */
		err = mdfld_dsi_send_dcs(sender,
		err = mdfld_dsi_send_dcs(sender,
					 set_tear_on,
					 DCS_SET_TEAR_ON,
					 &param,
					 &param,
					 1,
					 1,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 CMD_DATA_SRC_SYSTEM_MEM,
@@ -203,53 +174,53 @@ int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
		 * FIXME: remove this later
		 * FIXME: remove this later
		 */
		 */
		err = mdfld_dsi_send_dcs(sender,
		err = mdfld_dsi_send_dcs(sender,
					 write_mem_start,
					 DCS_WRITE_MEM_START,
					 NULL,
					 NULL,
					 0,
					 0,
					 CMD_DATA_SRC_PIPE,
					 CMD_DATA_SRC_PIPE,
					 MDFLD_DSI_QUEUE_PACKAGE);
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
							set_display_on);
						DCS_WRITE_MEM_START);
			goto power_err;
			goto power_err;
		}
		}
	} else {
	} else {
		/*set tear effect off */
		/* Set tear effect off */
		err = mdfld_dsi_send_dcs(sender,
		err = mdfld_dsi_send_dcs(sender,
					 set_tear_off,
					 DCS_SET_TEAR_OFF,
					 NULL,
					 NULL,
					 0,
					 0,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
							set_tear_off);
							DCS_SET_TEAR_OFF);
			goto power_err;
			goto power_err;
		}
		}


		/*set display off*/
		/* Turn display off */
		err = mdfld_dsi_send_dcs(sender,
		err = mdfld_dsi_send_dcs(sender,
					 set_display_off,
					 DCS_SET_DISPLAY_OFF,
					 NULL,
					 NULL,
					 0,
					 0,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
							set_display_off);
						DCS_SET_DISPLAY_OFF);
			goto power_err;
			goto power_err;
		}
		}


		/*enter sleep mode*/
		/* Now enter sleep mode */
		err = mdfld_dsi_send_dcs(sender,
		err = mdfld_dsi_send_dcs(sender,
					 enter_sleep_mode,
					 DCS_ENTER_SLEEP_MODE,
					 NULL,
					 NULL,
					 0,
					 0,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 CMD_DATA_SRC_SYSTEM_MEM,
					 MDFLD_DSI_QUEUE_PACKAGE);
					 MDFLD_DSI_QUEUE_PACKAGE);
		if (err) {
		if (err) {
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
			dev_err(dev->dev, "DCS 0x%x sent failed\n",
							enter_sleep_mode);
							DCS_ENTER_SLEEP_MODE);
			goto power_err;
			goto power_err;
		}
		}
	}
	}
@@ -283,7 +254,6 @@ int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
	return ret;
	return ret;
}
}



/*
/*
 * Enter DSR
 * Enter DSR
 */
 */
@@ -299,11 +269,12 @@ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
	u32 pipeconf_reg = PIPEACONF;
	u32 pipeconf_reg = PIPEACONF;
	u32 dspcntr_reg = DSPACNTR;
	u32 dspcntr_reg = DSPACNTR;


	dev_priv->is_in_idle = true;

	if (!dbi_output)
	if (!dbi_output)
		return;
		return;


	/* FIXME check if can go */
	dev_priv->is_in_idle = true;

	gdbi_output = dbi_output;
	gdbi_output = dbi_output;
	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
@@ -319,16 +290,17 @@ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
		dev_err(dev->dev, "hw begin failed\n");
		dev_err(dev->dev, "hw begin failed\n");
		return;
		return;
	}
	}
	/*disable te interrupts. */
	/* Disable te interrupts */
	mdfld_disable_te(dev, pipe);
	mdfld_disable_te(dev, pipe);


	/*disable plane*/
	/* Disable plane */
	reg_val = REG_READ(dspcntr_reg);
	reg_val = REG_READ(dspcntr_reg);
	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
		REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE);
		REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE);
		REG_READ(dspcntr_reg);
		REG_READ(dspcntr_reg);
	}
	}
	/*disable pipe*/

	/* Disable pipe */
	reg_val = REG_READ(pipeconf_reg);
	reg_val = REG_READ(pipeconf_reg);
	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
		reg_val &= ~DISPLAY_PLANE_ENABLE;
		reg_val &= ~DISPLAY_PLANE_ENABLE;
@@ -338,7 +310,7 @@ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
		mdfldWaitForPipeDisable(dev, pipe);
		mdfldWaitForPipeDisable(dev, pipe);
	}
	}


	/*disable DPLL*/
	/* Disable DPLL */
	reg_val = REG_READ(dpll_reg);
	reg_val = REG_READ(dpll_reg);
	if (!(reg_val & DPLL_VCO_ENABLE)) {
	if (!(reg_val & DPLL_VCO_ENABLE)) {
		reg_val &= ~DPLL_VCO_ENABLE;
		reg_val &= ~DPLL_VCO_ENABLE;
@@ -357,10 +329,9 @@ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)


#ifndef CONFIG_MDFLD_DSI_DPU
#ifndef CONFIG_MDFLD_DSI_DPU
static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
			int pipe, void *p_surfaceAddr, bool check_hw_on_only)
			int pipe)
{
{
	struct drm_device *dev = dbi_output->dev;
	struct drm_device *dev = dbi_output->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct drm_crtc *crtc = dbi_output->base.base.crtc;
	struct drm_crtc *crtc = dbi_output->base.base.crtc;
	struct psb_intel_crtc *psb_crtc = (crtc) ?
	struct psb_intel_crtc *psb_crtc = (crtc) ?
					to_psb_intel_crtc(crtc) : NULL;
					to_psb_intel_crtc(crtc) : NULL;
@@ -368,7 +339,6 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
	u32 dpll_reg = MRST_DPLL_A;
	u32 dpll_reg = MRST_DPLL_A;
	u32 pipeconf_reg = PIPEACONF;
	u32 pipeconf_reg = PIPEACONF;
	u32 dspcntr_reg = DSPACNTR;
	u32 dspcntr_reg = DSPACNTR;
	u32 dspsurf_reg = DSPASURF;
	u32 reg_offset = 0;
	u32 reg_offset = 0;


	/*if mode setting on-going, back off*/
	/*if mode setting on-going, back off*/
@@ -380,24 +350,17 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
		dpll_reg = MRST_DPLL_A;
		dpll_reg = MRST_DPLL_A;
		pipeconf_reg = PIPECCONF;
		pipeconf_reg = PIPECCONF;
		dspcntr_reg = DSPCCNTR;
		dspcntr_reg = DSPCCNTR;
		dspsurf_reg = DSPCSURF;
		reg_offset = MIPIC_REG_OFFSET;
		reg_offset = MIPIC_REG_OFFSET;
	}
	}


	if (check_hw_on_only) {
	if (!gma_power_begin(dev, true)) {
		if (0/* FIXME!ospm_power_is_hw_on(_DISPLAY_ISLAND)*/) {
			dev_err(dev->dev, "hw begin failed\n");
			return;
		}
	} else if (!gma_power_begin(dev, true)) {
		dev_err(dev->dev, "hw begin failed\n");
		dev_err(dev->dev, "hw begin failed\n");
		return;
		return;
	}
	}


	/*enable DPLL*/
	/* Enable DPLL */
	reg_val = REG_READ(dpll_reg);
	reg_val = REG_READ(dpll_reg);
	if (!(reg_val & DPLL_VCO_ENABLE)) {
	if (!(reg_val & DPLL_VCO_ENABLE)) {

		if (reg_val & MDFLD_PWR_GATE_EN) {
		if (reg_val & MDFLD_PWR_GATE_EN) {
			reg_val &= ~MDFLD_PWR_GATE_EN;
			reg_val &= ~MDFLD_PWR_GATE_EN;
			REG_WRITE(dpll_reg, reg_val);
			REG_WRITE(dpll_reg, reg_val);
@@ -415,7 +378,7 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
			cpu_relax();
			cpu_relax();
	}
	}


	/*enable pipe*/
	/* Enable pipe */
	reg_val = REG_READ(pipeconf_reg);
	reg_val = REG_READ(pipeconf_reg);
	if (!(reg_val & PIPEACONF_ENABLE)) {
	if (!(reg_val & PIPEACONF_ENABLE)) {
		reg_val |= PIPEACONF_ENABLE;
		reg_val |= PIPEACONF_ENABLE;
@@ -425,7 +388,7 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
		mdfldWaitForPipeEnable(dev, pipe);
		mdfldWaitForPipeEnable(dev, pipe);
	}
	}


	/*enable plane*/
	/* Enable plane */
	reg_val = REG_READ(dspcntr_reg);
	reg_val = REG_READ(dspcntr_reg);
	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
		reg_val |= DISPLAY_PLANE_ENABLE;
		reg_val |= DISPLAY_PLANE_ENABLE;
@@ -434,15 +397,9 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
		udelay(500);
		udelay(500);
	}
	}


	/* update the surface base address. */
	/* Enable TE interrupt on this pipe */
	if (p_surfaceAddr)
		REG_WRITE(dspsurf_reg, *((u32 *)p_surfaceAddr));

	if (!check_hw_on_only)
		gma_power_end(dev);

	/*enable TE interrupt on this pipe*/
	mdfld_enable_te(dev, pipe);
	mdfld_enable_te(dev, pipe);
	gma_power_end(dev);


	/*clean IN_DSR flag*/
	/*clean IN_DSR flag*/
	dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
	dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
@@ -451,33 +408,33 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
/*
/*
 * Exit from DSR
 * Exit from DSR
 */
 */
void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src,
void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src)
				void *p_surfaceAddr, bool check_hw_on_only)
{
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
	struct mdfld_dsi_dbi_output **dbi_output;
	struct mdfld_dsi_dbi_output **dbi_output;
	int i;
	int i;
	int pipe;


	/* FIXME can go ? */
	dev_priv->is_in_idle = false;
	dev_priv->is_in_idle = false;
	dbi_output = dsr_info->dbi_outputs;
	dbi_output = dsr_info->dbi_outputs;


#ifdef CONFIG_PM_RUNTIME
#ifdef CONFIG_PM_RUNTIME
	 if (!enable_gfx_rtpm) {
	 if (!enable_gfx_rtpm) {
/*                pm_runtime_allow(&gpDrmDevice->pdev->dev); */
/*                pm_runtime_allow(&gpDrmDevice->pdev->dev); */
/*		schedule_delayed_work(&rtpm_work, 120 * 1000); */
/*		schedule_delayed_work(&rtpm_work, 30 * 1000);*/ /* FIXME: HZ ? */
	}
	}
#endif
#endif


	/*for each output, exit dsr*/
	/* For each output, exit dsr */
	for (i = 0; i < dsr_info->dbi_output_num; i++) {
	for (i = 0; i < dsr_info->dbi_output_num; i++) {
		/*if panel has been turned off, skip*/
		/* If panel has been turned off, skip */
		if (!dbi_output[i]->dbi_panel_on)
		if (!dbi_output[i] || !dbi_output[i]->dbi_panel_on)
			continue;
			continue;
		if (dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR) {
		pipe = dbi_output[i]->channel_num ? 2 : 0;
		enter_dsr = 0;
		enter_dsr = 0;
			mdfld_dbi_output_exit_dsr(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0, p_surfaceAddr, check_hw_on_only);
		mdfld_dbi_output_exit_dsr(dbi_output[i], pipe);
		}
	}
	}
	dev_priv->dsr_fb_update |= update_src;
	dev_priv->dsr_fb_update |= update_src;
}
}
@@ -496,7 +453,7 @@ static bool mdfld_dbi_is_in_dsr(struct drm_device *dev)
	return true;
	return true;
}
}


/* Perodically update dbi panel */
/* Periodically update dbi panel */
void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
{
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct drm_psb_private *dev_priv = dev->dev_private;
@@ -504,8 +461,8 @@ void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
	struct mdfld_dsi_dbi_output **dbi_outputs;
	struct mdfld_dsi_dbi_output **dbi_outputs;
	struct mdfld_dsi_dbi_output *dbi_output;
	struct mdfld_dsi_dbi_output *dbi_output;
	int i;
	int i;
	int enter_dsr = 0;
	int can_enter_dsr = 0;
	u32 damage_mask = 0;
	u32 damage_mask;


	dbi_outputs = dsr_info->dbi_outputs;
	dbi_outputs = dsr_info->dbi_outputs;
	dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0];
	dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0];
@@ -514,13 +471,13 @@ void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
		return;
		return;


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


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


@@ -538,11 +495,24 @@ void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
		dbi_output->dsr_idle_count++;
		dbi_output->dsr_idle_count++;
	}
	}


	/*try to enter DSR*/
	switch (dsr_info->dbi_output_num) {
	if (dbi_outputs[0]->dsr_idle_count > 1
	case 1:
	    && dbi_outputs[1]->dsr_idle_count > 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++) {
		for (i = 0; i < dsr_info->dbi_output_num; i++) {
			if (!mdfld_dbi_is_in_dsr(dev) &&
			if (!mdfld_dbi_is_in_dsr(dev) && dbi_outputs[i] &&
			   !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) {
			   !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) {
				mdfld_dsi_dbi_enter_dsr(dbi_outputs[i],
				mdfld_dsi_dbi_enter_dsr(dbi_outputs[i],
					dbi_outputs[i]->channel_num ? 2 : 0);
					dbi_outputs[i]->channel_num ? 2 : 0);
@@ -565,61 +535,6 @@ void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
	}
	}
}
}


/*timers for DSR*/
static void mdfld_dsi_dbi_dsr_timer_func(unsigned long data)
{
	struct drm_device *dev = (struct drm_device *)data;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
	struct timer_list *dsr_timer = &dsr_info->dsr_timer;
	unsigned long flags;

	mdfld_dbi_update_panel(dev, 0);

	if (dsr_info->dsr_idle_count > 1)
		return;

	spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
	if (!timer_pending(dsr_timer)) {
		dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
		add_timer(dsr_timer);
	}
	spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
}

static int mdfld_dsi_dbi_dsr_timer_init(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
	struct timer_list *dsr_timer = &dsr_info->dsr_timer;
	unsigned long flags;

	spin_lock_init(&dsr_info->dsr_timer_lock);
	spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);

	init_timer(dsr_timer);

	dsr_timer->data = (unsigned long)dev;
	dsr_timer->function = mdfld_dsi_dbi_dsr_timer_func;
	dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;

	spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
	return 0;
}

void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info *dsr_info)
{
	struct timer_list *dsr_timer = &dsr_info->dsr_timer;
	unsigned long flags;

	spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
	if (!timer_pending(dsr_timer)) {
		dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
		add_timer(dsr_timer);
	}
	spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
}

int mdfld_dbi_dsr_init(struct drm_device *dev)
int mdfld_dbi_dsr_init(struct drm_device *dev)
{
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct drm_psb_private *dev_priv = dev->dev_private;
@@ -643,7 +558,6 @@ void mdfld_dbi_dsr_exit(struct drm_device *dev)
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;


	if (dsr_info) {
	if (dsr_info) {
		del_timer_sync(&dsr_info->dsr_timer);
		kfree(dsr_info);
		kfree(dsr_info);
		dev_priv->dbi_dsr_info = NULL;
		dev_priv->dbi_dsr_info = NULL;
	}
	}
@@ -660,10 +574,10 @@ void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,


	dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
	dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);


	/*un-ready device*/
	/* Un-ready device */
	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);


	/*init dsi adapter before kicking off*/
	/* Init dsi adapter before kicking off */
	REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
	REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);


	/* TODO: figure out how to setup these registers */
	/* TODO: figure out how to setup these registers */
@@ -674,16 +588,16 @@ void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
	REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
	REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
	REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
	REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);


	/*enable all interrupts*/
	/* Enable all interrupts */
	REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
	REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
	/*max value: 20 clock cycles of txclkesc*/
	/* Max value: 20 clock cycles of txclkesc */
	REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
	REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
	/*min 21 txclkesc, max: ffffh*/
	/* Min 21 txclkesc, max: ffffh */
	REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
	REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
	/*min: 7d0 max: 4e20*/
	/* Min: 7d0 max: 4e20 */
	REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
	REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);


	/*set up func_prg*/
	/* Set up func_prg */
	val |= lane_count;
	val |= lane_count;
	val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
	val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
	val |= DSI_DBI_COLOR_FORMAT_OPTION2;
	val |= DSI_DBI_COLOR_FORMAT_OPTION2;
@@ -692,7 +606,7 @@ void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
	REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
	REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
	REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
	REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);


	/*de-assert dbi_stall when half of DBI FIFO is empty*/
	/* De-assert dbi_stall when half of DBI FIFO is empty */
	/* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
	/* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */


	REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
	REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
@@ -718,42 +632,6 @@ static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {


#endif
#endif


static int mdfld_dbi_panel_reset(struct mdfld_dsi_dbi_output *output)
{
	unsigned gpio;
	int ret;

	switch (output->channel_num) {
	case 0:
		gpio = 128;
		break;
	case 1:
		gpio = 34;
		break;
	default:
		pr_err("Invalid output\n");
		return -EINVAL;
	}

	ret = gpio_request(gpio, "gfx");
	if (ret) {
		pr_err("gpio_rqueset failed\n");
		return ret;
	}

	ret = gpio_direction_output(gpio, 1);
	if (ret) {
		pr_err("gpio_direction_output failed\n");
		goto gpio_error;
	}
	gpio_get_value(128);
gpio_error:
	if (gpio_is_valid(gpio))
		gpio_free(gpio);

	return ret;
}

/*
/*
 * Init DSI DBI encoder.
 * Init DSI DBI encoder.
 * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
 * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
@@ -776,13 +654,44 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
#else
#else
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL;
	struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL;
#endif
#endif
	u32 data = 0;
	int pipe;
	int ret;
	int ret;


	if (!pg || !dsi_connector) {
	if (!pg || !dsi_connector || !p_funcs) {
		WARN_ON(1);
		WARN_ON(1);
		return NULL;
		return NULL;
	}
	}


	dsi_config = mdfld_dsi_get_config(dsi_connector);
	pipe = dsi_connector->pipe;

	/*panel hard-reset*/
	if (p_funcs->reset) {
		ret = p_funcs->reset(pipe);
		if (ret) {
			DRM_ERROR("Panel %d hard-reset failed\n", pipe);
			return NULL;
		}
	}
	/* Panel drvIC init */
	if (p_funcs->drv_ic_init)
		p_funcs->drv_ic_init(dsi_config, pipe);

	/* Panel power mode detect */
	ret = mdfld_dsi_get_power_mode(dsi_config,
				       &data,
				       MDFLD_DSI_HS_TRANSMISSION);
	if (ret) {
		DRM_ERROR("Panel %d get power mode failed\n", pipe);
		dsi_connector->status = connector_status_disconnected;
	} else {
		DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
		dsi_connector->status = connector_status_connected;
	}

	/*TODO: get panel info from DDB*/

	dbi_output = kzalloc(sizeof(struct mdfld_dsi_dbi_output), GFP_KERNEL);
	dbi_output = kzalloc(sizeof(struct mdfld_dsi_dbi_output), GFP_KERNEL);
	if (!dbi_output) {
	if (!dbi_output) {
		dev_err(dev->dev, "No memory\n");
		dev_err(dev->dev, "No memory\n");
@@ -802,23 +711,10 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,


	dbi_output->dev = dev;
	dbi_output->dev = dev;
	dbi_output->p_funcs = p_funcs;
	dbi_output->p_funcs = p_funcs;

	/*panel reset*/
	ret = mdfld_dbi_panel_reset(dbi_output);
	if (ret) {
		dev_err(dev->dev, "reset panel error\n");
		goto out_err1;
	}

	/*TODO: get panel info from DDB*/

	/*get fixed mode*/
	dsi_config = mdfld_dsi_get_config(dsi_connector);
	fixed_mode = dsi_config->fixed_mode;
	fixed_mode = dsi_config->fixed_mode;

	dbi_output->panel_fixed_mode = fixed_mode;
	dbi_output->panel_fixed_mode = fixed_mode;


	/*create drm encoder object*/
	/* Create drm encoder object */
	connector = &dsi_connector->base.base;
	connector = &dsi_connector->base.base;
	encoder = &dbi_output->base.base;
	encoder = &dbi_output->base.base;
	drm_encoder_init(dev,
	drm_encoder_init(dev,
@@ -827,10 +723,10 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
			DRM_MODE_ENCODER_MIPI);
			DRM_MODE_ENCODER_MIPI);
	drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs);
	drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs);


	/*attach to given connector*/
	/* Attach to given connector */
	drm_mode_connector_attach_encoder(connector, encoder);
	drm_mode_connector_attach_encoder(connector, encoder);


	/*set possible crtcs and clones*/
	/* Set possible CRTCs and clones */
	if (dsi_connector->pipe) {
	if (dsi_connector->pipe) {
		encoder->possible_crtcs = (1 << 2);
		encoder->possible_crtcs = (1 << 2);
		encoder->possible_clones = (1 << 1);
		encoder->possible_clones = (1 << 1);
@@ -842,28 +738,31 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
	dev_priv->dsr_fb_update = 0;
	dev_priv->dsr_fb_update = 0;
	dev_priv->dsr_enable = false;
	dev_priv->dsr_enable = false;
	dev_priv->exit_idle = mdfld_dsi_dbi_exit_dsr;
	dev_priv->exit_idle = mdfld_dsi_dbi_exit_dsr;
#if defined(CONFIG_MDFLD_DSI_DPU) || defined(CONFIG_MDFLD_DSI_DSR)
	dev_priv->dsr_enable_config = false;
#endif /*CONFIG_MDFLD_DSI_DSR*/


	dbi_output->first_boot = true;
	dbi_output->first_boot = true;
	dbi_output->mode_flags = MODE_SETTING_IN_ENCODER;
	dbi_output->mode_flags = MODE_SETTING_IN_ENCODER;


#ifdef CONFIG_MDFLD_DSI_DPU
#ifdef CONFIG_MDFLD_DSI_DPU
	/*add this output to dpu_info*/
	/* Add this output to dpu_info */
	if (dsi_connector->status == connector_status_connected) {
		if (dsi_connector->pipe == 0)
		if (dsi_connector->pipe == 0)
			dpu_info->dbi_outputs[0] = dbi_output;
			dpu_info->dbi_outputs[0] = dbi_output;
	} else {
		else
			dpu_info->dbi_outputs[1] = dbi_output;
			dpu_info->dbi_outputs[1] = dbi_output;
	}

		dpu_info->dbi_output_num++;
		dpu_info->dbi_output_num++;
	}

#else /*CONFIG_MDFLD_DSI_DPU*/
#else /*CONFIG_MDFLD_DSI_DPU*/
	/*add this output to dsr_info*/
	if (dsi_connector->status == connector_status_connected) {
		/* Add this output to dsr_info */
		if (dsi_connector->pipe == 0)
		if (dsi_connector->pipe == 0)
			dsr_info->dbi_outputs[0] = dbi_output;
			dsr_info->dbi_outputs[0] = dbi_output;
		else
		else
			dsr_info->dbi_outputs[1] = dbi_output;
			dsr_info->dbi_outputs[1] = dbi_output;

		dsr_info->dbi_output_num++;
		dsr_info->dbi_output_num++;
	}
#endif
#endif
	return &dbi_output->base;
	return &dbi_output->base;
out_err1:
out_err1:
+2 −19
Original line number Original line Diff line number Diff line
@@ -59,9 +59,6 @@ struct mdfld_dsi_dbi_output {
	/* Backlight operations */
	/* Backlight operations */


	/* DSR timer */
	/* DSR timer */
	spinlock_t dsr_timer_lock;
	struct timer_list dsr_timer;
	void(*dsi_timer_func)(unsigned long data);
	u32 dsr_idle_count;
	u32 dsr_idle_count;
	bool dsr_fb_update_done;
	bool dsr_fb_update_done;


@@ -81,22 +78,11 @@ struct mdfld_dbi_dsr_info {
	int dbi_output_num;
	int dbi_output_num;
	struct mdfld_dsi_dbi_output *dbi_outputs[2];
	struct mdfld_dsi_dbi_output *dbi_outputs[2];


	spinlock_t dsr_timer_lock;
	struct timer_list dsr_timer;
	u32 dsr_idle_count;
	u32 dsr_idle_count;
};
};


#define DBI_CB_TIMEOUT_COUNT	0xffff
#define DBI_CB_TIMEOUT_COUNT	0xffff


/* DCS commands */
#define enter_sleep_mode	0x10
#define exit_sleep_mode		0x11
#define set_display_off		0x28
#define	set_dispaly_on		0x29
#define set_column_address	0x2a
#define set_page_addr		0x2b
#define write_mem_start		0x2c

/* Offsets */
/* Offsets */
#define CMD_MEM_ADDR_OFFSET	0
#define CMD_MEM_ADDR_OFFSET	0


@@ -132,7 +118,7 @@ static inline int mdfld_dsi_dbi_cmd_sent(struct mdfld_dsi_dbi_output *dbi_output


	/* Query the command execution status */
	/* Query the command execution status */
	while (retry--)
	while (retry--)
		if (!(REG_READ(MIPIA_CMD_ADD_REG + reg_offset) & (1 << 10)))
		if (!(REG_READ(MIPIA_CMD_ADD_REG + reg_offset) & (1 << 0)))
			break;
			break;


	if (!retry) {
	if (!retry) {
@@ -164,13 +150,11 @@ static inline int mdfld_dsi_dbi_cb_ready(struct mdfld_dsi_dbi_output *dbi_output


extern void mdfld_dsi_dbi_output_init(struct drm_device *dev,
extern void mdfld_dsi_dbi_output_init(struct drm_device *dev,
			struct psb_intel_mode_device *mode_dev, int pipe);
			struct psb_intel_mode_device *mode_dev, int pipe);
extern void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src,
extern void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src);
			void *p_surfaceAddr, bool check_hw_on_only);
extern void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output,
extern void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output,
			int pipe);
			int pipe);
extern int mdfld_dbi_dsr_init(struct drm_device *dev);
extern int mdfld_dbi_dsr_init(struct drm_device *dev);
extern void mdfld_dbi_dsr_exit(struct drm_device *dev);
extern void mdfld_dbi_dsr_exit(struct drm_device *dev);
extern void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info *dsr_info);
extern struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
extern struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
			struct mdfld_dsi_connector *dsi_connector,
			struct mdfld_dsi_connector *dsi_connector,
			struct panel_funcs *p_funcs);
			struct panel_funcs *p_funcs);
@@ -178,7 +162,6 @@ extern int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
			u8 dcs, u8 *param, u32 num, u8 data_src);
			u8 dcs, u8 *param, u32 num, u8 data_src);
extern int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
extern int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
			u16 x1, u16 y1, u16 x2, u16 y2);
			u16 x1, u16 y1, u16 x2, u16 y2);
extern void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info *dsr_info);
extern int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
extern int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
			int mode);
			int mode);
extern void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
extern void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
+0 −3
Original line number Original line Diff line number Diff line
@@ -90,9 +90,6 @@ static inline int mdfld_dpu_region_extent(struct psb_drm_dpu_rect *origin,
{
{
	int x1, y1, x2, y2;
	int x1, y1, x2, y2;


	/* PSB_DEBUG_ENTRY("rect (%d, %d, %d, %d)\n",
		rect->x, rect->y, rect->width, rect->height); */

	x1 = origin->x + origin->width;
	x1 = origin->x + origin->width;
	y1 = origin->y + origin->height;
	y1 = origin->y + origin->height;


+64 −255

File changed.

Preview size limit exceeded, changes collapsed.

+2 −4
Original line number Original line Diff line number Diff line
@@ -47,6 +47,8 @@ struct mdfld_dsi_dpi_output {


	int panel_on;
	int panel_on;
	int first_boot;
	int first_boot;

	struct panel_funcs *p_funcs;
};
};


#define MDFLD_DSI_DPI_OUTPUT(dsi_encoder) \
#define MDFLD_DSI_DPI_OUTPUT(dsi_encoder) \
@@ -73,8 +75,4 @@ extern void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output,
			int pipe);
			int pipe);
extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *si_config,
extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *si_config,
			int pipe);
			int pipe);
extern void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe);
extern void psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe,
			u32 mask);

#endif /*__MDFLD_DSI_DPI_H__*/
#endif /*__MDFLD_DSI_DPI_H__*/
Loading