[Meego-kernel] [PATCH] GFX-Display: Re-architech Display Controller code to support MIPI Panels

hitesh.k.patel at intel.com hitesh.k.patel at intel.com
Sun Oct 10 00:27:30 PDT 2010


From: Hitesh K. Patel <hitesh.k.patel at intel.com>

Patch from:
Thomas Eaton <thomas.g.eaton at intel.com>
Scott Rowe <scott.m.rowe at intel.com>

1. Allows easier interface to enable new MIPI panel.
2. Enables TPO, and Pyrenees panel.
3. It will auto detect Panel attached.

Signed-off-by: Hitesh K. Patel <hitesh.k.patel at intel.com>
---
 drivers/staging/mrst/drv/displays/hdmi.h    |   41 ++
 drivers/staging/mrst/drv/displays/pyr_cmd.h |   44 +++
 drivers/staging/mrst/drv/displays/pyr_vid.h |   46 +++
 drivers/staging/mrst/drv/displays/tmd_cmd.h |   45 +++
 drivers/staging/mrst/drv/displays/tmd_vid.h |   44 +++
 drivers/staging/mrst/drv/displays/tpo_cmd.h |   45 +++
 drivers/staging/mrst/drv/displays/tpo_vid.h |   41 ++
 drivers/staging/mrst/drv/mdfld_dsi_dbi.c    |  374 +-----------------
 drivers/staging/mrst/drv/mdfld_dsi_dbi.h    |    6 +-
 drivers/staging/mrst/drv/mdfld_dsi_dpi.c    |   23 +-
 drivers/staging/mrst/drv/mdfld_dsi_dpi.h    |   15 +-
 drivers/staging/mrst/drv/mdfld_dsi_output.c |   54 ++-
 drivers/staging/mrst/drv/mdfld_dsi_output.h |    8 +-
 drivers/staging/mrst/drv/mdfld_output.c     |  131 +++++++
 drivers/staging/mrst/drv/mdfld_output.h     |   66 ++++
 drivers/staging/mrst/drv/psb_fb.c           |   12 +-
 drivers/staging/mrst/drv/pyr_cmd.c          |  560 +++++++++++++++++++++++++++
 drivers/staging/mrst/drv/tpo_cmd.c          |  478 +++++++++++++++++++++++
 drivers/staging/mrst/drv/tpo_vid.c          |  125 ++++++
 drivers/staging/mrst/medfield/Makefile      |    6 +-
 drivers/staging/mrst/moorestown/Makefile    |    7 +-
 21 files changed, 1770 insertions(+), 401 deletions(-)
 create mode 100644 drivers/staging/mrst/drv/displays/hdmi.h
 create mode 100644 drivers/staging/mrst/drv/displays/pyr_cmd.h
 create mode 100644 drivers/staging/mrst/drv/displays/pyr_vid.h
 create mode 100644 drivers/staging/mrst/drv/displays/tmd_cmd.h
 create mode 100644 drivers/staging/mrst/drv/displays/tmd_vid.h
 create mode 100644 drivers/staging/mrst/drv/displays/tpo_cmd.h
 create mode 100644 drivers/staging/mrst/drv/displays/tpo_vid.h
 create mode 100644 drivers/staging/mrst/drv/mdfld_output.c
 create mode 100644 drivers/staging/mrst/drv/mdfld_output.h
 create mode 100644 drivers/staging/mrst/drv/pyr_cmd.c
 create mode 100644 drivers/staging/mrst/drv/tpo_cmd.c
 create mode 100644 drivers/staging/mrst/drv/tpo_vid.c

diff --git a/drivers/staging/mrst/drv/displays/hdmi.h b/drivers/staging/mrst/drv/displays/hdmi.h
new file mode 100644
index 0000000..984a04c
--- /dev/null
+++ b/drivers/staging/mrst/drv/displays/hdmi.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+*/
+
+
+#ifndef HDMI_H
+#define HDMI_H
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+
+#include "mdfld_output.h"
+
+void hdmi_init(struct drm_device* dev);
+
+#endif
diff --git a/drivers/staging/mrst/drv/displays/pyr_cmd.h b/drivers/staging/mrst/drv/displays/pyr_cmd.h
new file mode 100644
index 0000000..d771633
--- /dev/null
+++ b/drivers/staging/mrst/drv/displays/pyr_cmd.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+ */
+
+
+#ifndef PYR_CMD_H
+#define PYR_CMD_H
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+
+#include "mdfld_output.h"
+
+void pyr_cmd_init(struct drm_device* dev, struct panel_funcs* p_funcs);
+struct drm_display_mode*
+pyr_cmd_get_config_mode(struct drm_device* dev);
+
+#endif
+
diff --git a/drivers/staging/mrst/drv/displays/pyr_vid.h b/drivers/staging/mrst/drv/displays/pyr_vid.h
new file mode 100644
index 0000000..2aa1479
--- /dev/null
+++ b/drivers/staging/mrst/drv/displays/pyr_vid.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+*/
+
+
+
+#ifndef PYR_VID_H
+#define PYR_VID_H
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+
+#include "mdfld_output.h"
+
+void pyr_vid_init(struct drm_device* dev, struct panel_funcs* p_funcs);
+struct drm_display_mode*
+pyr_vid_get_config_mode(struct drm_device* dev);
+
+
+
+#endif
diff --git a/drivers/staging/mrst/drv/displays/tmd_cmd.h b/drivers/staging/mrst/drv/displays/tmd_cmd.h
new file mode 100644
index 0000000..ce7ddb4
--- /dev/null
+++ b/drivers/staging/mrst/drv/displays/tmd_cmd.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+*/
+
+
+
+#ifndef TMD_CMD_H
+#define TMD_CMD_H
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+
+#include "mdfld_output.h"
+
+void tmd_cmd_init(struct drm_device* dev, struct panel_funcs* p_funcs);
+struct drm_display_mode*
+tmd_cmd_get_config_mode(struct drm_device* dev);
+
+
+#endif
diff --git a/drivers/staging/mrst/drv/displays/tmd_vid.h b/drivers/staging/mrst/drv/displays/tmd_vid.h
new file mode 100644
index 0000000..e001bc5
--- /dev/null
+++ b/drivers/staging/mrst/drv/displays/tmd_vid.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+*/
+
+
+#ifndef TMD_VID_H
+#define TMD_VID_H
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+
+#include "mdfld_output.h"
+
+void tmd_vid_init(struct drm_device* dev, struct panel_funcs* p_funcs);
+struct drm_display_mode*
+tmd_vid_get_config_mode(struct drm_device* dev);
+
+
+#endif
diff --git a/drivers/staging/mrst/drv/displays/tpo_cmd.h b/drivers/staging/mrst/drv/displays/tpo_cmd.h
new file mode 100644
index 0000000..e37fbf0
--- /dev/null
+++ b/drivers/staging/mrst/drv/displays/tpo_cmd.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+*/
+
+
+
+#ifndef TPO_CMD_H
+#define TPO_CMD_H
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+
+#include "mdfld_output.h"
+
+void tpo_cmd_init(struct drm_device* dev, struct panel_funcs* p_funcs);
+/* struct drm_display_mode* */
+/* tpo_cmd_get_config_mode(struct drm_device* dev); */
+
+
+#endif
diff --git a/drivers/staging/mrst/drv/displays/tpo_vid.h b/drivers/staging/mrst/drv/displays/tpo_vid.h
new file mode 100644
index 0000000..63c86bb
--- /dev/null
+++ b/drivers/staging/mrst/drv/displays/tpo_vid.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+*/
+
+
+#ifndef TPO_VID_H
+#define TPO_VID_H
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+
+#include "mdfld_output.h"
+
+void tpo_vid_init(struct drm_device* dev, struct panel_funcs* p_funcs);
+
+#endif
diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dbi.c b/drivers/staging/mrst/drv/mdfld_dsi_dbi.c
index dc21ffd..ccbfcca 100644
--- a/drivers/staging/mrst/drv/mdfld_dsi_dbi.c
+++ b/drivers/staging/mrst/drv/mdfld_dsi_dbi.c
@@ -286,88 +286,6 @@ send_dcs_out:
 	return ret;			
 }
 
