From: Hitesh K. Patel <[email protected]>

rewrote the display controller interrupt functions and hook up HDMI audio 
interrupts.
Hook up the DC interrupt with 3rd party display code.  This will enable audio 
playback
through HDMI.

Change-Id: I71086b7d0f1e17b046062badf6e37b672adfed4a
Author: Jim Liu <[email protected]>
Signed-off-by: Hitesh K. Patel <[email protected]>
---
 drivers/staging/mrst/drv/mdfld_hdmi_audio.c        |    7 +-
 drivers/staging/mrst/drv/psb_drm.h                 |    2 +-
 drivers/staging/mrst/drv/psb_drv.c                 |    1 +
 drivers/staging/mrst/drv/psb_drv.h                 |   21 +-
 drivers/staging/mrst/drv/psb_intel_hdmi.c          |    1 -
 drivers/staging/mrst/drv/psb_intel_reg.h           |   32 +-
 drivers/staging/mrst/drv/psb_irq.c                 |  580 ++++++++++++--------
 drivers/staging/mrst/drv/psb_powermgmt.c           |    4 +
 .../linux_framebuffer_mrst/mrstlfb_displayclass.c  |  152 +++---
 .../linux_framebuffer_mrst/mrstlfb_linux.c         |   43 +--
 10 files changed, 469 insertions(+), 374 deletions(-)

diff --git a/drivers/staging/mrst/drv/mdfld_hdmi_audio.c 
b/drivers/staging/mrst/drv/mdfld_hdmi_audio.c
index 35ae683..3d33527 100644
--- a/drivers/staging/mrst/drv/mdfld_hdmi_audio.c
+++ b/drivers/staging/mrst/drv/mdfld_hdmi_audio.c
@@ -186,14 +186,15 @@ static struct hdmi_audio_query_set_ops 
mdfld_hdmi_audio_get_set_ops = {
 };
 
 int intel_hdmi_audio_query_capabilities (had_event_call_back audio_callbacks, 
struct hdmi_audio_registers_ops **reg_ops,struct hdmi_audio_query_set_ops 
**query_ops) {
+    struct drm_device *dev = hdmi_priv->dev;
+    struct drm_psb_private *dev_priv = (struct drm_psb_private *) 
dev->dev_private;
     int ret = 0;
 
     *reg_ops = &mdfld_hdmi_audio_reg_ops; 
     *query_ops = &mdfld_hdmi_audio_get_set_ops;
-    hdmi_priv->mdfld_had_event_callbacks = audio_callbacks;
+    dev_priv->mdfld_had_event_callbacks = audio_callbacks;
 
     return ret;
-
-
 }
+
 EXPORT_SYMBOL(intel_hdmi_audio_query_capabilities);
diff --git a/drivers/staging/mrst/drv/psb_drm.h 
b/drivers/staging/mrst/drv/psb_drm.h
index 21d278d..eb48565 100644
--- a/drivers/staging/mrst/drv/psb_drm.h
+++ b/drivers/staging/mrst/drv/psb_drm.h
@@ -47,7 +47,7 @@
 #define PSB_FIXED_SHIFT 16
 
 
-#define PSB_NUM_PIPE 4
+#define PSB_NUM_PIPE 3
 
 /*
  * Public memory types.
diff --git a/drivers/staging/mrst/drv/psb_drv.c 
b/drivers/staging/mrst/drv/psb_drv.c
index 0287630..61eba6c 100644
--- a/drivers/staging/mrst/drv/psb_drv.c
+++ b/drivers/staging/mrst/drv/psb_drv.c
@@ -1382,6 +1382,7 @@ static int psb_driver_load(struct drm_device *dev, 
unsigned long chipset)
        dev_priv->vdc_irq_mask = 0;
        dev_priv->pipestat[0] = 0;
        dev_priv->pipestat[1] = 0;
+       dev_priv->pipestat[2] = 0;
        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
        PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
        PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
diff --git a/drivers/staging/mrst/drv/psb_drv.h 
b/drivers/staging/mrst/drv/psb_drv.h
index eed9aa7..f578348 100644
--- a/drivers/staging/mrst/drv/psb_drv.h
+++ b/drivers/staging/mrst/drv/psb_drv.h
@@ -43,6 +43,10 @@
 #include "private_data.h"
 #include "pvr_drm.h"
 
+#ifdef MDFLD_HDCP
+#include "mdfld_hdmi_audio_if.h"
+#endif /* MDFLD_HDCP */
+
 /*Append new drm mode definition here, align with libdrm definition*/
 #define DRM_MODE_SCALE_NO_SCALE   2
 
@@ -149,14 +153,22 @@ enum {
 #define PSB_HWSTAM               0x2098
 #define PSB_INSTPM               0x20C0
 #define PSB_INT_IDENTITY_R        0x20A4
-#define _PSB_PIPEB_EVENT (1<<4)
-#define _PSB_DPST_PIPEB_FLAG (1<<4)
+#define _MDFLD_PIPEC_EVENT_FLAG   (1<<2)
+#define _MDFLD_PIPEC_VBLANK_FLAG  (1<<3)
+#define _PSB_DPST_PIPEB_FLAG      (1<<4)
+#define _MDFLD_PIPEB_EVENT_FLAG   (1<<4)
 #define _PSB_VSYNC_PIPEB_FLAG    (1<<5)
+#define _PSB_DPST_PIPEA_FLAG      (1<<6)
+#define _PSB_PIPEA_EVENT_FLAG     (1<<6)
 #define _PSB_VSYNC_PIPEA_FLAG    (1<<7)
-#define _PSB_DPST_PIPEA_FLAG     (1<<6)
+#define _MDFLD_MIPIA_FLAG        (1<<16)
+#define _MDFLD_MIPIC_FLAG        (1<<17)
 #define _PSB_IRQ_SGX_FLAG        (1<<18)
 #define _PSB_IRQ_MSVDX_FLAG      (1<<19)
 #define _LNC_IRQ_TOPAZ_FLAG      (1<<20)
+/* This flag includes all the display IRQ bits excepts the vblank irqs. */
+#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | 
_MDFLD_PIPEB_EVENT_FLAG | \
+        _PSB_PIPEA_EVENT_FLAG | _PSB_VSYNC_PIPEA_FLAG | _MDFLD_MIPIA_FLAG | 
_MDFLD_MIPIC_FLAG)
 #define PSB_INT_IDENTITY_R       0x20A4
 #define PSB_INT_MASK_R           0x20A8
 #define PSB_INT_ENABLE_R         0x20A0
