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

It can be disabled by "make menuconfig".
Added support in Kconfig.

Signed-off-by: Li Zeng <[email protected]>
Signed-off-by: Guoqiang Cao <[email protected]>
Signed-off-by: Hitesh K. Patel <[email protected]>
---
 drivers/staging/mrst/Kconfig                       |    6 +
 drivers/staging/mrst/drv/mdfld_gl3.c               |  130 ++++++++++++++++++++
 drivers/staging/mrst/drv/mdfld_gl3.h               |  126 +++++++++++++++++++
 drivers/staging/mrst/drv/mdfld_hdmi_audio.c        |    2 +-
 drivers/staging/mrst/drv/psb_drv.c                 |   24 ++++
 drivers/staging/mrst/drv/psb_drv.h                 |   19 +++-
 drivers/staging/mrst/drv/psb_irq.c                 |   63 +++++++++-
 drivers/staging/mrst/drv/psb_powermgmt.c           |   38 +++++--
 drivers/staging/mrst/drv/psb_reg.h                 |   14 ++-
 drivers/staging/mrst/drv/psb_sgx.c                 |   29 +++++
 drivers/staging/mrst/imgv/pnw_topaz.c              |    2 +
 drivers/staging/mrst/imgv/psb_msvdx.c              |    2 +
 drivers/staging/mrst/medfield/Makefile             |    2 +
 drivers/staging/mrst/moorestown/Makefile           |    4 +-
 .../mrst/pvr/services4/srvkm/devices/sgx/sgxkick.c |   14 ++
 15 files changed, 455 insertions(+), 20 deletions(-)
 create mode 100644 drivers/staging/mrst/drv/mdfld_gl3.c
 create mode 100644 drivers/staging/mrst/drv/mdfld_gl3.h

diff --git a/drivers/staging/mrst/Kconfig b/drivers/staging/mrst/Kconfig
index 9ff95ff..1e5b669 100644
--- a/drivers/staging/mrst/Kconfig
+++ b/drivers/staging/mrst/Kconfig
@@ -85,3 +85,9 @@ config MDFD_HDMI
         help
           xxxxxx
 