-/**
- * Update the DBI MIPI Panel Frame Buffer.
- */
-void mdfld_dsi_dbi_update_fb (struct mdfld_dsi_dbi_output * dbi_output, int pipe)
-{
-	struct drm_device * dev = dbi_output->dev;
-	struct drm_crtc * crtc = dbi_output->base.base.crtc;
-	struct psb_intel_crtc * psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; 
-	u8 * cmd_buf = dbi_output->dbi_cb_addr;
-	u32 cmd_phy = dbi_output->dbi_cb_phy;
-	u32 * index;
-	u32 dpll_reg = MRST_DPLL_A;
-	u32 dspcntr_reg = DSPACNTR;
-	u32 pipeconf_reg = PIPEACONF;
-	u32 dsplinoff_reg = DSPALINOFF;
-	u32 dspsurf_reg = DSPASURF;
-	u32 mipi_state_reg = MIPIA_INTR_STAT_REG;
-	u32 reg_offset = 0;
-	
-	/*if mode setting on-going, back off*/
-	if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
-		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) 
-		return;
-		
-	if(pipe == 2) {
-		dspcntr_reg = DSPCCNTR;
-		pipeconf_reg = PIPECCONF;
-		dsplinoff_reg = DSPCLINOFF;
-		dspsurf_reg = DSPCSURF;
-		
-		reg_offset = MIPIC_REG_OFFSET;
-	}
-
-	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true))
-		return;
-		
-	/*check DBI FIFO status*/
-	if(!(REG_READ((MIPIA_GEN_FIFO_STAT_REG + reg_offset)) & BIT27) ||
-	   !(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
-	   !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
-	   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) {
-		PSB_DEBUG_ENTRY("DBI FIFO is busy, DSI %d state %x\n", 
-				pipe, 
-				REG_READ(mipi_state_reg + reg_offset)); 
-		goto update_fb_out0;
-	}
-	
-	if(!spin_trylock(&dbi_output->cb_lock)) {
-		goto update_fb_out0;
-	}
-	
-	index = &dbi_output->cb_write;
-		
-	/*send write_mem_start cmd*/
-	if(*index) {
-		DRM_ERROR("Command buffer is used by others\n");
-		goto update_fb_out1;
-	}
-	
-	/*refresh plane changes*/
-	REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
-	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
-	REG_READ(dspsurf_reg);
-	
-	*(cmd_buf + ((*index)++)) = write_mem_start;
-	
-	/**
-	 * NOTE: we don't need add a 3ms delay here, dsr update were scheduled
-	 * by DSR timer.
-	 */
-	REG_WRITE((MIPIA_CMD_LEN_REG + reg_offset), 1);
-	REG_WRITE((MIPIA_CMD_ADD_REG + reg_offset), cmd_phy | BIT0 | BIT1);
-	
-	dbi_output->dsr_fb_update_done = true;
-	
-	*index = 0;
-	
-update_fb_out1:
-	spin_unlock(&dbi_output->cb_lock);
-update_fb_out0:
-	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-}
 
 /**
  * Enter DSR 
@@ -556,8 +474,9 @@ static void mdfld_dsi_dbi_dsr_timer_func(unsigned long data)
 		for(i=0; i<dsr_info->dbi_output_num; i++) {
 			if ((dbi_output[i]->dbi_panel_on)) {
 				dbi_output[i]->dsr_fb_update_done = false;
-				mdfld_dsi_dbi_update_fb(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0);
-				
+				if(dbi_output[i]->p_funcs->update_fb)
+					dbi_output[i]->p_funcs->update_fb(dbi_output[i], 
+								dbi_output[i]->channel_num ? 2 : 0);
 				if (dev_priv->b_dsr_enable && dbi_output[i]->dsr_fb_update_done)
 					dev_priv->dsr_fb_update &= ~(dev_priv->dsr_fb_update);
 			}
@@ -670,34 +589,7 @@ void mdfld_dbi_dsr_exit(struct drm_device * dev)
 }
 #endif
 
-static bool mdfld_dsi_dbi_mode_fixup(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_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;
-}
-
-static void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe)
+void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe)
 {
 	struct drm_device * dev = dsi_config->dev;
 	u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
@@ -759,250 +651,8 @@ void mdfld_dsi_adapter_init(struct mdfld_dsi_config * dsi_config, int pipe)
 	mdfld_dsi_controller_dbi_init(dsi_config, pipe);
 }
 
-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 = (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;
-	
-	/*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);
-
-	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) {
-		if(!dev_priv->dbi_panel_on) {
-			DRM_ERROR("bad thing happened\n");
-			return;
-		}
-		
-		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))
-		return;
-	
-	/*set up pipe related registers*/
-	REG_WRITE(mipi_reg, mipi_val);
-	REG_READ(mipi_reg);
-	
-	mdfld_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;
-	}
-	
-	/*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");
-	}
-}
-
-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 drm_device * dev = dbi_output->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))
-		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;
-		}
-		
-	} 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;
-		}
-					
-		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");
-    }
-}
-
-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);
-	
-	PSB_DEBUG_ENTRY("\n");
-	
-	dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
-
-	mdfld_dsi_dbi_set_power(encoder, false);
-	
-}
-
-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;
-	
-/*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_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*/
-		mdfld_dbi_dpu_timer_start(dev_priv->dbi_dpu_info);
-#else 
-		mdfld_dbi_dsr_timer_start(dev_priv->dbi_dsr_info);
-#endif
-	}
-}
-
-static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
-{
-	PSB_DEBUG_ENTRY("%s \n",  (mode == DRM_MODE_DPMS_ON ? "on":"off"));
-
-	if (mode == DRM_MODE_DPMS_ON)
-		mdfld_dsi_dbi_set_power(encoder, true);
-	else
-		mdfld_dsi_dbi_set_power(encoder, false);
-}
 
+#if 0
 /*DBI encoder helper funcs*/
 static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
 	.dpms = mdfld_dsi_dbi_dpms,
@@ -1017,6 +667,8 @@ static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
 	.destroy = drm_encoder_cleanup,
 };
 