@@ -376,7 +388,7 @@ struct drm_psb_private {
         */
 
        uint32_t vdc_irq_mask;
-       u32 pipestat[PSB_NUM_PIPE];
+       uint32_t pipestat[PSB_NUM_PIPE];
        bool vblanksEnabledForFlips;
 
        spinlock_t irqmask_lock;
@@ -946,6 +958,7 @@ struct drm_psb_private {
        bool dsi_device_ready;
 
 #ifdef MDFLD_HDCP
+       had_event_call_back mdfld_had_event_callbacks;
        uint32_t hdmi_audio_interrupt_mask;
 #endif /* MDFLD_HDCP */
 
diff --git a/drivers/staging/mrst/drv/psb_intel_hdmi.c 
b/drivers/staging/mrst/drv/psb_intel_hdmi.c
index 28bd9e8..b4fb811 100644
--- a/drivers/staging/mrst/drv/psb_intel_hdmi.c
+++ b/drivers/staging/mrst/drv/psb_intel_hdmi.c
@@ -55,7 +55,6 @@ struct mid_intel_hdmi_priv {
        bool is_hdcp_supported;
        struct i2c_adapter *hdmi_i2c_adapter;   /* for control functions */
        struct drm_device *dev;
-       had_event_call_back mdfld_had_event_callbacks;
 #endif /* MDFLD_HDCP */
 };
 
diff --git a/drivers/staging/mrst/drv/psb_intel_reg.h 
b/drivers/staging/mrst/drv/psb_intel_reg.h
index f8bcb57..831c9bb 100644
--- a/drivers/staging/mrst/drv/psb_intel_reg.h
+++ b/drivers/staging/mrst/drv/psb_intel_reg.h
@@ -398,26 +398,32 @@
 #define PIPEBGCMAXGREEN                0x71014
 #define PIPEBGCMAXBLUE         0x71018
 
-#define PIPEASTAT       0x70024
+#define PIPEASTAT               0x70024
 #define PIPEBSTAT              0x71024
-#define PIPE_VBLANK_CLEAR         (1 << 1)
-#define PIPE_VSYNC_CLEAR (1UL<<9)
-#define PIPE_VBLANK_INTERRUPT_ENABLE           (1UL<<17)
-#define PIPE_START_VBLANK_INTERRUPT_ENABLE     (1UL<<18)
-
-
-#define PIPE_VSYNC_ENABL               (1UL<<25)
-#define PIPE_HDMI_AUDIO_UNDERRUN (1UL<<26)
-#define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL<<27)
+#define PIPECSTAT              0x72024
+#define PIPE_VBLANK_INTERRUPT_STATUS         (1UL<<1)
+#define PIPE_START_VBLANK_INTERRUPT_STATUS   (1UL<<2)
+#define PIPE_VBLANK_CLEAR                    (1 << 1)
+#define PIPE_VBLANK_STATUS                   (1 << 1)
+#define PIPE_DPST_EVENT_STATUS              (1UL<<7)
+#define PIPE_VSYNC_CLEAR                     (1UL<<9)
+#define PIPE_VSYNC_STATUS                    (1UL<<9)
+#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS      (1UL<<10)
+#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS   (1UL<<11)
+#define PIPE_VBLANK_INTERRUPT_ENABLE         (1UL<<17)
+#define PIPE_START_VBLANK_INTERRUPT_ENABLE   (1UL<<18)
+#define PIPE_DPST_EVENT_ENABLE               (1UL<<23)
+#define PIPE_VSYNC_ENABL                     (1UL<<25)
+#define PIPE_HDMI_AUDIO_UNDERRUN             (1UL<<26)
+#define PIPE_HDMI_AUDIO_BUFFER_DONE          (1UL<<27)
 #define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | 
PIPE_HDMI_AUDIO_BUFFER_DONE)
-#define PIPEB_EVENT_MASK 
(BIT29|BIT28|BIT27|BIT26|BIT25|BIT24|BIT23|BIT22|BIT21|BIT20|BIT18|BIT17|BIT16) 
+#define PIPE_EVENT_MASK 
(BIT29|BIT28|BIT27|BIT26|BIT24|BIT23|BIT22|BIT21|BIT20|BIT16)
+#define PIPE_VBLANK_MASK (BIT25|BIT24|BIT18|BIT17)
 #define HISTOGRAM_INT_CONTROL          0x61268
 #define HISTOGRAM_BIN_DATA             0X61264
 #define HISTOGRAM_LOGIC_CONTROL                0x61260
 #define PWM_CONTROL_LOGIC              0x61250
-#define PIPE_DPST_EVENT_ENABLE         (1UL<<23)
 #define PIPE_HOTPLUG_INTERRUPT_STATUS  (1UL<<10)
-#define PIPE_DPST_EVENT_STATUS         (1UL<<7)
 #define HISTOGRAM_INTERRUPT_ENABLE     (1UL<<31)
 #define HISTOGRAM_LOGIC_ENABLE         (1UL<<31)
 #define PWM_LOGIC_ENABLE               (1UL<<31)
diff --git a/drivers/staging/mrst/drv/psb_irq.c 
b/drivers/staging/mrst/drv/psb_irq.c
index 6ae003b..4ccf6a0 100644
--- a/drivers/staging/mrst/drv/psb_irq.c
+++ b/drivers/staging/mrst/drv/psb_irq.c
@@ -32,45 +32,252 @@
 #include "psb_powermgmt.h"
 
 /*
- * Video display controller interrupt.
+ * inline functions
  */
 
+static inline u32
+psb_pipestat(int pipe)
+{
+       if (pipe == 0)
+               return PIPEASTAT;
+       if (pipe == 1)
+               return PIPEBSTAT;
+       if (pipe == 2)
+               return PIPECSTAT;
+       BUG();
+}
+
+static inline u32
+mid_pipe_event(int pipe)
+{
+       if (pipe == 0)
+               return _PSB_PIPEA_EVENT_FLAG;
+       if (pipe == 1)
+               return _MDFLD_PIPEB_EVENT_FLAG;
+       if (pipe == 2)
+               return _MDFLD_PIPEC_EVENT_FLAG;
+       BUG();
+}
+
+static inline u32
+mid_pipe_vsync(int pipe)
+{
+       if (pipe == 0)
+               return _PSB_VSYNC_PIPEA_FLAG;
+       if (pipe == 1)
+               return _PSB_VSYNC_PIPEB_FLAG;
+       if (pipe == 2)
+               return _MDFLD_PIPEC_VBLANK_FLAG;
+       BUG();
+}
+
+static inline u32
+mid_pipeconf(int pipe)
+{
+       if (pipe == 0)
+               return PIPEACONF;
+       if (pipe == 1)
+               return PIPEBCONF;
+       if (pipe == 2)
+               return PIPECCONF;
+       BUG();
+}
+
+void
+psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
+{
+       if ((dev_priv->pipestat[pipe] & mask) != mask) {
+               u32 reg = psb_pipestat(pipe);
+               dev_priv->pipestat[pipe] |= mask;
+               /* Enable the interrupt, clear any pending status */
+               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
+                       u32 writeVal = PSB_RVDC32(reg);
+                       writeVal |= (mask | (mask >> 16));
+                       PSB_WVDC32(writeVal, reg);
+                       (void) PSB_RVDC32(reg);
+                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+               }
+       }
+}
+
+void
+psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
+{
+       if ((dev_priv->pipestat[pipe] & mask) != 0) {
+               u32 reg = psb_pipestat(pipe);
+               dev_priv->pipestat[pipe] &= ~mask;
+               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
+                       u32 writeVal = PSB_RVDC32(reg);
+                       writeVal &= ~mask;
+                       PSB_WVDC32(writeVal, reg);
+                       (void) PSB_RVDC32(reg);
+                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+               }
+       }
+}
+
+void
+mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
+{
+       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
+               u32 pipe_event = mid_pipe_event(pipe);
+               dev_priv->vdc_irq_mask |= pipe_event;
+               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
+               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
+               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+       }
+}
+
+void
+mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
+{
+       if (dev_priv->pipestat[pipe] == 0) {
+               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
+                       u32 pipe_event = mid_pipe_event(pipe);
+                       dev_priv->vdc_irq_mask &= ~pipe_event;
+                       PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
+                       PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
+                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+               }
+       }
+}
+
 /**
- * TODO: 
- * Re-Enable vdc interrupt due to some overwrite
- * This could be removed later, and display class should handle this interrupt
+ * Display controller interrupt handler for vsync/vblank.
+ *
  */