+config MDFD_GL3
+       bool "Enable GL3 Cache for GUNIT"
+       depends on DRM_MDFLD
+       default n
+       help
+         xxxxxx
diff --git a/drivers/staging/mrst/drv/mdfld_gl3.c 
b/drivers/staging/mrst/drv/mdfld_gl3.c
new file mode 100644
index 0000000..bf130b8
--- /dev/null
+++ b/drivers/staging/mrst/drv/mdfld_gl3.c
@@ -0,0 +1,130 @@
+/*
+ * 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 Bish <jim.bish@@intel.com>
+ */
+
+#ifdef CONFIG_MDFD_GL3
+
+#include "mdfld_gl3.h"
+
+extern int drm_psb_debug;
+extern struct drm_device *gpDrmDevice;
+
+void gl3_enable(void)
+{
+       struct drm_psb_private *dev_priv =
+                   (struct drm_psb_private *) gpDrmDevice->dev_private;
+
+       PSB_DEBUG_ENTRY("gl3_enable called on platform %x\n",   
dev_priv->platform_rev_id);
+       if (gl3_exist()) {
+               if( !ospm_power_using_hw_begin(OSPM_GRAPHICS_ISLAND, true) )
+                       return;
+               MDFLD_GL3_WRITE(MDFLD_GL3_ENABLE_CACHE, MDFLD_GL3_CONTROL);
+               PSB_DEBUG_GENERAL("gl3 cache enabled with mask %x\n", 
MDFLD_GL3_ENABLE_CACHE);
+               ospm_power_using_hw_end(OSPM_GRAPHICS_ISLAND);
+       }
+}
+
+void gl3_disable(void)
+{
+       struct drm_psb_private *dev_priv =
+                   (struct drm_psb_private *) gpDrmDevice->dev_private;
+
+       PSB_DEBUG_ENTRY("gl3_disable called on platform %x\n",  
dev_priv->platform_rev_id);
+       if (gl3_exist()) {
+               if( !ospm_power_using_hw_begin(OSPM_GRAPHICS_ISLAND, true) )
+                       return;
+               MDFLD_GL3_WRITE(MDFLD_GL3_DISABLE_CACHE, MDFLD_GL3_CONTROL);
+               PSB_DEBUG_GENERAL("gl3 cache disabled with mask %x\n", 
MDFLD_GL3_DISABLE_CACHE);
+               ospm_power_using_hw_end(OSPM_GRAPHICS_ISLAND);
+       }
+}
+
+void gl3_invalidate(void)
+{
+       struct drm_psb_private *dev_priv =
+                   (struct drm_psb_private *) gpDrmDevice->dev_private;
+
+       PSB_DEBUG_ENTRY("gl3_invalidate called on platform %x\n",       
dev_priv->platform_rev_id);
+       if (gl3_exist()) {
+               if( !ospm_power_using_hw_begin(OSPM_GRAPHICS_ISLAND, true) )
+                       return;
+               // Invalidate the cache
+               MDFLD_GL3_WRITE(MDFLD_GL3_INVALIDATE_CACHE, MDFLD_GL3_CONTROL);
+               PSB_DEBUG_GENERAL("gl3 cache invalidated with mask %x\n", 
MDFLD_GL3_INVALIDATE_CACHE);
+               ospm_power_using_hw_end(OSPM_GRAPHICS_ISLAND);
+       }
+}
+
+void gl3_flush(void)
+{
+       struct drm_psb_private *dev_priv =
+                   (struct drm_psb_private *) gpDrmDevice->dev_private;
+
+       PSB_DEBUG_ENTRY("gl3_flush called on platform %x\n",    
dev_priv->platform_rev_id);
+       if (gl3_exist()) {
+               if( !ospm_power_using_hw_begin(OSPM_GRAPHICS_ISLAND, true) )
+                       return;
+               // Flush the cache
+               MDFLD_GL3_WRITE(MDFLD_GL3_FLUSH_CACHE, MDFLD_GL3_CONTROL);
+               PSB_DEBUG_GENERAL("gl3 cache flushed with mask %x\n", 
MDFLD_GL3_FLUSH_CACHE);
+               ospm_power_using_hw_end(OSPM_GRAPHICS_ISLAND);\
+       }
+}
+
+void gl3_reset(void)
+{
+       struct drm_psb_private *dev_priv =
+                   (struct drm_psb_private *) gpDrmDevice->dev_private;
+
+       PSB_DEBUG_ENTRY("gl3_reset called on platform %x\n",    
dev_priv->platform_rev_id);
+       if (gl3_exist()) {
+               if( !ospm_power_using_hw_begin(OSPM_GRAPHICS_ISLAND, true) )
+                       return;
+               // Reset the cache
+               MDFLD_GL3_WRITE(MDFLD_GL3_SOFT_RESET_ENABLE, 
MDFLD_GL3_G_CONTROL);
+               PSB_DEBUG_GENERAL("gl3 cache soft reset with mas %x\n", 
MDFLD_GL3_SOFT_RESET_ENABLE);
+               ospm_power_using_hw_end(OSPM_GRAPHICS_ISLAND);\
+       }
+}
+
+bool gl3_exist(void)
+{
+       struct drm_psb_private *dev_priv =
+                   (struct drm_psb_private *) gpDrmDevice->dev_private;
+
+       if (IS_MRST(gpDrmDevice)) {
+               return false;
+       }
+       else if (IS_MDFLD(gpDrmDevice) && dev_priv->platform_rev_id != 
MDFLD_PNW_A0) {
+               return true;
+       }
+       else {
+               PSB_DEBUG_ENTRY("gl3 not supported in unknown platform");
+       }
+
+       return false;
+}
+
+#endif /* CONFIG_MDFD_GL3 */
diff --git a/drivers/staging/mrst/drv/mdfld_gl3.h 
b/drivers/staging/mrst/drv/mdfld_gl3.h
new file mode 100644
index 0000000..35f9e34
--- /dev/null
+++ b/drivers/staging/mrst/drv/mdfld_gl3.h
@@ -0,0 +1,126 @@
+/*
+ * 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 Bish <[email protected]>
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drm.h"
+#include "psb_drv.h"
+#include "psb_fb.h"
+#include "psb_reg.h"
+#include "psb_intel_reg.h"
+#include "psb_intel_bios.h"
+#include "psb_msvdx.h"
+#include "lnc_topaz.h"
+#include "pnw_topaz.h"
+#include <drm/drm_pciids.h>
+#include "pvr_drm_shared.h"
+#include "psb_powermgmt.h"
+#include <linux/cpu.h>
+#include <linux/notifier.h>
+#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
+
+#ifdef CONFIG_MDFD_GL3
+
+/*
+ * GL3 Control
+ */
+
+#define MDFLD_GCL_CR_CTL2                              0xB0000
+#define MDFLD_GCL_ERR_ADDR                             0xB0004         /* 
address at location is the address that had the error */
+#define MDFLD_GCL_ERR_STATUS                   0xB0008
+
+#define MDFLD_IMG_MASK                                 0x20A8          /* 
unmask bit 21 to get GL3 interrupts */
+/*
+ * GL3 registers and bits
+ */
+
+#define MDFLD_GL3_CONTROL                              0x2100
+#define MDFLD_GL3_USE_WRT_INVAL                        0x2104
+#define MDFLD_GL3_STATUS                               0x2108
+#define MDFLD_GL3_G_CONTROL                            0x20FC
+#define MDFLD_GL3_SOFT_RESET_ENABLE            (1<<4)
+
+#define MDFLD_GL3_DISABLE                              (1<<31)
+#define MDFLD_GL3_BYP_PREQ2_USSE3              (1<<29)
+#define MDLFD_GL3_BYP_PREQ2_USSE2              (1<<28)
+#define MDFLD_GL3_BYP_PREQ2_PDS                        (1<<27)
+#define MDFLD_GL3_BYP_PREQ2_USEC               (1<<26)
+#define MDFLD_GL3_FLUSH                                        (1<<25)
+#define MDFLD_GL3_FLUSH_CTL                            (1<<24)
+#define MDFLD_GL3_BYP_CPU_COH                  (1<<23)
+#define MDFLD_GL3_BYP_VED                              (1<<21)
+#define MDFLD_GL3_BYP_VEC                              (1<<20)
+#define MDFLD_GL3_BYP_GFX                              (1<<19)
+#define MDFLD_GL3_BYP_PREQ1_USE1               (1<<18)
+#define MDFLD_GL3_BYP_PREQ1_USE0               (1<<17)
+#define MDFLD_GL3_BYP_PREQ1_ISPZ               (1<<16)
+#define MDFLD_GL3_BYP_PREQ1_ISPP               (1<<15)
+#define MDFLD_GL3_BYP_PREQ1_TSPP               (1<<14)
+#define MDFLD_GL3_BYP_PREQ1_PBE                        (1<<13)
+#define MDFLD_GL3_BYP_PREQ1_VDM                        (1<<12)
+#define MDFLD_GL3_BYP_PREQ1_TA                 (1<<11)
+#define MDFLD_GL3_BYP_PREQ1_MADD               (1<<10)
+#define MDFLD_GL3_BYP_PREQ1_MMU                        (1<<9)
+#define MDFLD_GL3_USE_INVAL_REQ_USSE3  (1<<8)
+#define MDFLD_GL3_USE_INVAL_REQ_USSE2  (1<<7)
+#define MDFLD_GL3_USE_INVAL_REQ_USSE1  (1<<6)
+#define MDFLD_GL3_USE_INVAL_REQ_USSE0  (1<<5)
+#define MDFLD_GL3_BYP_WR                               (1<<4)
+#define MDFLD_GL3_IGN_VED_HINT                 (1<<3)
+#define MDFLD_GL3_IGN_VEC_HINT                 (1<<2)
+#define MDFLD_GL3_INVALIDATE                   (1<<1)
+#define MDFLD_GL3_PAUSE                                        (1)
+
+/*
+ * GL3 Masks
+ */
+
+#define MDFLD_GL3_ENABLE_CACHE (MDFLD_GL3_BYP_PREQ2_USSE3 | 
MDLFD_GL3_BYP_PREQ2_USSE2 | \
+               MDFLD_GL3_BYP_PREQ1_USE1 | MDFLD_GL3_BYP_PREQ1_USE0 | 
MDFLD_GL3_BYP_PREQ1_ISPZ  | \
+               MDFLD_GL3_BYP_PREQ1_PBE | MDFLD_GL3_BYP_PREQ1_VDM | 
MDFLD_GL3_BYP_PREQ1_TA | \
+               MDFLD_GL3_BYP_PREQ1_MMU | MDFLD_GL3_IGN_VEC_HINT)
+
+#define MDFLD_GL3_INVALIDATE_CACHE (MDFLD_GL3_ENABLE_CACHE | 
MDFLD_GL3_INVALIDATE)
+
+#define MDFLD_GL3_FLUSH_CACHE (MDFLD_GL3_ENABLE_CACHE | MDFLD_GL3_FLUSH)
+
+#define MDFLD_GL3_DISABLE_CACHE (MDFLD_GL3_ENABLE_CACHE | MDFLD_GL3_DISABLE)
+
+// GL3
+#define MDFLD_GL3_WRITE(_val, _offs ) \
+       iowrite32(_val, dev_priv->gl3_reg + (_offs))
+#define MDFLD_GL3_READ(_offs) \
+       ioread32(dev_priv->gl3_reg + (_offs))
+
+void gl3_enable(void);
+void gl3_invalidate(void);
+void gl3_flush(void);
+void gl3_reset(void);
+bool gl3_exist(void);
+void gl3_disable(void);
+
+#endif
diff --git a/drivers/staging/mrst/drv/mdfld_hdmi_audio.c 
b/drivers/staging/mrst/drv/mdfld_hdmi_audio.c
index 4e0c8fc..9fa12f3 100644
--- a/drivers/staging/mrst/drv/mdfld_hdmi_audio.c
+++ b/drivers/staging/mrst/drv/mdfld_hdmi_audio.c
@@ -202,4 +202,4 @@ int intel_hdmi_audio_query_capabilities 
(had_event_call_back audio_callbacks, st
     return ret;
 }
 