+#endif
+
 static int mdfld_dbi_cb_init(struct mdfld_dsi_dbi_output * output, struct psb_gtt * pg) {
 	uint32_t phy;
 	void * virt_addr = NULL;
@@ -1105,7 +757,8 @@ gpio_error:
  * return pointer of newly allocated DBI encoder, NULL on error
  */ 
 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 drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
 	struct mdfld_dsi_dbi_output * dbi_output = NULL;
@@ -1147,6 +800,7 @@ struct mdfld_dsi_encoder * mdfld_dsi_dbi_init(struct drm_device * dev,
 	}
 	
 	dbi_output->dev = dev;
+	dbi_output->p_funcs = p_funcs;
 
 	/*init dbi command buffer*/
 	ret = mdfld_dbi_cb_init(dbi_output, pg);
@@ -1173,8 +827,12 @@ struct mdfld_dsi_encoder * mdfld_dsi_dbi_init(struct drm_device * dev,
 	/*create drm encoder object*/
 	connector = &dsi_connector->base.base;
 	encoder = &dbi_output->base.base;
-	drm_encoder_init(dev, encoder, &mdfld_dsi_dbi_encoder_funcs, DRM_MODE_ENCODER_MIPI);
-	drm_encoder_helper_add(encoder, &mdfld_dsi_dbi_helper_funcs);
+	drm_encoder_init(dev,
+			encoder,
+			p_funcs->encoder_funcs,
+			DRM_MODE_ENCODER_MIPI);
+	drm_encoder_helper_add( encoder,
+				p_funcs->encoder_helper_funcs);
 	
 	/*attach to given connector*/
 	drm_mode_connector_attach_encoder(connector, encoder);
diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dbi.h b/drivers/staging/mrst/drv/mdfld_dsi_dbi.h
index 420bd47..f42b6ab 100644
--- a/drivers/staging/mrst/drv/mdfld_dsi_dbi.h
+++ b/drivers/staging/mrst/drv/mdfld_dsi_dbi.h
@@ -41,6 +41,7 @@
 #include "psb_powermgmt.h"
 
 #include "mdfld_dsi_output.h"
+#include "mdfld_output.h"
 
 #define DRM_MODE_ENCODER_MIPI  5
 
@@ -88,6 +89,7 @@ struct mdfld_dsi_dbi_output {
         /*panel status*/
         bool dbi_panel_on;
         bool first_boot;
+	struct panel_funcs* p_funcs;
 };
 
 #define MDFLD_DSI_DBI_OUTPUT(dsi_encoder) container_of(dsi_encoder, struct mdfld_dsi_dbi_output, base)
@@ -191,11 +193,13 @@ 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_timer_start(struct mdfld_dbi_dsr_info * dsr_info);
 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);
 extern void mdfld_dsi_adapter_init(struct mdfld_dsi_config * dsi_config, int pipe);
 extern int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output * dbi_output, u8 dcs, u8 * param, u32 num, u8 data_src);
 extern int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output * dbi_output, 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, int mode);
+extern void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe);
 
 #endif /*__MDFLD_DSI_DBI_H__*/
diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dpi.c b/drivers/staging/mrst/drv/mdfld_dsi_dpi.c
index 5f725a8..bcb586f 100644
--- a/drivers/staging/mrst/drv/mdfld_dsi_dpi.c
+++ b/drivers/staging/mrst/drv/mdfld_dsi_dpi.c
@@ -537,7 +537,7 @@ static void mdfld_dsi_dpi_set_power(struct drm_encoder * encoder, bool on)
 	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
 }
 
-static void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
+void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
 {
 	PSB_DEBUG_ENTRY("%s \n",  (mode == DRM_MODE_DPMS_ON ? "on":"off"));
 
@@ -547,7 +547,7 @@ static void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
 		mdfld_dsi_dpi_set_power(encoder, false);
 }
 
-static bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder * encoder,
+bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder * encoder,
 				     struct drm_display_mode * mode,
 				     struct drm_display_mode * adjusted_mode)
 {
@@ -573,21 +573,21 @@ static bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder * encoder,
 	return true;
 }
 
-static void mdfld_dsi_dpi_prepare(struct drm_encoder * encoder) 
+void mdfld_dsi_dpi_prepare(struct drm_encoder * encoder) 
 {
 	PSB_DEBUG_ENTRY("\n");
 	
 	mdfld_dsi_dpi_set_power(encoder, false);
 }
 
-static void mdfld_dsi_dpi_commit(struct drm_encoder * encoder) 
+void mdfld_dsi_dpi_commit(struct drm_encoder * encoder) 
 {
 	PSB_DEBUG_ENTRY("\n");
 	
 	mdfld_dsi_dpi_set_power(encoder, true);
 }
 