-#if 0
-static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
+static void mid_vblank_handler(struct drm_device *dev, uint32_t pipe)
 {
        struct drm_psb_private *dev_priv =
            (struct drm_psb_private *) dev->dev_private;
+#if 0 /* FIXME_JLIU7 revisit it*/
+       uint32_t *vbl_received = &dev->vbl_received;
+
+       switch (pipe) {
+       case 0:
+               break;
+       case 1:
+               vbl_received = &dev->vbl_received1;
+               break;
+       case 2:
+               vbl_received = &dev->vbl_received2;
+               break;
+       default:
+               DRM_ERROR("%s, invalded pipe. \n", __FUNCTION__);
+               return;
+       }
+
 
-       if (!drm_psb_disable_vsync && (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)) {
 #ifdef PSB_FIXME
-               atomic_inc(&dev->vbl_received);
+       atomic_inc(vbl_received);
 #endif
-               PSB_WVDC32(PIPE_VBLANK_INTERRUPT_ENABLE |
-                          PIPE_VBLANK_CLEAR, PIPEASTAT);
-               drm_handle_vblank(dev, 0);
+#endif /* FIXME_JLIU7 revisit it*/
+
+       drm_handle_vblank(dev, pipe);
        
-               if( dev_priv->psb_vsync_handler != NULL)
-                       (*dev_priv->psb_vsync_handler)(dev,0);
+       if( dev_priv->psb_vsync_handler != NULL)
+               (*dev_priv->psb_vsync_handler)(dev,pipe);
+}
+
+#ifdef MDFLD_HDCP
+/**
+ * Display controller interrupt handler for pipe hdmi audio underrun.
+ *
+ */
+static void mdfld_pipe_hdmi_audio_underrun(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv =
+           (struct drm_psb_private *) dev->dev_private;
+
+       if (dev_priv->mdfld_had_event_callbacks)
+               
(*dev_priv->mdfld_had_event_callbacks)(HAD_EVENT_AUDIO_BUFFER_UNDERRUN, NULL);
+}
+
+/**
+ * Display controller interrupt handler for pipe hdmi audio buffer done.
+ *
+ */
+static void mdfld_pipe_hdmi_audio_buffer_done(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv =
+           (struct drm_psb_private *) dev->dev_private;
+
+       if (dev_priv->mdfld_had_event_callbacks)
+               
(*dev_priv->mdfld_had_event_callbacks)(HAD_EVENT_AUDIO_BUFFER_DONE, NULL);
+}
+#endif /* MDFLD_HDCP */
+
+/**
+ * Display controller interrupt handler for pipe event.
+ *
+ */
+static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe)
+{
+       struct drm_psb_private *dev_priv =
+           (struct drm_psb_private *) dev->dev_private;
+
+       uint32_t pipe_stat_val = 0;
+       uint32_t pipe_stat_reg = psb_pipestat(pipe);
+       uint32_t pipe_enable = dev_priv->pipestat[pipe];
+       uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16;
+
+       spin_lock(&dev_priv->irqmask_lock);
+
+       pipe_stat_val = PSB_RVDC32(pipe_stat_reg);
+       pipe_stat_val &= pipe_enable | pipe_status;
+       pipe_stat_val &= pipe_stat_val >> 16;
+
+       spin_unlock(&dev_priv->irqmask_lock);
+
+       if (pipe_stat_val & PIPE_DPST_EVENT_STATUS) {
+
        }
 
-       if (!drm_psb_disable_vsync && (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)) {
-#ifdef PSB_FIXME
-               atomic_inc(&dev->vbl_received2);
-#endif
-               PSB_WVDC32(PIPE_VBLANK_INTERRUPT_ENABLE |
-                          PIPE_VBLANK_CLEAR, PIPEBSTAT);
-               drm_handle_vblank(dev, 1);
+       if (pipe_stat_val & PIPE_VBLANK_STATUS) {
+               mid_vblank_handler(dev, pipe);
+       }
+
+#ifdef MDFLD_HDCP
+       if (pipe_stat_val & PIPE_HDMI_AUDIO_UNDERRUN_STATUS) {
+               mdfld_pipe_hdmi_audio_underrun(dev);
+       }
 
-               if( dev_priv->psb_vsync_handler != NULL)
-                       (*dev_priv->psb_vsync_handler)(dev,1);
+       if (pipe_stat_val & PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS) {
+               mdfld_pipe_hdmi_audio_buffer_done(dev);
+       }
+#endif /* MDFLD_HDCP */
+
+       /* clear the 2nd level interrupt status bits */
+       PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg);
+       (void) PSB_RVDC32(pipe_stat_reg);
+}
+
+/**
+ * Display controller interrupt handler.
+ */
+static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
+{
+
+       if (vdc_stat & _PSB_PIPEA_EVENT_FLAG) {
+               mid_pipe_event_handler(dev, 0);
+       }
+
+       if (vdc_stat & _MDFLD_PIPEB_EVENT_FLAG) {
+               mid_pipe_event_handler(dev, 1);
+       }
+
+       if (vdc_stat & _MDFLD_PIPEC_EVENT_FLAG) {
+               mid_pipe_event_handler(dev, 2);
+       }
+
+       if (vdc_stat & _MDFLD_MIPIA_FLAG) {
+               /* mid_mipi_event_handler(dev, 0); */
+       }
+
+       if (vdc_stat & _MDFLD_MIPIC_FLAG) {
+               /* mid_mipi_event_handler(dev, 2); */
        }
 }