-EXPORT_SYMBOL(intel_hdmi_audio_query_capabilities);
+/* EXPORT_SYMBOL(intel_hdmi_audio_query_capabilities); */
diff --git a/drivers/staging/mrst/drv/psb_drv.c 
b/drivers/staging/mrst/drv/psb_drv.c
index c05dd17..1096864 100644
--- a/drivers/staging/mrst/drv/psb_drv.c
+++ b/drivers/staging/mrst/drv/psb_drv.c
@@ -48,6 +48,11 @@
 #include "mdfld_dsi_dbi_dpu.h"
 #endif
 
+#ifdef CONFIG_MDFD_GL3
+#include "mdfld_gl3.h"
+#endif
+
+
 /*IMG headers*/
 #include "pvr_drm_shared.h"
 #include "img_types.h"
@@ -1145,6 +1150,13 @@ static int psb_driver_unload(struct drm_device *dev)
                        iounmap(dev_priv->sgx_reg);
                        dev_priv->sgx_reg = NULL;
                }
+#ifdef CONFIG_MDFD_GL3
+               if( IS_MDFLD(dev) && dev_priv->platform_rev_id != MDFLD_PNW_A0 
) {
+                       iounmap(dev_priv->gl3_reg);
+                       dev_priv->gl3_reg = NULL;
+               }
+#endif
+
                if (dev_priv->msvdx_reg) {
                        iounmap(dev_priv->msvdx_reg);
                        dev_priv->msvdx_reg = NULL;
@@ -1300,6 +1312,13 @@ static int psb_driver_load(struct drm_device *dev, 
unsigned long chipset)
                psb_intel_init_bios(dev);
        }
 
