[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