-#endif
 
 irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
 {
@@ -78,13 +285,20 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
        struct drm_psb_private *dev_priv =
            (struct drm_psb_private *) dev->dev_private;
 
-       uint32_t vdc_stat, sgx_int = 0, msvdx_int = 0, topaz_int = 0;
+       uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, msvdx_int = 0, topaz_int = 
0;
        int handled = 0;
 
+/*     PSB_DEBUG_ENTRY("\n"); */
+
        spin_lock(&dev_priv->irqmask_lock);
 
        vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
 
+       if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) {
+               PSB_DEBUG_IRQ("Got DISP interrupt\n");
+               dsp_int = 1;
+       }
+
        if (vdc_stat & _PSB_IRQ_SGX_FLAG) {
                PSB_DEBUG_IRQ("Got SGX interrupt\n");
                sgx_int = 1;
@@ -102,7 +316,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
        vdc_stat &= dev_priv->vdc_irq_mask;
        spin_unlock(&dev_priv->irqmask_lock);
 
-       if (msvdx_int && ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
+       if (dsp_int && ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
+               psb_vdc_interrupt(dev, vdc_stat);
+               handled = 1;
+       }
+
+       if (msvdx_int && (IS_MDFLD(dev)
+                   || ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND))) {
                psb_msvdx_interrupt(dev);
                handled = 1;
        }
@@ -110,7 +330,7 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
        if ((IS_MDFLD(dev) && topaz_int)) {
                pnw_topaz_interrupt(dev);
                handled = 1;
-       } else if (IS_MRST(dev) && topaz_int &&
+       } else if (IS_MID(dev) && topaz_int &&
                ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) {
                /* sometimes, even topaz power down, IIR 
                 * may still have topaz bit set
@@ -131,7 +351,6 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
        if (!handled)
                return IRQ_NONE;
 
-
        return IRQ_HANDLED;
 }
 
@@ -149,6 +368,8 @@ void psb_irq_preinstall_islands(struct drm_device *dev, int 
hw_islands)
            (struct drm_psb_private *) dev->dev_private;
        unsigned long irqflags;
 
+       PSB_DEBUG_ENTRY("\n");
+
        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
        if (hw_islands & OSPM_DISPLAY_ISLAND) {
@@ -156,9 +377,11 @@ void psb_irq_preinstall_islands(struct drm_device *dev, 
int hw_islands)
                        if (IS_POULSBO(dev))
                                PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
                        if (dev->vblank_enabled[0])
-                               dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
+                               dev_priv->vdc_irq_mask |= _PSB_PIPEA_EVENT_FLAG;
                        if (dev->vblank_enabled[1])
-                               dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
+                               dev_priv->vdc_irq_mask |= 
_MDFLD_PIPEB_EVENT_FLAG;
+                       if (dev->vblank_enabled[2])
+                               dev_priv->vdc_irq_mask |= 
_MDFLD_PIPEC_EVENT_FLAG;
                }
        }
        if (hw_islands & OSPM_GRAPHICS_ISLAND)
@@ -190,6 +413,8 @@ int psb_irq_postinstall_islands(struct drm_device *dev, int 
hw_islands)
            (struct drm_psb_private *) dev->dev_private;
        unsigned long irqflags;
 
+       PSB_DEBUG_ENTRY("\n");
+
        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
        /*This register is safe even if display island is off*/
@@ -199,31 +424,27 @@ int psb_irq_postinstall_islands(struct drm_device *dev, 
int hw_islands)
                if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) 
{        
                        if (IS_POULSBO(dev))
                                PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-                       if (dev->vblank_enabled[0]) {
-                               if (IS_MID(dev))
-                                       psb_enable_pipestat(dev_priv, 0,
-                                           PIPE_START_VBLANK_INTERRUPT_ENABLE |
-                                           PIPE_VBLANK_INTERRUPT_ENABLE);
-                               else
-                                       psb_enable_pipestat(dev_priv, 0,
-                                           PIPE_VBLANK_INTERRUPT_ENABLE);
-                       } else
+
+                       if (dev->vblank_enabled[0])
+                               psb_enable_pipestat(dev_priv, 0,
+                                   PIPE_VBLANK_INTERRUPT_ENABLE);
+                       else
                                psb_disable_pipestat(dev_priv, 0,
-                                   PIPE_VBLANK_INTERRUPT_ENABLE |
-                                   PIPE_START_VBLANK_INTERRUPT_ENABLE);
+                                   PIPE_VBLANK_INTERRUPT_ENABLE);
 
-                       if (dev->vblank_enabled[1]) {
-                               if (IS_MID(dev))
-                                       psb_enable_pipestat(dev_priv, 1,
-                                           PIPE_START_VBLANK_INTERRUPT_ENABLE |
-                                           PIPE_VBLANK_INTERRUPT_ENABLE);
-                               else
+                       if (dev->vblank_enabled[1])
                                        psb_enable_pipestat(dev_priv, 1,
                                            PIPE_VBLANK_INTERRUPT_ENABLE);
-                       } else
+                       else
                                psb_disable_pipestat(dev_priv, 1,
-                                   PIPE_VBLANK_INTERRUPT_ENABLE |
-                                   PIPE_START_VBLANK_INTERRUPT_ENABLE);
+                                   PIPE_VBLANK_INTERRUPT_ENABLE);
+
+                       if (dev->vblank_enabled[2])
+                               psb_enable_pipestat(dev_priv, 2,
+                                   PIPE_VBLANK_INTERRUPT_ENABLE);
+                       else
+                               psb_disable_pipestat(dev_priv, 2,
+                                   PIPE_VBLANK_INTERRUPT_ENABLE);
                }
        }
 
@@ -252,20 +473,26 @@ void psb_irq_uninstall_islands(struct drm_device *dev, 
int hw_islands)
            (struct drm_psb_private *) dev->dev_private;
        unsigned long irqflags;
 
+       PSB_DEBUG_ENTRY("\n");
+
        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
        
        if (hw_islands & OSPM_DISPLAY_ISLAND) {
                if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) {
                        if (IS_POULSBO(dev))
                                PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
+
                        if (dev->vblank_enabled[0])
                                psb_disable_pipestat(dev_priv, 0,
-                                   PIPE_VBLANK_INTERRUPT_ENABLE |
-                                   PIPE_START_VBLANK_INTERRUPT_ENABLE);
+                                   PIPE_VBLANK_INTERRUPT_ENABLE);
+
                        if (dev->vblank_enabled[1])
                                psb_disable_pipestat(dev_priv, 1,
-                                   PIPE_VBLANK_INTERRUPT_ENABLE |
-                                   PIPE_START_VBLANK_INTERRUPT_ENABLE);
+                                   PIPE_VBLANK_INTERRUPT_ENABLE);
+
+                       if (dev->vblank_enabled[2])
+                               psb_disable_pipestat(dev_priv, 2,
+                                   PIPE_VBLANK_INTERRUPT_ENABLE);
                }
                dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
                                          _PSB_IRQ_MSVDX_FLAG |
@@ -275,10 +502,10 @@ void psb_irq_uninstall_islands(struct drm_device *dev, 
int hw_islands)
        if (hw_islands & OSPM_GRAPHICS_ISLAND)
                dev_priv->vdc_irq_mask &= ~_PSB_IRQ_SGX_FLAG;
 
-       if ((hw_islands & OSPM_VIDEO_DEC_ISLAND) && IS_MID(dev))
+       if ((hw_islands & OSPM_VIDEO_DEC_ISLAND) && IS_MRST(dev))
                dev_priv->vdc_irq_mask &= ~_PSB_IRQ_MSVDX_FLAG;
 
-       if ((hw_islands & OSPM_VIDEO_ENC_ISLAND) && IS_MID(dev))
+       if ((hw_islands & OSPM_VIDEO_ENC_ISLAND) && IS_MRST(dev))
                dev_priv->vdc_irq_mask &= ~_LNC_IRQ_TOPAZ_FLAG;
 
        /*These two registers are safe even if display island is off*/
@@ -307,7 +534,6 @@ void psb_irq_turn_on_dpst(struct drm_device *dev)
                (struct drm_psb_private *) dev->dev_private;
        u32 hist_reg;
        u32 pwm_reg;