+#ifdef CONFIG_MDFD_GL3
+       // GL3
+       if( IS_MDFLD(dev) && dev_priv->platform_rev_id != MDFLD_PNW_A0 )
+               dev_priv->gl3_reg =
+                       ioremap(resource_start + MDFLD_GL3_OFFSET, 
MDFLD_GL3_SIZE);
+#endif
+
        PSB_DEBUG_INIT("Init TTM fence and BO driver\n");
 
        if (IS_MRST(dev)) {
@@ -1484,6 +1503,11 @@ static int psb_driver_load(struct drm_device *dev, 
unsigned long chipset)
        pm_runtime_enable(&dev->pdev->dev);
        pm_runtime_set_active(&dev->pdev->dev);
 
+       // GL3
+#ifdef CONFIG_MDFD_GL3
+       gl3_enable();
+#endif
+
        /*Intel drm driver load is done, continue doing pvr load*/
        DRM_DEBUG("Pvr driver load\n");
 
diff --git a/drivers/staging/mrst/drv/psb_drv.h 
b/drivers/staging/mrst/drv/psb_drv.h
index f270125..02c45a7 100644
--- a/drivers/staging/mrst/drv/psb_drv.h
+++ b/drivers/staging/mrst/drv/psb_drv.h
@@ -110,6 +110,10 @@ enum panel_type {
 #define MDFLD_MMIO_SIZE          0x000100000
 #define PSB_SGX_SIZE            0x8000
 #define PSB_SGX_OFFSET          0x00040000
+#ifdef CONFIG_MDFD_GL3
+#define MDFLD_GL3_OFFSET        0x00000000
+#define MDFLD_GL3_SIZE          0x00040000
+#endif
 #define MRST_SGX_OFFSET                 0x00080000
 #define PSB_MMIO_RESOURCE       0
 #define PSB_GATT_RESOURCE       2
@@ -127,6 +131,9 @@ enum panel_type {
 #define PSB_MEM_MMU_START       0x00000000
 #define PSB_MEM_TT_START        0xE0000000
 
+#define PSB_GL3_CACHE_CTL      0x2100
+#define PSB_GL3_CACHE_STAT     0x2108
+
 /*
  *Flags for external memory type field.
  */
@@ -138,9 +145,9 @@ enum panel_type {
 
 #define LNC_TOPAZ_OFFSET       0xA0000
 #define PNW_TOPAZ_OFFSET       0xC0000
+#define PNW_GL3_OFFSET         0xB0000
 #define LNC_TOPAZ_SIZE         0x10000
 #define PNW_TOPAZ_SIZE         0x30000 /* PNW VXE285 has two cores */
-
 #define PSB_MMU_CACHED_MEMORY    0x0001        /* Bind to MMU only */
 #define PSB_MMU_RO_MEMORY        0x0002        /* MMU RO memory */
 #define PSB_MMU_WO_MEMORY        0x0004        /* MMU WO memory */
@@ -179,6 +186,11 @@ enum panel_type {
 #define _PSB_IRQ_SGX_FLAG        (1<<18)
 #define _PSB_IRQ_MSVDX_FLAG      (1<<19)
 #define _LNC_IRQ_TOPAZ_FLAG      (1<<20)
+#ifdef CONFIG_MDFD_GL3
+#define _MDFLD_GL3_IRQ_FLAG      (1<<21)
+#define _MDFLD_GL3_ECC_FLAG      (1<<2)  /* unrecoverable ecc error.  We must 
flush and reset */
+#endif
+
 /* 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)
@@ -385,6 +397,9 @@ struct drm_psb_private {
 
        uint8_t *sgx_reg;
        uint8_t *vdc_reg;
+#ifdef CONFIG_MDFD_GL3
+       uint8_t *gl3_reg;
+#endif
        uint32_t gatt_free_offset;
 
        /*
@@ -1064,7 +1079,7 @@ extern int psb_validate_kernel_buffer(struct psb_context 
*context,
                                      uint64_t set_flags,
                                      uint64_t clr_flags);
 
-
+extern void psb_gl3_global_invalidation(struct drm_device *dev);
 /*
  *psb_irq.c
  */
diff --git a/drivers/staging/mrst/drv/psb_irq.c 
b/drivers/staging/mrst/drv/psb_irq.c
index f32b61a..fc5bcd3 100644
--- a/drivers/staging/mrst/drv/psb_irq.c
+++ b/drivers/staging/mrst/drv/psb_irq.c
@@ -33,6 +33,10 @@
 
 #include "mdfld_dsi_dbi_dpu.h"
 
+#ifdef CONFIG_MDFD_GL3
+#include "mdfld_gl3.h"
+#endif
+
 /*
  * inline functions
  */
@@ -301,7 +305,7 @@ static void mid_pipe_event_handler(struct drm_device *dev, 
uint32_t pipe)
        }
 
        if (pipe_stat_val & PIPE_TE_STATUS) {
-#ifdef CONFIG_MDFLD_DSI_DPU
+#ifdef CONFIG_MDFD_DSI_DPU
                mdfld_dpu_update_panel(dev);
 #else
                mdfld_dbi_update_panel (dev, pipe);
@@ -346,6 +350,30 @@ static void psb_vdc_interrupt(struct drm_device *dev, 
uint32_t vdc_stat)
        }
 }
 
+/**
+ * Medfield Gl3 Cache interrupt handler.
+ */
+#ifdef CONFIG_MDFD_GL3
+static void mdfld_gl3_interrupt(struct drm_device *dev, uint32_t vdc_stat)
+{
+       struct drm_psb_private *dev_priv =
+                   (struct drm_psb_private *) dev->dev_private;
+       uint32_t gl3_err_status = 0;
+
+       gl3_err_status = MDFLD_GL3_READ(MDFLD_GCL_ERR_STATUS);
+       if (gl3_err_status & _MDFLD_GL3_ECC_FLAG) {
+               gl3_flush();
+               gl3_reset();
+       }
+
+       dev_priv->vdc_irq_mask &= ~_MDFLD_GL3_IRQ_FLAG;
+       PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
+       PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
+
+}
+#endif
+
+
 irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
 {
        struct drm_device *dev = (struct drm_device *) arg;
@@ -355,6 +383,10 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
        uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, msvdx_int = 0, topaz_int = 
0;
        int handled = 0;
 
+#ifdef CONFIG_MDFD_GL3
+       uint32_t gl3_int = 0;
+#endif
+
 /*     PSB_DEBUG_ENTRY("\n"); */
 
        spin_lock(&dev_priv->irqmask_lock);
@@ -380,6 +412,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
                topaz_int = 1;
        }
        
+#ifdef CONFIG_MDFD_GL3
+       if (vdc_stat & _MDFLD_GL3_IRQ_FLAG) {
+               PSB_DEBUG_IRQ("Got GL3 interrupt\n");
+               gl3_int = 1;
+       }
+#endif
+
        vdc_stat &= dev_priv->vdc_irq_mask;
        spin_unlock(&dev_priv->irqmask_lock);
 
@@ -411,6 +450,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
                        handled = 1;
        }
 
+#ifdef CONFIG_MDFD_GL3
+       if( gl3_int ) {
+               mdfld_gl3_interrupt(dev, vdc_stat);
+               handled = 1;
+       }
+#endif
+
        PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
        (void) PSB_RVDC32(PSB_INT_IDENTITY_R);
        DRM_READMEMORYBARRIER();
@@ -451,8 +497,12 @@ void psb_irq_preinstall_islands(struct drm_device *dev, 
int hw_islands)
                                dev_priv->vdc_irq_mask |= 
_MDFLD_PIPEC_EVENT_FLAG;
                }
        }
