Merge remote-tracking branch 'origin/omaplfb' into p-ti-android-3.8.y-video
authorPraneeth Bajjuri <praneeth@ti.com>
Fri, 26 Jul 2013 01:52:18 +0000 (20:52 -0500)
committerPraneeth Bajjuri <praneeth@ti.com>
Fri, 26 Jul 2013 01:54:21 +0000 (20:54 -0500)
This contains GC320 series

* origin/omaplfb:
  ARM: OMAP5/DRA7: hwmod: add ADDR_TYPE_RT to bb2d address flags
  gc320: gcx: [WA] Allocate MMU page tables as non cached
  gc320: Added  missing programming of MTLB base second time
  gc320: Increase VRAM buffers to 4
  gc320: adding gcxxx support in Makefiles
  gc320: Adapt GC320 driver for K3.8
  devices: Initialize GC320 as part of devices init
  platform_data: Added platform data for GC320
  gc320: OMAP4: Adding cache-2dmanager

Signed-off-by: Praneeth Bajjuri <praneeth@ti.com>
17 files changed:
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/omap_hwmod_54xx_data.c
arch/arm/mach-omap2/omap_hwmod_7xx_data.c
arch/arm/plat-omap/sgx_omaplfb.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/cache-2dmanager/Kconfig [new file with mode: 0644]
drivers/misc/cache-2dmanager/Makefile [new file with mode: 0644]
drivers/misc/cache-2dmanager/cache-2dmanager.c [new file with mode: 0644]
drivers/misc/gcx/gcbv/gcmain.c
drivers/misc/gcx/gccore/gcmain.c
drivers/misc/gcx/gccore/gcmmu.c
drivers/misc/gcx/gccore/gcqueue.c
drivers/misc/gcx/gcioctl/gcif.c
include/linux/cache-2dmanager.h [new file with mode: 0644]
include/linux/gccore.h
include/linux/platform_data/omap_gcx.h [new file with mode: 0644]

index 2d4f9c02dccf29cae8b5e322f046fed2ca252cb4..a8f1557a225cb0a10c2db77d1f898f06cbad2c65 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/platform_data/omap_ocp2scp.h>
 #include <linux/usb/omap_control_usb.h>
 #include <linux/platform_data/mailbox-omap.h>
+#include <linux/platform_data/omap_gcx.h>
+#include "omap-pm.h"
 
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
@@ -447,6 +449,70 @@ static void __init omap_init_dmic(void)
 static inline void omap_init_dmic(void) {}
 #endif
 
+static int gcxxx_scale_dev(struct device *dev, unsigned long val);
+static int gcxxx_set_l3_bw(struct device *dev, unsigned long val);
+
+static struct omap_gcx_platform_data omap_gcxxx = {
+       .get_context_loss_count = omap_pm_get_dev_context_loss_count,
+       .scale_dev = gcxxx_scale_dev,
+       .set_bw = gcxxx_set_l3_bw,
+};
+
+struct omap_device_pm_latency omap_gcxxx_latency[] = {
+       {
+               .deactivate_func = omap_device_idle_hwmods,
+               .activate_func   = omap_device_enable_hwmods,
+               .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+       }
+};
+
+static int gcxxx_scale_dev(struct device *dev, unsigned long val)
+{
+       /*omap_device_scale(dev, val) is not supported, returning with no-op
+        * for now. */
+       return 0;
+}
+
+static int gcxxx_set_l3_bw(struct device *dev, unsigned long val)
+{
+       return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, val);
+}
+
+int __init gcxxx_init(void)
+{
+       int retval = 0;
+       struct omap_hwmod *oh;
+       struct platform_device *pdev;
+       /*struct omap_device *od;
+       struct device *dev;*/
+       const char *oh_name = "bb2d";
+       const char *dev_name = "gccore";
+
+       /*
+        * Hwmod lookup will fail in case our platform doesn't support the
+        * hardware spinlock module, so it is safe to run this initcall
+        * on all omaps
+        */
+       oh = omap_hwmod_lookup(oh_name);
+       if (oh == NULL)
+               return -EINVAL;
+
+       omap_gcxxx.regbase = omap_hwmod_get_mpu_rt_va(oh);
+       omap_gcxxx.is_hw_present = (soc_is_omap543x()
+                               || soc_is_dra7xx()) ? true : false;
+       pdev = omap_device_build(dev_name, 0, oh, &omap_gcxxx,
+                               sizeof(omap_gcxxx), omap_gcxxx_latency,
+                               ARRAY_SIZE(omap_gcxxx_latency), false);
+       if (IS_ERR(pdev)) {
+               pr_err("Can't build omap_device for %s:%s\n", dev_name,
+                                                               oh_name);
+               retval = PTR_ERR(pdev);
+       }
+
+       return retval;
+}
+
+
 #if defined(CONFIG_SND_OMAP_SOC_ABE) || \
        defined(CONFIG_SND_OMAP_SOC_ABE_MODULE)
 