-       u32 pipea_stat;
 
        if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
                PSB_WVDC32(BIT31, HISTOGRAM_LOGIC_CONTROL);
@@ -321,11 +547,8 @@ void psb_irq_turn_on_dpst(struct drm_device *dev)
                           PWM_CONTROL_LOGIC);
                pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
 
-               pipea_stat = PSB_RVDC32(PIPEASTAT);
-               PSB_WVDC32(pipea_stat | PIPE_DPST_EVENT_ENABLE, PIPEASTAT);
-               pipea_stat = PSB_RVDC32(PIPEASTAT);
+               psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
 
-               PSB_WVDC32(pipea_stat | PIPE_DPST_EVENT_STATUS, PIPEASTAT);
                hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
                PSB_WVDC32(hist_reg | 
HISTOGRAM_INT_CTRL_CLEAR,HISTOGRAM_INT_CONTROL);
                pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
@@ -341,16 +564,14 @@ int psb_irq_enable_dpst(struct drm_device *dev)
                (struct drm_psb_private *) dev->dev_private;
        unsigned long irqflags;
 
+       PSB_DEBUG_ENTRY("\n");
+
        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
-               /* enable DPST */
-               dev_priv->vdc_irq_mask |= _PSB_DPST_PIPEA_FLAG;
-               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
 
-               psb_irq_turn_on_dpst(dev);
-               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-       }
+       /* enable DPST */
+       mid_enable_pipe_event(dev_priv, 0);
+       psb_irq_turn_on_dpst(dev);
+
        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
        return 0;
 }
@@ -361,15 +582,12 @@ void psb_irq_turn_off_dpst(struct drm_device *dev)
            (struct drm_psb_private *) dev->dev_private;
        u32 hist_reg;
        u32 pwm_reg;
-       u32 pipea_stat;
 
        if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
                PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
                hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
 
-               pipea_stat = PSB_RVDC32(PIPEASTAT);
-               PSB_WVDC32(pipea_stat & ~PIPE_DPST_EVENT_ENABLE, PIPEASTAT);
-               pipea_stat = PSB_RVDC32(PIPEASTAT);
+               psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
 
                pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
                PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), 
PWM_CONTROL_LOGIC);
@@ -384,36 +602,19 @@ int psb_irq_disable_dpst(struct drm_device *dev)
        struct drm_psb_private *dev_priv =
            (struct drm_psb_private *) dev->dev_private;
        unsigned long irqflags;
-       u32 hist_reg;
-       u32 pwm_reg;
-       u32 pipea_stat;
 
-       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
-               dev_priv->vdc_irq_mask &= ~_PSB_DPST_PIPEA_FLAG;
-               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
+       PSB_DEBUG_ENTRY("\n");
 
-               PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
-               hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
-
-               pipea_stat = PSB_RVDC32(PIPEASTAT);
-               PSB_WVDC32(pipea_stat & ~PIPE_DPST_EVENT_ENABLE, PIPEASTAT);
-               pipea_stat = PSB_RVDC32(PIPEASTAT);
+       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
-               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
-               PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), 
PWM_CONTROL_LOGIC);
-               pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
+       mid_disable_pipe_event(dev_priv, 0);
+       psb_irq_turn_off_dpst(dev);
 
-               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-       }
        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 
        return 0;
 }
 
-
-
 #ifdef PSB_FIXME
 static int psb_vblank_do_wait(struct drm_device *dev,
                              unsigned int *sequence, atomic_t *counter)
@@ -429,7 +630,6 @@ static int psb_vblank_do_wait(struct drm_device *dev,
 }
 #endif
 
-
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
@@ -438,36 +638,25 @@ int psb_enable_vblank(struct drm_device *dev, int pipe)
        struct drm_psb_private *dev_priv =
            (struct drm_psb_private *) dev->dev_private;
        unsigned long irqflags;
-       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-       u32 pipeconf = 0;
+       uint32_t reg_val = 0;
+       uint32_t pipeconf_reg = mid_pipeconf(pipe);
 
-       return 0;
+       PSB_DEBUG_ENTRY("\n");
 
-       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false)) {
-               pipeconf = REG_READ(pipeconf_reg);
+       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
+               reg_val = REG_READ(pipeconf_reg);
                ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
        }
-       if (!(pipeconf & PIPEACONF_ENABLE))
+
+       if (!(reg_val & PIPEACONF_ENABLE))
                return -EINVAL;
 
        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false)) {
-               drm_psb_disable_vsync = 0;
-               if (pipe == 0)
-                       dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
-               else
-                       dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
-               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-               if (IS_MID(dev)) {
-                       psb_enable_pipestat(dev_priv, pipe,
-                           PIPE_START_VBLANK_INTERRUPT_ENABLE |
-                           PIPE_VBLANK_INTERRUPT_ENABLE);
-               } else
-                       psb_enable_pipestat(dev_priv, pipe,
-                           PIPE_VBLANK_INTERRUPT_ENABLE);
-               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-       }
+
+       drm_psb_disable_vsync = 0;
+       mid_enable_pipe_event(dev_priv, pipe);
+       psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
+
        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 
        return 0;
@@ -481,87 +670,16 @@ void psb_disable_vblank(struct drm_device *dev, int pipe)
        struct drm_psb_private *dev_priv =
            (struct drm_psb_private *) dev->dev_private;
        unsigned long irqflags;
-       
-       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false)) {
-               if (pipe == 0)
-                       dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG;
-               else
-                       dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG;
-               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-               psb_disable_pipestat(dev_priv, pipe,
-                   PIPE_VBLANK_INTERRUPT_ENABLE |
-                   PIPE_START_VBLANK_INTERRUPT_ENABLE);
-               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-       }
-       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-}
 
-static inline u32
-psb_pipestat(int pipe)
-{
-       if (pipe == 0)
-               return PIPEASTAT;
-       if (pipe == 1)
-               return PIPEBSTAT;
-       BUG();
-}
-
-void
-psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
-{
-       if ((dev_priv->pipestat[pipe] & mask) != mask) {
-               u32 reg = psb_pipestat(pipe);
-               dev_priv->pipestat[pipe] |= mask;
-               /* Enable the interrupt, clear any pending status */
-               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
-                       u32 writeVal = PSB_RVDC32(reg);
-                       writeVal |= (mask | (mask >> 16));
-                       PSB_WVDC32(writeVal, reg);
-                       (void) PSB_RVDC32(reg);
-                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-               }
-       }
-}
-
-void
-psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
-{
-       if ((dev_priv->pipestat[pipe] & mask) != 0) {
-               u32 reg = psb_pipestat(pipe);
-               dev_priv->pipestat[pipe] &= ~mask;
-               if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
-                       u32 writeVal = PSB_RVDC32(reg);
-                       writeVal &= ~mask;
-                       PSB_WVDC32(writeVal, reg);
-                       (void) PSB_RVDC32(reg);
-                       ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-               }
-       }
-}
+       PSB_DEBUG_ENTRY("\n");
 