-       if (hw_islands & OSPM_GRAPHICS_ISLAND)
+       if (hw_islands & OSPM_GRAPHICS_ISLAND) {
                dev_priv->vdc_irq_mask |= _PSB_IRQ_SGX_FLAG;
+#ifdef CONFIG_MDFD_GL3
+               dev_priv->vdc_irq_mask |= _MDFLD_GL3_IRQ_FLAG;
+#endif
+       }
 
        if (hw_islands & OSPM_VIDEO_DEC_ISLAND)
                if (IS_MID(dev) && ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND))
@@ -568,10 +618,17 @@ void psb_irq_uninstall_islands(struct drm_device *dev, 
int hw_islands)
                dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
                                          _PSB_IRQ_MSVDX_FLAG |
                                          _LNC_IRQ_TOPAZ_FLAG;
+#ifdef CONFIG_MDFD_GL3
+               dev_priv->vdc_irq_mask &= _MDFLD_GL3_IRQ_FLAG;
+#endif
        }
        /*TODO: remove follwoing code*/
-       if (hw_islands & OSPM_GRAPHICS_ISLAND)
+       if (hw_islands & OSPM_GRAPHICS_ISLAND) {
                dev_priv->vdc_irq_mask &= ~_PSB_IRQ_SGX_FLAG;
+#ifdef CONFIG_MDFD_GL3
+               dev_priv->vdc_irq_mask &= ~_MDFLD_GL3_IRQ_FLAG;
+#endif
+       }
 
        if ((hw_islands & OSPM_VIDEO_DEC_ISLAND) && IS_MID(dev))
                dev_priv->vdc_irq_mask &= ~_PSB_IRQ_MSVDX_FLAG;