@@ -683,6 +749,7 @@ static int __init omap2_init_devices(void)
        omap_init_audio();
        omap_init_camera();
        omap_init_mbox();
+       gcxxx_init();
        /* If dtb is there, the devices will be created dynamically */
        if (!of_have_populated_dt()) {
                omap_init_control_usb();
index ee7f4a9a77aaa3820ed3037d3575314aed78dfa2..73c152d17a91fabd2d6bdd95abdef72805c1e945 100644 (file)
@@ -45,6 +45,9 @@
 /* Base offset for all OMAP5 dma requests */
 #define OMAP54XX_DMA_REQ_START 1
 
+/* Backward references (IPs with Bus Master capability) */
+static struct omap_hwmod omap54xx_bb2d_hwmod;
+
 
 /*
  * IP blocks
@@ -339,6 +342,24 @@ static struct omap_hwmod_irq_info omap54xx_bb2d_irqs[] = {
        { .irq = -1 }
 };
 
+static struct omap_hwmod_addr_space omap54xx_bb2d_addrs[] = {
+       {
+               .pa_start       = 0x59000000,
+               .pa_end         = 0x590007ff,
+               .flags      = ADDR_TYPE_RT
+       },
+       { }
+};
+
+/* l3_main_2 -> bb2d */
+static struct omap_hwmod_ocp_if omap54xx_l3_main_2__bb2d = {
+       .master         = &omap54xx_l3_main_2_hwmod,
+       .slave          = &omap54xx_bb2d_hwmod,
+       .clk            = "l3_iclk_div",
+       .addr           = omap54xx_bb2d_addrs,
+       .user           = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod omap54xx_bb2d_hwmod = {
        .name           = "bb2d",
        .class          = &omap54xx_bb2d_hwmod_class,
@@ -3961,13 +3982,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_abe__aess = {
        .user           = OCP_USER_MPU,
 };
 
-/* l3_main_2 -> bb2d */
-static struct omap_hwmod_ocp_if omap54xx_l3_main_2__bb2d = {
-       .master         = &omap54xx_l3_main_2_hwmod,
-       .slave          = &omap54xx_bb2d_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
 
 static struct omap_hwmod_addr_space omap54xx_c2c_addrs[] = {
        {
index e8d09dfbaf6ca88b268ebba23f4a54139b34ae4c..1976fc952c506c39cb29902792f8d55002a7b5ce 100644 (file)
@@ -3801,6 +3801,7 @@ static struct omap_hwmod_addr_space dra7xx_bb2d_addrs[] = {
        {
                .pa_start       = 0x59000000,
                .pa_end         = 0x590007ff,
+               .flags      = ADDR_TYPE_RT
        },
        { }
 };
index efa08a6d691762be27090b3ca37c6882e4f12287..e4cad796c80e580fba61a4f5e4eda1e55134c71a 100644 (file)
 
 static struct sgx_omaplfb_config omaplfb_config[OMAPLFB_NUM_DEV] = {
        {
-       .vram_buffers = 2,
+       .vram_buffers = 4,
        .swap_chain_length = 2,
        },
        {
        .tiler2d_buffers = 0,
-       .vram_buffers = 2,
+       .vram_buffers = 4,
        .swap_chain_length = 2,
        }
 };
index 29818b28925f759a1551e60419853614ff1c3e7f..cd68921b36e4297b3b2c9f445308b6bf9dc3699a 100644 (file)
@@ -509,6 +509,10 @@ source "drivers/misc/cb710/Kconfig"
 source "drivers/misc/ti-st/Kconfig"
 source "drivers/misc/lis3lv02d/Kconfig"
 source "drivers/misc/carma/Kconfig"
+source "drivers/misc/gcx/gccore/Kconfig"
+source "drivers/misc/gcx/gcioctl/Kconfig"
+source "drivers/misc/gcx/gcbv/Kconfig"
+source "drivers/misc/cache-2dmanager/Kconfig"
 source "drivers/misc/altera-stapl/Kconfig"
 source "drivers/misc/mei/Kconfig"
 endmenu
index f547db387dd745ac5440fa1719c71de76352277d..a43854760d2b61e05c42f0a2ddee3f51fe6447e5 100644 (file)
@@ -50,3 +50,7 @@ obj-y                         += carma/
 obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
 obj-$(CONFIG_ALTERA_STAPL)     +=altera-stapl/
 obj-$(CONFIG_INTEL_MEI)                += mei/
+obj-$(CONFIG_GCCORE)           += gcx/gccore/
+obj-$(CONFIG_GCBV)             += gcx/gcbv/
+obj-$(CONFIG_GCIOCTL)          += gcx/gcioctl/
+obj-$(CONFIG_CACHE2DMANAGER)   += cache-2dmanager/
diff --git a/drivers/misc/cache-2dmanager/Kconfig b/drivers/misc/cache-2dmanager/Kconfig
new file mode 100644 (file)
index 0000000..4b74fde
--- /dev/null
@@ -0,0 +1,5 @@
+config CACHE2DMANAGER
+       tristate "2D Cache operation driver"
+       default y
+       help
+           Enable 2D Cache operation support
diff --git a/drivers/misc/cache-2dmanager/Makefile b/drivers/misc/cache-2dmanager/Makefile
new file mode 100644 (file)
index 0000000..c112df1
--- /dev/null
@@ -0,0 +1,4 @@
+obj-$(CONFIG_CACHE2DMANAGER) += cache2d.o
+
+cache2d-y := \
+       cache-2dmanager.o \
diff --git a/drivers/misc/cache-2dmanager/cache-2dmanager.c b/drivers/misc/cache-2dmanager/cache-2dmanager.c
new file mode 100644 (file)
index 0000000..a1f0839
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * cache-2dmanager.c
+ *
+ * Copyright (C) 2011-2012 Texas Instruments Corporation.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <asm/cacheflush.h>
+#include <linux/sched.h>
+#include <linux/cache-2dmanager.h>
+
+static void per_cpu_cache_flush_arm(void *arg)
+{
+       flush_cache_all();
+}
+
+void c2dm_l1cache(int count,           /* number of regions */
+               struct c2dmrgn rgns[],  /* array of regions */
+               int dir)                /* cache operation */
+{
+       unsigned long size = 0;
+       int rgn;
+       for (rgn = 0; rgn < count; rgn++)
+               size += rgns[rgn].span * rgns[rgn].lines;
+
+       /* If the total size of the caller's request exceeds the threshold,
+        * we can perform the operation on the entire cache instead.
+        *
+        * If the caller requests a clean larger than the threshold, we want
+        * to clean all.  But this function does not exist in the L1 cache
+        * routines. So we use flush all.
+        *
+        * If the caller requests an invalidate larger than the threshold, we
+        * want to invalidate all. However, if the client does not fill the
+        * cache, an invalidate all will lose data from other processes, which
+        * can be catastrophic.  So we must clean the entire cache before we
+        * invalidate it. Flush all cleans and invalidates in one operation.
+        */
+       if (size >= L1THRESHOLD) {
+               switch (dir) {
+               case DMA_TO_DEVICE:
+                       /* Use clean all when available */
+                       /* Fall through for now */
+               case DMA_BIDIRECTIONAL:
+                       /* Can't invalidate all without cleaning, so fall
+                        * through to flush all to do both. */
+               case DMA_FROM_DEVICE:
+                       on_each_cpu(per_cpu_cache_flush_arm, NULL, 1);
+                       break;
+               }
+       } else {
+               int rgn;
+               for (rgn = 0; rgn < count; rgn++) {
+                       int line;
+                       char *start = rgns[rgn].start;
+                       for (line = 0; line < rgns[rgn].lines; line++) {
+                               if (dir == DMA_BIDIRECTIONAL)
+                                       cpu_cache.dma_flush_range(
+                                               start,
+                                               start + rgns[rgn].span);
+                               else
+                                       cpu_cache.dma_map_area(
+                                               start,
+                                               rgns[rgn].span,
+                                               dir);
+                               start += rgns[rgn].stride;
+                       }
+               }
+       }
+}
+EXPORT_SYMBOL(c2dm_l1cache);
+
+static u32 virt2phys(u32 usr)
+{
+       pmd_t *pmd;
+       pte_t *ptep;
+       pgd_t *pgd = pgd_offset(current->mm, usr);
+
+       if (pgd_none(*pgd) || pgd_bad(*pgd))
+               return 0;
+
+       pmd = pmd_offset((pud_t *)pgd, usr);
+       if (pmd_none(*pmd) || pmd_bad(*pmd))
+               return 0;
+
+       ptep = pte_offset_map(pmd, usr);
+       if (ptep && pte_present(*ptep))
+               return (*ptep & PAGE_MASK) | (~PAGE_MASK & usr);
+
+       return 0;
+}
+
+void c2dm_l2cache(int count,           /* number of regions */
+               struct c2dmrgn rgns[],  /* array of regions */
+               int dir)                /* cache operation */
+{
+
+       unsigned long size = 0;
+       int rgn;
+
+       for (rgn = 0; rgn < count; rgn++)
+               size += rgns[rgn].span * rgns[rgn].lines;
+
+       if (size >= L2THRESHOLD) {
+               switch (dir) {
+               case DMA_TO_DEVICE:
+                       /* Use clean all when available */
+                       /* Fall through for now */
+               case DMA_BIDIRECTIONAL:
+                       /* Can't invalidate all without cleaning, so fall
+                        * through to flush all to do both. */
+               case DMA_FROM_DEVICE:
+                       outer_flush_all();
+                       break;
+               }
+               return;
+       }
+
+       for (rgn = 0; rgn < count; rgn++) {
+               int i, j;
+               unsigned long linestart, start;
+               unsigned long page_begin, end, offset,
+                       pageremain, lineremain;
+               unsigned long phys, opsize;
+               int page_num;
+
+               /* beginning virtual address of each line */
+               start = (unsigned long)rgns[rgn].start;
+
+               for (i = 0; i < rgns[rgn].lines; i++) {
+
+                       linestart = start + (i * rgns[rgn].stride);
+
+                       /* beginning of the page for the new line */
+                       page_begin = linestart & PAGE_MASK;
+
+                       /* end of the new line */
+                       end = (unsigned long)linestart +
+                               rgns[rgn].span;
+
+                       page_num = DIV_ROUND_UP(
+                               end-page_begin, PAGE_SIZE);
+
+                       /* offset of the new line from page begin */
+                       offset = linestart - page_begin;
+
+                       /* track how long it is to the end of
+                          the current page */
+                       pageremain = PAGE_SIZE - offset;
+
+                       /* keep track of how much of the line remains
+                          to be copied */
+                       lineremain = rgns[rgn].span;
+
+                       for (j = 0; j < page_num; j++) {
+
+                               opsize = (lineremain < pageremain) ?
+                                       lineremain : pageremain;
+
+                               phys = virt2phys(page_begin);
+                               if (phys) {
+                                       phys = phys + offset;
+                                       switch (dir) {
+                                       case DMA_TO_DEVICE:
+                                               outer_clean_range(
+                                                       phys, phys + opsize);
+                                               break;
+                                       case DMA_FROM_DEVICE:
+                                               outer_inv_range(
+                                                       phys, phys + opsize);
+                                               break;
+                                       case DMA_BIDIRECTIONAL:
+                                               outer_flush_range(
+                                                       phys, phys + opsize);
+                                               break;
+                                       }
+                               }
+
+                               lineremain -= opsize;
+                               /* Move to next page */
+                               page_begin += PAGE_SIZE;
+
+                               /* After first page, start address
+                                * will be page aligned so offset
+                                * is 0 */
+                               offset = 0;
+
+                               if (!lineremain)
+                                       break;
+
+                               pageremain -= opsize;
+                               if (!pageremain)
+                                       pageremain = PAGE_SIZE;
+
+                       }
+               }
+       }
+}
+EXPORT_SYMBOL(c2dm_l2cache);
index aa8be6601bab3e8e80d43e6aa1ac22822129ce4a..c9d7e8feb962408aad7de575e117b469832bc94f 100644 (file)
@@ -13,9 +13,6 @@
  */
 
 #include "gcbv.h"
-#include <plat/cpu.h>
-#include <plat/omap_hwmod.h>
-
 
 /*******************************************************************************
  * BLTsville interface exposure.
@@ -244,9 +241,10 @@ static int __init mod_init(void)
 {
        bv_init();
 
-       /* Assign BV function parameters only if SoC contains a GC core */
-       if (cpu_is_omap447x())
+       if (gc_is_hw_present())
                gcbv_assign();
+       else
+               GCERR("gcx hardware is not present\n");
 
        return 0;
 }
index 26939ed0e0ddac5d942cb8021bf0f5ce7ee6c56c..2cc723451ab2f24c2402989166ee5eea52fdd679 100644 (file)
 #include <linux/uaccess.h>
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
-#include <plat/omap_gcx.h>
 #include <linux/opp.h>
 #include <linux/io.h>
-#include <plat/omap_hwmod.h>
-#include <plat/omap-pm.h>
+#include <linux/platform_data/omap_gcx.h>
 #include "gcmain.h"
 
+
+
 #define GCZONE_NONE            0
 #define GCZONE_ALL             (~0U)
 #define GCZONE_INIT            (1 << 0)
@@ -188,11 +188,12 @@ void gc_write_reg(unsigned int address, unsigned int data)
 
 static void gcpwr_enable_clock(struct gccorecontext *gccorecontext)
 {
-       bool ctxlost;
+       int ctxlost;
 
        GCENTER(GCZONE_POWER);
 
        ctxlost = gccorecontext->plat->get_context_loss_count(gccorecontext->device);
+       GCDBG(GCZONE_POWER, "lost count = %d\n", ctxlost);
 
        if (!gccorecontext->clockenabled) {
                /* Enable the clock. */
@@ -217,6 +218,7 @@ static void gcpwr_enable_clock(struct gccorecontext *gccorecontext)
        if (ctxlost || (gccorecontext->gcpower == GCPWR_UNKNOWN))
                gcpwr_reset(gccorecontext);
 
+
        GCEXIT(GCZONE_POWER);
 }
 
@@ -235,6 +237,9 @@ static void gcpwr_disable_clock(struct gccorecontext *gccorecontext)
 
                /* Clock disabled. */
                gccorecontext->clockenabled = false;
+
+               /* Reset the current pipe. */
+               gccorecontext->gcpipe = GCPWR_UNKNOWN;
        }
 
        GCDBG(GCZONE_POWER, "clock %s.\n",
@@ -249,6 +254,9 @@ static void gcpwr_scale(struct gccorecontext *gccorecontext, int index)
 
        GCENTERARG(GCZONE_FREQSCALE, "index=%d\n", index);
 
+       if (gccorecontext->opp_count == 0)
+               goto exit;
+
        if ((index < 0) || (index >= gccorecontext->opp_count)) {
                GCERR("invalid index %d.\n", index);
                goto exit;
@@ -260,6 +268,7 @@ static void gcpwr_scale(struct gccorecontext *gccorecontext, int index)
                goto exit;
        }
 
+
        if (gccorecontext->cur_freq == gccorecontext->opp_freqs[index])
                goto exit;
 
@@ -493,6 +502,13 @@ unsigned int gcpwr_get_speed(void)
  * Public API.
  */
 
+bool gc_is_hw_present(void)
+{
+       struct gccorecontext *gccorecontext = &g_context;
+       return gccorecontext->plat->is_hw_present;
+}
+
+
 void gc_caps(struct gcicaps *gcicaps)
 {
        struct gccorecontext *gccorecontext = &g_context;
@@ -871,22 +887,30 @@ done:
 static int gc_probe(struct platform_device *pdev)
 {
        struct gccorecontext *gccorecontext = &g_context;
+       int ret;
 
        GCENTER(GCZONE_PROBE);
 
        gccorecontext->bb2ddevice = &pdev->dev;
        gccorecontext->plat = (struct omap_gcx_platform_data *)
                               pdev->dev.platform_data;
+
+       if (!gccorecontext->plat->is_hw_present) {
+               GCERR("gc_probe failed. gcx hardware is not present\n");
+               return -ENODEV;
+       }
+
        gccorecontext->regbase = gccorecontext->plat->regbase;
        gccorecontext->irqline = platform_get_irq(pdev, pdev->id);
        gccorecontext->device = &pdev->dev;
 
+
        pm_runtime_enable(gccorecontext->device);
        gccorecontext->plat->get_context_loss_count(gccorecontext->device);
 
        gc_probe_opp(pdev);
 
-       pm_runtime_get_sync(gccorecontext->device);
+       ret = pm_runtime_get_sync(gccorecontext->device);
 
        gccorecontext->gcmodel = gc_read_reg(GC_CHIP_ID_Address);
        gccorecontext->gcrevision = gc_read_reg(GC_CHIP_REV_Address);
@@ -987,12 +1011,6 @@ static int gc_init(struct gccorecontext *gccorecontext)
 
        GCENTER(GCZONE_INIT);
 
-       /* check if hardware is available */
-       if (!cpu_is_omap447x()) {
-               GCDBG(GCZONE_INIT, "gcx hardware is not present\n");
-               goto exit;
-       }
-
        /* Initialize data structutres. */
        GCLOCK_INIT(&gccorecontext->powerlock);
        GCLOCK_INIT(&gccorecontext->resetlock);
@@ -1003,13 +1021,6 @@ static int gc_init(struct gccorecontext *gccorecontext)
        /* Pulse skipping isn't known. */
        gccorecontext->pulseskipping = -1;
 
-       /* Initialize MMU. */
-       if (gcmmu_init(gccorecontext) != GCERR_NONE) {
-               GCERR("failed to initialize MMU.\n");
-               result = -EINVAL;
-               goto fail;
-       }
-
        result = platform_driver_register(&plat_drv);
        if (result < 0) {
                GCERR("failed to register platform driver.\n");
@@ -1017,6 +1028,13 @@ static int gc_init(struct gccorecontext *gccorecontext)
        }
        gccorecontext->platdriver = true;
 
+       /* Initialize MMU. */
+       if (gcmmu_init(gccorecontext) != GCERR_NONE) {
+               GCERR("failed to initialize MMU.\n");
+               result = -EINVAL;
+               goto fail;
+       }
+
 #if CONFIG_HAS_EARLYSUSPEND
        register_early_suspend(&early_suspend_info);
 #endif
@@ -1031,7 +1049,6 @@ static int gc_init(struct gccorecontext *gccorecontext)
        /* Create debugfs entry. */
        gc_debug_init();
 
-exit:
        GCEXIT(GCZONE_INIT);
        return 0;
 
@@ -1046,7 +1063,7 @@ static void gc_exit(struct gccorecontext *gccorecontext)
 {
        GCENTER(GCZONE_INIT);
 
-       if (cpu_is_omap447x()) {
+       if (gc_is_hw_present()) {
                /* Stop command queue thread. */
                gcqueue_stop(gccorecontext);
 
@@ -1094,6 +1111,7 @@ static void __exit gc_exit_wrapper(void)
        GCDBG_EXIT();
 }
 
+
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("www.vivantecorp.com");
 MODULE_AUTHOR("www.ti.com");
index 31a873a09ac1abeb487ee244eec9563f344a05e4..2bfe52d7e0cfd730827827039bb2d31353c21ac8 100644 (file)
@@ -45,6 +45,8 @@ GCDBG_FILTERDEF(mmu, GCZONE_NONE,
                "dumpunmap")
 
 
+#define USE_CACHED_MASTER      0
+#define USE_CACHED_SLAVE       0
 /*******************************************************************************
  * Internal definitions.
  */
@@ -180,7 +182,11 @@ static enum gcerror allocate_slave(struct gcmmucontext *gcmmucontext,
              prealloccount);
 
        /* Allocate slave table pool. */
+#if USE_CACHED_SLAVE
        gcerror = gc_alloc_cached(&block->pages, preallocsize);
+#else
+       gcerror = gc_alloc_noncached(&block->pages, preallocsize);
+#endif
        if (gcerror != GCERR_NONE) {
                GCERR("failed to allocate slave page table\n");
                gcerror = GCERR_SETGRP(gcerror, GCERR_MMU_STLB_ALLOC);
@@ -218,11 +224,16 @@ static enum gcerror allocate_slave(struct gcmmucontext *gcmmucontext,
                        ((unsigned char *) logical + GCMMU_STLB_SIZE);
        }
 
+#if USE_CACHED_MASTER
        /* Flush CPU cache. */
        gc_flush_region(gcmmucontext->master.physical,
                        gcmmucontext->master.logical,
                        index.loc.mtlb * sizeof(unsigned int),
                        prealloccount * sizeof(unsigned int));
+#else
+               mb();
+#endif
+
 
        GCEXIT(GCZONE_MAPPING);
        return GCERR_NONE;
@@ -499,7 +510,11 @@ enum gcerror gcmmu_create_context(struct gccorecontext *gccorecontext,
        gcmmucontext->pid = pid;
 
        /* Allocate MTLB table. */
+#if USE_CACHED_MASTER
        gcerror = gc_alloc_cached(&gcmmucontext->master, GCMMU_MTLB_SIZE);
+#else
+       gcerror = gc_alloc_noncached(&gcmmucontext->master, GCMMU_MTLB_SIZE);
+#endif
        if (gcerror != GCERR_NONE) {
                gcerror = GCERR_SETGRP(gcerror, GCERR_MMU_MTLB_ALLOC);
                goto exit;
@@ -583,14 +598,26 @@ enum gcerror gcmmu_destroy_context(struct gccorecontext *gccorecontext,
 
        /* Free slave tables. */
        while (gcmmucontext->slavealloc != NULL) {
+#if USE_CACHED_SLAVE
                gc_free_cached(&gcmmucontext->slavealloc->pages);
+#else
+               gc_free_noncached(&gcmmucontext->slavealloc->pages);
+#endif
                nextblock = gcmmucontext->slavealloc->next;
                kfree(gcmmucontext->slavealloc);
                gcmmucontext->slavealloc = nextblock;
        }
 
+       /* Reset the master table. */
+       if (gcmmu->master == gcmmucontext->mmuconfig.raw)
+               gcmmu->master = ~0U;
+
        /* Free the master table. */
+#if USE_CACHED_MASTER
        gc_free_cached(&gcmmucontext->master);
+#else
+       gc_free_noncached(&gcmmucontext->master);
+#endif
 
        /* Free arenas. */
        GCLOCK(&gcmmu->lock);
@@ -877,10 +904,14 @@ enum gcerror gcmmu_map(struct gccorecontext *gccorecontext,
                                | GCMMU_STLB_EXCEPTION
                                | GCMMU_STLB_WRITEABLE;
 
+#if USE_CACHED_SLAVE
                /* Flush CPU cache. */
                gc_flush_region(slave->physical, slave->logical,
                                index.loc.stlb * sizeof(unsigned int),
                                allocated * sizeof(unsigned int));
+#else
+               mb();
+#endif
 
                GCDBG(GCZONE_MAPPING, "allocated %d pages at %d.%d\n",
                      allocated, index.loc.mtlb, index.loc.stlb);
@@ -1029,10 +1060,14 @@ enum gcerror gcmmu_unmap(struct gccorecontext *gccorecontext,
                for (i = 0; i < freed; i += 1)
                        *stlblogical++ = GCMMU_STLB_ENTRY_VACANT;
 
+#if USE_CACHED_SLAVE
                /* Flush CPU cache. */
                gc_flush_region(slave->physical, slave->logical,
                                index.loc.stlb * sizeof(unsigned int),
                                freed * sizeof(unsigned int));
+#else
+               mb();
+#endif
 
                /* Advance. */
                slave += 1;
index c5a1921c64e66791b9dd0b461f1952e83a116aea..32e7d9546fa5c43464be40b6140c3deb2df1ad2b 100644 (file)
@@ -772,6 +772,7 @@ static int gccmdthread(void *_gccorecontext)
                                GCSETFIELD(0, GCREG_CMD_BUFFER_CTRL,
                                        PREFETCH, headcmdbuf->count));
 
+                       GCDBG(GCZONE_THREAD, "queue restarted.\n");
                        GCUNLOCK(&gcqueue->queuelock);
                        continue;
                }
@@ -821,6 +822,7 @@ static int gccmdthread(void *_gccorecontext)
                                GCDBG(GCZONE_THREAD,
                                      "current location @ 0x%08X.\n",
                                      dmapc);
+                               GCGPUSTATUS();
                                GCUNLOCK(&gcqueue->queuelock);
                                continue;
                        }
@@ -846,6 +848,7 @@ static int gccmdthread(void *_gccorecontext)
                        if (!list_empty(&gcqueue->queue)) {
                                GCDBG(GCZONE_THREAD,
                                      "aborting shutdown to process events\n");
+                               GCGPUSTATUS();
                                GCUNLOCK(&gcqueue->queuelock);
                                continue;
                        }
index 262522c5084073183f8678bf0e6a7eb3a2629a21..267ada8bab8771150cfe9c1955847cf11a9bb167 100644 (file)
@@ -945,10 +945,12 @@ static struct device *dev_object;
 
 static int dev_open(struct inode *inode, struct file *file)
 {
-       if (cpu_is_omap447x())
+       if (gc_is_hw_present()) {
                return 0;
-       else
-               return -1;
+       } else {
+               GCERR("gcx hardware is not present\n");
+               return -ENODEV;
+       }
 }
 
 static int dev_release(struct inode *inode, struct file *file)
diff --git a/include/linux/cache-2dmanager.h b/include/linux/cache-2dmanager.h
new file mode 100644 (file)
index 0000000..2f452da
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * cache-2dmanager.h
+ *
+ * Copyright (C) 2011-2012 Texas Instruments Corporation.
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef CACHE_2DMANAGER_H_
+#define CACHE_2DMANAGER_H_
+
+#include "slab.h"
+
+#ifdef CONFIG_ARCH_OMAP4
+#define L1CACHE_SIZE 32768
+#define L2CACHE_SIZE 1048576
+
+#define L1THRESHOLD L1CACHE_SIZE
+#define L2THRESHOLD L2CACHE_SIZE
+#else
+#error Cache configuration must be specified.
+#endif
+
+struct c2dmrgn {
+       char *start;    /* addr of upper left of rect */
+       size_t span;    /* bytes to be operated on per line */
+       size_t lines;   /* lines to be operated on */
+       long stride;    /* bytes per line */
+};
+
+/*
+ *     c2dm_l1cache(count, rgns, dir)
+ *
+ *     L1 Cache operations in 2D
+ *
+ *     - count  - number of regions
+ *     - rgns   - array of regions
+ *     - dir    - cache operation direction
+ *
+ */
+void c2dm_l1cache(int count, struct c2dmrgn rgns[], int dir);
+
+/*
+ *     c2dm_l2cache(count, rgns, dir)
+ *
+ *     L2 Cache operations in 2D
+ *
+ *     - count  - number of regions
+ *     - rgns   - array of regions
+ *     - dir    - cache operation direction
+ *
+ */
+void c2dm_l2cache(int count, struct c2dmrgn rgns[], int dir);
+
+
+#endif /* CACHE_2DMANAGER_H_ */
index ce9ed4fb75ee0ef6e7f5caba79930c3187eefa7d..ae64f2f75c6d6218d9244ba786329a16490e32b8 100644 (file)
 #include "sched.h"
 #include "gcioctl.h"
 
+
+/* Hw availability query */
+bool gc_is_hw_present(void);
+
 /* Capability query. */
 void gc_caps(struct gcicaps *gcicaps);
 
diff --git a/include/linux/platform_data/omap_gcx.h b/include/linux/platform_data/omap_gcx.h
new file mode 100644 (file)
index 0000000..82abd8a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  arch/arm/plat-omap/include/plat/omap_gcx.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef OMAP_GCX_H
+#define OMAP_GCX_H
+
+struct omap_gcx_platform_data {
+       bool is_hw_present;
+       void *regbase;
+       /*bool (*was_context_lost)(struct device *dev);*/
+       int (*get_context_loss_count)(struct device *dev);
+       /* device scale */
+       int (*scale_dev)(struct device *dev, unsigned long freq);
+       /* bandwith */
+       int (*set_bw)(struct device *dev, unsigned long v);
+};
+
+#endif