-/**
- * psb_pipe_enabled - check if a pipe is enabled
- * @dev: DRM device
- * @pipe: pipe to check
- *
- * Reading certain registers when the pipe is disabled can hang the chip.
- * Use this routine to make sure the PLL is running and the pipe is active
- * before reading such registers if unsure.
- */
-static int
-psb_pipe_enabled(struct drm_device *dev, int pipe)
-{
-       unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
-       int ret = 0;
+       spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
-       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false)) {
-               ret = (REG_READ(pipeconf) & PIPEACONF_ENABLE);
-               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-       }
+       drm_psb_disable_vsync = 1;
+       mid_disable_pipe_event(dev_priv, pipe);
+       psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
 
-       return ret;
+       spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 }
 
 /* Called from drm generic code, passed a 'crtc', which
@@ -569,21 +687,40 @@ psb_pipe_enabled(struct drm_device *dev, int pipe)
  */
 u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)
 {
-       unsigned long high_frame;
-       unsigned long low_frame;
-       u32 high1, high2, low;
-       u32 count = 0;
+       uint32_t high_frame = PIPEAFRAMEHIGH;
+       uint32_t low_frame = PIPEAFRAMEPIXEL;
+       uint32_t pipeconf_reg = PIPEACONF;
+       uint32_t reg_val = 0;
+       uint32_t high1 = 0, high2 = 0, low = 0, count = 0;
 
-       return 0;
-       
        high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
        low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
 
+       switch (pipe) {
+       case 0:
+               break;
+       case 1:
+               high_frame = PIPEBFRAMEHIGH;
+               low_frame = PIPEBFRAMEPIXEL;
+               pipeconf_reg = PIPEBCONF;
+               break;
+       case 2:
+               high_frame = PIPECFRAMEHIGH;
+               low_frame = PIPECFRAMEPIXEL;
+               pipeconf_reg = PIPECCONF;
+               break;
+       default:
+               DRM_ERROR("%s, invalded pipe. \n", __FUNCTION__);
+               return 0;
+       }
+
        if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false)) 
                return 0;
 
-       if (!psb_pipe_enabled(dev, pipe)) {
-               DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", 
pipe);
+       reg_val = REG_READ(pipeconf_reg);
+
+       if (!(reg_val & PIPEACONF_ENABLE)) {
+               DRM_ERROR("trying to get vblank count for disabled pipe %d\n", 
pipe);
                goto psb_get_vblank_counter_exit;
        }
 
@@ -610,6 +747,7 @@ psb_get_vblank_counter_exit:
        return count;
 }
 
+
 #ifdef MDFLD_HDCP
 int mdfld_irq_enable_hdmi_audio(struct drm_device *dev)
 {
@@ -628,21 +766,11 @@ int mdfld_irq_enable_hdmi_audio(struct drm_device *dev)
 
        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
-       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
-               /* enable HDMI audio interrupt*/
-               dev_priv->vdc_irq_mask |= _PSB_PIPEB_EVENT;
-               PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-               PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-
-               reg_val = PSB_RVDC32(PIPEBSTAT);
-               reg_val &= ~PIPE_HDMI_AUDIO_INT_MASK;
-               mask = dev_priv->hdmi_audio_interrupt_mask;
-               reg_val |= (mask | (mask >> 16));
-               PSB_WVDC32(reg_val, PIPEBSTAT);
-               (void) PSB_RVDC32(PIPEBSTAT);
-
-               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-       }
+       /* enable HDMI audio interrupt*/
+       mid_enable_pipe_event(dev_priv, 1);
+       dev_priv->pipestat[1] &= ~PIPE_HDMI_AUDIO_INT_MASK;
+       mask = dev_priv->hdmi_audio_interrupt_mask;
+       psb_enable_pipestat(dev_priv, 1, mask);
 
        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
        return 0;
@@ -653,24 +781,12 @@ int mdfld_irq_disable_hdmi_audio(struct drm_device *dev)
        struct drm_psb_private *dev_priv =
        (struct drm_psb_private *) dev->dev_private;
        unsigned long irqflags;
-       u32 reg_val = 0;
 
        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
-       if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, 
OSPM_UHB_ONLY_IF_ON)) {
-               reg_val = PSB_RVDC32(PIPEBSTAT);
-               reg_val &= ~PIPE_HDMI_AUDIO_INT_MASK;
-               PSB_WVDC32(reg_val, PIPEBSTAT);
-               (void) PSB_RVDC32(PIPEBSTAT);
-
-               /* Disable PIPEB event only if no PIPEB event is enabled. */
-               if (!(reg_val & PIPEB_EVENT_MASK)) {
-                       dev_priv->vdc_irq_mask &= ~_PSB_PIPEB_EVENT;
-                       PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-                       PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-               }
 
-               ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
-       }
+       mid_disable_pipe_event(dev_priv, 1);
+       psb_disable_pipestat(dev_priv, 1, PIPE_HDMI_AUDIO_INT_MASK);
+
        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
        return 0;
 }
diff --git a/drivers/staging/mrst/drv/psb_powermgmt.c 
b/drivers/staging/mrst/drv/psb_powermgmt.c
index 7f82ab9..6962b71 100644
--- a/drivers/staging/mrst/drv/psb_powermgmt.c
+++ b/drivers/staging/mrst/drv/psb_powermgmt.c
@@ -1764,8 +1764,10 @@ bool ospm_power_using_hw_begin(int hw_island, bool 
force_on)
        struct pci_dev *pdev = gpDrmDevice->pdev;
        IMG_UINT32 deviceID = 0;
 
+#if 0 /* conflict with X holding the lock*/
        if (!b_atomic)
                mutex_lock(&g_ospm_mutex);
+#endif
 
        island_is_off = hw_island & (OSPM_ALL_ISLANDS & 
~g_hw_power_status_mask);
 
@@ -1881,8 +1883,10 @@ bool ospm_power_using_hw_begin(int hw_island, bool 
force_on)
                //printk(KERN_ALERT "Mrst Runtime PM: %s , ref_count:%d, 
hw_island:%d\n", __func__, atomic_read(&pdev->dev.power.usage_count), 
hw_island);
        }
 
+#if 0 /* conflict with X holding the lock*/
        if (!b_atomic)
                mutex_unlock(&g_ospm_mutex);
+#endif
 
        return ret;
 }
diff --git 
a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c
 
b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c
index f7763aa..4385153 100644
--- 
a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c
+++ 
b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_displayclass.c
@@ -1040,7 +1040,7 @@ MRSTLFBVSyncISR(struct drm_device *psDrmDevice, int iPipe)
 }
 #endif
 
-#if defined(MRST_USING_INTERRUPTS)
+#if 0 /* defined(MRST_USING_INTERRUPTS) */
 static IMG_BOOL
 MRSTLFBISRHandler(IMG_VOID* pvDevInfo)
 {
@@ -1159,7 +1159,7 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE  hCmdCookie,
        MRSTLFB_DEVINFO *psDevInfo;
        MRSTLFB_BUFFER *psBuffer;
        MRSTLFB_SWAPCHAIN *psSwapChain;
-#if 0//defined(MRST_USING_INTERRUPTS)
+#if defined(MRST_USING_INTERRUPTS)
        MRSTLFB_VSYNC_FLIP_ITEM* psFlipItem;
 #endif
        unsigned long ulLockFlags;
@@ -1186,7 +1186,7 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE  hCmdCookie,
 
        spin_lock_irqsave(&psDevInfo->sSwapChainLock, ulLockFlags);
 
-#if 0//defined(MRST_USING_INTERRUPTS)
+#if defined(MRST_USING_INTERRUPTS)
        
        if(psFlipCmd->ui32SwapInterval == 0 || psDevInfo->bFlushCommands)
        {
@@ -1197,7 +1197,7 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE  hCmdCookie,
        
                psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, 
IMG_TRUE);
 
-#if 0//defined(MRST_USING_INTERRUPTS)
+#if defined(MRST_USING_INTERRUPTS)
                goto ExitTrueUnlock;
        }
 