-static void mdfld_dsi_dpi_mode_set(struct drm_encoder * encoder,
+void mdfld_dsi_dpi_mode_set(struct drm_encoder * encoder,
 				   struct drm_display_mode * mode,
 				   struct drm_display_mode * adjusted_mode)
 {
@@ -654,6 +654,7 @@ static void mdfld_dsi_dpi_mode_set(struct drm_encoder * encoder,
 	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
 }
 
+#if 0
 /*DPI encoder helper funcs*/
 static const struct drm_encoder_helper_funcs mdfld_dsi_dpi_helper_funcs = {
 	.dpms = mdfld_dsi_dpi_dpms,
@@ -667,6 +668,7 @@ static const struct drm_encoder_helper_funcs mdfld_dsi_dpi_helper_funcs = {
 static const struct drm_encoder_funcs mdfld_dsi_dpi_encoder_funcs = {
 	.destroy = drm_encoder_cleanup,
 };
+#endif
 
 static int mdfld_dpi_panel_reset(int pipe) {
 	unsigned gpio;
@@ -713,7 +715,8 @@ gpio_error:
  * return pointer of newly allocated DPI encoder, NULL on error
  */ 
 struct mdfld_dsi_encoder * mdfld_dsi_dpi_init(struct drm_device * dev, 
-							struct mdfld_dsi_connector * dsi_connector)
+				struct mdfld_dsi_connector * dsi_connector,
+				struct panel_funcs* p_funcs)
 {
 	struct mdfld_dsi_dpi_output * dpi_output = NULL;
 	struct mdfld_dsi_config * dsi_config;
@@ -758,8 +761,12 @@ struct mdfld_dsi_encoder * mdfld_dsi_dpi_init(struct drm_device * dev,
 	/*create drm encoder object*/
 	connector = &dsi_connector->base.base;
 	encoder = &dpi_output->base.base;
-	drm_encoder_init(dev, encoder, &mdfld_dsi_dpi_encoder_funcs, DRM_MODE_ENCODER_MIPI);
-	drm_encoder_helper_add(encoder, &mdfld_dsi_dpi_helper_funcs);
+	drm_encoder_init(dev,
+			encoder,
+			p_funcs->encoder_funcs,
+			DRM_MODE_ENCODER_MIPI);
+	drm_encoder_helper_add(encoder,
+				p_funcs->encoder_helper_funcs);
 	
 	/*attach to given connector*/
 	drm_mode_connector_attach_encoder(connector, encoder);
diff --git a/drivers/staging/mrst/drv/mdfld_dsi_dpi.h b/drivers/staging/mrst/drv/mdfld_dsi_dpi.h
index 701ad0d..e6656cc 100644
--- a/drivers/staging/mrst/drv/mdfld_dsi_dpi.h
+++ b/drivers/staging/mrst/drv/mdfld_dsi_dpi.h
@@ -29,6 +29,7 @@
 #define __MDFLD_DSI_DPI_H__
 
 #include "mdfld_dsi_output.h"
+#include "mdfld_output.h"
 
 struct mdfld_dsi_dpi_timing {
 	u16 hsync_count;
@@ -55,6 +56,18 @@ extern int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode * mode,
 									struct mdfld_dsi_dpi_timing * dpi_timing,
 									int num_lane, int bpp);
 extern struct mdfld_dsi_encoder * mdfld_dsi_dpi_init(struct drm_device * dev, 
-									struct mdfld_dsi_connector * dsi_connector);
+				struct mdfld_dsi_connector * dsi_connector,
+				struct panel_funcs* p_funcs);
+				
+/*MDFLD DPI helper functions*/
+extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode);
+extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder * encoder,
+				     struct drm_display_mode * mode,
+				     struct drm_display_mode * adjusted_mode);
+extern void mdfld_dsi_dpi_prepare(struct drm_encoder * encoder);
+extern void mdfld_dsi_dpi_commit(struct drm_encoder * encoder);
+extern void mdfld_dsi_dpi_mode_set(struct drm_encoder * encoder,
+				   struct drm_display_mode * mode,
+				   struct drm_display_mode * adjusted_mode);
 
 #endif /*__MDFLD_DSI_DPI_H__*/
diff --git a/drivers/staging/mrst/drv/mdfld_dsi_output.c b/drivers/staging/mrst/drv/mdfld_dsi_output.c
index d9e8c6c..3b0cf00 100644
--- a/drivers/staging/mrst/drv/mdfld_dsi_output.c
+++ b/drivers/staging/mrst/drv/mdfld_dsi_output.c
@@ -28,6 +28,7 @@
 #include "mdfld_dsi_output.h"
 #include "mdfld_dsi_dbi.h"
 #include "mdfld_dsi_dpi.h"
+#include "mdfld_output.h"
 
 #define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100
 /*use command mode by default*/
@@ -601,7 +602,7 @@ static int mdfld_dsi_connector_mode_valid(struct drm_connector * connector, stru
 	struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
 	struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
 
-	PSB_DEBUG_ENTRY("\n");
+	PSB_DEBUG_ENTRY("mode %p, fixed mode %p\n", mode, fixed_mode);
 
 	if(mode->flags & DRM_MODE_FLAG_DBLSCAN) 
 		return MODE_NO_DBLESCAN;
@@ -621,6 +622,8 @@ static int mdfld_dsi_connector_mode_valid(struct drm_connector * connector, stru
 			return MODE_PANEL;
 	}
 
+	PSB_DEBUG_ENTRY("ok\n");
+
 	return MODE_OK;
 }
 
@@ -779,8 +782,11 @@ mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe)
  * Do the initialization of a MIPI output, including create DRM mode objects
  * initialization of DSI output on @pipe 
  */
-void mdfld_dsi_output_init(struct drm_device * dev, int pipe, 
-							struct mdfld_dsi_config * config)
+void mdfld_dsi_output_init(struct drm_device * dev,
+			   int pipe, 
+			   struct mdfld_dsi_config * config,
+			   struct panel_funcs* p_cmd_funcs,
+			   struct panel_funcs* p_vid_funcs)
 {
 	struct mdfld_dsi_config * dsi_config;
 	struct mdfld_dsi_connector * dsi_connector;
@@ -788,7 +794,7 @@ void mdfld_dsi_output_init(struct drm_device * dev, int pipe,
 	struct drm_connector * connector;
 	struct mdfld_dsi_encoder * encoder;
 	struct drm_psb_private * dev_priv = dev->dev_private;
-		
+
 	PSB_DEBUG_ENTRY("init DSI output on pipe %d\n", pipe);
 	
 	if(!dev || ((pipe != 0) && (pipe != 2))) {
@@ -822,7 +828,13 @@ void mdfld_dsi_output_init(struct drm_device * dev, int pipe,
 	
 	dsi_config->changed = 1;
 	dsi_config->dev = dev;
-	dsi_config->fixed_mode = mdfld_dsi_get_configuration_mode(dsi_config, pipe);
+	
+	/*init fixed mode basing on DSI config type*/
+	if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) 
+		dsi_config->fixed_mode = p_cmd_funcs->get_config_mode(dev);
+	else if(dsi_config->type == MDFLD_DSI_ENCODER_DPI)
+		dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev);
+		
 	dsi_config->mode = dsi_config->fixed_mode;
 	dsi_config->connector = dsi_connector;
 	
@@ -854,22 +866,26 @@ void mdfld_dsi_output_init(struct drm_device * dev, int pipe,
 	drm_connector_attach_property(connector, dev_priv->backlight_property, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL);
 
 	/*init DBI & DPI encoders*/
-	encoder = mdfld_dsi_dbi_init(dev, dsi_connector);
-	if(!encoder) {
-		DRM_ERROR("Create DBI encoder failed\n");
-		goto dsi_init_err1;
+	if(p_cmd_funcs) {
+		encoder = mdfld_dsi_dbi_init(dev, dsi_connector, p_cmd_funcs);
+		if(!encoder) {
+			DRM_ERROR("Create DBI encoder failed\n");
+			goto dsi_init_err1;
+		}
+		encoder->private = dsi_config;
+		dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder;
 	}
-	encoder->private = dsi_config;
-	dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder;
-
-	encoder = mdfld_dsi_dpi_init(dev, dsi_connector);
-	if(!encoder) {
-		DRM_ERROR("Create DPI encoder failed\n");
-		goto dsi_init_err1;
+	
+	if(p_vid_funcs) {
+		encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs);
+		if(!encoder) {
+			DRM_ERROR("Create DPI encoder failed\n");
+			goto dsi_init_err1;
+		}
+		encoder->private = dsi_config;
+		dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder;
 	}
-	encoder->private = dsi_config;
-	dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder;
-
+	
 	drm_sysfs_connector_add(connector);
 	
 	PSB_DEBUG_ENTRY("successfully\n");
diff --git a/drivers/staging/mrst/drv/mdfld_dsi_output.h b/drivers/staging/mrst/drv/mdfld_dsi_output.h
index 57ddf27..4f7fdfb 100644
--- a/drivers/staging/mrst/drv/mdfld_dsi_output.h
+++ b/drivers/staging/mrst/drv/mdfld_dsi_output.h
@@ -39,6 +39,7 @@
 #include "psb_intel_drv.h"
 #include "psb_intel_reg.h"
 #include "psb_powermgmt.h"
+#include "mdfld_output.h"
 
 #define DRM_MODE_ENCODER_MIPI  5
 
@@ -276,7 +277,10 @@ static inline int mdfld_dsi_encoder_get_pipe(struct mdfld_dsi_encoder * encoder)
 extern void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u32 fifo_stat);
 extern void mdfld_dsi_brightness_init (struct mdfld_dsi_config * dsi_config, int pipe);
 extern void mdfld_dsi_brightness_control (struct drm_device *dev, int pipe, int level);
-extern void mdfld_dsi_output_init(struct drm_device * dev, int pipe, 
-							struct mdfld_dsi_config * config);
+extern void mdfld_dsi_output_init(struct drm_device * dev,
+				int pipe,
+				struct mdfld_dsi_config * config,
+				struct panel_funcs * p_cmd_funcs,
+				struct panel_funcs * p_vid_funcs);
 
 #endif /*__MDFLD_DSI_OUTPUT_H__*/
diff --git a/drivers/staging/mrst/drv/mdfld_output.c b/drivers/staging/mrst/drv/mdfld_output.c
new file mode 100644
index 0000000..3fd238e
--- /dev/null
+++ b/drivers/staging/mrst/drv/mdfld_output.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+*/
+
+
+#include "mdfld_output.h"
+#include "mdfld_dsi_dbi.h"
+#include "mdfld_dsi_dpi.h"
+#include "mdfld_dsi_output.h"
+
+#include "displays/tpo_cmd.h"
+#include "displays/tpo_vid.h"
+#include "displays/tmd_cmd.h"
+#include "displays/tmd_vid.h"
+#include "displays/pyr_cmd.h"
+#include "displays/pyr_vid.h"
+#include "displays/hdmi.h"
+
+enum panel_type get_panel_type(struct drm_device *dev, int pipe)
+{
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) dev->dev_private;
+
+	pipe = 0;
+	if (dev_priv->gct_data.bpi == 2) {
+		return PYR_CMD;
+	}
+	else {
+		return TPO_CMD;
+	}
+}
+
+void mdfld_output_init(struct drm_device* dev)
+{
+	enum panel_type p_type1, p_type2;
+
+	/* MIPI panel 1 */
+	p_type1 = get_panel_type(dev, 0);
+	init_panel(dev, 0, p_type1);
+
+	p_type2 = PYR_CMD; // Set the panel type as PYR_CMD by default
+#ifdef CONFIG_MDFD_DUAL_MIPI
+	/* MIPI panel 2 */
+	p_type2 = get_panel_type(dev, 2);
+	init_panel(dev, 2, p_type2);
+#endif
+
+#ifdef CONFIG_MDFD_HDMI
+	/* HDMI panel */
+	init_panel(dev, 0, HDMI);
+#endif
+}
+
+void init_panel(struct drm_device* dev, int mipi_pipe, enum panel_type p_type)
+{
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) dev->dev_private;
+	struct panel_funcs * p_cmd_funcs = NULL; 
+	struct panel_funcs * p_vid_funcs = NULL;
+
+	p_cmd_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
+	p_vid_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
+	
+	switch (p_type) {
+	case TPO_CMD:
+		tpo_cmd_init(dev, p_cmd_funcs);
+		mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
+		break;
+	case TPO_VID:
+		/*tpo_vid_init(dev, p_vid_funcs);*/
+		mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
+		break;
+	case TMD_CMD:
+		/*tmd_cmd_init(dev, p_cmd_funcs);*/
+		mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
+		break;
+	case TMD_VID:
+		/*tmd_vid_init(dev, p_vid_funcs);*/
+		mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
+		break;
+	case PYR_CMD:
+		pyr_cmd_init(dev, p_cmd_funcs);
+		mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
+		break;
+	case PYR_VID:
+		/*pyr_vid_init(dev, p_vid_funcs);*/
+		mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL ,p_vid_funcs);
+		break;
+	case TPO:	/*TPO panel supports both cmd & vid interfaces*/
+		tpo_cmd_init(dev, p_cmd_funcs);
+		tpo_vid_init(dev, p_vid_funcs);
+		mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, p_vid_funcs);
+		break;
+	case TMD:
+		break;
+	case PYR:
+		break;
+	case HDMI:
+		/*hdmi_init(dev);*/
+		printk(KERN_ALERT "GFX: Initializing HDMI");
+		mdfld_hdmi_init(dev, &dev_priv->mode_dev);
+		/*hdmi_output_init(dev);*/
+		break;
+	default:
+		break;
+	}
+}
+
diff --git a/drivers/staging/mrst/drv/mdfld_output.h b/drivers/staging/mrst/drv/mdfld_output.h
new file mode 100644
index 0000000..bbd2e4b
--- /dev/null
+++ b/drivers/staging/mrst/drv/mdfld_output.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+*/
+
+
+
+#ifndef MDFLD_OUTPUT_H
+#define MDFLD_OUTPUT_H
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+
+#include "psb_drv.h"
+
+enum panel_type {
+	TPO_CMD,
+	TPO_VID,
+	TMD_CMD,
+	TMD_VID,
+	PYR_CMD,
+	PYR_VID,
+	TPO,
+	TMD,
+	PYR,
+	HDMI
+};
+
+struct panel_funcs {
+	const struct drm_encoder_funcs* encoder_funcs;
+	const struct drm_encoder_helper_funcs* encoder_helper_funcs;
+	struct drm_display_mode* (*get_config_mode)(struct drm_device*);
+	void (*update_fb)(struct mdfld_dsi_dbi_output*, int);
+};
+
+void mdfld_output_init(struct drm_device* dev);
+
+void init_panel(struct drm_device* dev, int mipi_pipe, enum panel_type p_type);
+
+#endif
+
+
diff --git a/drivers/staging/mrst/drv/psb_fb.c b/drivers/staging/mrst/drv/psb_fb.c
index 9463ce9..013bbe5 100644
--- a/drivers/staging/mrst/drv/psb_fb.c
+++ b/drivers/staging/mrst/drv/psb_fb.c
@@ -43,6 +43,7 @@
 
 #include "mdfld_dsi_dbi.h"
 #include "mdfld_dsi_output.h"
+#include "mdfld_output.h"
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
 static int fill_fb_bitfield(struct fb_var_screeninfo *var, int depth)
@@ -1634,16 +1635,7 @@ static void psb_setup_outputs(struct drm_device *dev)
 	psb_create_backlight_property(dev);
 
 	if (IS_MDFLD(dev)) {
-		/* Set up integrated MIPI for MDFLD */
-		mdfld_dsi_output_init(dev, 0, NULL);
-#ifdef CONFIG_MDFD_DUAL_MIPI
-		mdfld_dsi_output_init(dev, 2, NULL);
-#endif /* CONFIG_DUAL_MIPI */
-
-#ifdef CONFIG_MDFD_HDMI
-		mdfld_hdmi_init(dev, &dev_priv->mode_dev);
-#endif /* CONFIG_MDFD_HDMI */
-
+		mdfld_output_init(dev);
 	} else if (IS_MRST(dev)) {
 		if (dev_priv->iLVDS_enable)
 			/* Set up integrated LVDS for MRST */
diff --git a/drivers/staging/mrst/drv/pyr_cmd.c b/drivers/staging/mrst/drv/pyr_cmd.c
new file mode 100644
index 0000000..5db6faa
--- /dev/null
+++ b/drivers/staging/mrst/drv/pyr_cmd.c
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+*/
+
+
+
+#include "displays/pyr_cmd.h"
+#include "mdfld_dsi_dbi.h"
+
+struct drm_display_mode*
+pyr_cmd_get_config_mode(struct drm_device* dev)
+{
+	struct drm_display_mode *mode;
+	/*struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) dev->dev_private;*/
+	/*struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;*/
+
+	PSB_DEBUG_ENTRY("\n");
+
+	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+	if (!mode)
+		return NULL;
+
+	PSB_DEBUG_ENTRY("hdisplay is %d\n", mode->hdisplay);
+	PSB_DEBUG_ENTRY("vdisplay is %d\n", mode->vdisplay);
+	PSB_DEBUG_ENTRY("HSS is %d\n", mode->hsync_start);
+	PSB_DEBUG_ENTRY("HSE is %d\n", mode->hsync_end);
+	PSB_DEBUG_ENTRY("htotal is %d\n", mode->htotal);
+	PSB_DEBUG_ENTRY("VSS is %d\n", mode->vsync_start);
+	PSB_DEBUG_ENTRY("VSE is %d\n", mode->vsync_end);
+	PSB_DEBUG_ENTRY("vtotal is %d\n", mode->vtotal);
+	PSB_DEBUG_ENTRY("clock is %d\n", mode->clock);
+
+	mode->hdisplay = 480;
+	mode->vdisplay = 864;
+	mode->hsync_start = 487;
+	mode->hsync_end = 490;
+	mode->htotal = 499;
+	mode->vsync_start = 874;
+	mode->vsync_end = 878;
+	mode->vtotal = 886;
+	mode->clock = 25777;
+
+	drm_mode_set_name(mode);
+	drm_mode_set_crtcinfo(mode, 0);
+	
+	mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+	return mode;
+}
+
+static bool pyr_dsi_dbi_mode_fixup(struct drm_encoder * encoder,
+				     struct drm_display_mode * mode,
+				     struct drm_display_mode * adjusted_mode)
+{
+	struct drm_device* dev = encoder->dev;
+	struct drm_display_mode * fixed_mode = pyr_cmd_get_config_mode(dev);
+
+	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);
+		kfree(fixed_mode);
+	}
+	
+	return true;
+}
+
+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))
+		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;
+		}
+		
+	} 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;
+		}
+					
+		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");
+    }
+}
+
+static void pyr_dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe)
+{
+	struct drm_device * dev = dsi_config->dev;
+	u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
+	int lane_count = dsi_config->lane_count;
+	u32 val = 0;
+
+	PSB_DEBUG_ENTRY("Init DBI interface on pipe %d...\n", pipe);
+
+	/*un-ready device*/
+	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
+	
+	/*init dsi adapter before kicking off*/
+	REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
+	
+	/*TODO: figure out how to setup these registers*/
+	REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c600F);
+	REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), 0x000a0014);
+	REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
+	REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
+	
+	/*enable all interrupts*/
+	REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
+	/*max value: 20 clock cycles of txclkesc*/
+	REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
+	/*min 21 txclkesc, max: ffffh*/
+	REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
+	/*min: 7d0 max: 4e20*/
+	REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
+		
+	/*set up func_prg*/
+	val |= lane_count;
+	val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
+	val |= DSI_DBI_COLOR_FORMAT_OPTION2;
+	REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
+	
+	REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
+	REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
+
+	/*de-assert dbi_stall when half of DBI FIFO is empty*/
+	//REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000);
+	
+	REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
+	REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000002);
+	REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
+	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
+}
+
+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;
+	
+	/*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);
+
+	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) {
+		if(!dev_priv->dbi_panel_on) {
+			DRM_ERROR("bad thing happened\n");
+			return;
+		}
+		
+		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))
+		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;
+	}
+	
+	/*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");
+	}
+}
+
+static void pyr_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;
+
+	pyr_dsi_dbi_set_power(encoder, false);
+	
+}
+
+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*/
+		mdfld_dbi_dpu_timer_start(dev_priv->dbi_dpu_info);
+#else 
+		mdfld_dbi_dsr_timer_start(dev_priv->dbi_dsr_info);
+#endif
+	}
+}
+
+static void pyr_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
+{
+	PSB_DEBUG_ENTRY("%s \n",  (mode == DRM_MODE_DPMS_ON ? "on":"off"));
+
+	if (mode == DRM_MODE_DPMS_ON)
+		pyr_dsi_dbi_set_power(encoder, true);
+	else
+		pyr_dsi_dbi_set_power(encoder, false);
+}
+
+/**
+ * Update the DBI MIPI Panel Frame Buffer.
+ */
+static void pyr_dsi_dbi_update_fb (struct mdfld_dsi_dbi_output * dbi_output, int pipe)
+{
+	struct drm_device * dev = dbi_output->dev;
+	struct drm_crtc * crtc = dbi_output->base.base.crtc;
+	struct psb_intel_crtc * psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; 
+	u8 * cmd_buf = dbi_output->dbi_cb_addr;
+	u32 cmd_phy = dbi_output->dbi_cb_phy;
+	u32 * index;
+	u32 dpll_reg = MRST_DPLL_A;
+	u32 dspcntr_reg = DSPACNTR;
+	u32 pipeconf_reg = PIPEACONF;
+	u32 dsplinoff_reg = DSPALINOFF;
+	u32 dspsurf_reg = DSPASURF;
+	/*u32 mipi_state_reg = MIPIA_INTR_STAT_REG;*/
+	u32 hs_gen_ctrl_reg = HS_GEN_CTRL_REG;
+	u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
+	u32 reg_offset = 0;
+
+	u32 intr_status;
+	u32 fifo_stat_reg_val;
+	u32 dpll_reg_val;
+	u32 dspcntr_reg_val;
+	u32 pipeconf_reg_val;
+
+	/*
+ 	 * Look for errors here.  In particular we're checking for whatever
+ 	 * error status might have appeared during the last frame transmit
+ 	 * (memory write).
+ 	 *
+ 	 * Normally, the bits we're testing here would be set infrequently,
+ 	 * if at all.  However, the Pyrenees panel (at least) returns
+ 	 * at least one error bit on most frames.  So we've disabled the
+ 	 * kernel message for now.
+ 	 *
+ 	 * Still clear whatever error bits are set, except don't clear the
+ 	 * ones that would make the Penwell DSI controller reset if we
+ 	 * cleared them.
+ 	 */
+	intr_status = REG_READ(INTR_STAT_REG);
+	if ((intr_status & 0x26FFFFFF) != 0) {
+		/* DRM_ERROR("DSI status: 0x%08X\n", intr_status); */
+		intr_status &= 0x26F3FFFF;
+	        REG_WRITE(INTR_STAT_REG, intr_status);
+	}
+
+	/*if mode setting on-going, back off*/
+	if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
+		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) 
+		return;
+		
+	if(pipe == 2) {
+		dspcntr_reg = DSPCCNTR;
+		pipeconf_reg = PIPECCONF;
+		dsplinoff_reg = DSPCLINOFF;
+		dspsurf_reg = DSPCSURF;
+
+		hs_gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
+		gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET,
+
+		reg_offset = MIPIC_REG_OFFSET;
+	}
+
+	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true))
+		return;
+
+	fifo_stat_reg_val = REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset);
+	dpll_reg_val = REG_READ(dpll_reg);
+	dspcntr_reg_val = REG_READ(dspcntr_reg);
+	pipeconf_reg_val = REG_READ(pipeconf_reg);
+
+	if(!(fifo_stat_reg_val & BIT27) ||
+	   !(dpll_reg_val & DPLL_VCO_ENABLE) ||
+	   !(dspcntr_reg_val & DISPLAY_PLANE_ENABLE) ||
+	   !(pipeconf_reg_val & DISPLAY_PLANE_ENABLE)) {
+		/* DRM_ERROR("DBI FIFO is busy\n"); */
+		PSB_DEBUG_ENTRY("fifo    0x%08X\n", fifo_stat_reg_val);
+		PSB_DEBUG_ENTRY("dpll    0x%08X\n", dpll_reg_val);
+		PSB_DEBUG_ENTRY("dspcntr 0x%08X\n", dspcntr_reg_val);
+		PSB_DEBUG_ENTRY("pipecnf 0x%08X\n", pipeconf_reg_val);
+		goto update_fb_out0;
+	}
+
+	if(!spin_trylock(&dbi_output->cb_lock)) {
+		goto update_fb_out0;
+	}
+	
+	index = &dbi_output->cb_write;
+		
+	/*send write_mem_start cmd*/
+	if(*index) {
+		DRM_ERROR("Command buffer is used by others\n");
+		goto update_fb_out1;
+	}
+	
+	/*refresh plane changes*/
+	REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
+	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
+	REG_READ(dspsurf_reg);
+	
+	*(cmd_buf + ((*index)++)) = write_mem_start;
+	
+	/**
+	 * NOTE: we don't need add a 3ms delay here, dsr update were scheduled
+	 * by DSR timer.
+	 */
+	REG_WRITE((MIPIA_CMD_LEN_REG + reg_offset), 1);
+	REG_WRITE((MIPIA_CMD_ADD_REG + reg_offset), cmd_phy | BIT0 | BIT1);
+
+	/*
+ 	 * The idea here is to transmit a Generic Read command after the
+ 	 * Write Memory Start/Continue commands finish.  This asks for
+ 	 * the panel to return an "ACK No Errors," or (if it has errors
+ 	 * to report) an Error Report.  This allows us to monitor the
+ 	 * panel's perception of the health of the DSI.
+ 	 */
+	mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg,
+		HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
+	REG_WRITE(hs_gen_ctrl_reg, (1 << WORD_COUNTS_POS) | GEN_READ_0);
+
+	dbi_output->dsr_fb_update_done = true;
+
+	*index = 0;
+
+update_fb_out1:
+	spin_unlock(&dbi_output->cb_lock);
+update_fb_out0:
+	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+}
+
+/*
+ * NOTE: this function was used by OSPM.
+ * TODO: will be removed later, should work out display interfaces for OSPM
+ */
+void pyr_dsi_adapter_init(struct mdfld_dsi_config * dsi_config, int pipe)
+{
+	if(!dsi_config || ((pipe != 0) && (pipe != 2))) {
+		DRM_ERROR("Invalid parameters\n");
+		return;
+	}
+	
+	pyr_dsi_controller_dbi_init(dsi_config, pipe);
+}
+
+/*TPO DBI encoder helper funcs*/
+static const struct drm_encoder_helper_funcs pyr_dsi_dbi_helper_funcs = {
+	.dpms = pyr_dsi_dbi_dpms,
+	.mode_fixup = pyr_dsi_dbi_mode_fixup,
+	.prepare = pyr_dsi_dbi_prepare,
+	.mode_set = pyr_dsi_dbi_mode_set,
+	.commit = pyr_dsi_dbi_commit,
+};
+
+/*TPO DBI encoder funcs*/
+static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+void pyr_cmd_init(struct drm_device* dev, struct panel_funcs* p_funcs)
+{
+	p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
+	p_funcs->encoder_helper_funcs = &pyr_dsi_dbi_helper_funcs;
+	p_funcs->get_config_mode = &pyr_cmd_get_config_mode;
+	p_funcs->update_fb = pyr_dsi_dbi_update_fb;
+}
diff --git a/drivers/staging/mrst/drv/tpo_cmd.c b/drivers/staging/mrst/drv/tpo_cmd.c
new file mode 100644
index 0000000..91249f0
--- /dev/null
+++ b/drivers/staging/mrst/drv/tpo_cmd.c
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c)  2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas.g.eaton at intel.com>
+ * Scott Rowe <scott.m.rowe at intel.com>
+*/
+
+
+
+#include "displays/tpo_cmd.h"
+#include "mdfld_dsi_dbi.h"
+
+static struct drm_display_mode*
+tpo_cmd_get_config_mode(struct drm_device* dev)
+{
+	struct drm_display_mode *mode;
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) dev->dev_private;
+	struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
+	bool use_gct = false;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+	if (!mode)
+		return NULL;
+
+	if (use_gct) {
+		PSB_DEBUG_ENTRY("gct find MIPI panel. \n");
+
+		mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
+		mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
+		mode->hsync_start = mode->hdisplay + \
+				((ti->hsync_offset_hi << 8) | \
+				ti->hsync_offset_lo);
+		mode->hsync_end = mode->hsync_start + \
+				((ti->hsync_pulse_width_hi << 8) | \
+				ti->hsync_pulse_width_lo);
+		mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
+								ti->hblank_lo);
+		mode->vsync_start = \
+			mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
+						ti->vsync_offset_lo);
+		mode->vsync_end = \
+			mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
+						ti->vsync_pulse_width_lo);
+		mode->vtotal = mode->vdisplay + \
+				((ti->vblank_hi << 8) | ti->vblank_lo);
+		mode->clock = ti->pixel_clock * 10;
+
+		PSB_DEBUG_ENTRY("hdisplay is %d\n", mode->hdisplay);
+		PSB_DEBUG_ENTRY("vdisplay is %d\n", mode->vdisplay);
+		PSB_DEBUG_ENTRY("HSS is %d\n", mode->hsync_start);
+		PSB_DEBUG_ENTRY("HSE is %d\n", mode->hsync_end);
+		PSB_DEBUG_ENTRY("htotal is %d\n", mode->htotal);
+		PSB_DEBUG_ENTRY("VSS is %d\n", mode->vsync_start);
+		PSB_DEBUG_ENTRY("VSE is %d\n", mode->vsync_end);
+		PSB_DEBUG_ENTRY("vtotal is %d\n", mode->vtotal);
+		PSB_DEBUG_ENTRY("clock is %d\n", mode->clock);
+	} else {
+		mode->hdisplay = 864;
+		mode->vdisplay = 480;
+		mode->hsync_start = 872;
+		mode->hsync_end = 876;
+		mode->htotal = 884;
+		mode->vsync_start = 482;
+		mode->vsync_end = 494;
+		mode->vtotal = 486;
+		mode->clock = 25777;
+	}
+
+	drm_mode_set_name(mode);
+	drm_mode_set_crtcinfo(mode, 0);
+	
+	mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+	return mode;
+}
+
+static bool mdfld_dsi_dbi_mode_fixup(struct drm_encoder * encoder,
+				     struct drm_display_mode * mode,
+				     struct drm_display_mode * adjusted_mode)
+{
+	struct drm_device* dev = encoder->dev;
+	struct drm_display_mode * fixed_mode = tpo_cmd_get_config_mode(dev);
+
+	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);
+		kfree(fixed_mode);
+	}
+	
+	return true;
+}
+
+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 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))
+		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;
+		}
+		
+	} 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;
+		}
+					
+		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");
+    }
+}
+
+
+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 = (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;
+	
+	/*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);
+
+	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) {
+		if(!dev_priv->dbi_panel_on) {
+			DRM_ERROR("bad thing happened\n");
+			return;
+		}
+		
+		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))
+		return;
+	
+	/*set up pipe related registers*/
+	REG_WRITE(mipi_reg, mipi_val);
+	REG_READ(mipi_reg);
+	
+	mdfld_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;
+	}
+	
+	/*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");
+	}
+}
+
+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);
+	
+	PSB_DEBUG_ENTRY("\n");
+	
+	dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
+
+	mdfld_dsi_dbi_set_power(encoder, false);
+	
+}
+
+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;
+	
+/*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_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*/
+		mdfld_dbi_dpu_timer_start(dev_priv->dbi_dpu_info);
+#else 
+		mdfld_dbi_dsr_timer_start(dev_priv->dbi_dsr_info);
+#endif
+	}
+}
+
+static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
+{
+	PSB_DEBUG_ENTRY("%s \n",  (mode == DRM_MODE_DPMS_ON ? "on":"off"));
+
+	if (mode == DRM_MODE_DPMS_ON)
+		mdfld_dsi_dbi_set_power(encoder, true);
+	else
+		mdfld_dsi_dbi_set_power(encoder, false);
+}
+
+
+/**
+ * Update the DBI MIPI Panel Frame Buffer.
+ */
+static void mdfld_dsi_dbi_update_fb (struct mdfld_dsi_dbi_output * dbi_output, int pipe)
+{
+	struct drm_device * dev = dbi_output->dev;
+	struct drm_crtc * crtc = dbi_output->base.base.crtc;
+	struct psb_intel_crtc * psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; 
+	u8 * cmd_buf = dbi_output->dbi_cb_addr;
+	u32 cmd_phy = dbi_output->dbi_cb_phy;
+	u32 * index;
+	u32 dpll_reg = MRST_DPLL_A;
+	u32 dspcntr_reg = DSPACNTR;
+	u32 pipeconf_reg = PIPEACONF;
+	u32 dsplinoff_reg = DSPALINOFF;
+	u32 dspsurf_reg = DSPASURF;
+	u32 mipi_state_reg = MIPIA_INTR_STAT_REG;
+	u32 reg_offset = 0;
+	
+	/*if mode setting on-going, back off*/
+	if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
+		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) 
+		return;
+		
+	if(pipe == 2) {
+		dspcntr_reg = DSPCCNTR;
+		pipeconf_reg = PIPECCONF;
+		dsplinoff_reg = DSPCLINOFF;
+		dspsurf_reg = DSPCSURF;
+		
+		reg_offset = MIPIC_REG_OFFSET;
+	}
+
+	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true))
+		return;
+		
+	/*check DBI FIFO status*/
+	if(!(REG_READ((MIPIA_GEN_FIFO_STAT_REG + reg_offset)) & BIT27) ||
+	   !(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
+	   !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
+	   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) {
+		PSB_DEBUG_ENTRY("DBI FIFO is busy, DSI %d state %x\n", 
+				pipe, 
+				REG_READ(mipi_state_reg + reg_offset)); 
+		goto update_fb_out0;
+	}
+	
+	if(!spin_trylock(&dbi_output->cb_lock)) {
+		goto update_fb_out0;
+	}
+	
+	index = &dbi_output->cb_write;
+		
+	/*send write_mem_start cmd*/
+	if(*index) {
+		DRM_ERROR("Command buffer is used by others\n");
+		goto update_fb_out1;
+	}
+	
+	/*refresh plane changes*/
+	REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
+	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
+	REG_READ(dspsurf_reg);
+	
+	*(cmd_buf + ((*index)++)) = write_mem_start;
+	
+	/**
+	 * NOTE: we don't need add a 3ms delay here, dsr update were scheduled
+	 * by DSR timer.
+	 */
+	REG_WRITE((MIPIA_CMD_LEN_REG + reg_offset), 1);
+	REG_WRITE((MIPIA_CMD_ADD_REG + reg_offset), cmd_phy | BIT0 | BIT1);
+	
+	dbi_output->dsr_fb_update_done = true;
+	
+	*index = 0;
+	
+update_fb_out1:
+	spin_unlock(&dbi_output->cb_lock);
+update_fb_out0:
+	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+}
+
+
+
+/*TPO DBI encoder helper funcs*/
+static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
+	.dpms = mdfld_dsi_dbi_dpms,
+	.mode_fixup = mdfld_dsi_dbi_mode_fixup,
+	.prepare = mdfld_dsi_dbi_prepare,
+	.mode_set = mdfld_dsi_dbi_mode_set,
+	.commit = mdfld_dsi_dbi_commit,
+};
+
+/*TPO DBI encoder funcs*/
+static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+void tpo_cmd_init(struct drm_device* dev, struct panel_funcs* p_funcs)
+{
+	p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
+	p_funcs->encoder_helper_funcs = &mdfld_dsi_dbi_helper_funcs;
+	p_funcs->get_config_mode = &tpo_cmd_get_config_mode;
+	p_funcs->update_fb = mdfld_dsi_dbi_update_fb;
+}
diff --git a/drivers/staging/mrst/drv/tpo_vid.c b/drivers/staging/mrst/drv/tpo_vid.c
new file mode 100644
index 0000000..960c4b2
--- /dev/null
+++ b/drivers/staging/mrst/drv/tpo_vid.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * jim liu <jim.liu at intel.com>
+ * Jackie Li<yaodong.li at intel.com>
+ */
+
+#include "displays/tpo_vid.h"
+#include "mdfld_dsi_dpi.h"
+
+static struct drm_display_mode*
+tpo_vid_get_config_mode(struct drm_device* dev)
+{
+	struct drm_display_mode *mode;
+	struct drm_psb_private *dev_priv =
+		(struct drm_psb_private *) dev->dev_private;
+	struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
+	bool use_gct = false;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+	if (!mode)
+		return NULL;
+
+	if (use_gct) {
+		PSB_DEBUG_ENTRY("gct find MIPI panel. \n");
+
+		mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
+		mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
+		mode->hsync_start = mode->hdisplay + \
+				((ti->hsync_offset_hi << 8) | \
+				ti->hsync_offset_lo);
+		mode->hsync_end = mode->hsync_start + \
+				((ti->hsync_pulse_width_hi << 8) | \
+				ti->hsync_pulse_width_lo);
+		mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
+								ti->hblank_lo);
+		mode->vsync_start = \
+			mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
+						ti->vsync_offset_lo);
+		mode->vsync_end = \
+			mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
+						ti->vsync_pulse_width_lo);
+		mode->vtotal = mode->vdisplay + \
+				((ti->vblank_hi << 8) | ti->vblank_lo);
+		mode->clock = ti->pixel_clock * 10;
+
+		PSB_DEBUG_ENTRY("hdisplay is %d\n", mode->hdisplay);
+		PSB_DEBUG_ENTRY("vdisplay is %d\n", mode->vdisplay);
+		PSB_DEBUG_ENTRY("HSS is %d\n", mode->hsync_start);
+		PSB_DEBUG_ENTRY("HSE is %d\n", mode->hsync_end);
+		PSB_DEBUG_ENTRY("htotal is %d\n", mode->htotal);
+		PSB_DEBUG_ENTRY("VSS is %d\n", mode->vsync_start);
+		PSB_DEBUG_ENTRY("VSE is %d\n", mode->vsync_end);
+		PSB_DEBUG_ENTRY("vtotal is %d\n", mode->vtotal);
+		PSB_DEBUG_ENTRY("clock is %d\n", mode->clock);
+	} else {
+		mode->hdisplay = 864;
+		mode->vdisplay = 480;
+		mode->hsync_start = 873;
+		mode->hsync_end = 876;
+		mode->htotal = 887;
+		mode->vsync_start = 487;
+		mode->vsync_end = 490;
+		mode->vtotal = 499;
+		mode->clock = 33264;
+	}
+
+	drm_mode_set_name(mode);
+	drm_mode_set_crtcinfo(mode, 0);
+	
+	mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+	return mode;
+}
+
+/*TPO DPI encoder helper funcs*/
+static const struct drm_encoder_helper_funcs mdfld_tpo_dpi_encoder_helper_funcs = {
+	.dpms = mdfld_dsi_dpi_dpms,
+	.mode_fixup = mdfld_dsi_dpi_mode_fixup,
+	.prepare = mdfld_dsi_dpi_prepare,
+	.mode_set = mdfld_dsi_dpi_mode_set,
+	.commit = mdfld_dsi_dpi_commit,
+};
+
+/*TPO DPI encoder funcs*/
+static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+void tpo_vid_init(struct drm_device* dev, struct panel_funcs* p_funcs)
+{
+	if(!dev || !p_funcs) {
+		DRM_ERROR("Invalid parameters\n");
+		return;
+	}
+	
+	PSB_DEBUG_ENTRY("\n");
+	
+	p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs;
+	p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs;
+	p_funcs->get_config_mode = &tpo_vid_get_config_mode;
+	p_funcs->update_fb = NULL;
+}
diff --git a/drivers/staging/mrst/medfield/Makefile b/drivers/staging/mrst/medfield/Makefile
index 898a169..0cfa7f0 100644
--- a/drivers/staging/mrst/medfield/Makefile
+++ b/drivers/staging/mrst/medfield/Makefile
@@ -148,7 +148,11 @@ medfield_gfx-y += $(DRMDRVDIR)/psb_bl.medfield.o \
 	  $(DRMDRVDIR)/psb_intel_dsi_aava.medfield.o \
 	  $(DRMDRVDIR)/mdfld_dsi_dbi.medfield.o \
 	  $(DRMDRVDIR)/mdfld_dsi_dpi.medfield.o \