diff --git a/drivers/staging/mrst/drv/psb_powermgmt.c 
b/drivers/staging/mrst/drv/psb_powermgmt.c
index f692f10..59509b6 100644
--- a/drivers/staging/mrst/drv/psb_powermgmt.c
+++ b/drivers/staging/mrst/drv/psb_powermgmt.c
@@ -1670,8 +1670,13 @@ void ospm_power_island_up(int hw_islands)
 
                pwr_mask = 0;
                if (hw_islands & OSPM_GRAPHICS_ISLAND) {
-                       pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
-                       pwr_mask |= PSB_PWRGT_GFX_MASK;
+                       if (IS_MDFLD(gpDrmDevice) && dev_priv->platform_rev_id 
!= MDFLD_PNW_A0) {
+                               pwr_cnt &= ~PSB_PWRGT_GFX_MASK_B0;
+                               pwr_mask |= PSB_PWRGT_GFX_MASK_B0;
+                       } else {
+                               pwr_cnt &= ~PSB_PWRGT_GFX_MASK;
+                               pwr_mask |= PSB_PWRGT_GFX_MASK;
+                       }
             #ifdef OSPM_STAT
             if (dev_priv->graphics_state == PSB_PWR_STATE_OFF) {
                 dev_priv->gfx_off_time += (jiffies - 
dev_priv->gfx_last_mode_change) * 1000 / HZ;
@@ -1712,8 +1717,12 @@ void ospm_power_island_up(int hw_islands)
                pwr_cnt &= ~pwr_mask;
                outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
 
-               if (IS_MDFLD(gpDrmDevice))
-                       pwr_mask = MDFLD_PWRGT_DISPLAY_STS;
+               if (IS_MDFLD(gpDrmDevice)) {
+                       if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
+                               pwr_mask = MDFLD_PWRGT_DISPLAY_STS_B0;
+                       else
+                               pwr_mask = MDFLD_PWRGT_DISPLAY_STS;
+               }
 
                while (true) {
                        pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
@@ -1779,8 +1788,13 @@ void ospm_power_island_down(int islands)
        g_hw_power_status_mask &= ~islands;
 
        if (islands & OSPM_GRAPHICS_ISLAND) {
-               pwr_cnt |= PSB_PWRGT_GFX_MASK;
-               pwr_mask |= PSB_PWRGT_GFX_MASK;
+               if (IS_MDFLD(gpDrmDevice) && dev_priv->platform_rev_id != 
MDFLD_PNW_A0) {
+                       pwr_cnt |= PSB_PWRGT_GFX_MASK_B0;
+                       pwr_mask |= PSB_PWRGT_GFX_MASK_B0;
+               } else {
+                       pwr_cnt |= PSB_PWRGT_GFX_MASK;
+                       pwr_mask |= PSB_PWRGT_GFX_MASK;
+               }
         #ifdef OSPM_STAT
         if (dev_priv->graphics_state == PSB_PWR_STATE_ON) {
             dev_priv->gfx_on_time += (jiffies - 
dev_priv->gfx_last_mode_change) * 1000 / HZ;
@@ -1819,8 +1833,12 @@ void ospm_power_island_down(int islands)
 
                outl(pwr_mask, (dev_priv->ospm_base + PSB_PM_SSC));
 
-               if (IS_MDFLD(gpDrmDevice))
-                       pwr_mask = MDFLD_PWRGT_DISPLAY_STS;
+               if (IS_MDFLD(gpDrmDevice)) {
+                       if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
+                               pwr_mask = MDFLD_PWRGT_DISPLAY_STS_B0;
+                       else
+                               pwr_mask = MDFLD_PWRGT_DISPLAY_STS;
+               }
 
                while (true) {
                        pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
@@ -1868,8 +1886,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
        if (!b_atomic)
                mutex_lock(&g_ospm_mutex);
+#endif
 
        island_is_off = hw_island & (OSPM_ALL_ISLANDS & 
~g_hw_power_status_mask);
 
@@ -1984,8 +2004,10 @@ bool ospm_power_using_hw_begin(int hw_island, bool 
force_on)
                pm_runtime_get(&pdev->dev);
        }
 
+#if 0
        if (!b_atomic)
                mutex_unlock(&g_ospm_mutex);
+#endif
 
        return ret;
 }
diff --git a/drivers/staging/mrst/drv/psb_reg.h 
b/drivers/staging/mrst/drv/psb_reg.h
index fe9f9fb..0c110c2 100644
--- a/drivers/staging/mrst/drv/psb_reg.h
+++ b/drivers/staging/mrst/drv/psb_reg.h
@@ -561,7 +561,6 @@
 #define PSB_APMBA                  0x7a
 #define PSB_APM_CMD                0x0
 #define PSB_APM_STS                0x04
-#define PSB_PWRGT_GFX_MASK         0x3
 #define PSB_PWRGT_VID_ENC_MASK     0x30
 #define PSB_PWRGT_VID_DEC_MASK     0xc
 
@@ -573,9 +572,16 @@
 #define MDFLD_PWRGT_DISPLAY_C_CNTR  0x00030000 
 #define MDFLD_PWRGT_DISP_MIPI_CNTR  0x000c0000 
 #define MDFLD_PWRGT_DISPLAY_CNTR    (MDFLD_PWRGT_DISPLAY_A_CNTR | 
MDFLD_PWRGT_DISPLAY_C_CNTR)// 0x000fc00c 
-#define MDFLD_PWRGT_DISPLAY_A_STS  0x000000c0 
-#define MDFLD_PWRGT_DISPLAY_B_STS  0x00000300 
-#define MDFLD_PWRGT_DISPLAY_C_STS  0x00000c00 
+// Display SSS register bits are different in A0 vs. B0
+#define PSB_PWRGT_GFX_MASK         0x3
+#define MDFLD_PWRGT_DISPLAY_A_STS              0x000000c0
+#define MDFLD_PWRGT_DISPLAY_B_STS              0x00000300
+#define MDFLD_PWRGT_DISPLAY_C_STS              0x00000c00
+#define PSB_PWRGT_GFX_MASK_B0                  0xc3
+#define MDFLD_PWRGT_DISPLAY_A_STS_B0   0x0000000c
+#define MDFLD_PWRGT_DISPLAY_B_STS_B0   0x0000c000
+#define MDFLD_PWRGT_DISPLAY_C_STS_B0   0x00030000
 #define MDFLD_PWRGT_DISP_MIPI_STS  0x000c0000 
 #define MDFLD_PWRGT_DISPLAY_STS    (MDFLD_PWRGT_DISPLAY_A_STS | 
MDFLD_PWRGT_DISPLAY_C_STS)// 0x000fc00c 
+#define MDFLD_PWRGT_DISPLAY_STS_B0    (MDFLD_PWRGT_DISPLAY_A_STS_B0 | 
MDFLD_PWRGT_DISPLAY_C_STS_B0)// 0x000fc00c
 #endif
diff --git a/drivers/staging/mrst/drv/psb_sgx.c 
b/drivers/staging/mrst/drv/psb_sgx.c
index 657593f..befc15f 100644
--- a/drivers/staging/mrst/drv/psb_sgx.c
+++ b/drivers/staging/mrst/drv/psb_sgx.c
@@ -943,3 +943,32 @@ out_err0:
        return ret;
 }
 