@@ -1628,8 +1628,6 @@ MRST_ERROR MRSTLFBInit(struct drm_device * dev)
                psDevInfo->sDisplayInfo.ui32MinSwapInterval = 0;
 
                strncpy(psDevInfo->sDisplayInfo.szDisplayName, 
DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE);
-
-               
        
 
                DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX
@@ -1668,6 +1666,7 @@ MRST_ERROR MRSTLFBInit(struct drm_device * dev)
 
                printk("Device ID: %d\n", (int)psDevInfo->uiDeviceID);
 
+#if 0
 #if defined (SYS_USING_INTERRUPTS)
                if 
(psDevInfo->sPVRJTable.pfnPVRSRVRegisterSystemISRHandler(MRSTLFBISRHandler,
                                                                            
psDevInfo,
@@ -1678,7 +1677,7 @@ MRST_ERROR MRSTLFBInit(struct drm_device * dev)
                        return (MRST_ERROR_INIT_FAILURE);
                }
 #endif
-#if 0
+
                if 
(psDevInfo->sPVRJTable.pfnPVRSRVRegisterPowerDevice((IMG_UINT32)psDevInfo->uiDeviceID,
                                                                       
MRSTLFBPrePowerState, MRSTLFBPostPowerState,
                                                                       
IMG_NULL, IMG_NULL,
@@ -1690,16 +1689,6 @@ MRST_ERROR MRSTLFBInit(struct drm_device * dev)
                }
 #endif
 
-               
-
-
-
-               
-
-
-
-
-
 #if defined (MRST_USING_INTERRUPTS)
        
        if(MRSTLFBInstallVSyncISR(psDevInfo,MRSTLFBVSyncISR) != MRST_OK)
@@ -1716,9 +1705,6 @@ MRST_ERROR MRSTLFBInit(struct drm_device * dev)
        aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; 
        aui32SyncCountList[DC_FLIP_COMMAND][1] = 2; 
        
-       
-
-
 
        if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList 
(psDevInfo->uiDeviceID,
                                                                
&pfnCmdProcList[0],
@@ -1780,7 +1766,7 @@ MRST_ERROR MRSTLFBDeinit(void)
                        return (MRST_ERROR_GENERIC);
                }
 
-#if defined (SYS_USING_INTERRUPTS)
+#if 0 /* defined (SYS_USING_INTERRUPTS) */
                if 
(psDevInfo->sPVRJTable.pfnPVRSRVRegisterSystemISRHandler(IMG_NULL, IMG_NULL, 0,
                                                                            
(IMG_UINT32)psDevInfo->uiDeviceID) != PVRSRV_OK)
                {
@@ -1814,7 +1800,68 @@ MRST_ERROR MRSTLFBDeinit(void)
        return (MRST_OK);
 }
 
+MRST_ERROR MRSTLFBAllocBuffer(struct MRSTLFB_DEVINFO_TAG *psDevInfo, 
IMG_UINT32 ui32Size, MRSTLFB_BUFFER **ppBuffer)
+{
+       IMG_VOID *pvBuf;
+       IMG_UINT32 ulPagesNumber;
+       IMG_UINT32 ulCounter;
+       int i;
 
+       pvBuf = __vmalloc( ui32Size, GFP_KERNEL | __GFP_HIGHMEM, 
__pgprot((pgprot_val(PAGE_KERNEL ) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) );
+       if( pvBuf == NULL )
+       {
+               return MRST_ERROR_OUT_OF_MEMORY;
+       }
+
+       ulPagesNumber = (ui32Size + PAGE_SIZE -1) / PAGE_SIZE;
+
+       *ppBuffer = MRSTLFBAllocKernelMem( sizeof( MRSTLFB_BUFFER ) );
+       (*ppBuffer)->sCPUVAddr = pvBuf;
+       (*ppBuffer)->ui32BufferSize = ui32Size;
+       (*ppBuffer)->uSysAddr.psNonCont = MRSTLFBAllocKernelMem( sizeof( 
IMG_SYS_PHYADDR ) * ulPagesNumber);
+       (*ppBuffer)->bIsAllocated = MRST_TRUE;
+       (*ppBuffer)->bIsContiguous = MRST_FALSE;
+       (*ppBuffer)->ui32OwnerTaskID = task_tgid_nr(current);
+
+       i = 0;
+       for(ulCounter = 0; ulCounter < ui32Size; ulCounter += PAGE_SIZE)
+       {
+               (*ppBuffer)->uSysAddr.psNonCont[i++].uiAddr = vmalloc_to_pfn( 
pvBuf + ulCounter ) << PAGE_SHIFT;
+       }
+
+       psb_gtt_map_pvr_memory( psDevInfo->psDrmDevice,
+                                                       (unsigned int)*ppBuffer,
+                                                       
(*ppBuffer)->ui32OwnerTaskID,
+                                                       (IMG_CPU_PHYADDR*) 
(*ppBuffer)->uSysAddr.psNonCont,
+                                                       ulPagesNumber,
+                                                       
&(*ppBuffer)->sDevVAddr.uiAddr );
+
+       (*ppBuffer)->sDevVAddr.uiAddr <<= PAGE_SHIFT;
+
+       return MRST_OK;
+}
+
+MRST_ERROR MRSTLFBFreeBuffer(struct MRSTLFB_DEVINFO_TAG *psDevInfo, 
MRSTLFB_BUFFER **ppBuffer)
+{
+       if( !(*ppBuffer)->bIsAllocated )
+               return MRST_ERROR_INVALID_PARAMS;
+
+       psb_gtt_unmap_pvr_memory( psDevInfo->psDrmDevice,
+                                                         (unsigned 
int)*ppBuffer,
+                                                         
(*ppBuffer)->ui32OwnerTaskID);
+
+       vfree( (*ppBuffer)->sCPUVAddr );
+
+       MRSTLFBFreeKernelMem( (*ppBuffer)->uSysAddr.psNonCont );
+
+       MRSTLFBFreeKernelMem( *ppBuffer);
+
+       *ppBuffer = NULL;
+
+       return MRST_OK;
+}
+
+#if 0
 /*
  * save_display_registers
  *
@@ -2086,68 +2133,6 @@ static void restore_display_registers(struct drm_device 
*dev)
        PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG, 
HISTOGRAM_LOGIC_CONTROL);
 }
 
-MRST_ERROR MRSTLFBAllocBuffer(struct MRSTLFB_DEVINFO_TAG *psDevInfo, 
IMG_UINT32 ui32Size, MRSTLFB_BUFFER **ppBuffer)
-{
-       IMG_VOID *pvBuf;
-       IMG_UINT32 ulPagesNumber;
-       IMG_UINT32 ulCounter;
-       int i;
-
-       pvBuf = __vmalloc( ui32Size, GFP_KERNEL | __GFP_HIGHMEM, 
__pgprot((pgprot_val(PAGE_KERNEL ) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) );
-       if( pvBuf == NULL ) 
-       {
-               return MRST_ERROR_OUT_OF_MEMORY;
-       }
-
-       ulPagesNumber = (ui32Size + PAGE_SIZE -1) / PAGE_SIZE;
-
-       *ppBuffer = MRSTLFBAllocKernelMem( sizeof( MRSTLFB_BUFFER ) );  
-       (*ppBuffer)->sCPUVAddr = pvBuf;
-       (*ppBuffer)->ui32BufferSize = ui32Size;
-       (*ppBuffer)->uSysAddr.psNonCont = MRSTLFBAllocKernelMem( sizeof( 
IMG_SYS_PHYADDR ) * ulPagesNumber);    
-       (*ppBuffer)->bIsAllocated = MRST_TRUE;
-       (*ppBuffer)->bIsContiguous = MRST_FALSE;
-       (*ppBuffer)->ui32OwnerTaskID = task_tgid_nr(current);
-
-       i = 0;
-       for(ulCounter = 0; ulCounter < ui32Size; ulCounter += PAGE_SIZE) 
-       {
-               (*ppBuffer)->uSysAddr.psNonCont[i++].uiAddr = vmalloc_to_pfn( 
pvBuf + ulCounter ) << PAGE_SHIFT;
-       }
-       
-       psb_gtt_map_pvr_memory( psDevInfo->psDrmDevice, 
-                                                       (unsigned 
int)*ppBuffer, 
-                                                       
(*ppBuffer)->ui32OwnerTaskID,
-                                                       (IMG_CPU_PHYADDR*) 
(*ppBuffer)->uSysAddr.psNonCont, 
-                                                       ulPagesNumber,
-                                                       
&(*ppBuffer)->sDevVAddr.uiAddr );
-
-       (*ppBuffer)->sDevVAddr.uiAddr <<= PAGE_SHIFT;
-
-       return MRST_OK; 
-}
-
-MRST_ERROR MRSTLFBFreeBuffer(struct MRSTLFB_DEVINFO_TAG *psDevInfo, 
MRSTLFB_BUFFER **ppBuffer)
-{
-       if( !(*ppBuffer)->bIsAllocated )
-               return MRST_ERROR_INVALID_PARAMS;
-       
-       psb_gtt_unmap_pvr_memory( psDevInfo->psDrmDevice, 
-                                                         (unsigned 
int)*ppBuffer,
-                                                         
(*ppBuffer)->ui32OwnerTaskID);
-
-       vfree( (*ppBuffer)->sCPUVAddr );
-
-       MRSTLFBFreeKernelMem( (*ppBuffer)->uSysAddr.psNonCont );
-       
-       MRSTLFBFreeKernelMem( *ppBuffer);
-
-       *ppBuffer = NULL;
-
-       return MRST_OK; 
-}
-
-
 
 PVRSRV_ERROR MRSTLFBPrePowerState(IMG_HANDLE            hDevHandle,
                                  PVRSRV_DEV_POWER_STATE eNewPowerState,
@@ -2262,3 +2247,4 @@ PVRSRV_ERROR MRSTLFBPostPowerState(IMG_HANDLE             
  hDevHandle,
 
        return PVRSRV_OK;
 }
+#endif
diff --git 
a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c
 
b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c
index d540b73..9132ede 100644
--- 
a/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c
+++ 
b/drivers/staging/mrst/pvr/services4/3rdparty/linux_framebuffer_mrst/mrstlfb_linux.c
@@ -110,33 +110,11 @@ unsigned long MRSTLFBVSyncReadReg(MRSTLFB_DEVINFO * 
psDevinfo, unsigned long ulO
 void MRSTLFBEnableVSyncInterrupt(MRSTLFB_DEVINFO * psDevinfo)
 {
 #if defined(MRST_USING_INTERRUPTS)
-
-#if defined(SUPPORT_DRI_DRM)
-
     struct drm_psb_private *dev_priv =
        (struct drm_psb_private *) psDevinfo->psDrmDevice->dev_private;
     dev_priv->vblanksEnabledForFlips = true;
     psb_enable_vblank(psDevinfo->psDrmDevice, 0);
 
-#else
-
-    unsigned long vdc_irq_mask;
-
-    vdc_irq_mask = ~MRSTLFBVSyncReadReg( psDevinfo, PSB_INT_MASK_R);
-    vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
-
-    MRSTLFBVSyncWriteReg(psDevinfo, PSB_INT_MASK_R, ~vdc_irq_mask);
-    MRSTLFBVSyncWriteReg(psDevinfo, PSB_INT_ENABLE_R, vdc_irq_mask);
-
-    {
-       unsigned int writeVal = MRSTLFBVSyncReadReg(psDevinfo, PIPEASTAT);
-       unsigned int mask = PIPE_START_VBLANK_INTERRUPT_ENABLE |  
PIPE_VBLANK_INTERRUPT_ENABLE;
-
-       writeVal |= (mask | (mask >> 16));
-       MRSTLFBVSyncWriteReg(psDevinfo, PIPEASTAT, writeVal);
-       MRSTLFBVSyncReadReg(psDevinfo, PIPEASTAT);
-    }
-#endif
 #endif
 }
 
@@ -156,18 +134,18 @@ void MRSTLFBDisableVSyncInterrupt(MRSTLFB_DEVINFO * 
psDevinfo)
 #if defined(MRST_USING_INTERRUPTS)
 MRST_ERROR MRSTLFBInstallVSyncISR(MRSTLFB_DEVINFO *psDevInfo, 
MRSTLFB_VSYNC_ISR_PFN pVsyncHandler)
 {
-       //struct drm_psb_private *dev_priv =
-       //    (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
-       //dev_priv->psb_vsync_handler = pVsyncHandler;
+       struct drm_psb_private *dev_priv =
+           (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
+       dev_priv->psb_vsync_handler = pVsyncHandler;
        return (MRST_OK);
 }
 
 
 MRST_ERROR MRSTLFBUninstallVSyncISR(MRSTLFB_DEVINFO    *psDevInfo)
 {
-       //struct drm_psb_private *dev_priv =
-       //    (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
-       //dev_priv->psb_vsync_handler = NULL;
+       struct drm_psb_private *dev_priv =
+           (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
+       dev_priv->psb_vsync_handler = NULL;
        return (MRST_OK);
 }
 #endif 
@@ -182,15 +160,6 @@ void MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo,  
unsigned long uiAddr)
        {
                if (IS_MRST(psDevInfo->psDrmDevice)) {
                        MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
-               } else if (IS_MDFLD(psDevInfo->psDrmDevice)) {
-                       dspsurf = DSPASURF;
-                       MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
-#if defined(CONFIG_MDFD_DUAL_MIPI)
-                       dspsurf = DSPCSURF;
-                       MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
-#endif
-                       /*TODO: Add plane B flip here*/
-
                } else {
                        MRSTLFBVSyncWriteReg(psDevInfo, dspbase, uiAddr);
                }
-- 
1.7.1

_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to