-	  $(DRMDRVDIR)/mdfld_dsi_output.medfield.o
+	  $(DRMDRVDIR)/mdfld_dsi_output.medfield.o \
+	  $(DRMDRVDIR)/mdfld_output.medfield.o \
+	  $(DRMDRVDIR)/tpo_cmd.medfield.o \
+	  $(DRMDRVDIR)/tpo_vid.medfield.o \
+	  $(DRMDRVDIR)/pyr_cmd.medfield.o
 
 medfield_gfx-y += $(IMGVDIR)/lnc_topaz.medfield.o \
 	  $(IMGVDIR)/topaz_power.medfield.o \
diff --git a/drivers/staging/mrst/moorestown/Makefile b/drivers/staging/mrst/moorestown/Makefile
index 0afa2af..24a6a1e 100644
--- a/drivers/staging/mrst/moorestown/Makefile
+++ b/drivers/staging/mrst/moorestown/Makefile
@@ -148,7 +148,12 @@ mrst_gfx-y += $(DRMDRVDIR)/psb_bl.mrst.o \
 	  $(DRMDRVDIR)/psb_intel_dsi.mrst.o \
 	  $(DRMDRVDIR)/mdfld_dsi_dbi.mrst.o \
 	  $(DRMDRVDIR)/mdfld_dsi_output.mrst.o \
-	  $(DRMDRVDIR)/mdfld_dsi_dpi.mrst.o
+	  $(DRMDRVDIR)/mdfld_dsi_dpi.mrst.o \
+	  $(DRMDRVDIR)/mdfld_output.mrst.o \
+          $(DRMDRVDIR)/tpo_cmd.mrst.o \
+          $(DRMDRVDIR)/tpo_vid.mrst.o \
+          $(DRMDRVDIR)/pyr_cmd.mrst.o
+
 
 mrst_gfx-y += $(IMGVDIR)/lnc_topaz.mrst.o \
 	  $(IMGVDIR)/topaz_power.mrst.o \
-- 
1.7.2.2



More information about the Meego-kernel mailing list