+void psb_gl3_global_invalidation(struct drm_device *dev)
+{
+#ifdef CONFIG_MDFD_GL3
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       uint32_t gl3_ctl, gl3_stat, poll_count = 0x1000;
+
+       /* IS there a way to avoid multiple invalidation simultaneously? Maybe 
a ATOM value */
+
+       gl3_ctl = PSB_RVDC32(PSB_GL3_CACHE_CTL);
+       //gl3_ctl = PSB_RVDC32(0xb0000);
+       //printk("GCL_CR_CTL2 is 0x%08x\n", gl3_ctl);
+
+       PSB_WVDC32(gl3_ctl | 0x2, PSB_GL3_CACHE_CTL);
+
+       while(poll_count) {
+               gl3_stat = PSB_RVDC32(PSB_GL3_CACHE_STAT);
+               if(gl3_stat & 0x1) {
+                       PSB_WVDC32(gl3_stat | 0x1, PSB_GL3_CACHE_STAT); /* 
Frome D.Will : write 1 to Inval_done bit to clear it */
+                       //return 0;
+                       return;
+               }
+               cpu_relax();
+               poll_count--;
+       }
+
+       DRM_ERROR("Invalidation GL3 timeout\n");
+       //return -1;
+#endif
+}
diff --git a/drivers/staging/mrst/imgv/pnw_topaz.c 
b/drivers/staging/mrst/imgv/pnw_topaz.c
index 5795bf8..3f884a5 100644
--- a/drivers/staging/mrst/imgv/pnw_topaz.c
+++ b/drivers/staging/mrst/imgv/pnw_topaz.c
@@ -428,6 +428,8 @@ pnw_topaz_send(struct drm_device *dev, void *cmd,
 
        PSB_DEBUG_GENERAL("TOPAZ: send the command in the buffer one by one\n");
 
+       psb_gl3_global_invalidation(dev);
+
        while (cmd_size > 0) {
                cur_cmd_header = (struct topaz_cmd_header *) command;
                cur_cmd_id = cur_cmd_header->id;
diff --git a/drivers/staging/mrst/imgv/psb_msvdx.c 
b/drivers/staging/mrst/imgv/psb_msvdx.c
index ab66e3d..81f27f2 100644
--- a/drivers/staging/mrst/imgv/psb_msvdx.c
+++ b/drivers/staging/mrst/imgv/psb_msvdx.c
@@ -442,6 +442,8 @@ static int psb_msvdx_send(struct drm_device *dev, void *cmd,
        int ret = 0;
        struct drm_psb_private *dev_priv = dev->dev_private;
 
+       psb_gl3_global_invalidation(dev);
+
        while (cmd_size > 0) {
                uint32_t cur_cmd_size = MEMIO_READ_FIELD(cmd, FWRK_GENMSG_SIZE);
                uint32_t cur_cmd_id = MEMIO_READ_FIELD(cmd, FWRK_GENMSG_ID);
diff --git a/drivers/staging/mrst/medfield/Makefile 
b/drivers/staging/mrst/medfield/Makefile
index 2658c22..6d8f753 100644
--- a/drivers/staging/mrst/medfield/Makefile
+++ b/drivers/staging/mrst/medfield/Makefile
@@ -192,6 +192,8 @@ medfield_gfx-y += $(IMGVDIR)/lnc_topaz.medfield.o \
 
 medfield_gfx-$(CONFIG_MDFLD_DSI_DPU) += 
$(DRMDRVDIR)/mdfld_dsi_dbi_dpu.medfield.o
 
+medfield_gfx-$(CONFIG_MDFD_GL3) += $(DRMDRVDIR)/mdfld_gl3.medfield.o
+
 medfield_gfx-y += $(DRMDRVDIR)/psb_powermgmt.medfield.o 
$(DRMDRVDIR)/psb_irq.medfield.o
 
 obj-$(CONFIG_DRM_MDFLD) += medfield_gfx.o
diff --git a/drivers/staging/mrst/moorestown/Makefile 
b/drivers/staging/mrst/moorestown/Makefile
index 6c748d0..ec9ef4a 100644
--- a/drivers/staging/mrst/moorestown/Makefile
+++ b/drivers/staging/mrst/moorestown/Makefile
@@ -171,8 +171,8 @@ mrst_gfx-y += $(DRMDRVDIR)/psb_bl.mrst.o \
           $(DRMDRVDIR)/tpo_cmd.mrst.o \
          $(DRMDRVDIR)/tmd_vid.mrst.o \
           $(DRMDRVDIR)/tpo_vid.mrst.o \
-          $(DRMDRVDIR)/pyr_cmd.mrst.o
-
+          $(DRMDRVDIR)/pyr_cmd.mrst.o \
+          $(DRMDRVDIR)/mdfld_gl3.mrst.o
 
 mrst_gfx-y += $(IMGVDIR)/lnc_topaz.mrst.o \
          $(IMGVDIR)/topaz_power.mrst.o \
diff --git a/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxkick.c 
b/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxkick.c
index 8a229c9..500e86f 100644
--- a/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxkick.c
+++ b/drivers/staging/mrst/pvr/services4/srvkm/devices/sgx/sgxkick.c
@@ -37,6 +37,10 @@
 #include "pvr_debug.h"
 #include "sgxutils.h"
 
+#ifdef CONFIG_MDFD_GL3
+extern void gl3_invalidate(void);
+#endif
+
 IMG_EXPORT
 PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick)
 {
@@ -51,6 +55,11 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK 
*psCCBKick)
                PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset"));
                return PVRSRV_ERROR_INVALID_PARAMS;
        }
+
+#ifdef CONFIG_MDFD_GL3
+       // GL3
+       gl3_invalidate();
+#endif
        
        
        psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, 
psCCBKick, ui32CCBOffset);
@@ -708,6 +717,11 @@ PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, 
SGX_CCB_KICK *psCCBKick)
        }
 #endif
 
+#ifdef CONFIG_MDFD_GL3
+       // GL3
+       gl3_invalidate();
+#endif
+
        return eError;
 }
 
-- 
1.7.1

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

Reply via email to