mali/__malidrv_build_info.c
+*.o
+*.cmd
+*.ko
+*.mod.c
+modules.order
+Module.symvers
+.tmp_versions
--- /dev/null
+/*
+ * Copyright (C) 2014-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+* ARM Mali-300/400/450 GPU
+
+Required properties:
+- compatible:
+ At least one of these: "arm,mali-300", "arm,mali-400", "arm,mali-450"
+ Always: "arm,mali-utgard"
+ Mali-450 can also include "arm,mali-400" as it is compatible.
+ - "arm,mali-400", "arm,mali-utgard" for any Mali-400 GPU.
+ - "arm,mali-450", "arm,mali-400", "arm,mali-utgard" for any Mali-450 GPU.
+- reg:
+ Physical base address and length of the GPU's registers.
+- interrupts:
+ - List of all Mali interrupts.
+ - This list must match the number of and the order of entries in
+ interrupt-names.
+- interrupt-names:
+ - IRQPP<X> - Name for PP interrupts.
+ - IRQPPMMU<X> - Name for interrupts from the PP MMU.
+ - IRQPP - Name for the PP broadcast interrupt (Mali-450 only).
+ - IRQGP - Name for the GP interrupt.
+ - IRQGPMMU - Name for the interrupt from the GP MMU.
+ - IRQPMU - Name for the PMU interrupt (If pmu is implemented in HW, it must be contained).
+
+Optional properties:
+- pmu_domain_config:
+ - If the Mali internal PMU is present and the PMU IRQ is specified in
+ interrupt/interrupt-names ("IRQPMU").This contains the mapping of
+ Mali HW units to the PMU power domain.
+ -Mali Dynamic power domain configuration in sequence from 0-11, like:
+ <GP PP0 PP1 PP2 PP3 PP4 PP5 PP6 PP7 L2$0 L2$1 L2$2>.
+- pmu-switch-delay:
+ - Only needed if the power gates are connected to the PMU in a high fanout
+ network. This value is the number of Mali clock cycles it takes to
+ enable the power gates and turn on the power mesh. This value will
+ have no effect if a daisy chain implementation is used.
+
+Platform related properties:
+- clocks: Phandle to clock for Mali utgard device.
+- clock-names: the corresponding names of clock in clocks property.
+- regulator: Phandle to regulator which is power supplier of mali device.
+
+Example for a Mali400_MP1_PMU device:
+
+/ {
+ ...
+
+ gpu@12300000 {
+ compatible = "arm,mali-400", "arm,mali-utgard";
+ reg = <0x12300000 0x30000>;
+ interrupts = <0 55 4>, <0 56 4>, <0 57 4>, <0 58 4>, <0 59 4>;
+ interrupt-names = "IRQGP", "IRQGPMMU", "IRQPP0", "IRQPPMMU0", "IRQPMU";
+
+ pmu_domain_config = <0x1 0x4 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x2 0x0 0x0>;
+ pmu_switch_delay = <0xff>;
+ clocks = <clock 122>, <clock 123>;
+ clock-names = "mali_parent", "mali";
+ vdd_g3d-supply = <regulator_Phandle>;
+ };
+}
--- /dev/null
+#
+# Copyright (C) 2010, 2012-2013, 2015 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained from Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+MALI_DRM_FILE_PREFIX =
+
+# For each arch check: CROSS_COMPILE , KDIR , CFLAGS += -DARCH
+
+ARCH ?= arm
+## @note Should allow overriding of building MALI DRM for non-debug:
+EXTRA_CFLAGS += -DDEBUG
+
+DRM_SYMVERS_FILE = ../drm/Module.symvers
+KBUILD_EXTRA_SYMBOLS = $(KBUILD_EXTMOD)/$(DRM_SYMVERS_FILE)
+
+
+# linux build system integration
+
+ifneq ($(KERNELRELEASE),)
+# Inside the kernel build system
+
+EXTRA_CFLAGS += -I$(KBUILD_EXTMOD) -I$(KBUILD_EXTMOD)/include -I$(KBUILD_EXTMOD)/../drm/include/
+
+SRC += $(MALI_DRM_FILE_PREFIX)mali/mali_drv.c \
+ $(MALI_DRM_FILE_PREFIX)mali/mali_mm.c
+
+# Selecting files to compile by parsing the config file
+
+MODULE:=mali_drm.ko
+
+obj-m := $(MODULE:.ko=.o)
+$(MODULE:.ko=-y) := $(SRC:.c=.o)
+
+else
+# Outside the kernel build system
+
+# Get any user defined KDIR-<names> or maybe even a hardcoded KDIR
+-include KDIR_CONFIGURATION
+
+# Define host system directory
+KDIR-$(shell uname -m):=/lib/modules/$(shell uname -r)/build
+
+ifeq ($(ARCH), arm)
+ # when compiling for ARM we're cross compiling
+ export CROSS_COMPILE ?= arm-none-linux-gnueabi-
+ # default to Virtex5
+ CONFIG ?= pb-virtex5
+else
+ # Compiling for the host
+ CONFIG ?= $(shell uname -m)
+endif
+
+# default cpu to select
+CPU ?= ct11mp
+
+# look up KDIR based om CPU selection
+KDIR ?= $(KDIR-$(CPU))
+ifeq ($(KDIR),)
+$(error No KDIR found for platform $(CPU))
+endif
+
+all:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) modules
+
+kernelrelease:
+ $(MAKE) -C $(KDIR) kernelrelease
+
+clean:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
+
+endif
--- /dev/null
+unifdef-y += drm.h drm_sarea.h
+unifdef-y += i810_drm.h
+unifdef-y += i830_drm.h
+unifdef-y += i915_drm.h
+unifdef-y += mga_drm.h
+unifdef-y += r128_drm.h
+unifdef-y += radeon_drm.h
+unifdef-y += sis_drm.h
+unifdef-y += savage_drm.h
+unifdef-y += via_drm.h
+unifdef-y += mali_drm.h
--- /dev/null
+/*
+ * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_DRM_H__
+#define __MALI_DRM_H__
+
+/* Mali specific ioctls */
+#define NOT_USED_0_3
+#define DRM_MALI_FB_ALLOC 0x04
+#define DRM_MALI_FB_FREE 0x05
+#define NOT_USED_6_12
+#define DRM_MALI_MEM_INIT 0x13
+#define DRM_MALI_MEM_ALLOC 0x14
+#define DRM_MALI_MEM_FREE 0x15
+#define DRM_MALI_FB_INIT 0x16
+
+#define DRM_IOCTL_MALI_FB_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_MALI_FB_ALLOC, drm_mali_mem_t)
+#define DRM_IOCTL_MALI_FB_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_MALI_FB_FREE, drm_mali_mem_t)
+#define DRM_IOCTL_MALI_MEM_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_MALI_MEM_INIT, drm_mali_mem_t)
+#define DRM_IOCTL_MALI_MEM_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_MALI_MEM_ALLOC, drm_mali_mem_t)
+#define DRM_IOCTL_MALI_MEM_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_MALI_MEM_FREE, drm_mali_mem_t)
+#define DRM_IOCTL_MALI_FB_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MALI_FB_INIT, drm_mali_fb_t)
+
+typedef struct
+{
+ int context;
+ unsigned int offset;
+ unsigned int size;
+ unsigned long free;
+} drm_mali_mem_t;
+
+typedef struct
+{
+ unsigned int offset, size;
+} drm_mali_fb_t;
+
+#endif /* __MALI_DRM_H__ */
--- /dev/null
+#
+# Copyright (C) 2010, 2012-2013, 2015 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained from Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#
+# Makefile for the drm device driver. This driver provides support for the
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
+
+ccflags-y = -Iinclude/drm
+mali_drm-y := mali_drv.o mali_mm.o
+
+obj-$(CONFIG_DRM_MALI) += mali_drm.o
+
+
--- /dev/null
+/*
+ * Copyright (C) 2010, 2012-2013, 2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/vermagic.h>
+#include <linux/version.h>
+#include "drmP.h"
+#include "mali_drm.h"
+#include "mali_drv.h"
+
+static struct platform_device *pdev;
+
+static int mali_platform_drm_probe(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static int mali_platform_drm_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static int mali_platform_drm_suspend(struct platform_device *dev, pm_message_t state)
+{
+ return 0;
+}
+
+static int mali_platform_drm_resume(struct platform_device *dev)
+{
+ return 0;
+}
+
+
+static char mali_drm_device_name[] = "mali_drm";
+static struct platform_driver platform_drm_driver =
+{
+ .probe = mali_platform_drm_probe,
+ .remove = mali_platform_drm_remove,
+ .suspend = mali_platform_drm_suspend,
+ .resume = mali_platform_drm_resume,
+ .driver = {
+ .name = mali_drm_device_name,
+ .owner = THIS_MODULE,
+ },
+};
+
+#if 0
+static const struct drm_device_id dock_device_ids[] =
+{
+ {"MALIDRM", 0},
+ {"", 0},
+};
+#endif
+
+static int mali_driver_load(struct drm_device *dev, unsigned long chipset)
+{
+ int ret;
+ unsigned long base, size;
+ drm_mali_private_t *dev_priv;
+ printk(KERN_ERR "DRM: mali_driver_load start\n");
+
+ dev_priv = drm_calloc(1, sizeof(drm_mali_private_t), DRM_MEM_DRIVER);
+
+ if (dev_priv == NULL)
+ {
+ return -ENOMEM;
+ }
+
+ dev->dev_private = (void *)dev_priv;
+
+ if (NULL == dev->platformdev)
+ {
+ dev->platformdev = platform_device_register_simple(mali_drm_device_name, 0, NULL, 0);
+ pdev = dev->platformdev;
+ }
+
+#if 0
+ base = drm_get_resource_start(dev, 1);
+ size = drm_get_resource_len(dev, 1);
+#endif
+ ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
+
+ if (ret)
+ {
+ drm_free(dev_priv, sizeof(dev_priv), DRM_MEM_DRIVER);
+ }
+
+ //if ( ret ) kfree( dev_priv );
+
+ printk(KERN_ERR "DRM: mali_driver_load done\n");
+
+ return ret;
+}
+
+static int mali_driver_unload(struct drm_device *dev)
+{
+ drm_mali_private_t *dev_priv = dev->dev_private;
+ printk(KERN_ERR "DRM: mali_driver_unload start\n");
+
+ drm_sman_takedown(&dev_priv->sman);
+ drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+ //kfree( dev_priv );
+ printk(KERN_ERR "DRM: mali_driver_unload done\n");
+
+ return 0;
+}
+
+static struct drm_driver driver =
+{
+ .driver_features = DRIVER_USE_PLATFORM_DEVICE,
+ .load = mali_driver_load,
+ .unload = mali_driver_unload,
+ .context_dtor = NULL,
+ .dma_quiescent = mali_idle,
+ .reclaim_buffers = NULL,
+ .reclaim_buffers_idlelocked = mali_reclaim_buffers_locked,
+ .lastclose = mali_lastclose,
+ .get_map_ofs = drm_core_get_map_ofs,
+ .get_reg_ofs = drm_core_get_reg_ofs,
+ .ioctls = mali_ioctls,
+ .fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)
+ .ioctl = drm_ioctl,
+#else
+ .unlocked_ioctl = drm_ioctl,
+#endif
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ },
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESC,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+ .patchlevel = DRIVER_PATCHLEVEL,
+};
+
+static int __init mali_init(void)
+{
+ driver.num_ioctls = mali_max_ioctl;
+ return drm_init(&driver);
+}
+
+static void __exit mali_exit(void)
+{
+ platform_device_unregister(pdev);
+ drm_exit(&driver);
+}
+
+module_init(mali_init);
+module_exit(mali_exit);
+
+MODULE_INFO(vermagic, VERMAGIC_STRING);
+MODULE_AUTHOR("ARM Ltd.");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
--- /dev/null
+/*
+ * Copyright (C) 2010, 2012-2013, 2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _MALI_DRV_H_
+#define _MALI_DRV_H_
+
+#define DRIVER_AUTHOR "ARM"
+#define DRIVER_NAME "mali_drm"
+#define DRIVER_DESC "DRM module for Mali-200, Mali-400"
+#define DRIVER_DATE "20100520"
+#define DRIVER_MAJOR 0
+#define DRIVER_MINOR 1
+#define DRIVER_PATCHLEVEL 0
+
+#include "drm_sman.h"
+
+typedef struct drm_mali_private
+{
+ drm_local_map_t *mmio;
+ unsigned int idle_fault;
+ struct drm_sman sman;
+ int vram_initialized;
+ unsigned long vram_offset;
+} drm_mali_private_t;
+
+extern int mali_idle(struct drm_device *dev);
+extern void mali_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv);
+extern void mali_lastclose(struct drm_device *dev);
+extern struct drm_ioctl_desc mali_ioctls[];
+extern int mali_max_ioctl;
+
+#endif /* _MALI_DRV_H_ */
--- /dev/null
+/*
+ * Copyright (C) 2010, 2012-2013, 2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "drmP.h"
+#include "mali_drm.h"
+#include "mali_drv.h"
+
+#define VIDEO_TYPE 0
+#define MEM_TYPE 1
+
+#define MALI_MM_ALIGN_SHIFT 4
+#define MALI_MM_ALIGN_MASK ( (1 << MALI_MM_ALIGN_SHIFT) - 1)
+
+
+static void *mali_sman_mm_allocate(void *private, unsigned long size, unsigned alignment)
+{
+ printk(KERN_ERR "DRM: %s\n", __func__);
+ return NULL;
+}
+
+static void mali_sman_mm_free(void *private, void *ref)
+{
+ printk(KERN_ERR "DRM: %s\n", __func__);
+}
+
+static void mali_sman_mm_destroy(void *private)
+{
+ printk(KERN_ERR "DRM: %s\n", __func__);
+}
+
+static unsigned long mali_sman_mm_offset(void *private, void *ref)
+{
+ printk(KERN_ERR "DRM: %s\n", __func__);
+ return ~((unsigned long)ref);
+}
+
+static int mali_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ drm_mali_private_t *dev_priv = dev->dev_private;
+ drm_mali_fb_t *fb = data;
+ int ret;
+ printk(KERN_ERR "DRM: %s\n", __func__);
+
+ mutex_lock(&dev->struct_mutex);
+ {
+ struct drm_sman_mm sman_mm;
+ sman_mm.private = (void *)0xFFFFFFFF;
+ sman_mm.allocate = mali_sman_mm_allocate;
+ sman_mm.free = mali_sman_mm_free;
+ sman_mm.destroy = mali_sman_mm_destroy;
+ sman_mm.offset = mali_sman_mm_offset;
+ ret = drm_sman_set_manager(&dev_priv->sman, VIDEO_TYPE, &sman_mm);
+ }
+
+ if (ret)
+ {
+ DRM_ERROR("VRAM memory manager initialisation error\n");
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+
+ dev_priv->vram_initialized = 1;
+ dev_priv->vram_offset = fb->offset;
+
+ mutex_unlock(&dev->struct_mutex);
+ DRM_DEBUG("offset = %u, size = %u\n", fb->offset, fb->size);
+
+ return 0;
+}
+
+static int mali_drm_alloc(struct drm_device *dev, struct drm_file *file_priv, void *data, int pool)
+{
+ drm_mali_private_t *dev_priv = dev->dev_private;
+ drm_mali_mem_t *mem = data;
+ int retval = 0;
+ struct drm_memblock_item *item;
+ printk(KERN_ERR "DRM: %s\n", __func__);
+
+ mutex_lock(&dev->struct_mutex);
+
+ if (0 == dev_priv->vram_initialized)
+ {
+ DRM_ERROR("Attempt to allocate from uninitialized memory manager.\n");
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
+ }
+
+ mem->size = (mem->size + MALI_MM_ALIGN_MASK) >> MALI_MM_ALIGN_SHIFT;
+ item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0,
+ (unsigned long)file_priv);
+
+ mutex_unlock(&dev->struct_mutex);
+
+ if (item)
+ {
+ mem->offset = dev_priv->vram_offset + (item->mm->offset(item->mm, item->mm_info) << MALI_MM_ALIGN_SHIFT);
+ mem->free = item->user_hash.key;
+ mem->size = mem->size << MALI_MM_ALIGN_SHIFT;
+ }
+ else
+ {
+ mem->offset = 0;
+ mem->size = 0;
+ mem->free = 0;
+ retval = -ENOMEM;
+ }
+
+ DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem->size, mem->offset);
+
+ return retval;
+}
+
+static int mali_drm_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ drm_mali_private_t *dev_priv = dev->dev_private;
+ drm_mali_mem_t *mem = data;
+ int ret;
+ printk(KERN_ERR "DRM: %s\n", __func__);
+
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_sman_free_key(&dev_priv->sman, mem->free);
+ mutex_unlock(&dev->struct_mutex);
+ DRM_DEBUG("free = 0x%lx\n", mem->free);
+
+ return ret;
+}
+
+static int mali_fb_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ printk(KERN_ERR "DRM: %s\n", __func__);
+ return mali_drm_alloc(dev, file_priv, data, VIDEO_TYPE);
+}
+
+static int mali_ioctl_mem_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
+{
+ drm_mali_private_t *dev_priv = dev->dev_private;
+ drm_mali_mem_t *mem = data;
+ int ret;
+ dev_priv = dev->dev_private;
+ printk(KERN_ERR "DRM: %s\n", __func__);
+
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_sman_set_range(&dev_priv->sman, MEM_TYPE, 0, mem->size >> MALI_MM_ALIGN_SHIFT);
+
+ if (ret)
+ {
+ DRM_ERROR("MEM memory manager initialisation error\n");
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
+static int mali_ioctl_mem_alloc(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+
+ printk(KERN_ERR "DRM: %s\n", __func__);
+ return mali_drm_alloc(dev, file_priv, data, MEM_TYPE);
+}
+
+static drm_local_map_t *mem_reg_init(struct drm_device *dev)
+{
+ struct drm_map_list *entry;
+ drm_local_map_t *map;
+ printk(KERN_ERR "DRM: %s\n", __func__);
+
+ list_for_each_entry(entry, &dev->maplist, head)
+ {
+ map = entry->map;
+
+ if (!map)
+ {
+ continue;
+ }
+
+ if (map->type == _DRM_REGISTERS)
+ {
+ return map;
+ }
+ }
+ return NULL;
+}
+
+int mali_idle(struct drm_device *dev)
+{
+ drm_mali_private_t *dev_priv = dev->dev_private;
+ uint32_t idle_reg;
+ unsigned long end;
+ int i;
+ printk(KERN_ERR "DRM: %s\n", __func__);
+
+ if (dev_priv->idle_fault)
+ {
+ return 0;
+ }
+
+ return 0;
+}
+
+
+void mali_lastclose(struct drm_device *dev)
+{
+ drm_mali_private_t *dev_priv = dev->dev_private;
+ printk(KERN_ERR "DRM: %s\n", __func__);
+
+ if (!dev_priv)
+ {
+ return;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+ drm_sman_cleanup(&dev_priv->sman);
+ dev_priv->vram_initialized = 0;
+ dev_priv->mmio = NULL;
+ mutex_unlock(&dev->struct_mutex);
+}
+
+void mali_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv)
+{
+ drm_mali_private_t *dev_priv = dev->dev_private;
+ printk(KERN_ERR "DRM: %s\n", __func__);
+
+ mutex_lock(&dev->struct_mutex);
+
+ if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv))
+ {
+ mutex_unlock(&dev->struct_mutex);
+ return;
+ }
+
+ if (dev->driver->dma_quiescent)
+ {
+ dev->driver->dma_quiescent(dev);
+ }
+
+ drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv);
+ mutex_unlock(&dev->struct_mutex);
+ return;
+}
+
+struct drm_ioctl_desc mali_ioctls[] =
+{
+ DRM_IOCTL_DEF(DRM_MALI_FB_ALLOC, mali_fb_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MALI_FB_FREE, mali_drm_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MALI_MEM_INIT, mali_ioctl_mem_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_MALI_MEM_ALLOC, mali_ioctl_mem_alloc, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MALI_MEM_FREE, mali_drm_free, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_MALI_FB_INIT, mali_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
+};
+
+int mali_max_ioctl = DRM_ARRAY_SIZE(mali_ioctls);
--- /dev/null
+How to build:
+KDIR=/work/kernel-2.6.35.7 make
+
+How to install:
+insmod drm/drm.ko
+insmod mali_drm/mali_drm.ko
+insmod trunk/src/devicedrv/mali/mali.ko
+
mali-y += linux/mali_memory_external.o
mali-y += linux/mali_memory_block_alloc.o
+mali-y += \
+ linux/mali_memory_manager.o \
+ linux/mali_memory_virtual.o \
+ linux/mali_memory_util.o
mali-y += \
linux/mali_ukk_mem.o \
linux/mali_ukk_gp.o \
mali-y += \
common/mali_kernel_core.o \
linux/mali_kernel_linux.o \
- common/mali_kernel_descriptor_mapping.o \
common/mali_session.o \
linux/mali_device_pause_resume.o \
common/mali_kernel_vsync.o \
mali-$(CONFIG_ARCH_MESONG9TV) += \
platform/meson_m450/platform_m8.o
+
+mali-$(CONFIG_ARCH_MESONG9BB) += \
+ platform/meson_m450/platform_m8b.o
endif
##################### end Kasin Added. ###################
menu "Mali GPU OpenGL device driver"
config MALI400
tristate "Mali-300/400/450 support"
- depends on ARM
+ depends on ARM || ARM64
default m
select DMA_SHARED_BUFFER
---help---
config MALI_DT
bool "Using device tree to initialize module"
- depends on MALI400 && CONFIG_OF
+ depends on MALI400 && OF
default n
---help---
This enable the Mali driver to choose the device tree path to get platform resoures
#
-# Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+# Copyright (C) 2010-2015 ARM Limited. All rights reserved.
#
# This program is free software and is provided to you under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2012, 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
if (mali_utilization_enabled()) {
struct mali_gpu_utilization_data *util_data = NULL;
u64 time_period = 0;
+ mali_bool need_add_timer = MALI_TRUE;
/* Calculate gpu utilization */
- util_data = mali_utilization_calculate(&period_start_time, &time_period);
+ util_data = mali_utilization_calculate(&period_start_time, &time_period, &need_add_timer);
if (util_data) {
#if defined(CONFIG_MALI_DVFS)
#else
mali_utilization_platform_realize(util_data);
#endif
- }
- if (MALI_TRUE == timer_running) {
- mali_control_timer_add(mali_control_timeout);
+ if (MALI_TRUE == need_add_timer) {
+ mali_control_timer_add(mali_control_timeout);
+ }
}
}
}
mali_bool mali_control_timer_resume(u64 time_now)
{
+ mali_utilization_data_assert_locked();
+
if (timer_running != MALI_TRUE) {
timer_running = MALI_TRUE;
return MALI_FALSE;
}
+void mali_control_timer_pause(void)
+{
+ mali_utilization_data_assert_locked();
+ if (timer_running == MALI_TRUE) {
+ timer_running = MALI_FALSE;
+ }
+}
+
void mali_control_timer_suspend(mali_bool suspend)
{
mali_utilization_data_lock();
/*
- * Copyright (C) 2010-2012, 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
mali_bool mali_control_timer_resume(u64 time_now);
void mali_control_timer_suspend(mali_bool suspend);
+void mali_control_timer_pause(void);
void mali_control_timer_add(u32 timeout);
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2012, 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2012, 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
MALI_DEBUG_PRINT(3, ("Executor: powering down %u groups\n", num_groups));
for (i = 0; i < num_groups; i++) {
- /* Groups must be either disabled or inactive */
+ /* Groups must be either disabled or inactive. while for virtual group,
+ * it maybe in empty state, because when we meet pm_runtime_suspend,
+ * virtual group could be powered off, and before we acquire mali_executor_lock,
+ * we must release mali_pm_state_lock, if there is a new physical job was queued,
+ * all of physical groups in virtual group could be pulled out, so we only can
+ * powered down an empty virtual group. Those physical groups will be powered
+ * up in following pm_runtime_resume callback function.
+ */
MALI_DEBUG_ASSERT(mali_executor_group_is_in_state(groups[i],
EXEC_STATE_DISABLED) ||
mali_executor_group_is_in_state(groups[i],
- EXEC_STATE_INACTIVE));
+ EXEC_STATE_INACTIVE) ||
+ mali_executor_group_is_in_state(groups[i],
+ EXEC_STATE_EMPTY));
MALI_DEBUG_PRINT(3, ("Executor: powering down group %s\n",
mali_group_core_description(groups[i])));
MALI_DEBUG_ASSERT_POINTER(job);
MALI_DEBUG_ASSERT(sub_job <= MALI_MAX_NUMBER_OF_PHYSICAL_PP_GROUPS);
-
+
/* Put job + group on list of jobs to start later on */
groups_to_start[num_jobs_to_start] = group;
}
}
- /* 3. Activate virtual group, if needed */
+
+ /* 3. Deactivate idle pp group , must put deactive here before active vitual group
+ * for cover case first only has physical job in normal queue but group inactive,
+ * so delay the job start go to active group, when group activated,
+ * call scheduler again, but now if we get high queue virtual job,
+ * we will do nothing in schedule cause executor schedule stop
+ */
+
+ if (MALI_TRUE == mali_executor_deactivate_list_idle(deactivate_idle_group
+ && (!mali_timeline_has_physical_pp_job()))) {
+ trigger_pm_update = MALI_TRUE;
+ }
+
+ /* 4. Activate virtual group, if needed */
if (EXEC_STATE_INACTIVE == virtual_group_state &&
0 < mali_scheduler_job_next_is_virtual()) {
}
}
- /* 4. To power up group asap, we trigger pm update here. */
+ /* 5. To power up group asap, we trigger pm update here. */
if (MALI_TRUE == trigger_pm_update) {
trigger_pm_update = MALI_FALSE;
mali_pm_update_async();
}
- /* 5. Deactivate idle pp group */
-
- if (MALI_TRUE == mali_executor_deactivate_list_idle(deactivate_idle_group
- && (!mali_timeline_has_physical_pp_job()))) {
- trigger_pm_update = MALI_TRUE;
- }
-
/* 6. Assign jobs to idle virtual group (or deactivate if no job) */
if (EXEC_STATE_IDLE == virtual_group_state) {
{
int current_core_scaling_mask[MALI_MAX_NUMBER_OF_DOMAINS] = { 0 };
int target_core_scaling_mask[MALI_MAX_NUMBER_OF_DOMAINS] = { 0 };
- mali_bool update_global_core_scaling_mask = MALI_FALSE;
int i;
MALI_DEBUG_ASSERT(0 < target_core_nr);
struct mali_pm_domain *domain;
if (num_physical_pp_cores_enabled >= target_core_nr) {
- update_global_core_scaling_mask = MALI_TRUE;
break;
}
* Here, we may still have some pp cores not been enabled because of some
* pp cores need to be disabled are still in working state.
*/
- if (update_global_core_scaling_mask) {
- for (i = 0; i < MALI_MAX_NUMBER_OF_DOMAINS; i++) {
- if (0 < target_core_scaling_mask[i]) {
- core_scaling_delay_up_mask[i] = target_core_scaling_mask[i];
- }
+ for (i = 0; i < MALI_MAX_NUMBER_OF_DOMAINS; i++) {
+ if (0 < target_core_scaling_mask[i]) {
+ core_scaling_delay_up_mask[i] = target_core_scaling_mask[i];
}
}
/*
- * Copyright (C) 2012, 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012, 2014-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
MALI_STATIC_INLINE enum mali_interrupt_result mali_gp_get_interrupt_result(struct mali_gp_core *core)
{
u32 stat_used = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT) &
- MALIGP2_REG_VAL_IRQ_MASK_USED;
+ MALIGP2_REG_VAL_IRQ_MASK_USED;
if (0 == stat_used) {
return MALI_INTERRUPT_RESULT_NONE;
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
- *
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ *
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
malifix_set_mmu_int_process_state(1, MMU_INT_NONE);
}
}
-#endif
+#endif
}
_mali_osk_errcode_t mali_group_upper_half_gp(void *data)
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
}
if (MALI_SHARED_MEMORY_DEFAULT_SIZE == mali_shared_mem_size &&
- 0 != data.shared_mem_size) {
+ 0 != data.shared_mem_size) {
mali_shared_mem_size = data.shared_mem_size;
}
}
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+++ /dev/null
-/*
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "mali_kernel_common.h"
-#include "mali_kernel_descriptor_mapping.h"
-#include "mali_osk.h"
-#include "mali_osk_bitops.h"
-#include "mali_memory_types.h"
-#include "mali_session.h"
-
-#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1))
-
-/**
- * Allocate a descriptor table capable of holding 'count' mappings
- * @param count Number of mappings in the table
- * @return Pointer to a new table, NULL on error
- */
-static mali_descriptor_table *descriptor_table_alloc(int count);
-
-/**
- * Free a descriptor table
- * @param table The table to free
- */
-static void descriptor_table_free(mali_descriptor_table *table);
-
-mali_descriptor_mapping *mali_descriptor_mapping_create(int init_entries, int max_entries)
-{
- mali_descriptor_mapping *map = _mali_osk_calloc(1, sizeof(mali_descriptor_mapping));
-
- init_entries = MALI_PAD_INT(init_entries);
- max_entries = MALI_PAD_INT(max_entries);
-
- if (NULL != map) {
- map->table = descriptor_table_alloc(init_entries);
- if (NULL != map->table) {
- map->lock = _mali_osk_mutex_rw_init(_MALI_OSK_LOCKFLAG_ORDERED, _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP);
- if (NULL != map->lock) {
- _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */
- map->max_nr_mappings_allowed = max_entries;
- map->current_nr_mappings = init_entries;
- return map;
- }
- descriptor_table_free(map->table);
- }
- _mali_osk_free(map);
- }
- return NULL;
-}
-
-void mali_descriptor_mapping_destroy(mali_descriptor_mapping *map)
-{
- descriptor_table_free(map->table);
- _mali_osk_mutex_rw_term(map->lock);
- _mali_osk_free(map);
-}
-
-_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping *map, void *target, int *odescriptor)
-{
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
- int new_descriptor;
- mali_mem_allocation *descriptor;
- struct mali_session_data *session;
-
- MALI_DEBUG_ASSERT_POINTER(map);
- MALI_DEBUG_ASSERT_POINTER(odescriptor);
- MALI_DEBUG_ASSERT_POINTER(target);
-
- _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
- new_descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
- if (new_descriptor == map->current_nr_mappings) {
- /* no free descriptor, try to expand the table */
- mali_descriptor_table *new_table, * old_table;
- if (map->current_nr_mappings >= map->max_nr_mappings_allowed) goto unlock_and_exit;
-
- map->current_nr_mappings += BITS_PER_LONG;
- new_table = descriptor_table_alloc(map->current_nr_mappings);
- if (NULL == new_table) goto unlock_and_exit;
-
- old_table = map->table;
- _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
- _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void *));
- map->table = new_table;
- descriptor_table_free(old_table);
- }
-
- /* we have found a valid descriptor, set the value and usage bit */
- _mali_osk_set_nonatomic_bit(new_descriptor, map->table->usage);
- map->table->mappings[new_descriptor] = target;
- *odescriptor = new_descriptor;
-
- /* To calculate the mali mem usage for the session */
- descriptor = (mali_mem_allocation *)target;
- session = descriptor->session;
-
- MALI_DEBUG_ASSERT_POINTER(session);
-
- session->mali_mem_array[descriptor->type] += descriptor->size;
- if ((MALI_MEM_OS == descriptor->type || MALI_MEM_BLOCK == descriptor->type) &&
- (session->mali_mem_array[MALI_MEM_OS] + session->mali_mem_array[MALI_MEM_BLOCK] > session->max_mali_mem_allocated)) {
- session->max_mali_mem_allocated = session->mali_mem_array[MALI_MEM_OS] + session->mali_mem_array[MALI_MEM_BLOCK];
- }
- err = _MALI_OSK_ERR_OK;
-
-unlock_and_exit:
- _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_ERROR(err);
-}
-
-void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping *map, void (*callback)(int, void *))
-{
- int i;
-
- MALI_DEBUG_ASSERT_POINTER(map);
- MALI_DEBUG_ASSERT_POINTER(callback);
-
- _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
- /* id 0 is skipped as it's an reserved ID not mapping to anything */
- for (i = 1; i < map->current_nr_mappings; ++i) {
- if (_mali_osk_test_bit(i, map->table->usage)) {
- callback(i, map->table->mappings[i]);
- }
- }
- _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
-}
-
-_mali_osk_errcode_t mali_descriptor_mapping_get(mali_descriptor_mapping *map, int descriptor, void **target)
-{
- _mali_osk_errcode_t result = _MALI_OSK_ERR_FAULT;
- MALI_DEBUG_ASSERT_POINTER(map);
- _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
- if ((descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage)) {
- *target = map->table->mappings[descriptor];
- result = _MALI_OSK_ERR_OK;
- } else *target = NULL;
- _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
- MALI_ERROR(result);
-}
-
-_mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping *map, int descriptor, void *target)
-{
- _mali_osk_errcode_t result = _MALI_OSK_ERR_FAULT;
- _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
- if ((descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage)) {
- map->table->mappings[descriptor] = target;
- result = _MALI_OSK_ERR_OK;
- }
- _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
- MALI_ERROR(result);
-}
-
-void *mali_descriptor_mapping_free(mali_descriptor_mapping *map, int descriptor)
-{
- void *old_value = NULL;
- mali_mem_allocation *tmp_descriptor;
- struct mali_session_data *session;
-
- _mali_osk_mutex_rw_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
- if ((descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage)) {
- old_value = map->table->mappings[descriptor];
- map->table->mappings[descriptor] = NULL;
- _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
- }
- if (NULL != old_value) {
- tmp_descriptor = (mali_mem_allocation *)old_value;
- session = tmp_descriptor->session;
-
- MALI_DEBUG_ASSERT_POINTER(session);
-
- MALI_DEBUG_ASSERT(session->mali_mem_array[tmp_descriptor->type] >= tmp_descriptor->size);
-
- session->mali_mem_array[tmp_descriptor->type] -= tmp_descriptor->size;
- }
- _mali_osk_mutex_rw_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
-
- return old_value;
-}
-
-static mali_descriptor_table *descriptor_table_alloc(int count)
-{
- mali_descriptor_table *table;
-
- table = _mali_osk_calloc(1, sizeof(mali_descriptor_table) + ((sizeof(unsigned long) * count) / BITS_PER_LONG) + (sizeof(void *) * count));
-
- if (NULL != table) {
- table->usage = (u32 *)((u8 *)table + sizeof(mali_descriptor_table));
- table->mappings = (void **)((u8 *)table + sizeof(mali_descriptor_table) + ((sizeof(unsigned long) * count) / BITS_PER_LONG));
- }
-
- return table;
-}
-
-static void descriptor_table_free(mali_descriptor_table *table)
-{
- _mali_osk_free(table);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
- *
- * This program is free software and is provided to you under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
- * A copy of the licence is included with the program, and can also be obtained from Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/**
- * @file mali_kernel_descriptor_mapping.h
- */
-
-#ifndef __MALI_KERNEL_DESCRIPTOR_MAPPING_H__
-#define __MALI_KERNEL_DESCRIPTOR_MAPPING_H__
-
-#include "mali_osk.h"
-
-struct mali_session_data;
-
-/**
- * The actual descriptor mapping table, never directly accessed by clients
- */
-typedef struct mali_descriptor_table {
- u32 *usage; /**< Pointer to bitpattern indicating if a descriptor is valid/used or not */
- void **mappings; /**< Array of the pointers the descriptors map to */
-} mali_descriptor_table;
-
-/**
- * The descriptor mapping object
- * Provides a separate namespace where we can map an integer to a pointer
- */
-typedef struct mali_descriptor_mapping {
- _mali_osk_mutex_rw_t *lock; /**< Lock protecting access to the mapping object */
- int max_nr_mappings_allowed; /**< Max number of mappings to support in this namespace */
- int current_nr_mappings; /**< Current number of possible mappings */
- mali_descriptor_table *table; /**< Pointer to the current mapping table */
-} mali_descriptor_mapping;
-
-/**
- * Create a descriptor mapping object
- * Create a descriptor mapping capable of holding init_entries growable to max_entries
- * @param init_entries Number of entries to preallocate memory for
- * @param max_entries Number of entries to max support
- * @return Pointer to a descriptor mapping object, NULL on failure
- */
-mali_descriptor_mapping *mali_descriptor_mapping_create(int init_entries, int max_entries);
-
-/**
- * Destroy a descriptor mapping object
- * @param map The map to free
- */
-void mali_descriptor_mapping_destroy(mali_descriptor_mapping *map);
-
-/**
- * Allocate a new mapping entry (descriptor ID)
- * Allocates a new entry in the map.
- * @param map The map to allocate a new entry in
- * @param target The value to map to
- * @return The descriptor allocated, a negative value on error
- */
-_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping *map, void *target, int *descriptor);
-
-/**
- * Get the value mapped to by a descriptor ID
- * @param map The map to lookup the descriptor id in
- * @param descriptor The descriptor ID to lookup
- * @param target Pointer to a pointer which will receive the stored value
- * @return 0 on successful lookup, negative on error
- */
-_mali_osk_errcode_t mali_descriptor_mapping_get(mali_descriptor_mapping *map, int descriptor, void **target);
-
-/**
- * Set the value mapped to by a descriptor ID
- * @param map The map to lookup the descriptor id in
- * @param descriptor The descriptor ID to lookup
- * @param target Pointer to replace the current value with
- * @return 0 on successful lookup, negative on error
- */
-_mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping *map, int descriptor, void *target);
-
-/**
- * Call the specified callback function for each descriptor in map.
- * Entire function is mutex protected.
- * @param map The map to do callbacks for
- * @param callback A callback function which will be calle for each entry in map
- */
-void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping *map, void (*callback)(int, void *));
-
-/**
- * Free the descriptor ID
- * For the descriptor to be reused it has to be freed
- * @param map The map to free the descriptor from
- * @param descriptor The descriptor ID to free
- *
- * @return old value of descriptor mapping
- */
-void *mali_descriptor_mapping_free(mali_descriptor_mapping *map, int descriptor);
-
-#endif /* __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ */
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
static u32 mali_control_first_timeout = 100;
static struct mali_gpu_utilization_data mali_util_data = {0, };
-struct mali_gpu_utilization_data *mali_utilization_calculate(u64 *start_time, u64 *time_period)
+struct mali_gpu_utilization_data *mali_utilization_calculate(u64 *start_time, u64 *time_period, mali_bool *need_add_timer)
{
u64 time_now;
u32 leading_zeroes;
*time_period = time_now - *start_time;
if (accumulated_work_time_gpu == 0 && work_start_time_gpu == 0) {
+ mali_control_timer_pause();
/*
* No work done for this period
* - No need to reschedule timer
mali_utilization_data_unlock();
- /* Stop add timer until the next job submited */
- mali_control_timer_suspend(MALI_FALSE);
+ *need_add_timer = MALI_FALSE;
mali_executor_hint_disable(MALI_EXECUTOR_HINT_GP_BOUND);
mali_utilization_data_unlock();
+ *need_add_timer = MALI_TRUE;
+
MALI_DEBUG_PRINT(4, ("last_utilization_gpu = %d \n", last_utilization_gpu));
MALI_DEBUG_PRINT(4, ("last_utilization_gp = %d \n", last_utilization_gp));
MALI_DEBUG_PRINT(4, ("last_utilization_pp = %d \n", last_utilization_pp));
_mali_osk_spinlock_irq_unlock(utilization_data_lock);
}
+void mali_utilization_data_assert_locked(void)
+{
+ MALI_DEBUG_ASSERT_LOCK_HELD(utilization_data_lock);
+}
+
u32 _mali_ukk_utilization_gp_pp(void)
{
return last_utilization_gpu;
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/**
* Should be called to calcution the GPU utilization
*/
-struct mali_gpu_utilization_data *mali_utilization_calculate(u64 *start_time, u64 *time_period);
+struct mali_gpu_utilization_data *mali_utilization_calculate(u64 *start_time, u64 *time_period, mali_bool *need_add_timer);
_mali_osk_spinlock_irq_t *mali_utilization_get_lock(void);
void mali_utilization_data_unlock(void);
+void mali_utilization_data_assert_locked(void);
+
void mali_utilization_reset(void);
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#define MALI400_L2_MAX_READS_NOT_SET -1
static struct mali_l2_cache_core *
- mali_global_l2s[MALI_MAX_NUMBER_OF_L2_CACHE_CORES] = { NULL, };
+ mali_global_l2s[MALI_MAX_NUMBER_OF_L2_CACHE_CORES] = { NULL, };
static u32 mali_global_num_l2s = 0;
int mali_l2_max_reads = MALI400_L2_MAX_READS_NOT_SET;
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
*/
/** Mali Page Order, as log to base 2 of the Page size. @see _MALI_OSK_MALI_PAGE_SIZE */
-#define _MALI_OSK_MALI_PAGE_ORDER ((u32)12)
+#define _MALI_OSK_MALI_PAGE_ORDER PAGE_SHIFT
/** Mali Page Size, in bytes. */
-#define _MALI_OSK_MALI_PAGE_SIZE (((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER))
+#define _MALI_OSK_MALI_PAGE_SIZE PAGE_SIZE
/** Mali Page Mask, which masks off the offset within a page */
-#define _MALI_OSK_MALI_PAGE_MASK (~((((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER)) - ((u32)1)))
+#define _MALI_OSK_MALI_PAGE_MASK PAGE_MASK
/** @} */ /* end of group _MALI_OSK_MALI_PAGE*/
/** @brief flags for mapping a user-accessible memory range
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
struct mali_group *groups_up[MALI_MAX_NUMBER_OF_GROUPS];
u32 num_groups_up = 0;
struct mali_l2_cache_core *
- l2_up[MALI_MAX_NUMBER_OF_L2_CACHE_CORES];
+ l2_up[MALI_MAX_NUMBER_OF_L2_CACHE_CORES];
u32 num_l2_up = 0;
u32 i;
struct mali_group *groups_down[MALI_MAX_NUMBER_OF_GROUPS];
u32 num_groups_down = 0;
struct mali_l2_cache_core *
- l2_down[MALI_MAX_NUMBER_OF_L2_CACHE_CORES];
+ l2_down[MALI_MAX_NUMBER_OF_L2_CACHE_CORES];
u32 num_l2_down = 0;
u32 i;
struct mali_group *groups_down[MALI_MAX_NUMBER_OF_GROUPS];
u32 num_groups_down = 0;
struct mali_l2_cache_core *
- l2_down[MALI_MAX_NUMBER_OF_L2_CACHE_CORES];
+ l2_down[MALI_MAX_NUMBER_OF_L2_CACHE_CORES];
u32 num_l2_down = 0;
u32 i;
/* L2gp/L2PP0/L2PP4 */
if (mali_is_mali400()) {
if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(
- MALI400_OFFSET_L2_CACHE0, NULL)) {
- domain_config[MALI_DOMAIN_INDEX_L20] = 0x01 << 1;
+ MALI400_OFFSET_L2_CACHE0, NULL)) {
+ domain_config[MALI_DOMAIN_INDEX_L20] = 0x01 << 1;
}
} else if (mali_is_mali450()) {
if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(
- MALI450_OFFSET_L2_CACHE0, NULL)) {
+ MALI450_OFFSET_L2_CACHE0, NULL)) {
domain_config[MALI_DOMAIN_INDEX_L20] = 0x01 << 0;
}
if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(
- MALI450_OFFSET_L2_CACHE1, NULL)) {
+ MALI450_OFFSET_L2_CACHE1, NULL)) {
domain_config[MALI_DOMAIN_INDEX_L21] = 0x01 << 1;
}
if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(
- MALI450_OFFSET_L2_CACHE2, NULL)) {
+ MALI450_OFFSET_L2_CACHE2, NULL)) {
domain_config[MALI_DOMAIN_INDEX_L22] = 0x01 << 3;
}
}
for (i = 0; i < MALI_MAX_NUMBER_OF_DOMAINS - 1; i++) {
if (0 != domain_config[i]) {
+ MALI_DEBUG_PRINT(2, ("Using customer pmu config:\n"));
break;
}
}
if (MALI_MAX_NUMBER_OF_DOMAINS - 1 == i) {
+ MALI_DEBUG_PRINT(2, ("Using hw detect pmu config:\n"));
mali_pm_set_default_pm_domain_config();
}
+ for (i = 0; i < MALI_MAX_NUMBER_OF_DOMAINS - 1; i++) {
+ if (domain_config[i]) {
+ MALI_DEBUG_PRINT(2, ("domain_config[%d] = 0x%x \n", i, domain_config[i]));
+ }
+ }
/* Can't override dummy domain mask */
domain_config[MALI_DOMAIN_INDEX_DUMMY] =
1 << MALI_DOMAIN_INDEX_DUMMY;
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
job = _mali_osk_calloc(1, sizeof(struct mali_pp_job));
if (NULL != job) {
+ u32 num_memory_cookies = 0;
if (0 != _mali_osk_copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_pp_start_job_s))) {
goto fail;
}
_mali_osk_atomic_init(&job->sub_jobs_completed, 0);
_mali_osk_atomic_init(&job->sub_job_errors, 0);
-
- if (job->uargs.num_memory_cookies > 0) {
+ num_memory_cookies = job->uargs.num_memory_cookies;
+ if (num_memory_cookies != 0) {
u32 size;
u32 __user *memory_cookies = (u32 __user *)(uintptr_t)job->uargs.memory_cookies;
- if (job->uargs.num_memory_cookies > session->descriptor_mapping->current_nr_mappings) {
+ if (num_memory_cookies > session->allocation_mgr.mali_allocation_nr) {
MALI_PRINT_ERROR(("Mali PP job: Too many memory cookies specified in job object\n"));
goto fail;
}
- size = sizeof(*memory_cookies) * job->uargs.num_memory_cookies;
+ size = sizeof(*memory_cookies) * num_memory_cookies;
job->memory_cookies = _mali_osk_malloc(size);
if (NULL == job->memory_cookies) {
MALI_PRINT_ERROR(("Mali PP job: Failed to copy %d bytes of memory cookies from user!\n", size));
goto fail;
}
-
-#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
- if (0 < job->uargs.num_memory_cookies) {
- job->dma_bufs = _mali_osk_calloc(job->uargs.num_memory_cookies,
- sizeof(struct mali_dma_buf_attachment *));
- if (NULL == job->dma_bufs) {
- MALI_PRINT_ERROR(("Mali PP job: Failed to allocate dma_bufs array!\n"));
- goto fail;
- }
- }
-#endif
}
if (_MALI_OSK_ERR_OK != mali_pp_job_check(job)) {
_mali_osk_notification_delete(job->finished_notification);
}
-#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
- /* Unmap buffers attached to job */
- if (0 < job->uargs.num_memory_cookies) {
- mali_dma_buf_unmap_job(job);
- if (NULL != job->dma_bufs) {
- _mali_osk_free(job->dma_bufs);
- }
- }
-#endif /* CONFIG_DMA_SHARED_BUFFER */
-
if (NULL != job->memory_cookies) {
_mali_osk_free(job->memory_cookies);
}
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
* No lock is thus needed for these.
*/
u32 *memory_cookies; /**< Memory cookies attached to job */
-#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
- struct mali_dma_buf_attachment **dma_bufs; /**< Array of DMA-bufs used by job */
-#endif
/*
* These members are used by the scheduler,
return MALI_FALSE;
}
-#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
-MALI_STATIC_INLINE u32 mali_pp_job_num_dma_bufs(struct mali_pp_job *job)
-{
- MALI_DEBUG_ASSERT_POINTER(job);
- return job->uargs.num_memory_cookies;
-}
-
-MALI_STATIC_INLINE struct mali_dma_buf_attachment *mali_pp_job_get_dma_buf(
- struct mali_pp_job *job, u32 index)
-{
- MALI_DEBUG_ASSERT_POINTER(job);
- MALI_DEBUG_ASSERT(index < job->uargs.num_memory_cookies);
- MALI_DEBUG_ASSERT_POINTER(job->dma_bufs);
- return job->dma_bufs[index];
-}
-
-MALI_STATIC_INLINE void mali_pp_job_set_dma_buf(struct mali_pp_job *job,
- u32 index, struct mali_dma_buf_attachment *mem)
-{
- MALI_DEBUG_ASSERT_POINTER(job);
- MALI_DEBUG_ASSERT(index < job->uargs.num_memory_cookies);
- MALI_DEBUG_ASSERT_POINTER(job->dma_bufs);
- job->dma_bufs[index] = mem;
-}
-#endif
-
MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_started(struct mali_pp_job *job, u32 sub_job)
{
MALI_DEBUG_ASSERT_POINTER(job);
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
_MALI_OSK_LIST_FOREACHENTRY(job, tmp, &list,
struct mali_pp_job, list) {
-
+
_mali_osk_list_delinit(&job->list);
mali_pp_job_delete(job); /* delete the job object itself */
}
/* unlock scheduler in this uncommon case */
mali_scheduler_unlock();
- mali_timeline_tracker_release(
- mali_pp_job_get_tracker(job));
+ schedule_mask |= mali_timeline_tracker_release(
+ mali_pp_job_get_tracker(job));
/* Notify user space and close the job object */
mali_scheduler_complete_pp_job(job, 0, MALI_TRUE,
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
mali_mem_usage = _mali_ukk_report_memory_usage();
total_mali_mem_size = _mali_ukk_report_total_memory_size();
_mali_osk_ctxprintf(print_ctx, "Mali mem usage: %u\nMali mem limit: %u\n", mali_mem_usage, total_mali_mem_size);
-}
\ No newline at end of file
+}
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#define __MALI_SESSION_H__
#include "mali_mmu_page_directory.h"
-#include "mali_kernel_descriptor_mapping.h"
#include "mali_osk.h"
#include "mali_osk_list.h"
#include "mali_memory_types.h"
+#include "mali_memory_manager.h"
struct mali_timeline_system;
struct mali_soft_system;
_mali_osk_notification_queue_t *ioctl_queue;
_mali_osk_mutex_t *memory_lock; /**< Lock protecting the vm manipulation */
- mali_descriptor_mapping *descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */
+#if 0
_mali_osk_list_t memory_head; /**< Track all the memory allocated in this session, for freeing on abnormal termination */
-
+#endif
struct mali_page_directory *page_directory; /**< MMU page directory for this session */
_MALI_OSK_LIST_HEAD(link); /**< Link for list of all sessions */
char *comm;
size_t mali_mem_array[MALI_MEM_TYPE_MAX]; /**< The array to record all mali mem types' usage for this session. */
size_t max_mali_mem_allocated; /**< The past max mali memory usage for this session. */
+ /* Added for new memroy system */
+ struct mali_allocation_manager allocation_mgr;
};
_mali_osk_errcode_t mali_session_initialize(void);
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
job->activated_notification = NULL;
}
-void mali_soft_job_system_activate_job(struct mali_soft_job *job)
+mali_scheduler_mask mali_soft_job_system_activate_job(struct mali_soft_job *job)
{
+ mali_scheduler_mask schedule_mask = MALI_SCHEDULER_MASK_EMPTY;
+
MALI_DEBUG_ASSERT_POINTER(job);
MALI_DEBUG_ASSERT_POINTER(job->system);
MALI_DEBUG_ASSERT_POINTER(job->system->session);
/* Since we are in shutdown, we can ignore the scheduling bitmask. */
mali_timeline_tracker_release(&job->tracker);
mali_soft_job_destroy(job);
- return;
+ return schedule_mask;
}
/* Send activated notification. */
/* If job type is self signaled, release tracker, move soft job to free list, and scheduler at once */
if (MALI_SOFT_JOB_TYPE_SELF_SIGNALED == job->type) {
- mali_scheduler_mask schedule_mask;
-
MALI_DEBUG_ASSERT(MALI_SOFT_JOB_STATE_STARTED == job->state);
job->state = MALI_SOFT_JOB_STATE_SIGNALED;
mali_soft_job_system_unlock(job->system);
- schedule_mask = mali_timeline_tracker_release(&job->tracker);
- mali_executor_schedule_from_mask(schedule_mask, MALI_FALSE);
+ schedule_mask |= mali_timeline_tracker_release(&job->tracker);
mali_soft_job_destroy(job);
} else {
mali_soft_job_system_unlock(job->system);
}
+
+ return schedule_mask;
}
mali_scheduler_mask mali_soft_job_system_timeout_job(struct mali_soft_job *job)
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
* Used by the Timeline system to activate a soft job.
*
* @param job The soft job that is being activated.
+ * @return A scheduling bitmask.
*/
-void mali_soft_job_system_activate_job(struct mali_soft_job *job);
+mali_scheduler_mask mali_soft_job_system_activate_job(struct mali_soft_job *job);
/**
* Used by the Timeline system to timeout a soft job.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
mali_spinlock_reentrant_signal(system->spinlock, tid);
+ /*
+ * Older versions of Linux, before 3.5, doesn't support fput() in interrupt
+ * context. For those older kernels, allocate a list object and put the
+ * fence object on that and defer the call to sync_fence_put() to a workqueue.
+ */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
{
struct mali_deferred_fence_put_entry *obj;
timeline = tracker->timeline;
MALI_DEBUG_ASSERT_POINTER(timeline);
- mali_soft_job_system_activate_job((struct mali_soft_job *) tracker->job);
+ schedule_mask |= mali_soft_job_system_activate_job((struct mali_soft_job *) tracker->job);
/* Start a soft timer to make sure the soft job be released in a limited time */
mali_spinlock_reentrant_wait(system->spinlock, tid);
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
sync_fence = sync_fence_fdget(fence->sync_fd);
if (likely(NULL != sync_fence)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
- if( 0 == sync_fence->status) {
+ if (0 == sync_fence->status) {
#else
if (0 == atomic_read(&sync_fence->status)) {
#endif
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
*/
_mali_osk_errcode_t _mali_ukk_mem_write_safe(_mali_uk_mem_write_safe_s *args);
-/** @brief Map a physically contiguous range of memory into Mali
- * @param args see _mali_uk_map_external_mem_s in mali_utgard_uk_types.h
- * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
- */
-_mali_osk_errcode_t _mali_ukk_map_external_mem(_mali_uk_map_external_mem_s *args);
-
-/** @brief Unmap a physically contiguous range of memory from Mali
- * @param args see _mali_uk_unmap_external_mem_s in mali_utgard_uk_types.h
- * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
- */
-_mali_osk_errcode_t _mali_ukk_unmap_external_mem(_mali_uk_unmap_external_mem_s *args);
-
-#if defined(CONFIG_MALI400_UMP)
-/** @brief Map UMP memory into Mali
- * @param args see _mali_uk_attach_ump_mem_s in mali_utgard_uk_types.h
- * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
- */
-_mali_osk_errcode_t _mali_ukk_attach_ump_mem(_mali_uk_attach_ump_mem_s *args);
-/** @brief Unmap UMP memory from Mali
- * @param args see _mali_uk_release_ump_mem_s in mali_utgard_uk_types.h
- * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
- */
-_mali_osk_errcode_t _mali_ukk_release_ump_mem(_mali_uk_release_ump_mem_s *args);
-#endif /* CONFIG_MALI400_UMP */
-
/** @} */ /* end group _mali_uk_memory */
/**
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/**
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
MALI_GPU_RESOURCES_MALI400_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq) \
MALI_GPU_RESOURCE_PMU(base_addr + MALI_OFFSET_PMU) \
-/* Mali-450 */
+ /* Mali-450 */
#define MALI_GPU_RESOURCES_MALI450_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp_bcast_irq) \
MALI_GPU_RESOURCE_L2(base_addr + MALI450_OFFSET_L2_CACHE0) \
MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + MALI_OFFSET_GP, gp_irq, base_addr + MALI_OFFSET_GP_MMU, gp_mmu_irq) \
.start = gp_irq, \
.end = gp_irq, \
}, \
-
+
#define MALI_GPU_RESOURCE_GP_WITH_MMU(gp_addr, gp_irq, gp_mmu_addr, gp_mmu_irq) \
{ \
.name = "Mali_GP", \
.start = pp_irq, \
.end = pp_irq, \
}, \
-
+
#define MALI_GPU_RESOURCE_PP_WITH_MMU(id, pp_addr, pp_irq, pp_mmu_addr, pp_mmu_irq) \
{ \
.name = "Mali_PP" #id, \
.end = pp_mmu_bcast_addr + 0x100, \
},
-struct mali_gpu_utilization_data {
- unsigned int utilization_gpu; /* Utilization for GP and all PP cores combined, 0 = no utilization, 256 = full utilization */
- unsigned int utilization_gp; /* Utilization for GP core only, 0 = no utilization, 256 = full utilization */
- unsigned int utilization_pp; /* Utilization for all PP cores combined, 0 = no utilization, 256 = full utilization */
-};
-
-struct mali_gpu_clk_item {
- unsigned int clock; /* unit(MHz) */
- unsigned int vol;
-};
-
-struct mali_gpu_clock {
- struct mali_gpu_clk_item *item;
- unsigned int num_of_steps;
-};
-
-struct mali_gpu_device_data {
- /* Shared GPU memory */
- unsigned long shared_mem_size;
-
- /*
- * Mali PMU switch delay.
- * Only needed if the power gates are connected to the PMU in a high fanout
- * network. This value is the number of Mali clock cycles it takes to
- * enable the power gates and turn on the power mesh.
- * This value will have no effect if a daisy chain implementation is used.
+ struct mali_gpu_utilization_data {
+ unsigned int utilization_gpu; /* Utilization for GP and all PP cores combined, 0 = no utilization, 256 = full utilization */
+ unsigned int utilization_gp; /* Utilization for GP core only, 0 = no utilization, 256 = full utilization */
+ unsigned int utilization_pp; /* Utilization for all PP cores combined, 0 = no utilization, 256 = full utilization */
+ };
+
+ struct mali_gpu_clk_item {
+ unsigned int clock; /* unit(MHz) */
+ unsigned int vol;
+ };
+
+ struct mali_gpu_clock {
+ struct mali_gpu_clk_item *item;
+ unsigned int num_of_steps;
+ };
+
+ struct mali_gpu_device_data {
+ /* Shared GPU memory */
+ unsigned long shared_mem_size;
+
+ /*
+ * Mali PMU switch delay.
+ * Only needed if the power gates are connected to the PMU in a high fanout
+ * network. This value is the number of Mali clock cycles it takes to
+ * enable the power gates and turn on the power mesh.
+ * This value will have no effect if a daisy chain implementation is used.
+ */
+ u32 pmu_switch_delay;
+
+ /* Mali Dynamic power domain configuration in sequence from 0-11
+ * GP PP0 PP1 PP2 PP3 PP4 PP5 PP6 PP7, L2$0 L2$1 L2$2
+ */
+ u16 pmu_domain_config[12];
+
+ /* Dedicated GPU memory range (physical). */
+ unsigned long dedicated_mem_start;
+ unsigned long dedicated_mem_size;
+
+ /* Frame buffer memory to be accessible by Mali GPU (physical) */
+ unsigned long fb_start;
+ unsigned long fb_size;
+
+ /* Max runtime [ms] for jobs */
+ int max_job_runtime;
+
+ /* Report GPU utilization and related control in this interval (specified in ms) */
+ unsigned long control_interval;
+
+ /* Function that will receive periodic GPU utilization numbers */
+ void (*utilization_callback)(struct mali_gpu_utilization_data *data);
+
+ /* Fuction that platform callback for freq setting, needed when CONFIG_MALI_DVFS enabled */
+ int (*set_freq)(int setting_clock_step);
+ /* Function that platfrom report it's clock info which driver can set, needed when CONFIG_MALI_DVFS enabled */
+ void (*get_clock_info)(struct mali_gpu_clock **data);
+ /* Function that get the current clock info, needed when CONFIG_MALI_DVFS enabled */
+ int (*get_freq)(void);
+ };
+
+ /**
+ * Pause the scheduling and power state changes of Mali device driver.
+ * mali_dev_resume() must always be called as soon as possible after this function
+ * in order to resume normal operation of the Mali driver.
*/
- u32 pmu_switch_delay;
+ void mali_dev_pause(void);
- /* Mali Dynamic power domain configuration in sequence from 0-11
- * GP PP0 PP1 PP2 PP3 PP4 PP5 PP6 PP7, L2$0 L2$1 L2$2
+ /**
+ * Resume scheduling and allow power changes in Mali device driver.
+ * This must always be called after mali_dev_pause().
*/
- u16 pmu_domain_config[12];
-
- /* Dedicated GPU memory range (physical). */
- unsigned long dedicated_mem_start;
- unsigned long dedicated_mem_size;
-
- /* Frame buffer memory to be accessible by Mali GPU (physical) */
- unsigned long fb_start;
- unsigned long fb_size;
-
- /* Max runtime [ms] for jobs */
- int max_job_runtime;
-
- /* Report GPU utilization and related control in this interval (specified in ms) */
- unsigned long control_interval;
-
- /* Function that will receive periodic GPU utilization numbers */
- void (*utilization_callback)(struct mali_gpu_utilization_data *data);
-
- /* Fuction that platform callback for freq setting, needed when CONFIG_MALI_DVFS enabled */
- int (*set_freq)(int setting_clock_step);
- /* Function that platfrom report it's clock info which driver can set, needed when CONFIG_MALI_DVFS enabled */
- void (*get_clock_info)(struct mali_gpu_clock **data);
- /* Function that get the current clock info, needed when CONFIG_MALI_DVFS enabled */
- int (*get_freq)(void);
-};
-
-/**
- * Pause the scheduling and power state changes of Mali device driver.
- * mali_dev_resume() must always be called as soon as possible after this function
- * in order to resume normal operation of the Mali driver.
- */
-void mali_dev_pause(void);
-
-/**
- * Resume scheduling and allow power changes in Mali device driver.
- * This must always be called after mali_dev_pause().
- */
-void mali_dev_resume(void);
-
-/** @brief Set the desired number of PP cores to use.
- *
- * The internal Mali PMU will be used, if present, to physically power off the PP cores.
- *
- * @param num_cores The number of desired cores
- * @return 0 on success, otherwise error. -EINVAL means an invalid number of cores was specified.
- */
-int mali_perf_set_num_pp_cores(unsigned int num_cores);
+ void mali_dev_resume(void);
+
+ /** @brief Set the desired number of PP cores to use.
+ *
+ * The internal Mali PMU will be used, if present, to physically power off the PP cores.
+ *
+ * @param num_cores The number of desired cores
+ * @return 0 on success, otherwise error. -EINVAL means an invalid number of cores was specified.
+ */
+ int mali_perf_set_num_pp_cores(unsigned int num_cores);
#endif
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#define MALI_IOC_SOFT_JOB_START _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_SOFT_JOB_START, _mali_uk_soft_job_start_s)
#define MALI_IOC_SOFT_JOB_SIGNAL _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_SOFT_JOB_SIGNAL, _mali_uk_soft_job_signal_s)
-#define MALI_IOC_MEM_MAP_EXT _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MAP_EXT_MEM, _mali_uk_map_external_mem_s)
-#define MALI_IOC_MEM_UNMAP_EXT _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_UNMAP_EXT_MEM, _mali_uk_unmap_external_mem_s)
-#define MALI_IOC_MEM_ATTACH_DMA_BUF _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_DMA_BUF, _mali_uk_attach_dma_buf_s)
-#define MALI_IOC_MEM_RELEASE_DMA_BUF _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_DMA_BUF, _mali_uk_release_dma_buf_s)
+#define MALI_IOC_MEM_ALLOC _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ALLOC_MEM, _mali_uk_alloc_mem_s)
+#define MALI_IOC_MEM_FREE _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_FREE_MEM, _mali_uk_free_mem_s)
+#define MALI_IOC_MEM_BIND _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_BIND_MEM, _mali_uk_bind_mem_s)
+#define MALI_IOC_MEM_UNBIND _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_UNBIND_MEM, _mali_uk_unbind_mem_s)
#define MALI_IOC_MEM_DMA_BUF_GET_SIZE _IOR(MALI_IOC_MEMORY_BASE, _MALI_UK_DMA_BUF_GET_SIZE, _mali_uk_dma_buf_get_size_s)
-#define MALI_IOC_MEM_ATTACH_UMP _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_UMP_MEM, _mali_uk_attach_ump_mem_s)
-#define MALI_IOC_MEM_RELEASE_UMP _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_UMP_MEM, _mali_uk_release_ump_mem_s)
#define MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, _mali_uk_query_mmu_page_table_dump_size_s)
#define MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_DUMP_MMU_PAGE_TABLE, _mali_uk_dump_mmu_page_table_s)
#define MALI_IOC_MEM_WRITE_SAFE _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MEM_WRITE_SAFE, _mali_uk_mem_write_safe_s)
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/** Memory functions */
- _MALI_UK_INIT_MEM = 0, /**< _mali_ukk_init_mem() */
- _MALI_UK_TERM_MEM, /**< _mali_ukk_term_mem() */
- _MALI_UK_MAP_MEM, /**< _mali_ukk_mem_mmap() */
- _MALI_UK_UNMAP_MEM, /**< _mali_ukk_mem_munmap() */
+ _MALI_UK_ALLOC_MEM = 0, /**< _mali_ukk_init_mem() */
+ _MALI_UK_FREE_MEM, /**< _mali_ukk_term_mem() */
+ _MALI_UK_BIND_MEM, /**< _mali_ukk_mem_mmap() */
+ _MALI_UK_UNBIND_MEM, /**< _mali_ukk_mem_munmap() */
_MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, /**< _mali_ukk_mem_get_mmu_page_table_dump_size() */
_MALI_UK_DUMP_MMU_PAGE_TABLE, /**< _mali_ukk_mem_dump_mmu_page_table() */
- _MALI_UK_ATTACH_DMA_BUF, /**< _mali_ukk_attach_dma_buf() */
- _MALI_UK_RELEASE_DMA_BUF, /**< _mali_ukk_release_dma_buf() */
_MALI_UK_DMA_BUF_GET_SIZE, /**< _mali_ukk_dma_buf_get_size() */
- _MALI_UK_ATTACH_UMP_MEM, /**< _mali_ukk_attach_ump_mem() */
- _MALI_UK_RELEASE_UMP_MEM, /**< _mali_ukk_release_ump_mem() */
- _MALI_UK_MAP_EXT_MEM, /**< _mali_uku_map_external_mem() */
- _MALI_UK_UNMAP_EXT_MEM, /**< _mali_uku_unmap_external_mem() */
_MALI_UK_MEM_WRITE_SAFE, /**< _mali_uku_mem_write_safe() */
/** Common functions for each core */
* The 16bit integer is stored twice in a 32bit integer
* For example, for version 1 the value would be 0x00010001
*/
-#define _MALI_API_VERSION 600
+#define _MALI_API_VERSION 800
#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION)
/**
/** @defgroup _mali_uk_memory U/K Memory
* @{ */
-/** Flag for _mali_uk_map_external_mem_s, _mali_uk_attach_ump_mem_s and _mali_uk_attach_dma_buf_s */
-#define _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE (1<<0)
+#define _MALI_MEMORY_ALLOCATE_RESIZEABLE (1<<4) /* BUFFER can trim dow/grow*/
+#define _MALI_MEMORY_ALLOCATE_NO_BIND_GPU (1<<5) /*Not map to GPU when allocate, must call bind later*/
typedef struct {
- u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 phys_addr; /**< [in] physical address */
- u32 size; /**< [in] size */
- u32 mali_address; /**< [in] mali address to map the physical memory to */
- u32 rights; /**< [in] rights necessary for accessing memory */
- u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
- u32 cookie; /**< [out] identifier for mapped memory object in kernel space */
-} _mali_uk_map_external_mem_s;
+ u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 gpu_vaddr; /**< [in] GPU virtual address */
+ u32 vsize; /**< [in] vitrual size of the allocation */
+ u32 psize; /**< [in] physical size of the allocation */
+ u32 flags;
+ u64 backend_handle; /**< [out] backend handle */
+ struct {
+ /* buffer types*/
+ /* CPU read/write info*/
+ } buffer_info;
+} _mali_uk_alloc_mem_s;
+
typedef struct {
- u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 cookie; /**< [out] identifier for mapped memory object in kernel space */
-} _mali_uk_unmap_external_mem_s;
+ u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 gpu_vaddr; /**< [in] use as handle to free allocation */
+} _mali_uk_free_mem_s;
+
+
+#define _MALI_MEMORY_BIND_BACKEND_UMP (1<<8)
+#define _MALI_MEMORY_BIND_BACKEND_DMA_BUF (1<<9)
+#define _MALI_MEMORY_BIND_BACKEND_MALI_MEMORY (1<<10)
+#define _MALI_MEMORY_BIND_BACKEND_EXTERNAL_MEMORY (1<<11)
+#define _MALI_MEMORY_BIND_BACKEND_EXT_COW (1<<12)
+#define _MALI_MEMORY_BIND_BACKEND_HAVE_ALLOCATION (1<<13)
+
+
+#define _MALI_MEMORY_BIND_BACKEND_MASK (_MALI_MEMORY_BIND_BACKEND_UMP| \
+ _MALI_MEMORY_BIND_BACKEND_DMA_BUF |\
+ _MALI_MEMORY_BIND_BACKEND_MALI_MEMORY |\
+ _MALI_MEMORY_BIND_BACKEND_EXTERNAL_MEMORY |\
+ _MALI_MEMORY_BIND_BACKEND_EXT_COW |\
+ _MALI_MEMORY_BIND_BACKEND_HAVE_ALLOCATION)
+
+
+#define _MALI_MEMORY_GPU_READ_ALLOCATE (1<<16)
+
-/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by memory descriptor */
typedef struct {
- u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 mem_fd; /**< [in] Memory descriptor */
- u32 size; /**< [in] size */
- u32 mali_address; /**< [in] mali address to map the physical memory to */
- u32 rights; /**< [in] rights necessary for accessing memory */
- u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
- u32 cookie; /**< [out] identifier for mapped memory object in kernel space */
-} _mali_uk_attach_dma_buf_s;
+ u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 vaddr; /**< [in] mali address to map the physical memory to */
+ u32 size; /**< [in] size */
+ u32 flags; /**< [in] see_MALI_MEMORY_BIND_BACKEND_* */
+ u32 padding; /** padding for 32/64 struct alignment */
+ union {
+ struct {
+ u32 secure_id; /**< [in] secure id */
+ u32 rights; /**< [in] rights necessary for accessing memory */
+ u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
+ } bind_ump;
+ struct {
+ u32 mem_fd; /**< [in] Memory descriptor */
+ u32 rights; /**< [in] rights necessary for accessing memory */
+ u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
+ } bind_dma_buf;
+ struct {
+ /**/
+ } bind_mali_memory;
+ struct {
+ u32 phys_addr; /**< [in] physical address */
+ u32 rights; /**< [in] rights necessary for accessing memory */
+ u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
+ } bind_ext_memory;
+ } mem_union;
+} _mali_uk_bind_mem_s;
+
+typedef struct {
+ u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 flags; /**< [in] see_MALI_MEMORY_BIND_BACKEND_* */
+ u32 vaddr; /**< [in] identifier for mapped memory object in kernel space */
+} _mali_uk_unbind_mem_s;
+
+typedef struct {
+ u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 target_handle; /**< [in] handle of allocation need to do COW */
+ u32 range_start; /**< [in] re allocate range start offset, offset from the start of allocation */
+ u32 size; /**< [in] re allocate size*/
+ u32 vaddr; /**< [in] mali address for the new allocaiton */
+ u32 backend_handle; /**< [out] backend handle */
+} _mali_uk_cow_mem_s;
typedef struct {
u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
u32 size; /**< [out] size */
} _mali_uk_dma_buf_get_size_s;
+/** Flag for _mali_uk_map_external_mem_s, _mali_uk_attach_ump_mem_s and _mali_uk_attach_dma_buf_s */
+#define _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE (1<<0)
+#if 0
typedef struct {
u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
- u64 cookie; /**< [in] identifier for mapped memory object in kernel space */
-} _mali_uk_release_dma_buf_s;
-
-/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by secure_id */
-typedef struct {
- u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 secure_id; /**< [in] secure id */
+ u32 phys_addr; /**< [in] physical address */
u32 size; /**< [in] size */
u32 mali_address; /**< [in] mali address to map the physical memory to */
u32 rights; /**< [in] rights necessary for accessing memory */
u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
u32 cookie; /**< [out] identifier for mapped memory object in kernel space */
-} _mali_uk_attach_ump_mem_s;
+} _mali_uk_map_external_mem_s;
typedef struct {
u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 cookie; /**< [in] identifier for mapped memory object in kernel space */
-} _mali_uk_release_ump_mem_s;
+ u32 cookie; /**< [out] identifier for mapped memory object in kernel space */
+} _mali_uk_unmap_external_mem_s;
+#endif
/**
* @brief Arguments for _mali_uk[uk]_mem_write_safe()
void *mapping; /**< [out] Returns user-space virtual address for the mapping */
u32 size; /**< [in] Size of the requested mapping */
u32 phys_addr; /**< [in] Physical address - could be offset, depending on caller+callee convention */
- u32 cookie; /**< [out] Returns a cookie for use in munmap calls */
} _mali_uk_mem_mmap_s;
/** @brief Arguments to _mali_ukk_mem_munmap()
u64 ctx; /**< [in,out] user-kernel context (trashed on output) */
void *mapping; /**< [in] The mapping returned from mmap call */
u32 size; /**< [in] The size passed to mmap call */
- u32 cookie; /**< [in] Cookie from mmap call */
} _mali_uk_mem_munmap_s;
/** @} */ /* end group _mali_uk_memory */
/*
- * Copyright (C) 2010, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/**
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/**
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#include "mali_kernel_license.h"
#include "mali_memory.h"
#include "mali_memory_dma_buf.h"
+#include "mali_memory_manager.h"
#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
#include "mali_profiling_internal.h"
#endif
MALI_DEBUG_PRINT(2, ("mali_module_init() Failed to register driver (%d)\n", err));
#ifdef MALI_FAKE_PLATFORM_DEVICE
#ifndef CONFIG_MALI_DT
- mali_platform_device_unregister();
+ mali_platform_device_unregister();
#endif
#endif
mali_platform_device = NULL;
/* Just call mali_get_current_gpu_clk_item(),to record current clk info.*/
mali_get_current_gpu_clk_item(&mali_gpu_clk[0]);
_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
- MALI_PROFILING_EVENT_CHANNEL_GPU |
- MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
- mali_gpu_clk[0].clock,
- mali_gpu_clk[0].vol / 1000,
- 0, 0, 0);
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+ mali_gpu_clk[0].clock,
+ mali_gpu_clk[0].vol / 1000,
+ 0, 0, 0);
#endif
MALI_PRINT(("Mali device driver loaded\n"));
#endif
- case MALI_IOC_MEM_WRITE_SAFE:
- BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_mem_write_safe_s), sizeof(u64)));
- err = mem_write_safe_wrapper(session_data, (_mali_uk_mem_write_safe_s __user *)arg);
+ case MALI_IOC_MEM_ALLOC:
+ BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_alloc_mem_s), sizeof(u64)));
+ err = mem_alloc_wrapper(session_data, (_mali_uk_alloc_mem_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_FREE:
+ BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_free_mem_s), sizeof(u64)));
+ err = mem_free_wrapper(session_data, (_mali_uk_free_mem_s __user *)arg);
break;
- case MALI_IOC_MEM_MAP_EXT:
- BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_map_external_mem_s), sizeof(u64)));
- err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg);
+ case MALI_IOC_MEM_BIND:
+ BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_bind_mem_s), sizeof(u64)));
+ err = mem_bind_wrapper(session_data, (_mali_uk_bind_mem_s __user *)arg);
break;
- case MALI_IOC_MEM_UNMAP_EXT:
- BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_unmap_external_mem_s), sizeof(u64)));
- err = mem_unmap_ext_wrapper(session_data, (_mali_uk_unmap_external_mem_s __user *)arg);
+ case MALI_IOC_MEM_UNBIND:
+ BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_unbind_mem_s), sizeof(u64)));
+ err = mem_unbind_wrapper(session_data, (_mali_uk_unbind_mem_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_WRITE_SAFE:
+ BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_mem_write_safe_s), sizeof(u64)));
+ err = mem_write_safe_wrapper(session_data, (_mali_uk_mem_write_safe_s __user *)arg);
break;
case MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE:
err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg);
break;
-#if defined(CONFIG_MALI400_UMP)
-
- case MALI_IOC_MEM_ATTACH_UMP:
- BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_attach_ump_mem_s), sizeof(u64)));
- err = mem_attach_ump_wrapper(session_data, (_mali_uk_attach_ump_mem_s __user *)arg);
- break;
-
- case MALI_IOC_MEM_RELEASE_UMP:
- BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_release_ump_mem_s), sizeof(u64)));
- err = mem_release_ump_wrapper(session_data, (_mali_uk_release_ump_mem_s __user *)arg);
- break;
-
-#else
-
- case MALI_IOC_MEM_ATTACH_UMP:
- case MALI_IOC_MEM_RELEASE_UMP: /* FALL-THROUGH */
- MALI_DEBUG_PRINT(2, ("UMP not supported\n"));
- err = -ENOTTY;
- break;
-#endif
-
-#ifdef CONFIG_DMA_SHARED_BUFFER
- case MALI_IOC_MEM_ATTACH_DMA_BUF:
- BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_attach_dma_buf_s), sizeof(u64)));
- err = mali_attach_dma_buf(session_data, (_mali_uk_attach_dma_buf_s __user *)arg);
- break;
-
- case MALI_IOC_MEM_RELEASE_DMA_BUF:
- BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_release_dma_buf_s), sizeof(u64)));
- err = mali_release_dma_buf(session_data, (_mali_uk_release_dma_buf_s __user *)arg);
- break;
-
case MALI_IOC_MEM_DMA_BUF_GET_SIZE:
+#ifdef CONFIG_DMA_SHARED_BUFFER
BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_dma_buf_get_size_s), sizeof(u64)));
err = mali_dma_buf_get_size(session_data, (_mali_uk_dma_buf_get_size_s __user *)arg);
- break;
#else
-
- case MALI_IOC_MEM_ATTACH_DMA_BUF: /* FALL-THROUGH */
- case MALI_IOC_MEM_RELEASE_DMA_BUF: /* FALL-THROUGH */
- case MALI_IOC_MEM_DMA_BUF_GET_SIZE: /* FALL-THROUGH */
MALI_DEBUG_PRINT(2, ("DMA-BUF not supported\n"));
err = -ENOTTY;
- break;
#endif
+ break;
case MALI_IOC_PP_START_JOB:
BUILD_BUG_ON(!IS_ALIGNED(sizeof(_mali_uk_pp_start_job_s), sizeof(u64)));
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#endif
#include <linux/cdev.h> /* character device definitions */
+#include <linux/idr.h>
+#include <linux/rbtree.h>
#include "mali_kernel_license.h"
#include "mali_osk_types.h"
/**
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
static ssize_t power_power_events_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
{
- if (!strncmp(ubuf, mali_power_events[_MALI_DEVICE_SUSPEND], strlen(mali_power_events[_MALI_DEVICE_SUSPEND])-1)) {
+ if (!strncmp(ubuf, mali_power_events[_MALI_DEVICE_SUSPEND], strlen(mali_power_events[_MALI_DEVICE_SUSPEND]) - 1)) {
mali_pm_os_suspend(MALI_TRUE);
- } else if (!strncmp(ubuf, mali_power_events[_MALI_DEVICE_RESUME], strlen(mali_power_events[_MALI_DEVICE_RESUME])-1)) {
+ } else if (!strncmp(ubuf, mali_power_events[_MALI_DEVICE_RESUME], strlen(mali_power_events[_MALI_DEVICE_RESUME]) - 1)) {
mali_pm_os_resume();
- } else if (!strncmp(ubuf, mali_power_events[_MALI_DEVICE_DVFS_PAUSE], strlen(mali_power_events[_MALI_DEVICE_DVFS_PAUSE])-1)) {
+ } else if (!strncmp(ubuf, mali_power_events[_MALI_DEVICE_DVFS_PAUSE], strlen(mali_power_events[_MALI_DEVICE_DVFS_PAUSE]) - 1)) {
mali_dev_pause();
- } else if (!strncmp(ubuf, mali_power_events[_MALI_DEVICE_DVFS_RESUME], strlen(mali_power_events[_MALI_DEVICE_DVFS_RESUME])-1)) {
+ } else if (!strncmp(ubuf, mali_power_events[_MALI_DEVICE_DVFS_RESUME], strlen(mali_power_events[_MALI_DEVICE_DVFS_RESUME]) - 1)) {
mali_dev_resume();
}
*ppos += cnt;
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/platform_device.h>
+#include <linux/idr.h>
#include "mali_osk.h"
-#include "mali_osk_mali.h"
-#include "mali_kernel_linux.h"
-#include "mali_scheduler.h"
#include "mali_executor.h"
-#include "mali_kernel_descriptor_mapping.h"
#include "mali_memory.h"
-#include "mali_memory_dma_buf.h"
#include "mali_memory_os_alloc.h"
#include "mali_memory_block_alloc.h"
+#include "mali_memory_util.h"
+#include "mali_memory_virtual.h"
+#include "mali_memory_manager.h"
extern unsigned int mali_dedicated_mem_size;
extern unsigned int mali_shared_mem_size;
/* session->memory_lock must be held when calling this function */
-static void mali_mem_release(mali_mem_allocation *descriptor)
-{
- MALI_DEBUG_ASSERT_POINTER(descriptor);
- MALI_DEBUG_ASSERT_LOCK_HELD(descriptor->session->memory_lock);
-
- MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == descriptor->magic);
-
- switch (descriptor->type) {
- case MALI_MEM_OS:
- mali_mem_os_release(descriptor);
- break;
- case MALI_MEM_DMA_BUF:
-#if defined(CONFIG_DMA_SHARED_BUFFER)
- mali_mem_dma_buf_release(descriptor);
-#endif
- break;
- case MALI_MEM_UMP:
-#if defined(CONFIG_MALI400_UMP)
- mali_mem_ump_release(descriptor);
-#endif
- break;
- case MALI_MEM_EXTERNAL:
- mali_mem_external_release(descriptor);
- break;
- case MALI_MEM_BLOCK:
- mali_mem_block_release(descriptor);
- break;
- default:
- MALI_DEBUG_PRINT(1, ("mem type %d is not in the mali_mem_type enum.\n", descriptor->type));
- break;
- }
-}
-
static void mali_mem_vma_open(struct vm_area_struct *vma)
{
- mali_mem_allocation *descriptor = (mali_mem_allocation *)vma->vm_private_data;
+ mali_mem_allocation *alloc = (mali_mem_allocation *)vma->vm_private_data;
MALI_DEBUG_PRINT(4, ("Open called on vma %p\n", vma));
- descriptor->cpu_mapping.ref++;
-
+ /* If need to share the allocation, add ref_count here */
+ mali_allocation_ref(alloc);
return;
}
-
static void mali_mem_vma_close(struct vm_area_struct *vma)
{
- mali_mem_allocation *descriptor;
- struct mali_session_data *session;
- mali_mem_virt_cpu_mapping *mapping;
-
- MALI_DEBUG_PRINT(3, ("Close called on vma %p\n", vma));
-
- descriptor = (mali_mem_allocation *)vma->vm_private_data;
- BUG_ON(!descriptor);
-
- MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == descriptor->magic);
-
- mapping = &descriptor->cpu_mapping;
- BUG_ON(0 == mapping->ref);
-
- mapping->ref--;
- if (0 != mapping->ref) {
- MALI_DEBUG_PRINT(3, ("Ignoring this close, %d references still exists\n", mapping->ref));
- return;
- }
+ /* If need to share the allocation, unref ref_count here */
+ mali_mem_allocation *alloc = (mali_mem_allocation *)vma->vm_private_data;
- session = descriptor->session;
-
- mali_descriptor_mapping_free(session->descriptor_mapping, descriptor->id);
-
- _mali_osk_mutex_wait(session->memory_lock);
- mali_mem_release(descriptor);
- _mali_osk_mutex_signal(session->memory_lock);
-
- mali_mem_descriptor_destroy(descriptor);
+ mali_allocation_unref(&alloc);
+ vma->vm_private_data = NULL;
}
-static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf)
+static int mali_mem_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- void __user *address;
- mali_mem_allocation *descriptor;
-
- address = vmf->virtual_address;
- descriptor = (mali_mem_allocation *)vma->vm_private_data;
-
- MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == descriptor->magic);
-
- /*
- * We always fail the call since all memory is pre-faulted when assigned to the process.
- * Only the Mali cores can use page faults to extend buffers.
- */
-
- MALI_DEBUG_PRINT(1, ("Page-fault in Mali memory region caused by the CPU.\n"));
- MALI_DEBUG_PRINT(1, ("Tried to access %p (process local virtual address) which is not currently mapped to any Mali memory.\n", (void *)address));
-
- MALI_IGNORE(address);
- MALI_IGNORE(descriptor);
-
- return VM_FAULT_SIGBUS;
+ /* Not support yet */
+ MALI_DEBUG_ASSERT(0);
+ return 0;
}
static struct vm_operations_struct mali_kernel_vm_ops = {
.open = mali_mem_vma_open,
.close = mali_mem_vma_close,
- .fault = mali_kernel_memory_cpu_page_fault_handler
+ .fault = mali_mem_vma_fault,
};
-/** @note munmap handler is done by vma close handler */
+
+/** @ map mali allocation to CPU address
+*
+* Supported backend types:
+* --MALI_MEM_OS
+* -- need to add COW?
+ *Not supported backend types:
+* -_MALI_MEMORY_BIND_BACKEND_UMP
+* -_MALI_MEMORY_BIND_BACKEND_DMA_BUF
+* -_MALI_MEMORY_BIND_BACKEND_EXTERNAL_MEMORY
+*
+*/
int mali_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct mali_session_data *session;
- mali_mem_allocation *descriptor;
- u32 size = vma->vm_end - vma->vm_start;
+ mali_mem_allocation *mali_alloc = NULL;
u32 mali_addr = vma->vm_pgoff << PAGE_SHIFT;
+ struct mali_vma_node *mali_vma_node = NULL;
+ mali_mem_backend *mem_bkend = NULL;
+ int ret;
session = (struct mali_session_data *)filp->private_data;
if (NULL == session) {
#endif
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */
-
- descriptor = mali_mem_block_alloc(mali_addr, size, vma, session);
- if (NULL == descriptor) {
- descriptor = mali_mem_os_alloc(mali_addr, size, vma, session);
- if (NULL == descriptor) {
- MALI_DEBUG_PRINT(3, ("MMAP failed\n"));
- return -ENOMEM;
+ vma->vm_ops = &mali_kernel_vm_ops;
+ /* Operations used on any memory system */
+
+ /* find mali allocation structure by vaddress*/
+ mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, mali_addr, 0);
+ if (likely(mali_vma_node)) {
+ mali_alloc = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node);
+ MALI_DEBUG_ASSERT(mali_addr == mali_vma_node->vm_node.start);
+ if (unlikely(mali_addr != mali_vma_node->vm_node.start)) {
+ /* only allow to use start address for mmap */
+ return -EFAULT;
}
+ } else {
+ MALI_DEBUG_ASSERT(NULL == mali_vma_node);
+ return -EFAULT;
}
- MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == descriptor->magic);
-
- vma->vm_private_data = (void *)descriptor;
+ mali_alloc->cpu_mapping.addr = (void __user *)vma->vm_start;
- /* Put on descriptor map */
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &descriptor->id)) {
- _mali_osk_mutex_wait(session->memory_lock);
- if (MALI_MEM_OS == descriptor->type) {
- mali_mem_os_release(descriptor);
- } else if (MALI_MEM_BLOCK == descriptor->type) {
- mali_mem_block_release(descriptor);
- }
- _mali_osk_mutex_signal(session->memory_lock);
+ /* Get backend memory & Map on CPU */
+ mutex_lock(&mali_idr_mutex);
+ if (!(mem_bkend = idr_find(&mali_backend_idr, mali_alloc->backend_handle))) {
+ MALI_DEBUG_PRINT(1, ("Can't find memory backend in mmap!\n"));
+ mutex_unlock(&mali_idr_mutex);
return -EFAULT;
}
-
- return 0;
-}
-
-
-/* Prepare memory descriptor */
-mali_mem_allocation *mali_mem_descriptor_create(struct mali_session_data *session, mali_mem_type type)
-{
- mali_mem_allocation *descriptor;
-
- descriptor = (mali_mem_allocation *)kzalloc(sizeof(mali_mem_allocation), GFP_KERNEL);
- if (NULL == descriptor) {
- MALI_DEBUG_PRINT(3, ("mali_ukk_mem_mmap: descriptor was NULL\n"));
- return NULL;
+ mutex_unlock(&mali_idr_mutex);
+
+ if (mem_bkend->type == MALI_MEM_OS) {
+ ret = mali_mem_os_cpu_map(&mem_bkend->os_mem, vma);
+ } else if (mem_bkend->type == MALI_MEM_BLOCK) {
+ ret = mali_mem_block_cpu_map(mem_bkend, vma);
+ } else {
+ /* Not support yet*/
+ MALI_DEBUG_ASSERT(0);
+ ret = -EFAULT;
}
- MALI_DEBUG_CODE(descriptor->magic = MALI_MEM_ALLOCATION_VALID_MAGIC);
-
- descriptor->flags = 0;
- descriptor->type = type;
- descriptor->session = session;
+ if (ret != 0)
+ return -EFAULT;
- return descriptor;
-}
+ MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == mali_alloc->magic);
-void mali_mem_descriptor_destroy(mali_mem_allocation *descriptor)
-{
- MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == descriptor->magic);
- MALI_DEBUG_CODE(descriptor->magic = MALI_MEM_ALLOCATION_FREED_MAGIC);
+ vma->vm_private_data = (void *)mali_alloc;
+ mali_allocation_ref(mali_alloc);
- kfree(descriptor);
+ return 0;
}
_mali_osk_errcode_t mali_mem_mali_map_prepare(mali_mem_allocation *descriptor)
{
- u32 size = descriptor->size;
+ u32 size = descriptor->psize;
struct mali_session_data *session = descriptor->session;
MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == descriptor->magic);
size += MALI_MMU_PAGE_SIZE;
}
- return mali_mmu_pagedir_map(session->page_directory, descriptor->mali_mapping.addr, size);
+ return mali_mmu_pagedir_map(session->page_directory, descriptor->mali_vma_node.vm_node.start, size);
}
-void mali_mem_mali_map_free(mali_mem_allocation *descriptor)
-{
- u32 size = descriptor->size;
- struct mali_session_data *session = descriptor->session;
- MALI_DEBUG_ASSERT(MALI_MEM_ALLOCATION_VALID_MAGIC == descriptor->magic);
-
- if (descriptor->flags & MALI_MEM_FLAG_MALI_GUARD_PAGE) {
+void mali_mem_mali_map_free(struct mali_session_data *session, u32 size, mali_address_t vaddr, u32 flags)
+{
+ if (flags & MALI_MEM_FLAG_MALI_GUARD_PAGE) {
size += MALI_MMU_PAGE_SIZE;
}
/* Umap and flush L2 */
- mali_mmu_pagedir_unmap(session->page_directory, descriptor->mali_mapping.addr, descriptor->size);
-
+ mali_mmu_pagedir_unmap(session->page_directory, vaddr, size);
mali_executor_zap_all_active(session);
}
{
u32 sum = 0;
- sum += mali_mem_block_allocator_stat();
+ if (MALI_TRUE == mali_memory_have_dedicated_memory()) {
+ sum += mali_mem_block_allocator_stat();
+ }
+
sum += mali_mem_os_stat();
return sum;
{
MALI_DEBUG_PRINT(5, ("Memory session begin\n"));
- /* Create descriptor mapping table */
- session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX);
-
- if (NULL == session_data->descriptor_mapping) {
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
session_data->memory_lock = _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_ORDERED,
_MALI_OSK_LOCK_ORDER_MEM_SESSION);
if (NULL == session_data->memory_lock) {
- mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
_mali_osk_free(session_data);
MALI_ERROR(_MALI_OSK_ERR_FAULT);
}
+ mali_memory_manager_init(&session_data->allocation_mgr);
+
MALI_DEBUG_PRINT(5, ("MMU session begin: success\n"));
MALI_SUCCESS;
}
-/** @brief Callback function that releases memory
- *
- * session->memory_lock must be held when calling this function.
- */
-static void descriptor_table_cleanup_callback(int descriptor_id, void *map_target)
-{
- mali_mem_allocation *descriptor;
-
- descriptor = (mali_mem_allocation *)map_target;
-
- MALI_DEBUG_ASSERT_LOCK_HELD(descriptor->session->memory_lock);
-
- MALI_DEBUG_PRINT(3, ("Cleanup of descriptor %d mapping to 0x%x in descriptor table\n", descriptor_id, map_target));
- MALI_DEBUG_ASSERT(descriptor);
-
- mali_mem_release(descriptor);
- mali_mem_descriptor_destroy(descriptor);
-}
-
void mali_memory_session_end(struct mali_session_data *session)
{
MALI_DEBUG_PRINT(3, ("MMU session end\n"));
MALI_DEBUG_PRINT(1, ("No session data found during session end\n"));
return;
}
-
- /* Lock the session so we can modify the memory list */
- _mali_osk_mutex_wait(session->memory_lock);
-
- /* Free all allocations still in the descriptor map, and terminate the map */
- if (NULL != session->descriptor_mapping) {
- mali_descriptor_mapping_call_for_each(session->descriptor_mapping, descriptor_table_cleanup_callback);
- mali_descriptor_mapping_destroy(session->descriptor_mapping);
- session->descriptor_mapping = NULL;
- }
-
- _mali_osk_mutex_signal(session->memory_lock);
+ /* free allocation */
+ mali_free_session_allocations(session);
+ /* do some check in unint*/
+ mali_memory_manager_uninit(&session->allocation_mgr);
/* Free the lock */
_mali_osk_mutex_term(session->memory_lock);
_mali_osk_errcode_t mali_memory_initialize(void)
{
+ idr_init(&mali_backend_idr);
+ mutex_init(&mali_idr_mutex);
return mali_mem_os_init();
}
void mali_memory_terminate(void)
{
mali_mem_os_term();
- mali_mem_block_allocator_destroy(NULL);
+ if (mali_memory_have_dedicated_memory()) {
+ mali_mem_block_allocator_destroy();
+ }
}
+
+
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
*/
int mali_mmap(struct file *filp, struct vm_area_struct *vma);
-/** @brief Allocate and initialize a Mali memory descriptor
- *
- * @param session Pointer to the session allocating the descriptor
- * @param type Type of memory the descriptor will represent
- */
-mali_mem_allocation *mali_mem_descriptor_create(struct mali_session_data *session, mali_mem_type type);
-
-/** @brief Destroy a Mali memory descriptor
- *
- * This function will only free the descriptor itself, and not the memory it
- * represents.
- *
- * @param descriptor Pointer to the descriptor to destroy
- */
-void mali_mem_descriptor_destroy(mali_mem_allocation *descriptor);
-
/** @brief Start a new memory session
*
* Called when a process opens the Mali device node.
*
* @param descriptor Pointer to the memory descriptor to unmap
*/
-void mali_mem_mali_map_free(mali_mem_allocation *descriptor);
+void mali_mem_mali_map_free(struct mali_session_data *session, u32 size, mali_address_t vaddr, u32 flags);
+
/** @brief Parse resource and prepare the OS memory allocator
*
_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(u32 start, u32 size);
-void mali_mem_ump_release(mali_mem_allocation *descriptor);
-void mali_mem_external_release(mali_mem_allocation *descriptor);
-
#endif /* __MALI_MEMORY_H__ */
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
- *
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+ *
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
#include "mali_kernel_common.h"
#include "mali_memory.h"
#include "mali_memory_block_alloc.h"
#include "mali_osk.h"
#include <linux/mutex.h>
-#define MALI_BLOCK_SIZE (256UL * 1024UL) /* 256 kB, remember to keep the ()s */
-struct block_info {
- struct block_info *next;
-};
-typedef struct block_info block_info;
+struct mali_block_node *_mali_block_node_allocate(mali_page_node_type type)
+{
+ mali_block_node *block_node = NULL;
+ block_node = kzalloc(sizeof(mali_block_node), GFP_KERNEL);
+ MALI_DEBUG_ASSERT(NULL != block_node);
-typedef struct block_allocator {
- struct mutex mutex;
- block_info *all_blocks;
- block_info *first_free;
- u32 base;
- u32 cpu_usage_adjust;
- u32 num_blocks;
- u32 free_blocks;
-} block_allocator;
+ if (block_node) {
+ block_node->type = type;
+ INIT_LIST_HEAD(&block_node->list);
+ }
-static block_allocator *mali_mem_block_gobal_allocator = NULL;
+ return block_node;
+}
-MALI_STATIC_INLINE u32 get_phys(block_allocator *info, block_info *block)
+void _mali_block_node_ref(struct mali_block_node *node)
{
- return info->base + ((block - info->all_blocks) * MALI_BLOCK_SIZE);
+ if (node->type == MALI_PAGE_NODE_BLOCK) {
+ mali_mem_block_add_ref(node);
+ } else
+ MALI_DEBUG_ASSERT(0);
}
-static mali_mem_allocator *mali_mem_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size)
+void _mali_block_node_unref(struct mali_block_node *node)
{
- block_allocator *info;
- u32 usable_size;
- u32 num_blocks;
+ if (node->type == MALI_PAGE_NODE_BLOCK) {
+ mali_mem_block_dec_ref(node);
+ } else
+ MALI_DEBUG_ASSERT(0);
+}
- usable_size = size & ~(MALI_BLOCK_SIZE - 1);
- MALI_DEBUG_PRINT(3, ("Mali block allocator create for region starting at 0x%08X length 0x%08X\n", base_address, size));
- MALI_DEBUG_PRINT(4, ("%d usable bytes\n", usable_size));
- num_blocks = usable_size / MALI_BLOCK_SIZE;
- MALI_DEBUG_PRINT(4, ("which becomes %d blocks\n", num_blocks));
- if (usable_size == 0) {
- MALI_DEBUG_PRINT(1, ("Memory block of size %d is unusable\n", size));
- return NULL;
- }
- info = _mali_osk_malloc(sizeof(block_allocator));
- if (NULL != info) {
- mutex_init(&info->mutex);
- info->all_blocks = _mali_osk_malloc(sizeof(block_info) * num_blocks);
- if (NULL != info->all_blocks) {
- u32 i;
- info->first_free = NULL;
- info->num_blocks = num_blocks;
- info->free_blocks = num_blocks;
-
- info->base = base_address;
- info->cpu_usage_adjust = cpu_usage_adjust;
-
- for (i = 0; i < num_blocks; i++) {
- info->all_blocks[i].next = info->first_free;
- info->first_free = &info->all_blocks[i];
- }
+void _mali_block_node_add_block_item(struct mali_block_node *node, mali_block_item *item)
+{
+ MALI_DEBUG_ASSERT(MALI_PAGE_NODE_BLOCK == node->type);
+ node->blk_it = item;
+}
- return (mali_mem_allocator *)info;
- }
- _mali_osk_free(info);
- }
- return NULL;
+int _mali_block_node_get_ref_count(struct mali_block_node *node)
+{
+ if (node->type == MALI_PAGE_NODE_BLOCK) {
+ return mali_mem_block_get_ref_count(node);
+ } else {
+ MALI_DEBUG_ASSERT(0);
+ }
+ return -1;
}
-void mali_mem_block_allocator_destroy(mali_mem_allocator *allocator)
+
+dma_addr_t _mali_block_node_get_phy_addr(struct mali_block_node *node)
{
- block_allocator *info = (block_allocator *)allocator;
+ if (node->type == MALI_PAGE_NODE_BLOCK) {
+ return _mali_blk_item_get_phy_addr(node->blk_it);
+ } else {
+ MALI_DEBUG_ASSERT(0);
+ }
+ return 0;
+}
- info = mali_mem_block_gobal_allocator;
- if (NULL == info) return;
- MALI_DEBUG_ASSERT_POINTER(info);
-
- _mali_osk_free(info->all_blocks);
- _mali_osk_free(info);
+unsigned long _mali_block_node_get_pfn(struct mali_block_node *node)
+{
+ if (node->type == MALI_PAGE_NODE_BLOCK) {
+ /* get phy addr for BLOCK page*/
+ return _mali_blk_item_get_pfn(node->blk_it);
+ } else {
+ MALI_DEBUG_ASSERT(0);
+ }
+ return 0;
}
-static void mali_mem_block_mali_map(mali_mem_allocation *descriptor, u32 phys, u32 virt, u32 size)
-{
- struct mali_page_directory *pagedir = descriptor->session->page_directory;
- u32 prop = descriptor->mali_mapping.properties;
- u32 offset = 0;
- while (size) {
- mali_mmu_pagedir_update(pagedir, virt + offset, phys + offset, MALI_MMU_PAGE_SIZE, prop);
+static mali_block_allocator *mali_mem_block_gobal_allocator = NULL;
- size -= MALI_MMU_PAGE_SIZE;
- offset += MALI_MMU_PAGE_SIZE;
- }
+unsigned long _mali_blk_item_get_phy_addr(mali_block_item *item)
+{
+ return (item->phy_addr & ~(MALI_BLOCK_REF_MASK));
}
-static int mali_mem_block_cpu_map(mali_mem_allocation *descriptor, struct vm_area_struct *vma, u32 mali_phys, u32 mapping_offset, u32 size, u32 cpu_usage_adjust)
+
+unsigned long _mali_blk_item_get_pfn(mali_block_item *item)
{
- u32 virt = vma->vm_start + mapping_offset;
- u32 cpu_phys = mali_phys + cpu_usage_adjust;
- u32 offset = 0;
- int ret;
+ return (item->phy_addr / MALI_BLOCK_SIZE);
+}
- while (size) {
- ret = vm_insert_pfn(vma, virt + offset, __phys_to_pfn(cpu_phys + offset));
- if (unlikely(ret)) {
- MALI_DEBUG_PRINT(1, ("Block allocator: Failed to insert pfn into vma\n"));
- return 1;
- }
+u32 mali_mem_block_get_ref_count(mali_block_node *node)
+{
+ MALI_DEBUG_ASSERT(node->type == MALI_PAGE_NODE_BLOCK);
+ return (node->blk_it->phy_addr & MALI_BLOCK_REF_MASK);
+}
- size -= MALI_MMU_PAGE_SIZE;
- offset += MALI_MMU_PAGE_SIZE;
- }
- return 0;
+/* Increase the refence count
+* It not atomic, so it need to get sp_lock before call this function
+*/
+
+u32 mali_mem_block_add_ref(mali_block_node *node)
+{
+ MALI_DEBUG_ASSERT(node->type == MALI_PAGE_NODE_BLOCK);
+ MALI_DEBUG_ASSERT(mali_mem_block_get_ref_count(node) < MALI_BLOCK_MAX_REF_COUNT);
+ return (node->blk_it->phy_addr++ & MALI_BLOCK_REF_MASK);
}
-mali_mem_allocation *mali_mem_block_alloc(u32 mali_addr, u32 size, struct vm_area_struct *vma, struct mali_session_data *session)
+/* Decase the refence count
+* It not atomic, so it need to get sp_lock before call this function
+*/
+u32 mali_mem_block_dec_ref(mali_block_node *node)
{
- _mali_osk_errcode_t err;
- mali_mem_allocation *descriptor;
- block_allocator *info;
- u32 left;
- block_info *last_allocated = NULL;
- block_allocator_allocation *ret_allocation;
- u32 offset = 0;
+ MALI_DEBUG_ASSERT(node->type == MALI_PAGE_NODE_BLOCK);
+ MALI_DEBUG_ASSERT(mali_mem_block_get_ref_count(node) > 0);
+ return (node->blk_it->phy_addr-- & MALI_BLOCK_REF_MASK);
+}
- size = ALIGN(size, MALI_BLOCK_SIZE);
- info = mali_mem_block_gobal_allocator;
- if (NULL == info) return NULL;
+static mali_block_allocator *mali_mem_block_allocator_create(u32 base_address, u32 size)
+{
+ mali_block_allocator *info;
+ u32 usable_size;
+ u32 num_blocks;
+ mali_block_node *m_node;
+ mali_block_item *mali_blk_items = NULL;
+ int i = 0;
- left = size;
- MALI_DEBUG_ASSERT(0 != left);
+ usable_size = size & ~(MALI_BLOCK_SIZE - 1);
+ MALI_DEBUG_PRINT(3, ("Mali block allocator create for region starting at 0x%08X length 0x%08X\n", base_address, size));
+ MALI_DEBUG_PRINT(4, ("%d usable bytes\n", usable_size));
+ num_blocks = usable_size / MALI_BLOCK_SIZE;
+ MALI_DEBUG_PRINT(4, ("which becomes %d blocks\n", num_blocks));
- descriptor = mali_mem_descriptor_create(session, MALI_MEM_BLOCK);
- if (NULL == descriptor) {
+ if (usable_size == 0) {
+ MALI_DEBUG_PRINT(1, ("Memory block of size %d is unusable\n", size));
return NULL;
}
- descriptor->mali_mapping.addr = mali_addr;
- descriptor->size = size;
- descriptor->cpu_mapping.addr = (void __user *)vma->vm_start;
- descriptor->cpu_mapping.ref = 1;
-
- if (VM_SHARED == (VM_SHARED & vma->vm_flags)) {
- descriptor->mali_mapping.properties = MALI_MMU_FLAGS_DEFAULT;
- } else {
- /* Cached Mali memory mapping */
- descriptor->mali_mapping.properties = MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE;
- vma->vm_flags |= VM_SHARED;
+ info = _mali_osk_calloc(1, sizeof(mali_block_allocator));
+ if (NULL != info) {
+ INIT_LIST_HEAD(&info->free);
+ spin_lock_init(&info->sp_lock);
+ info->total_num = num_blocks;
+ mali_blk_items = _mali_osk_calloc(1, sizeof(mali_block_item) * num_blocks);
+
+ if (mali_blk_items) {
+ info->items = mali_blk_items;
+ /* add blocks(4k size) to free list*/
+ for (i = 0 ; i < num_blocks ; i++) {
+ /* add block information*/
+ mali_blk_items[i].phy_addr = base_address + (i * MALI_BLOCK_SIZE);
+ /* add to free list */
+ m_node = _mali_block_node_allocate(MALI_PAGE_NODE_BLOCK);
+ if (m_node == NULL)
+ goto fail;
+ _mali_block_node_add_block_item(m_node, &(mali_blk_items[i]));
+ list_add_tail(&m_node->list, &info->free);
+ atomic_add(1, &info->free_num);
+ }
+ return info;
+ }
}
+fail:
+ mali_mem_block_allocator_destroy();
+ return NULL;
+}
- ret_allocation = &descriptor->block_mem.mem;
-
- ret_allocation->mapping_length = 0;
-
- _mali_osk_mutex_wait(session->memory_lock);
- mutex_lock(&info->mutex);
+void mali_mem_block_allocator_destroy(void)
+{
+ struct mali_block_node *m_page, *m_tmp;
+ mali_block_allocator *info = mali_mem_block_gobal_allocator;
+ MALI_DEBUG_ASSERT_POINTER(info);
+ MALI_DEBUG_PRINT(4, ("Memory block destroy !\n"));
- if (left > (info->free_blocks * MALI_BLOCK_SIZE)) {
- MALI_DEBUG_PRINT(2, ("Mali block allocator: not enough free blocks to service allocation (%u)\n", left));
- mutex_unlock(&info->mutex);
- _mali_osk_mutex_signal(session->memory_lock);
- mali_mem_descriptor_destroy(descriptor);
- return NULL;
- }
+ if (NULL == info)
+ return;
- err = mali_mem_mali_map_prepare(descriptor);
- if (_MALI_OSK_ERR_OK != err) {
- mutex_unlock(&info->mutex);
- _mali_osk_mutex_signal(session->memory_lock);
- mali_mem_descriptor_destroy(descriptor);
- return NULL;
+ list_for_each_entry_safe(m_page, m_tmp , &info->free, list) {
+ MALI_DEBUG_ASSERT(m_page->type == MALI_PAGE_NODE_BLOCK);
+ list_del(&m_page->list);
+ kfree(m_page);
}
- while ((left > 0) && (info->first_free)) {
- block_info *block;
- u32 phys_addr;
- u32 current_mapping_size;
-
- block = info->first_free;
- info->first_free = info->first_free->next;
- block->next = last_allocated;
- last_allocated = block;
+ _mali_osk_free(info->items);
+ _mali_osk_free(info);
+}
- phys_addr = get_phys(info, block);
+void mali_mem_block_release(mali_mem_backend *mem_bkend)
+{
+ mali_mem_allocation *alloc = mem_bkend->mali_allocation;;
+ MALI_DEBUG_PRINT(4, ("BLOCK Mem: Release size = 0x%x\n", mem_bkend->size));
- if (MALI_BLOCK_SIZE < left) {
- current_mapping_size = MALI_BLOCK_SIZE;
- } else {
- current_mapping_size = left;
- }
+ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_BLOCK);
- mali_mem_block_mali_map(descriptor, phys_addr, mali_addr + offset, current_mapping_size);
- if (mali_mem_block_cpu_map(descriptor, vma, phys_addr, offset, current_mapping_size, info->cpu_usage_adjust)) {
- /* release all memory back to the pool */
- while (last_allocated) {
- /* This relinks every block we've just allocated back into the free-list */
- block = last_allocated->next;
- last_allocated->next = info->first_free;
- info->first_free = last_allocated;
- last_allocated = block;
- }
+ /* Unmap the memory from the mali virtual address space. */
+ mali_mem_block_mali_unmap(alloc);
+ mali_mem_block_free(&mem_bkend->block_mem);
+}
- mutex_unlock(&info->mutex);
- _mali_osk_mutex_signal(session->memory_lock);
- mali_mem_mali_map_free(descriptor);
- mali_mem_descriptor_destroy(descriptor);
+int mali_mem_block_alloc(mali_mem_block_mem *block_mem, u32 size)
+{
+ struct mali_block_node *m_page, *m_tmp;
+ size_t page_count = PAGE_ALIGN(size) / _MALI_OSK_MALI_PAGE_SIZE;
+ mali_block_allocator *info = mali_mem_block_gobal_allocator;
+ MALI_DEBUG_ASSERT_POINTER(info);
- return NULL;
+ MALI_DEBUG_PRINT(4, ("BLOCK Mem: Allocate size = 0x%x\n", size));
+ /*do some init */
+ INIT_LIST_HEAD(&block_mem->pfns);
+
+ spin_lock(&info->sp_lock);
+ /*check if have enough space*/
+ if (atomic_read(&info->free_num) > page_count) {
+ list_for_each_entry_safe(m_page, m_tmp , &info->free, list) {
+ if (page_count > 0) {
+ MALI_DEBUG_ASSERT(m_page->type == MALI_PAGE_NODE_BLOCK);
+ MALI_DEBUG_ASSERT(mali_mem_block_get_ref_count(m_page) == 0);
+ list_move(&m_page->list, &block_mem->pfns);
+ block_mem->count++;
+ atomic_dec(&info->free_num);
+ _mali_block_node_ref(m_page);
+ } else {
+ break;
+ }
+ page_count--;
}
-
- left -= current_mapping_size;
- offset += current_mapping_size;
- ret_allocation->mapping_length += current_mapping_size;
-
- --info->free_blocks;
+ } else {
+ /* can't allocate from BLOCK memory*/
+ spin_unlock(&info->sp_lock);
+ return -1;
}
- mutex_unlock(&info->mutex);
- _mali_osk_mutex_signal(session->memory_lock);
+ spin_unlock(&info->sp_lock);
+ return 0;
+}
+
+void mali_mem_block_free(mali_mem_block_mem *block_mem)
+{
+ mali_mem_block_free_list(&block_mem->pfns);
+ MALI_DEBUG_PRINT(4, ("BLOCK Mem free : size = 0x%x\n", block_mem->count * _MALI_OSK_MALI_PAGE_SIZE));
+ block_mem->count = 0;
+ MALI_DEBUG_ASSERT(list_empty(&block_mem->pfns));
+}
- MALI_DEBUG_ASSERT(0 == left);
- /* Record all the information about this allocation */
- ret_allocation->last_allocated = last_allocated;
- ret_allocation->info = info;
+void mali_mem_block_free_list(struct list_head *list)
+{
+ struct mali_block_node *m_page, *m_tmp;
+ mali_block_allocator *info = mali_mem_block_gobal_allocator;
- return descriptor;
+ if (info) {
+ spin_lock(&info->sp_lock);
+ list_for_each_entry_safe(m_page, m_tmp , list, list) {
+ mali_mem_block_free_node(m_page);
+ }
+ spin_unlock(&info->sp_lock);
+ }
}
-void mali_mem_block_release(mali_mem_allocation *descriptor)
+/* free the node,*/
+void mali_mem_block_free_node(struct mali_block_node *node)
{
- block_allocator *info = descriptor->block_mem.mem.info;
- block_info *block, *next;
- block_allocator_allocation *allocation = &descriptor->block_mem.mem;
-
- MALI_DEBUG_ASSERT(MALI_MEM_BLOCK == descriptor->type);
+ mali_block_allocator *info = mali_mem_block_gobal_allocator;
+
+ /* only handle BLOCK node */
+ if (node->type == MALI_PAGE_NODE_BLOCK && info) {
+ /*Need to make this atomic?*/
+ if (1 == _mali_block_node_get_ref_count(node)) {
+ /*Move to free list*/
+ _mali_block_node_unref(node);
+ list_move_tail(&node->list, &info->free);
+ atomic_add(1, &info->free_num);
+ } else {
+ _mali_block_node_unref(node);
+ list_del(&node->list);
+ kfree(node);
+ }
+ }
+}
- block = allocation->last_allocated;
- MALI_DEBUG_ASSERT_POINTER(block);
+int mali_mem_block_mali_map(mali_mem_block_mem *block_mem, struct mali_session_data *session, u32 vaddr, u32 props)
+{
+ struct mali_page_directory *pagedir = session->page_directory;
+ struct mali_block_node *m_page;
+ dma_addr_t phys;
+ u32 virt = vaddr;
+ u32 prop = props;
+
+ list_for_each_entry(m_page, &block_mem->pfns, list) {
+ MALI_DEBUG_ASSERT(m_page->type == MALI_PAGE_NODE_BLOCK);
+ phys = _mali_block_node_get_phy_addr(m_page);
+#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT)
+ /* Verify that the "physical" address is 32-bit and
+ * usable for Mali, when on a system with bus addresses
+ * wider than 32-bit. */
+ MALI_DEBUG_ASSERT(0 == (phys >> 32));
+#endif
+ mali_mmu_pagedir_update(pagedir, virt, (mali_dma_addr)phys, MALI_MMU_PAGE_SIZE, prop);
+ virt += MALI_MMU_PAGE_SIZE;
+ }
- /* unmap */
- mali_mem_mali_map_free(descriptor);
+ return 0;
+}
- mutex_lock(&info->mutex);
+void mali_mem_block_mali_unmap(mali_mem_allocation *alloc)
+{
+ struct mali_session_data *session;
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+ session = alloc->session;
+ MALI_DEBUG_ASSERT_POINTER(session);
+
+ mali_session_memory_lock(session);
+ mali_mem_mali_map_free(session, alloc->psize, alloc->mali_vma_node.vm_node.start,
+ alloc->flags);
+ session->mali_mem_array[alloc->type] -= alloc->psize;
+ mali_session_memory_unlock(session);
+}
- while (block) {
- MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks))));
- next = block->next;
+int mali_mem_block_cpu_map(mali_mem_backend *mem_bkend, struct vm_area_struct *vma)
+{
+ int ret;
+ mali_mem_block_mem *block_mem = &mem_bkend->block_mem;
+ unsigned long addr = vma->vm_start;
+ struct mali_block_node *m_page;
+ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_BLOCK);
- /* relink into free-list */
- block->next = info->first_free;
- info->first_free = block;
+ list_for_each_entry(m_page, &block_mem->pfns, list) {
+ MALI_DEBUG_ASSERT(m_page->type == MALI_PAGE_NODE_BLOCK);
+ ret = vm_insert_pfn(vma, addr, _mali_block_node_get_pfn(m_page));
- /* advance the loop */
- block = next;
+ if (unlikely(0 != ret)) {
+ return -EFAULT;
+ }
+ addr += _MALI_OSK_MALI_PAGE_SIZE;
- ++info->free_blocks;
}
- mutex_unlock(&info->mutex);
+ return 0;
}
-u32 mali_mem_block_allocator_stat(void)
-{
- block_allocator *info = (block_allocator *)mali_mem_block_gobal_allocator;
-
- if (NULL == info) return 0;
-
- MALI_DEBUG_ASSERT_POINTER(info);
-
- return (info->num_blocks - info->free_blocks) * MALI_BLOCK_SIZE;
-}
_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(u32 start, u32 size)
{
- mali_mem_allocator *allocator;
+ mali_block_allocator *allocator;
/* Do the low level linux operation first */
}
/* Create generic block allocator object to handle it */
- allocator = mali_mem_block_allocator_create(start, 0 /* cpu_usage_adjust */, size);
+ allocator = mali_mem_block_allocator_create(start, size);
if (NULL == allocator) {
MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n"));
MALI_ERROR(_MALI_OSK_ERR_FAULT);
}
- mali_mem_block_gobal_allocator = (block_allocator *)allocator;
+ mali_mem_block_gobal_allocator = (mali_block_allocator *)allocator;
return _MALI_OSK_ERR_OK;
}
+
+mali_bool mali_memory_have_dedicated_memory(void)
+{
+ return mali_mem_block_gobal_allocator ? MALI_TRUE : MALI_FALSE;
+}
+
+u32 mali_mem_block_allocator_stat(void)
+{
+ mali_block_allocator *allocator = mali_mem_block_gobal_allocator;
+ MALI_DEBUG_ASSERT_POINTER(allocator);
+
+ return (allocator->total_num - atomic_read(&allocator->free_num)) * _MALI_OSK_MALI_PAGE_SIZE;
+}
/*
- * Copyright (C) 2010, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#include "mali_session.h"
#include "mali_memory.h"
+#include <linux/spinlock.h>
#include "mali_memory_types.h"
-typedef struct mali_mem_allocator mali_mem_allocator;
-
-mali_mem_allocator *mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size);
-void mali_mem_block_allocator_destroy(mali_mem_allocator *allocator);
-
-mali_mem_allocation *mali_mem_block_alloc(u32 mali_addr, u32 size, struct vm_area_struct *vma, struct mali_session_data *session);
-void mali_mem_block_release(mali_mem_allocation *descriptor);
-
+#define MALI_BLOCK_SIZE (PAGE_SIZE) /* 4 kB, manage BLOCK memory as page size */
+#define MALI_BLOCK_REF_MASK (0xFFF)
+#define MALI_BLOCK_MAX_REF_COUNT (0xFFF)
+
+
+
+typedef struct mali_block_allocator {
+ /*
+ * In free list, each node's ref_count is 0,
+ * ref_count added when allocated or referenced in COW
+ */
+ mali_block_item *items; /* information for each block item*/
+ struct list_head free; /*free list of mali_memory_node*/
+ spinlock_t sp_lock; /*lock for reference count & free list opertion*/
+ u32 total_num; /* Number of total pages*/
+ atomic_t free_num; /*number of free pages*/
+} mali_block_allocator;
+
+unsigned long _mali_blk_item_get_phy_addr(mali_block_item *item);
+unsigned long _mali_blk_item_get_pfn(mali_block_item *item);
+u32 mali_mem_block_get_ref_count(mali_block_node *node);
+u32 mali_mem_block_add_ref(mali_block_node *node);
+u32 mali_mem_block_dec_ref(mali_block_node *node);
+void mali_mem_block_release(mali_mem_backend *mem_bkend);
+int mali_mem_block_alloc(mali_mem_block_mem *block_mem, u32 size);
+int mali_mem_block_mali_map(mali_mem_block_mem *block_mem, struct mali_session_data *session, u32 vaddr, u32 props);
+void mali_mem_block_mali_unmap(mali_mem_allocation *alloc);
+
+int mali_mem_block_cpu_map(mali_mem_backend *mem_bkend, struct vm_area_struct *vma);
+_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(u32 start, u32 size);
+mali_bool mali_memory_have_dedicated_memory(void);
+void mali_mem_block_free(mali_mem_block_mem *block_mem);
+void mali_mem_block_free_list(struct list_head *list);
+void mali_mem_block_free_node(struct mali_block_node *node);
+void mali_mem_block_allocator_destroy(void);
u32 mali_mem_block_allocator_stat(void);
#endif /* __MALI_BLOCK_ALLOCATOR_H__ */
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#include "mali_memory.h"
#include "mali_memory_dma_buf.h"
-
+#include "mali_memory_virtual.h"
#include "mali_pp_job.h"
-static void mali_dma_buf_unmap(struct mali_dma_buf_attachment *mem);
-
-struct mali_dma_buf_attachment {
- struct dma_buf *buf;
- struct dma_buf_attachment *attachment;
- struct sg_table *sgt;
- struct mali_session_data *session;
- int map_ref;
- struct mutex map_lock;
- mali_bool is_mapped;
- wait_queue_head_t wait_queue;
-};
+static void mali_dma_buf_unmap(mali_mem_allocation *alloc, struct mali_dma_buf_attachment *mem);
-static void mali_dma_buf_release(struct mali_dma_buf_attachment *mem)
+void mali_mem_dma_buf_release(mali_mem_backend *mem_backend)
{
- MALI_DEBUG_PRINT(3, ("Mali DMA-buf: release attachment %p\n", mem));
+ struct mali_dma_buf_attachment *mem;
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+ MALI_DEBUG_ASSERT(MALI_MEM_DMA_BUF == mem_backend->type);
+ mem = mem_backend->dma_buf.attachment;
MALI_DEBUG_ASSERT_POINTER(mem);
MALI_DEBUG_ASSERT_POINTER(mem->attachment);
MALI_DEBUG_ASSERT_POINTER(mem->buf);
+ MALI_DEBUG_PRINT(3, ("Mali DMA-buf: release attachment %p\n", mem));
#if defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ MALI_DEBUG_ASSERT_POINTER(mem_backend->mali_allocation);
/* We mapped implicitly on attach, so we need to unmap on release */
- mali_dma_buf_unmap(mem);
+ mali_dma_buf_unmap(mem_backend->mali_allocation, mem);
#endif
-
/* Wait for buffer to become unmapped */
wait_event(mem->wait_queue, !mem->is_mapped);
MALI_DEBUG_ASSERT(!mem->is_mapped);
_mali_osk_free(mem);
}
-void mali_mem_dma_buf_release(mali_mem_allocation *descriptor)
-{
- struct mali_dma_buf_attachment *mem = descriptor->dma_buf.attachment;
-
- mali_dma_buf_release(mem);
-}
-
/*
* Map DMA buf attachment \a mem into \a session at virtual address \a virt.
*/
-static int mali_dma_buf_map(struct mali_dma_buf_attachment *mem, struct mali_session_data *session, u32 virt, u32 flags)
+static int mali_dma_buf_map(mali_mem_backend *mem_backend)
{
+ mali_mem_allocation *alloc;
+ struct mali_dma_buf_attachment *mem;
+ struct mali_session_data *session;
struct mali_page_directory *pagedir;
+ _mali_osk_errcode_t err;
struct scatterlist *sg;
+ u32 virt, flags;
int i;
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+
+ alloc = mem_backend->mali_allocation;
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+
+ mem = mem_backend->dma_buf.attachment;
MALI_DEBUG_ASSERT_POINTER(mem);
+
+ session = alloc->session;
MALI_DEBUG_ASSERT_POINTER(session);
MALI_DEBUG_ASSERT(mem->session == session);
- mutex_lock(&mem->map_lock);
+ virt = alloc->mali_vma_node.vm_node.start;
+ flags = alloc->flags;
+ mali_session_memory_lock(session);
mem->map_ref++;
MALI_DEBUG_PRINT(5, ("Mali DMA-buf: map attachment %p, new map_ref = %d\n", mem, mem->map_ref));
if (1 == mem->map_ref) {
+
/* First reference taken, so we need to map the dma buf */
MALI_DEBUG_ASSERT(!mem->is_mapped);
- pagedir = mali_session_get_page_directory(session);
- MALI_DEBUG_ASSERT_POINTER(pagedir);
-
mem->sgt = dma_buf_map_attachment(mem->attachment, DMA_BIDIRECTIONAL);
if (IS_ERR_OR_NULL(mem->sgt)) {
MALI_DEBUG_PRINT_ERROR(("Failed to map dma-buf attachment\n"));
+ mem->map_ref--;
+ mali_session_memory_unlock(session);
return -EFAULT;
}
+ err = mali_mem_mali_map_prepare(alloc);
+ if (_MALI_OSK_ERR_OK != err) {
+ MALI_DEBUG_PRINT(1, ("Mapping of DMA memory failed\n"));
+ mem->map_ref--;
+ mali_session_memory_unlock(session);
+ return -ENOMEM;
+ }
+
+ pagedir = mali_session_get_page_directory(session);
+ MALI_DEBUG_ASSERT_POINTER(pagedir);
+
for_each_sg(mem->sgt->sgl, sg, mem->sgt->nents, i) {
u32 size = sg_dma_len(sg);
dma_addr_t phys = sg_dma_address(sg);
}
mem->is_mapped = MALI_TRUE;
- mutex_unlock(&mem->map_lock);
-
+ session->mali_mem_array[mem_backend->type] += mem_backend->size;
+ mali_session_memory_unlock(session);
/* Wake up any thread waiting for buffer to become mapped */
wake_up_all(&mem->wait_queue);
} else {
MALI_DEBUG_ASSERT(mem->is_mapped);
- mutex_unlock(&mem->map_lock);
+ mali_session_memory_unlock(session);
}
return 0;
}
-static void mali_dma_buf_unmap(struct mali_dma_buf_attachment *mem)
+static void mali_dma_buf_unmap(mali_mem_allocation *alloc, struct mali_dma_buf_attachment *mem)
{
+ MALI_DEBUG_ASSERT_POINTER(alloc);
MALI_DEBUG_ASSERT_POINTER(mem);
MALI_DEBUG_ASSERT_POINTER(mem->attachment);
MALI_DEBUG_ASSERT_POINTER(mem->buf);
+ MALI_DEBUG_ASSERT_POINTER(alloc->session);
- mutex_lock(&mem->map_lock);
-
+ mali_session_memory_lock(alloc->session);
mem->map_ref--;
MALI_DEBUG_PRINT(5, ("Mali DMA-buf: unmap attachment %p, new map_ref = %d\n", mem, mem->map_ref));
if (0 == mem->map_ref) {
dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL);
-
+ if (MALI_TRUE == mem->is_mapped) {
+ mali_mem_mali_map_free(alloc->session, alloc->psize, alloc->mali_vma_node.vm_node.start,
+ alloc->flags);
+ }
mem->is_mapped = MALI_FALSE;
+ alloc->session->mali_mem_array[alloc->type] -= alloc->psize;
}
-
- mutex_unlock(&mem->map_lock);
-
+ mali_session_memory_unlock(alloc->session);
/* Wake up any thread waiting for buffer to become unmapped */
wake_up_all(&mem->wait_queue);
}
#if !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
int mali_dma_buf_map_job(struct mali_pp_job *job)
{
- mali_mem_allocation *descriptor;
struct mali_dma_buf_attachment *mem;
_mali_osk_errcode_t err;
int i;
int ret = 0;
u32 num_memory_cookies;
struct mali_session_data *session;
+ struct mali_vma_node *mali_vma_node = NULL;
+ mali_mem_allocation *mali_alloc = NULL;
+ mali_mem_backend *mem_bkend = NULL;
MALI_DEBUG_ASSERT_POINTER(job);
MALI_DEBUG_ASSERT_POINTER(session);
- mali_session_memory_lock(session);
-
for (i = 0; i < num_memory_cookies; i++) {
- u32 cookie = mali_pp_job_get_memory_cookie(job, i);
-
- if (0 == cookie) {
- /* 0 is not a valid cookie */
- MALI_DEBUG_ASSERT(NULL ==
- mali_pp_job_get_dma_buf(job, i));
+ u32 mali_addr = mali_pp_job_get_memory_cookie(job, i);
+ mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, mali_addr, 0);
+ MALI_DEBUG_ASSERT(NULL != mali_vma_node);
+ mali_alloc = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node);
+ MALI_DEBUG_ASSERT(NULL != mali_alloc);
+ if (MALI_MEM_DMA_BUF != mali_alloc->type) {
continue;
}
- MALI_DEBUG_ASSERT(0 < cookie);
+ /* Get backend memory & Map on CPU */
+ mutex_lock(&mali_idr_mutex);
+ mem_bkend = idr_find(&mali_backend_idr, mali_alloc->backend_handle);
+ mutex_unlock(&mali_idr_mutex);
+ MALI_DEBUG_ASSERT(NULL != mem_bkend);
- err = mali_descriptor_mapping_get(
- mali_pp_job_get_session(job)->descriptor_mapping,
- cookie, (void **)&descriptor);
-
- if (_MALI_OSK_ERR_OK != err) {
- MALI_DEBUG_PRINT_ERROR(("Mali DMA-buf: Failed to get descriptor for cookie %d\n", cookie));
- ret = -EFAULT;
- MALI_DEBUG_ASSERT(NULL ==
- mali_pp_job_get_dma_buf(job, i));
- continue;
- }
-
- if (MALI_MEM_DMA_BUF != descriptor->type) {
- /* Not a DMA-buf */
- MALI_DEBUG_ASSERT(NULL ==
- mali_pp_job_get_dma_buf(job, i));
- continue;
- }
-
- mem = descriptor->dma_buf.attachment;
+ mem = mem_bkend->dma_buf.attachment;
MALI_DEBUG_ASSERT_POINTER(mem);
MALI_DEBUG_ASSERT(mem->session == mali_pp_job_get_session(job));
- err = mali_dma_buf_map(mem, mem->session, descriptor->mali_mapping.addr, descriptor->flags);
+ err = mali_dma_buf_map(mem_bkend);
if (0 != err) {
- MALI_DEBUG_PRINT_ERROR(("Mali DMA-buf: Failed to map dma-buf for cookie %d at mali address %x\b",
- cookie, descriptor->mali_mapping.addr));
+ MALI_DEBUG_PRINT_ERROR(("Mali DMA-buf: Failed to map dma-buf for mali address %x\n", mali_addr));
ret = -EFAULT;
- MALI_DEBUG_ASSERT(NULL ==
- mali_pp_job_get_dma_buf(job, i));
continue;
}
-
- /* Add mem to list of DMA-bufs mapped for this job */
- mali_pp_job_set_dma_buf(job, i, mem);
}
-
- mali_session_memory_unlock(session);
-
return ret;
}
void mali_dma_buf_unmap_job(struct mali_pp_job *job)
{
- u32 i;
- u32 num_dma_bufs = mali_pp_job_num_dma_bufs(job);
+ struct mali_dma_buf_attachment *mem;
+ int i;
+ u32 num_memory_cookies;
+ struct mali_session_data *session;
+ struct mali_vma_node *mali_vma_node = NULL;
+ mali_mem_allocation *mali_alloc = NULL;
+ mali_mem_backend *mem_bkend = NULL;
+
+ MALI_DEBUG_ASSERT_POINTER(job);
+
+ num_memory_cookies = mali_pp_job_num_memory_cookies(job);
- for (i = 0; i < num_dma_bufs; i++) {
- struct mali_dma_buf_attachment *mem;
+ session = mali_pp_job_get_session(job);
- mem = mali_pp_job_get_dma_buf(job, i);
- if (NULL != mem) {
- mali_dma_buf_unmap(mem);
- mali_pp_job_set_dma_buf(job, i, NULL);
+ MALI_DEBUG_ASSERT_POINTER(session);
+
+ for (i = 0; i < num_memory_cookies; i++) {
+ u32 mali_addr = mali_pp_job_get_memory_cookie(job, i);
+ mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, mali_addr, 0);
+ MALI_DEBUG_ASSERT(NULL != mali_vma_node);
+ mali_alloc = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node);
+ MALI_DEBUG_ASSERT(NULL != mali_alloc);
+ if (MALI_MEM_DMA_BUF != mali_alloc->type) {
+ continue;
}
+
+ /* Get backend memory & Map on CPU */
+ mutex_lock(&mali_idr_mutex);
+ mem_bkend = idr_find(&mali_backend_idr, mali_alloc->backend_handle);
+ mutex_unlock(&mali_idr_mutex);
+ MALI_DEBUG_ASSERT(NULL != mem_bkend);
+
+ mem = mem_bkend->dma_buf.attachment;
+
+ MALI_DEBUG_ASSERT_POINTER(mem);
+ MALI_DEBUG_ASSERT(mem->session == mali_pp_job_get_session(job));
+ mali_dma_buf_unmap(mem_bkend->mali_allocation, mem);
}
}
#endif /* !CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH */
-int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *user_arg)
+int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *user_arg)
{
- struct dma_buf *buf;
- struct mali_dma_buf_attachment *mem;
- _mali_uk_attach_dma_buf_s args;
- mali_mem_allocation *descriptor;
- int md;
+ _mali_uk_dma_buf_get_size_s args;
int fd;
+ struct dma_buf *buf;
- /* Get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
- if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_attach_dma_buf_s))) {
+ /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_dma_buf_get_size_s))) {
return -EFAULT;
}
- if (args.mali_address & ~PAGE_MASK) {
- MALI_DEBUG_PRINT_ERROR(("Requested address (0x%08x) is not page aligned\n", args.mali_address));
- return -EINVAL;
- }
-
- if (args.mali_address >= args.mali_address + args.size) {
- MALI_DEBUG_PRINT_ERROR(("Requested address and size (0x%08x + 0x%08x) is too big\n", args.mali_address, args.size));
- return -EINVAL;
- }
-
+ /* Do DMA-BUF stuff */
fd = args.mem_fd;
buf = dma_buf_get(fd);
return PTR_RET(buf);
}
- /* Currently, mapping of the full buffer are supported. */
- if (args.size != buf->size) {
- MALI_DEBUG_PRINT_ERROR(("dma-buf size doesn't match mapping size.\n"));
- dma_buf_put(buf);
- return -EINVAL;
- }
-
- mem = _mali_osk_calloc(1, sizeof(struct mali_dma_buf_attachment));
- if (NULL == mem) {
- MALI_DEBUG_PRINT_ERROR(("Failed to allocate dma-buf tracing struct\n"));
+ if (0 != put_user(buf->size, &user_arg->size)) {
dma_buf_put(buf);
- return -ENOMEM;
- }
-
- mem->buf = buf;
- mem->session = session;
- mem->map_ref = 0;
- mutex_init(&mem->map_lock);
- init_waitqueue_head(&mem->wait_queue);
-
- mem->attachment = dma_buf_attach(mem->buf, &mali_platform_device->dev);
- if (NULL == mem->attachment) {
- MALI_DEBUG_PRINT_ERROR(("Failed to attach to dma-buf %d\n", fd));
- dma_buf_put(mem->buf);
- _mali_osk_free(mem);
return -EFAULT;
}
- /* Set up Mali memory descriptor */
- descriptor = mali_mem_descriptor_create(session, MALI_MEM_DMA_BUF);
- if (NULL == descriptor) {
- MALI_DEBUG_PRINT_ERROR(("Failed to allocate descriptor dma-buf %d\n", fd));
- mali_dma_buf_release(mem);
- return -ENOMEM;
- }
-
- descriptor->size = args.size;
- descriptor->mali_mapping.addr = args.mali_address;
+ dma_buf_put(buf);
- descriptor->dma_buf.attachment = mem;
+ return 0;
+}
- descriptor->flags |= MALI_MEM_FLAG_DONT_CPU_MAP;
- if (args.flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
- descriptor->flags = MALI_MEM_FLAG_MALI_GUARD_PAGE;
- }
+_mali_osk_errcode_t mali_memory_bind_dma_buf(mali_mem_allocation *alloc,
+ mali_mem_backend *mem_backend,
+ int fd, u32 flags)
+{
+ struct dma_buf *buf;
+ struct mali_dma_buf_attachment *dma_mem;
+ struct mali_session_data *session = alloc->session;
- mali_session_memory_lock(session);
+ MALI_DEBUG_ASSERT_POINTER(session);
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+ MALI_DEBUG_ASSERT_POINTER(alloc);
- /* Map dma-buf into this session's page tables */
- if (_MALI_OSK_ERR_OK != mali_mem_mali_map_prepare(descriptor)) {
- mali_session_memory_unlock(session);
- MALI_DEBUG_PRINT_ERROR(("Failed to map dma-buf on Mali\n"));
- mali_mem_descriptor_destroy(descriptor);
- mali_dma_buf_release(mem);
- return -ENOMEM;
+ /* get dma buffer */
+ buf = dma_buf_get(fd);
+ if (IS_ERR_OR_NULL(buf)) {
+ return _MALI_OSK_ERR_FAULT;
}
-#if defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
- /* Map memory into session's Mali virtual address space. */
-
- if (0 != mali_dma_buf_map(mem, session, descriptor->mali_mapping.addr, descriptor->flags)) {
- mali_mem_mali_map_free(descriptor);
- mali_session_memory_unlock(session);
-
- MALI_DEBUG_PRINT_ERROR(("Failed to map dma-buf %d into Mali address space\n", fd));
- mali_mem_descriptor_destroy(descriptor);
- mali_dma_buf_release(mem);
- return -ENOMEM;
+ /* Currently, mapping of the full buffer are supported. */
+ if (alloc->psize != buf->size) {
+ goto failed_alloc_mem;
}
-#endif
-
- mali_session_memory_unlock(session);
-
- /* Get descriptor mapping for memory. */
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md)) {
- mali_session_memory_lock(session);
- mali_mem_mali_map_free(descriptor);
- mali_session_memory_unlock(session);
-
- MALI_DEBUG_PRINT_ERROR(("Failed to create descriptor mapping for dma-buf %d\n", fd));
- mali_mem_descriptor_destroy(descriptor);
- mali_dma_buf_release(mem);
- return -EFAULT;
+ dma_mem = _mali_osk_calloc(1, sizeof(struct mali_dma_buf_attachment));
+ if (NULL == dma_mem) {
+ goto failed_alloc_mem;
}
- /* Return stuff to user space */
- if (0 != put_user(md, &user_arg->cookie)) {
- mali_session_memory_lock(session);
- mali_mem_mali_map_free(descriptor);
- mali_session_memory_unlock(session);
+ dma_mem->buf = buf;
+ dma_mem->session = session;
+ dma_mem->map_ref = 0;
+ init_waitqueue_head(&dma_mem->wait_queue);
- MALI_DEBUG_PRINT_ERROR(("Failed to return descriptor to user space for dma-buf %d\n", fd));
- mali_descriptor_mapping_free(session->descriptor_mapping, md);
- mali_dma_buf_release(mem);
- return -EFAULT;
+ dma_mem->attachment = dma_buf_attach(dma_mem->buf, &mali_platform_device->dev);
+ if (NULL == dma_mem->attachment) {
+ goto failed_dma_attach;
}
- return 0;
-}
-
-int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *user_arg)
-{
- int ret = 0;
- _mali_uk_release_dma_buf_s args;
- mali_mem_allocation *descriptor;
+ mem_backend->dma_buf.attachment = dma_mem;
- /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
- if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_release_dma_buf_s))) {
- return -EFAULT;
+ alloc->flags |= MALI_MEM_FLAG_DONT_CPU_MAP;
+ if (flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
+ alloc->flags |= MALI_MEM_FLAG_MALI_GUARD_PAGE;
}
- MALI_DEBUG_PRINT(3, ("Mali DMA-buf: release descriptor cookie %ld\n", args.cookie));
-
- mali_session_memory_lock(session);
-
- descriptor = mali_descriptor_mapping_free(session->descriptor_mapping, (u32)args.cookie);
-
- if (NULL != descriptor) {
- MALI_DEBUG_PRINT(3, ("Mali DMA-buf: Releasing dma-buf at mali address %x\n", descriptor->mali_mapping.addr));
-
- mali_mem_mali_map_free(descriptor);
- mali_dma_buf_release(descriptor->dma_buf.attachment);
-
- mali_mem_descriptor_destroy(descriptor);
- } else {
- MALI_DEBUG_PRINT_ERROR(("Invalid memory descriptor %ld used to release dma-buf\n", args.cookie));
- ret = -EINVAL;
+#if defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ /* Map memory into session's Mali virtual address space. */
+ if (0 != mali_dma_buf_map(mem_backend)) {
+ goto Failed_dma_map;
}
+#endif
- mali_session_memory_unlock(session);
+ return _MALI_OSK_ERR_OK;
- /* Return the error that _mali_ukk_map_external_ump_mem produced */
- return ret;
+#if defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+Failed_dma_map:
+ mali_dma_buf_unmap(alloc, dma_mem);
+#endif
+ /* Wait for buffer to become unmapped */
+ wait_event(dma_mem->wait_queue, !dma_mem->is_mapped);
+ MALI_DEBUG_ASSERT(!dma_mem->is_mapped);
+ dma_buf_detach(dma_mem->buf, dma_mem->attachment);
+failed_dma_attach:
+ _mali_osk_free(dma_mem);
+failed_alloc_mem:
+ dma_buf_put(buf);
+ return _MALI_OSK_ERR_FAULT;
}
-int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *user_arg)
-{
- _mali_uk_dma_buf_get_size_s args;
- int fd;
- struct dma_buf *buf;
- /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
- if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_dma_buf_get_size_s))) {
- return -EFAULT;
- }
-
- /* Do DMA-BUF stuff */
- fd = args.mem_fd;
-
- buf = dma_buf_get(fd);
- if (IS_ERR_OR_NULL(buf)) {
- MALI_DEBUG_PRINT_ERROR(("Failed to get dma-buf from fd: %d\n", fd));
- return PTR_RET(buf);
- }
-
- if (0 != put_user(buf->size, &user_arg->size)) {
- dma_buf_put(buf);
- return -EFAULT;
- }
+void mali_memory_unbind_dma_buf(mali_mem_backend *mem_backend)
+{
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+ mali_mem_dma_buf_release(mem_backend);
+}
- dma_buf_put(buf);
- return 0;
-}
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
struct mali_pp_job;
struct mali_dma_buf_attachment;
+struct mali_dma_buf_attachment {
+ struct dma_buf *buf;
+ struct dma_buf_attachment *attachment;
+ struct sg_table *sgt;
+ struct mali_session_data *session;
+ int map_ref;
+ struct mutex map_lock;
+ mali_bool is_mapped;
+ wait_queue_head_t wait_queue;
+};
-int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *arg);
-int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *arg);
int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *arg);
-void mali_mem_dma_buf_release(mali_mem_allocation *descriptor);
+void mali_mem_dma_buf_release(mali_mem_backend *mem_backend);
+
+_mali_osk_errcode_t mali_memory_bind_dma_buf(mali_mem_allocation *alloc,
+ mali_mem_backend *mem_backend,
+ int fd, u32 flags);
+
+void mali_memory_unbind_dma_buf(mali_mem_backend *mem_backend);
#if !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
int mali_dma_buf_map_job(struct mali_pp_job *job);
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#include "mali_osk.h"
#include "mali_ukk.h"
#include "mali_memory.h"
-#include "mali_kernel_descriptor_mapping.h"
#include "mali_mem_validation.h"
#include "mali_uk_types.h"
-void mali_mem_external_release(mali_mem_allocation *descriptor)
+void mali_mem_external_release(mali_mem_backend *mem_backend)
{
- MALI_DEBUG_ASSERT(MALI_MEM_EXTERNAL == descriptor->type);
-
- mali_mem_mali_map_free(descriptor);
+ mali_mem_allocation *alloc;
+ struct mali_session_data *session;
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+ alloc = mem_backend->mali_allocation;
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+ MALI_DEBUG_ASSERT(MALI_MEM_EXTERNAL == mem_backend->type);
+
+ session = alloc->session;
+ MALI_DEBUG_ASSERT_POINTER(session);
+ mali_session_memory_lock(session);
+ mali_mem_mali_map_free(session, alloc->psize, alloc->mali_vma_node.vm_node.start,
+ alloc->flags);
+ session->mali_mem_array[mem_backend->type] -= mem_backend->size;
+ mali_session_memory_unlock(session);
}
-_mali_osk_errcode_t _mali_ukk_map_external_mem(_mali_uk_map_external_mem_s *args)
+_mali_osk_errcode_t mali_memory_bind_ext_mem(mali_mem_allocation *alloc,
+ mali_mem_backend *mem_backend,
+ u32 phys_addr,
+ u32 flag)
{
struct mali_session_data *session;
- mali_mem_allocation *descriptor;
- int md;
_mali_osk_errcode_t err;
-
- MALI_DEBUG_ASSERT_POINTER(args);
-
- session = (struct mali_session_data *)(uintptr_t)args->ctx;
+ u32 virt, phys, size;
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+ size = alloc->psize;
+ session = (struct mali_session_data *)(uintptr_t)alloc->session;
MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_INVALID_ARGS);
/* check arguments */
/* NULL might be a valid Mali address */
- if (! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+ if (!size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
/* size must be a multiple of the system page size */
- if (args->size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
-
- MALI_DEBUG_PRINT(3,
- ("Requested to map physical memory 0x%x-0x%x into virtual memory 0x%x\n",
- args->phys_addr, (args->phys_addr + args->size - 1),
- args->mali_address));
+ if (size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
/* Validate the mali physical range */
- if (_MALI_OSK_ERR_OK != mali_mem_validation_check(args->phys_addr, args->size)) {
+ if (_MALI_OSK_ERR_OK != mali_mem_validation_check(phys_addr, size)) {
return _MALI_OSK_ERR_FAULT;
}
- descriptor = mali_mem_descriptor_create(session, MALI_MEM_EXTERNAL);
- if (NULL == descriptor) MALI_ERROR(_MALI_OSK_ERR_NOMEM);
-
- descriptor->mali_mapping.addr = args->mali_address;
- descriptor->size = args->size;
-
- if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
- descriptor->flags = MALI_MEM_FLAG_MALI_GUARD_PAGE;
+ if (flag & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
+ alloc->flags |= MALI_MEM_FLAG_MALI_GUARD_PAGE;
}
- _mali_osk_mutex_wait(session->memory_lock);
- {
- u32 virt = descriptor->mali_mapping.addr;
- u32 phys = args->phys_addr;
- u32 size = args->size;
+ mali_session_memory_lock(session);
- err = mali_mem_mali_map_prepare(descriptor);
- if (_MALI_OSK_ERR_OK != err) {
- _mali_osk_mutex_signal(session->memory_lock);
- mali_mem_descriptor_destroy(descriptor);
- return _MALI_OSK_ERR_NOMEM;
- }
+ virt = alloc->mali_vma_node.vm_node.start;
+ phys = phys_addr;
- mali_mmu_pagedir_update(session->page_directory, virt, phys, size, MALI_MMU_FLAGS_DEFAULT);
-
- if (descriptor->flags & MALI_MEM_FLAG_MALI_GUARD_PAGE) {
- mali_mmu_pagedir_update(session->page_directory, virt + size, phys, _MALI_OSK_MALI_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT);
- }
- }
- _mali_osk_mutex_signal(session->memory_lock);
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md)) {
- _mali_osk_mutex_wait(session->memory_lock);
- mali_mem_external_release(descriptor);
- _mali_osk_mutex_signal(session->memory_lock);
- mali_mem_descriptor_destroy(descriptor);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ err = mali_mem_mali_map_prepare(alloc);
+ if (_MALI_OSK_ERR_OK != err) {
+ mali_session_memory_unlock(session);
+ return _MALI_OSK_ERR_NOMEM;
}
- args->cookie = md;
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t _mali_ukk_unmap_external_mem(_mali_uk_unmap_external_mem_s *args)
-{
- mali_mem_allocation *descriptor;
- void *old_value;
- struct mali_session_data *session;
-
- MALI_DEBUG_ASSERT_POINTER(args);
+ mali_mmu_pagedir_update(session->page_directory, virt, phys, size, MALI_MMU_FLAGS_DEFAULT);
- session = (struct mali_session_data *)(uintptr_t)args->ctx;
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_INVALID_ARGS);
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session->descriptor_mapping, args->cookie, (void **)&descriptor)) {
- MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to unmap external memory\n", args->cookie));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ if (alloc->flags & MALI_MEM_FLAG_MALI_GUARD_PAGE) {
+ mali_mmu_pagedir_update(session->page_directory, virt + size, phys, _MALI_OSK_MALI_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT);
}
+ MALI_DEBUG_PRINT(3,
+ ("Requested to map physical memory 0x%x-0x%x into virtual memory 0x%x\n",
+ phys_addr, (phys_addr + size - 1),
+ virt));
+ session->mali_mem_array[mem_backend->type] += mem_backend->size;
+ mali_session_memory_unlock(session);
- old_value = mali_descriptor_mapping_free(session->descriptor_mapping, args->cookie);
+ MALI_SUCCESS;
+}
- if (NULL != old_value) {
- _mali_osk_mutex_wait(session->memory_lock);
- mali_mem_external_release(descriptor);
- _mali_osk_mutex_signal(session->memory_lock);
- mali_mem_descriptor_destroy(descriptor);
- }
- MALI_SUCCESS;
+void mali_memory_unbind_ext_mem(mali_mem_backend *mem_backend)
+{
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+ mali_mem_external_release(mem_backend);
}
+
--- /dev/null
+
+/*
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_MEMORY_EXTERNAL_H__
+#define __MALI_MEMORY_EXTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_mali_osk_errcode_t mali_memory_bind_ext_mem(mali_mem_allocation *alloc,
+ mali_mem_backend *mem_backend,
+ u32 phys_addr,
+ u32 flag);
+
+void mali_memory_unbind_ext_mem(mali_mem_backend *mem_backend);
+
+void mali_mem_external_release(mali_mem_backend *mem_backend);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/mm_types.h>
+#include <linux/fs.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+#include <linux/dma-buf.h>
+#endif
+#include <linux/idr.h>
+
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_kernel_linux.h"
+#include "mali_scheduler.h"
+#include "mali_memory.h"
+#include "mali_memory_os_alloc.h"
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+#include "mali_memory_dma_buf.h"
+#endif
+#if defined(CONFIG_MALI400_UMP)
+#include "mali_memory_ump.h"
+#endif
+#include "mali_memory_manager.h"
+#include "mali_memory_virtual.h"
+#include "mali_memory_util.h"
+#include "mali_memory_external.h"
+#include "mali_memory_block_alloc.h"
+
+#define MALI_S32_MAX 0x7fffffff
+
+/*
+* New memory system interface
+*/
+
+/*inti idr for backend memory */
+struct idr mali_backend_idr;
+struct mutex mali_idr_mutex;
+
+/* init allocation manager */
+int mali_memory_manager_init(struct mali_allocation_manager *mgr)
+{
+ /* init Locks */
+ rwlock_init(&mgr->vm_lock);
+ mutex_init(&mgr->list_mutex);
+
+ /* init link */
+ INIT_LIST_HEAD(&mgr->head);
+
+ /* init RB tree */
+ mgr->allocation_mgr_rb = RB_ROOT;
+ mgr->mali_allocation_nr = 0;
+ return 0;
+}
+
+/* deinit allocation manager
+* Do some check for debug
+*/
+void mali_memory_manager_uninit(struct mali_allocation_manager *mgr)
+{
+ /* check RB tree is empty */
+ MALI_DEBUG_ASSERT(((void *)(mgr->allocation_mgr_rb.rb_node) == (void *)rb_last(&mgr->allocation_mgr_rb)));
+ /* check allocation List */
+ MALI_DEBUG_ASSERT(list_empty(&mgr->head));
+}
+
+/* Prepare memory descriptor */
+static mali_mem_allocation *mali_mem_allocation_struct_create(struct mali_session_data *session)
+{
+ mali_mem_allocation *mali_allocation;
+
+ /* Allocate memory */
+ mali_allocation = (mali_mem_allocation *)kzalloc(sizeof(mali_mem_allocation), GFP_KERNEL);
+ if (NULL == mali_allocation) {
+ MALI_DEBUG_PRINT(1, ("mali_mem_allocation_struct_create: descriptor was NULL\n"));
+ return NULL;
+ }
+
+ MALI_DEBUG_CODE(mali_allocation->magic = MALI_MEM_ALLOCATION_VALID_MAGIC);
+
+ /* do init */
+ mali_allocation->flags = 0;
+ mali_allocation->session = session;
+
+ INIT_LIST_HEAD(&mali_allocation->list);
+ kref_init(&mali_allocation->ref);
+
+ /**
+ *add to session list
+ */
+ mutex_lock(&session->allocation_mgr.list_mutex);
+ list_add_tail(&mali_allocation->list, &session->allocation_mgr.head);
+ session->allocation_mgr.mali_allocation_nr++;
+ mutex_unlock(&session->allocation_mgr.list_mutex);
+
+ return mali_allocation;
+}
+
+
+void mali_mem_allocation_struct_destory(mali_mem_allocation *alloc)
+{
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+ MALI_DEBUG_ASSERT_POINTER(alloc->session);
+ mutex_lock(&alloc->session->allocation_mgr.list_mutex);
+ list_del(&alloc->list);
+ alloc->session->allocation_mgr.mali_allocation_nr--;
+ mutex_unlock(&alloc->session->allocation_mgr.list_mutex);
+
+ kfree(alloc);
+}
+
+int mali_mem_backend_struct_create(mali_mem_backend **backend, u32 psize)
+{
+ mali_mem_backend *mem_backend = NULL;
+ s32 ret = -ENOSPC;
+ s32 index = -1;
+ *backend = (mali_mem_backend *)kzalloc(sizeof(mali_mem_backend), GFP_KERNEL);
+ if (NULL == *backend) {
+ MALI_DEBUG_PRINT(1, ("mali_mem_backend_struct_create: backend descriptor was NULL\n"));
+ return -1;
+ }
+ mem_backend = *backend;
+ mem_backend->size = psize;
+ /* link backend with id */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
+again:
+ if (!idr_pre_get(&mali_backend_idr, GFP_KERNEL)) {
+ kfree(mem_backend);
+ return -ENOMEM;
+ }
+ mutex_lock(&mali_idr_mutex);
+ ret = idr_get_new_above(&mali_backend_idr, mem_backend, 1, &index);
+ mutex_unlock(&mali_idr_mutex);
+
+ if (-ENOSPC == ret) {
+ kfree(mem_backend);
+ return -ENOSPC;
+ }
+ if (-EAGAIN == ret)
+ goto again;
+#else
+ mutex_lock(&mali_idr_mutex);
+ ret = idr_alloc(&mali_backend_idr, mem_backend, 1, MALI_S32_MAX, GFP_KERNEL);
+ mutex_unlock(&mali_idr_mutex);
+ index = ret;
+ if (ret < 0) {
+ MALI_DEBUG_PRINT(1, ("mali_mem_backend_struct_create: Can't allocate idr for backend! \n"));
+ kfree(mem_backend);
+ return -ENOSPC;
+ }
+#endif
+ return index;
+}
+
+static void mali_mem_backend_struct_destory(mali_mem_backend **backend, s32 backend_handle)
+{
+ mali_mem_backend *mem_backend = *backend;
+
+ mutex_lock(&mali_idr_mutex);
+ idr_remove(&mali_backend_idr, backend_handle);
+ mutex_unlock(&mali_idr_mutex);
+ kfree(mem_backend);
+ *backend = NULL;
+}
+
+
+/* Set GPU MMU properties */
+static void _mali_memory_gpu_map_property_set(u32 *properties, u32 flags)
+{
+
+ if (_MALI_MEMORY_GPU_READ_ALLOCATE & flags) {
+ *properties = MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE;
+ } else {
+ *properties = MALI_MMU_FLAGS_DEFAULT;
+ }
+}
+
+
+/**
+* function@_mali_ukk_mem_allocate - allocate mali memory
+*/
+_mali_osk_errcode_t _mali_ukk_mem_allocate(_mali_uk_alloc_mem_s *args)
+{
+ struct mali_session_data *session = (struct mali_session_data *)(uintptr_t)args->ctx;
+ mali_mem_backend *mem_backend = NULL;
+ _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT;
+ int retval = 0;
+ mali_mem_allocation *mali_allocation = NULL;
+ struct mali_vma_node *mali_vma_node = NULL;
+
+ MALI_DEBUG_PRINT(4, (" _mali_ukk_mem_allocate, vaddr=0x%x, size =0x%x! \n", args->gpu_vaddr, args->psize));
+
+ /* Check if the address is allocated
+ * Can we trust User mode?
+ */
+ mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, args->gpu_vaddr, 0);
+ if (unlikely(mali_vma_node)) {
+ /* Not support yet */
+ MALI_DEBUG_ASSERT(0);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /**
+ *create mali memory allocation
+ */
+ mali_allocation = mali_mem_allocation_struct_create(session);
+
+ if (mali_allocation == NULL) {
+ MALI_DEBUG_PRINT(1, ("_mali_ukk_mem_allocate: Failed to create allocation struct! \n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+ mali_allocation->psize = args->psize;
+ mali_allocation->vsize = args->vsize;
+
+ /* check if have dedicated memory */
+ if (MALI_TRUE == mali_memory_have_dedicated_memory()) {
+ mali_allocation->type = MALI_MEM_BLOCK;
+ } else {
+ mali_allocation->type = MALI_MEM_OS;
+ }
+
+ /**
+ *add allocation node to RB tree for index
+ */
+ mali_allocation->mali_vma_node.vm_node.start = args->gpu_vaddr;
+ mali_allocation->mali_vma_node.vm_node.size = args->vsize;
+
+ mali_vma_offset_add(&session->allocation_mgr, &mali_allocation->mali_vma_node);
+
+ /* check if need to allocate backend */
+ if (mali_allocation->psize == 0)
+ return _MALI_OSK_ERR_OK;
+
+ /**
+ *allocate physical backend & pages
+ */
+ if (likely(mali_allocation->psize > 0)) {
+ mali_allocation->backend_handle = mali_mem_backend_struct_create(&mem_backend, args->psize);
+ if (mali_allocation->backend_handle < 0) {
+ ret = _MALI_OSK_ERR_NOMEM;
+ MALI_DEBUG_PRINT(1, ("mali_allocation->backend_handle < 0! \n"));
+ goto failed_alloc_backend;
+ }
+
+ mem_backend->mali_allocation = mali_allocation;
+ mem_backend->type = mali_allocation->type;
+
+ if (mem_backend->type == MALI_MEM_OS) {
+ retval = mali_mem_os_alloc_pages(&mem_backend->os_mem, mem_backend->size);
+ } else if (mem_backend->type == MALI_MEM_BLOCK) {
+ /* try to allocated from BLOCK memory first, then try OS memory if failed.*/
+ if (mali_mem_block_alloc(&mem_backend->block_mem, mem_backend->size)) {
+ retval = mali_mem_os_alloc_pages(&mem_backend->os_mem, mem_backend->size);
+ mem_backend->type = MALI_MEM_OS;
+ mali_allocation->type = MALI_MEM_OS;
+ }
+ } else {
+ /* ONLY support mem_os type */
+ MALI_DEBUG_ASSERT(0);
+ }
+
+ if (retval) {
+ ret = _MALI_OSK_ERR_NOMEM;
+ MALI_DEBUG_PRINT(1, (" can't allocate enough pages! \n"));
+ goto failed_alloc_pages;
+ }
+ }
+
+ /**
+ *map to GPU side
+ */
+ mali_allocation->mali_mapping.addr = args->gpu_vaddr;
+
+ /* set gpu mmu propery */
+ _mali_memory_gpu_map_property_set(&mali_allocation->mali_mapping.properties, args->flags);
+
+ if (!(args->flags & _MALI_MEMORY_ALLOCATE_NO_BIND_GPU) && mali_allocation->psize > 0) {
+ _mali_osk_mutex_wait(session->memory_lock);
+ /* Map on Mali */
+ ret = mali_mem_mali_map_prepare(mali_allocation);
+ if (0 != ret) {
+ MALI_DEBUG_PRINT(1, (" prepare map fail! \n"));
+ goto failed_gpu_map;
+ }
+ /* only support os memory type now */
+ if (mem_backend->type == MALI_MEM_OS) {
+ mali_mem_os_mali_map(mem_backend, args->gpu_vaddr,
+ mali_allocation->mali_mapping.properties);
+ } else if (mem_backend->type == MALI_MEM_BLOCK) {
+ mali_mem_block_mali_map(&mem_backend->block_mem, session, args->gpu_vaddr,
+ mali_allocation->mali_mapping.properties);
+ } else {
+ /* Not support yet */
+ MALI_DEBUG_ASSERT(0);
+ }
+ session->mali_mem_array[mem_backend->type] += mem_backend->size;
+ if (session->mali_mem_array[MALI_MEM_OS] + session->mali_mem_array[MALI_MEM_BLOCK] > session->max_mali_mem_allocated) {
+ session->max_mali_mem_allocated = session->mali_mem_array[MALI_MEM_OS] + session->mali_mem_array[MALI_MEM_BLOCK];
+ }
+ _mali_osk_mutex_signal(session->memory_lock);
+ }
+
+ return _MALI_OSK_ERR_OK;
+
+failed_gpu_map:
+ _mali_osk_mutex_signal(session->memory_lock);
+ if (mem_backend->type == MALI_MEM_OS) {
+ mali_mem_os_free(&mem_backend->os_mem);
+ } else {
+ mali_mem_block_free(&mem_backend->block_mem);
+ }
+failed_alloc_pages:
+ mali_mem_backend_struct_destory(&mem_backend, mali_allocation->backend_handle);
+failed_alloc_backend:
+
+ mali_vma_offset_remove(&session->allocation_mgr, &mali_allocation->mali_vma_node);
+ mali_mem_allocation_struct_destory(mali_allocation);
+
+ return ret;
+}
+
+
+_mali_osk_errcode_t _mali_ukk_mem_free(_mali_uk_free_mem_s *args)
+{
+ struct mali_session_data *session = (struct mali_session_data *)(uintptr_t)args->ctx;
+ u32 vaddr = args->gpu_vaddr;
+ mali_mem_allocation *mali_alloc = NULL;
+ struct mali_vma_node *mali_vma_node = NULL;
+
+ /* find mali allocation structure by vaddress*/
+ mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, vaddr, 0);
+
+ MALI_DEBUG_ASSERT(NULL != mali_vma_node);
+ mali_alloc = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node);
+
+ if (mali_alloc)
+ /* check ref_count */
+ mali_allocation_unref(&mali_alloc);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+
+/**
+* Function _mali_ukk_mem_bind -- bind a external memory to a new GPU address
+* It will allocate a new mem allocation and bind external memory to it.
+* Supported backend type are:
+* _MALI_MEMORY_BIND_BACKEND_UMP
+* _MALI_MEMORY_BIND_BACKEND_DMA_BUF
+* _MALI_MEMORY_BIND_BACKEND_EXTERNAL_MEMORY
+* CPU access is not supported yet
+*/
+_mali_osk_errcode_t _mali_ukk_mem_bind(_mali_uk_bind_mem_s *args)
+{
+ struct mali_session_data *session = (struct mali_session_data *)(uintptr_t)args->ctx;
+ mali_mem_backend *mem_backend = NULL;
+ _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT;
+ mali_mem_allocation *mali_allocation = NULL;
+ MALI_DEBUG_PRINT(5, (" _mali_ukk_mem_bind, vaddr=0x%x, size =0x%x! \n", args->vaddr, args->size));
+
+ /**
+ * allocate mali allocation.
+ */
+ mali_allocation = mali_mem_allocation_struct_create(session);
+
+ if (mali_allocation == NULL) {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+ mali_allocation->psize = args->size;
+ mali_allocation->vsize = args->size;
+ mali_allocation->mali_mapping.addr = args->vaddr;
+
+ /* add allocation node to RB tree for index */
+ mali_allocation->mali_vma_node.vm_node.start = args->vaddr;
+ mali_allocation->mali_vma_node.vm_node.size = args->size;
+ mali_vma_offset_add(&session->allocation_mgr, &mali_allocation->mali_vma_node);
+
+ /* allocate backend*/
+ if (mali_allocation->psize > 0) {
+ mali_allocation->backend_handle = mali_mem_backend_struct_create(&mem_backend, mali_allocation->psize);
+ if (mali_allocation->backend_handle < 0) {
+ goto Failed_alloc_backend;
+ }
+
+ } else {
+ goto Failed_alloc_backend;
+ }
+
+ mem_backend->size = mali_allocation->psize;
+ mem_backend->mali_allocation = mali_allocation;
+
+ switch (args->flags & _MALI_MEMORY_BIND_BACKEND_MASK) {
+ case _MALI_MEMORY_BIND_BACKEND_UMP:
+#if defined(CONFIG_MALI400_UMP)
+ mali_allocation->type = MALI_MEM_UMP;
+ mem_backend->type = MALI_MEM_UMP;
+ ret = mali_memory_bind_ump_buf(mali_allocation, mem_backend,
+ args->mem_union.bind_ump.secure_id, args->mem_union.bind_ump.flags);
+ if (_MALI_OSK_ERR_OK != ret) {
+ MALI_DEBUG_PRINT(1, ("Bind ump buf failed\n"));
+ goto Failed_bind_backend;
+ }
+#else
+ MALI_DEBUG_PRINT(1, ("UMP not supported\n"));
+ goto Failed_bind_backend;
+#endif
+ break;
+ case _MALI_MEMORY_BIND_BACKEND_DMA_BUF:
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+ mali_allocation->type = MALI_MEM_DMA_BUF;
+ mem_backend->type = MALI_MEM_DMA_BUF;
+ ret = mali_memory_bind_dma_buf(mali_allocation, mem_backend,
+ args->mem_union.bind_dma_buf.mem_fd, args->mem_union.bind_dma_buf.flags);
+ if (_MALI_OSK_ERR_OK != ret) {
+ MALI_DEBUG_PRINT(1, ("Bind dma buf failed\n"));
+ goto Failed_bind_backend;
+ }
+#else
+ MALI_DEBUG_PRINT(1, ("DMA not supported\n"));
+ goto Failed_bind_backend;
+#endif
+ break;
+ case _MALI_MEMORY_BIND_BACKEND_MALI_MEMORY:
+ /* not allowed */
+ MALI_DEBUG_ASSERT(0);
+ break;
+
+ case _MALI_MEMORY_BIND_BACKEND_EXTERNAL_MEMORY:
+ mali_allocation->type = MALI_MEM_EXTERNAL;
+ mem_backend->type = MALI_MEM_EXTERNAL;
+ ret = mali_memory_bind_ext_mem(mali_allocation, mem_backend, args->mem_union.bind_ext_memory.phys_addr,
+ args->mem_union.bind_ext_memory.flags);
+ if (_MALI_OSK_ERR_OK != ret) {
+ MALI_DEBUG_PRINT(1, ("Bind external buf failed\n"));
+ goto Failed_bind_backend;
+ }
+ break;
+
+ case _MALI_MEMORY_BIND_BACKEND_EXT_COW:
+ /* not allowed */
+ MALI_DEBUG_ASSERT(0);
+ break;
+
+ default:
+ MALI_DEBUG_ASSERT(0);
+ break;
+ }
+ return _MALI_OSK_ERR_OK;
+
+
+Failed_bind_backend:
+ mali_mem_backend_struct_destory(&mem_backend, mali_allocation->backend_handle);
+
+Failed_alloc_backend:
+ mali_vma_offset_remove(&session->allocation_mgr, &mali_allocation->mali_vma_node);
+ mali_mem_allocation_struct_destory(mali_allocation);
+
+ MALI_DEBUG_PRINT(1, (" _mali_ukk_mem_bind, return ERROR! \n"));
+ return ret;
+}
+
+
+/*
+* Function _mali_ukk_mem_unbind -- unbind a external memory to a new GPU address
+* This function unbind the backend memory and free the allocation
+* no ref_count for this type of memory
+*/
+_mali_osk_errcode_t _mali_ukk_mem_unbind(_mali_uk_unbind_mem_s *args)
+{
+ /**/
+ struct mali_session_data *session = (struct mali_session_data *)(uintptr_t)args->ctx;
+ mali_mem_allocation *mali_allocation = NULL;
+ struct mali_vma_node *mali_vma_node = NULL;
+ u32 mali_addr = args->vaddr;
+ MALI_DEBUG_PRINT(5, (" _mali_ukk_mem_unbind, vaddr=0x%x! \n", args->vaddr));
+
+ /* find the allocation by vaddr */
+ mali_vma_node = mali_vma_offset_search(&session->allocation_mgr, mali_addr, 0);
+ if (likely(mali_vma_node)) {
+ MALI_DEBUG_ASSERT(mali_addr == mali_vma_node->vm_node.start);
+ mali_allocation = container_of(mali_vma_node, struct mali_mem_allocation, mali_vma_node);
+ } else {
+ MALI_DEBUG_ASSERT(NULL != mali_vma_node);
+ /* Not support yet */
+ MALI_DEBUG_ASSERT(0);
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ if (NULL != mali_allocation)
+ /* check ref_count */
+ mali_allocation_unref(&mali_allocation);
+ return _MALI_OSK_ERR_OK;
+}
+
+
+
+/*
+* Function _mali_ukk_mem_cow -- COW for an allocation
+* This function allocate new pages for a range (range, range+size) of allocation
+* And Map it(keep use the not in range pages from target allocation ) to an GPU vaddr
+*/
+_mali_osk_errcode_t _mali_ukk_mem_cow(_mali_uk_cow_mem_s *args)
+{
+ _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT;
+
+ /* create new alloction if needed */
+
+ /* Get the target allocation and it's backend*/
+
+ /* allocate new pages from os mem for modified range */
+
+
+ /* fill the COW backend, all pages for this allocation
+ * including the new page for modified range and pages not modified in old allocation.
+ * Do Add ref to pages from target allocation
+ */
+
+
+ /* map it to GPU side */
+ return ret;
+}
+
+/**
+* attach a backend to an exist mali allocation
+*/
+
+
+/**
+* deattach a backend from an exist mali allocation
+*/
+
--- /dev/null
+/*
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_MEMORY_MANAGER_H__
+#define __MALI_MEMORY_MANAGER_H__
+
+#include "mali_osk.h"
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/rbtree.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include "mali_memory_types.h"
+#include "mali_memory_os_alloc.h"
+#include "mali_uk_types.h"
+
+struct mali_allocation_manager {
+ rwlock_t vm_lock;
+ struct rb_root allocation_mgr_rb;
+ struct list_head head;
+ struct mutex list_mutex;
+ u32 mali_allocation_nr;
+};
+
+extern struct idr mali_backend_idr;
+extern struct mutex mali_idr_mutex;
+
+int mali_memory_manager_init(struct mali_allocation_manager *mgr);
+void mali_memory_manager_uninit(struct mali_allocation_manager *mgr);
+
+void mali_mem_allocation_struct_destory(mali_mem_allocation *alloc);
+
+_mali_osk_errcode_t _mali_ukk_mem_allocate(_mali_uk_alloc_mem_s *args);
+_mali_osk_errcode_t _mali_ukk_mem_free(_mali_uk_free_mem_s *args);
+_mali_osk_errcode_t _mali_ukk_mem_bind(_mali_uk_bind_mem_s *args);
+_mali_osk_errcode_t _mali_ukk_mem_unbind(_mali_uk_unbind_mem_s *args);
+
+
+#endif
+
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#endif
#endif
static void mali_mem_os_trim_pool(struct work_struct *work);
+static void mali_mem_os_free_page(struct mali_page_node *m_page);
+
static struct mali_mem_os_allocator {
spinlock_t pool_lock;
#endif
};
-static void mali_mem_os_free(mali_mem_allocation *descriptor)
+void mali_mem_os_free(mali_mem_os_mem *os_mem)
{
LIST_HEAD(pages);
- MALI_DEBUG_ASSERT(MALI_MEM_OS == descriptor->type);
-
- atomic_sub(descriptor->os_mem.count, &mali_mem_os_allocator.allocated_pages);
+ atomic_sub(os_mem->count, &mali_mem_os_allocator.allocated_pages);
/* Put pages on pool. */
- list_cut_position(&pages, &descriptor->os_mem.pages, descriptor->os_mem.pages.prev);
+ list_cut_position(&pages, &os_mem->pages, os_mem->pages.prev);
spin_lock(&mali_mem_os_allocator.pool_lock);
list_splice(&pages, &mali_mem_os_allocator.pool_pages);
- mali_mem_os_allocator.pool_count += descriptor->os_mem.count;
+ mali_mem_os_allocator.pool_count += os_mem->count;
spin_unlock(&mali_mem_os_allocator.pool_lock);
}
}
-static int mali_mem_os_alloc_pages(mali_mem_allocation *descriptor, u32 size)
+/**
+* free memory without put it into page pool
+
+void mali_mem_os_free_not_pooled(mali_mem_os_mem *os_mem)
{
- struct page *new_page, *tmp;
- LIST_HEAD(pages);
+
+}
+*/
+
+int mali_mem_os_alloc_pages(mali_mem_os_mem *os_mem, u32 size)
+{
+ struct page *new_page;
+ LIST_HEAD(pages_list);
size_t page_count = PAGE_ALIGN(size) / _MALI_OSK_MALI_PAGE_SIZE;
size_t remaining = page_count;
+ struct mali_page_node *m_page, *m_tmp;
u32 i;
- MALI_DEBUG_ASSERT_POINTER(descriptor);
- MALI_DEBUG_ASSERT(MALI_MEM_OS == descriptor->type);
+ MALI_DEBUG_ASSERT_POINTER(os_mem);
+
+ if (atomic_read(&mali_mem_os_allocator.allocated_pages) * _MALI_OSK_MALI_PAGE_SIZE + size > mali_mem_os_allocator.allocation_limit) {
+ MALI_DEBUG_PRINT(2, ("Mali Mem: Unable to allocate %u bytes. Currently allocated: %lu, max limit %lu\n",
+ size,
+ atomic_read(&mali_mem_os_allocator.allocated_pages) * _MALI_OSK_MALI_PAGE_SIZE,
+ mali_mem_os_allocator.allocation_limit));
+ return -ENOMEM;
+ }
- INIT_LIST_HEAD(&descriptor->os_mem.pages);
- descriptor->os_mem.count = page_count;
+ INIT_LIST_HEAD(&os_mem->pages);
+ os_mem->count = page_count;
/* Grab pages from pool. */
{
pool_pages = min(remaining, mali_mem_os_allocator.pool_count);
for (i = pool_pages; i > 0; i--) {
BUG_ON(list_empty(&mali_mem_os_allocator.pool_pages));
- list_move(mali_mem_os_allocator.pool_pages.next, &pages);
+ list_move(mali_mem_os_allocator.pool_pages.next, &pages_list);
}
mali_mem_os_allocator.pool_count -= pool_pages;
remaining -= pool_pages;
/* Process pages from pool. */
i = 0;
- list_for_each_entry_safe(new_page, tmp, &pages, lru) {
- BUG_ON(NULL == new_page);
+ list_for_each_entry_safe(m_page, m_tmp, &pages_list, list) {
+ BUG_ON(NULL == m_page);
- list_move_tail(&new_page->lru, &descriptor->os_mem.pages);
+ list_move_tail(&m_page->list, &os_mem->pages);
}
/* Allocate new pages, if needed. */
for (i = 0; i < remaining; i++) {
dma_addr_t dma_addr;
- gfp_t flags = __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD;
+ struct mali_page_node *new_page_node = NULL;
+ gfp_t flags = __GFP_ZERO | __GFP_NORETRY | __GFP_NOWARN | __GFP_COLD;
int err;
#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_LPAE)
flags |= GFP_HIGHUSER;
#else
- /* After 3.15.0 kernel use ZONE_DMA replace ZONE_DMA32 */
+ /* After 3.15.0 kernel use ZONE_DMA replace ZONE_DMA32 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)
flags |= GFP_DMA32;
#else
if (unlikely(NULL == new_page)) {
/* Calculate the number of pages actually allocated, and free them. */
- descriptor->os_mem.count = (page_count - remaining) + i;
- atomic_add(descriptor->os_mem.count, &mali_mem_os_allocator.allocated_pages);
- mali_mem_os_free(descriptor);
+ os_mem->count = (page_count - remaining) + i;
+ atomic_add(os_mem->count, &mali_mem_os_allocator.allocated_pages);
+ mali_mem_os_free(os_mem);
return -ENOMEM;
}
MALI_DEBUG_PRINT_ERROR(("OS Mem: Failed to DMA map page %p: %u",
new_page, err));
__free_page(new_page);
- descriptor->os_mem.count = (page_count - remaining) + i;
- atomic_add(descriptor->os_mem.count, &mali_mem_os_allocator.allocated_pages);
- mali_mem_os_free(descriptor);
+ os_mem->count = (page_count - remaining) + i;
+ atomic_add(os_mem->count, &mali_mem_os_allocator.allocated_pages);
+ mali_mem_os_free(os_mem);
return -EFAULT;
}
SetPagePrivate(new_page);
set_page_private(new_page, dma_addr);
- list_add_tail(&new_page->lru, &descriptor->os_mem.pages);
+ new_page_node = kmalloc(sizeof(mali_page_node), GFP_KERNEL);
+ if (unlikely(NULL == new_page_node)) {
+ MALI_PRINT_ERROR(("OS Mem: Can't allocate mali_page node! \n"));
+ dma_unmap_page(&mali_platform_device->dev, page_private(new_page),
+ _MALI_OSK_MALI_PAGE_SIZE, DMA_TO_DEVICE);
+ ClearPagePrivate(new_page);
+ __free_page(new_page);
+ os_mem->count = (page_count - remaining) + i;
+ atomic_add(os_mem->count, &mali_mem_os_allocator.allocated_pages);
+ mali_mem_os_free(os_mem);
+ return -EFAULT;
+ }
+ new_page_node->page = new_page;
+ INIT_LIST_HEAD(&new_page_node->list);
+
+ list_add_tail(&new_page_node->list, &os_mem->pages);
}
atomic_add(page_count, &mali_mem_os_allocator.allocated_pages);
return 0;
}
-static int mali_mem_os_mali_map(mali_mem_allocation *descriptor, struct mali_session_data *session)
+
+void mali_mem_os_mali_map(mali_mem_backend *mem_bkend, u32 vaddr, u32 props)
{
- struct mali_page_directory *pagedir = session->page_directory;
- struct page *page;
- _mali_osk_errcode_t err;
- u32 virt = descriptor->mali_mapping.addr;
- u32 prop = descriptor->mali_mapping.properties;
+ struct mali_session_data *session;
+ struct mali_page_directory *pagedir;
+ struct mali_page_node *m_page;
+ u32 virt = vaddr;
+ u32 prop = props;
- MALI_DEBUG_ASSERT(MALI_MEM_OS == descriptor->type);
+ MALI_DEBUG_ASSERT_POINTER(mem_bkend);
+ MALI_DEBUG_ASSERT_POINTER(mem_bkend->mali_allocation);
- err = mali_mem_mali_map_prepare(descriptor);
- if (_MALI_OSK_ERR_OK != err) {
- return -ENOMEM;
- }
+ session = mem_bkend->mali_allocation->session;
+ MALI_DEBUG_ASSERT_POINTER(session);
+ pagedir = session->page_directory;
- list_for_each_entry(page, &descriptor->os_mem.pages, lru) {
- dma_addr_t phys = page_private(page);
+ list_for_each_entry(m_page, &mem_bkend->os_mem.pages, list) {
+ dma_addr_t phys = page_private(m_page->page);
#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT)
/* Verify that the "physical" address is 32-bit and
mali_mmu_pagedir_update(pagedir, virt, (mali_dma_addr)phys, MALI_MMU_PAGE_SIZE, prop);
virt += MALI_MMU_PAGE_SIZE;
}
-
- return 0;
}
-static void mali_mem_os_mali_unmap(struct mali_session_data *session, mali_mem_allocation *descriptor)
+
+static void mali_mem_os_mali_unmap(mali_mem_allocation *alloc)
{
- mali_mem_mali_map_free(descriptor);
+ struct mali_session_data *session;
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+ session = alloc->session;
+ MALI_DEBUG_ASSERT_POINTER(session);
+
+ mali_session_memory_lock(session);
+ mali_mem_mali_map_free(session, alloc->psize, alloc->mali_vma_node.vm_node.start,
+ alloc->flags);
+ session->mali_mem_array[alloc->type] -= alloc->psize;
+ mali_session_memory_unlock(session);
}
-static int mali_mem_os_cpu_map(mali_mem_allocation *descriptor, struct vm_area_struct *vma)
+int mali_mem_os_cpu_map(mali_mem_os_mem *os_mem, struct vm_area_struct *vma)
{
+ struct mali_page_node *m_page;
struct page *page;
int ret;
unsigned long addr = vma->vm_start;
- list_for_each_entry(page, &descriptor->os_mem.pages, lru) {
+ list_for_each_entry(m_page, &os_mem->pages, list) {
/* We should use vm_insert_page, but it does a dcache
* flush which makes it way slower than remap_pfn_range or vm_insert_pfn.
ret = vm_insert_page(vma, addr, page);
*/
+ page = m_page->page;
ret = vm_insert_pfn(vma, addr, page_to_pfn(page));
if (unlikely(0 != ret)) {
return 0;
}
-mali_mem_allocation *mali_mem_os_alloc(u32 mali_addr, u32 size, struct vm_area_struct *vma, struct mali_session_data *session)
+void mali_mem_os_release(mali_mem_backend *mem_bkend)
{
- mali_mem_allocation *descriptor;
- int err;
-
- if (atomic_read(&mali_mem_os_allocator.allocated_pages) * _MALI_OSK_MALI_PAGE_SIZE + size > mali_mem_os_allocator.allocation_limit) {
- MALI_DEBUG_PRINT(2, ("Mali Mem: Unable to allocate %u bytes. Currently allocated: %lu, max limit %lu\n",
- size,
- atomic_read(&mali_mem_os_allocator.allocated_pages) * _MALI_OSK_MALI_PAGE_SIZE,
- mali_mem_os_allocator.allocation_limit));
- return NULL;
- }
- descriptor = mali_mem_descriptor_create(session, MALI_MEM_OS);
- if (NULL == descriptor) return NULL;
+ mali_mem_allocation *alloc;
+ MALI_DEBUG_ASSERT_POINTER(mem_bkend);
+ MALI_DEBUG_ASSERT(MALI_MEM_OS == mem_bkend->type);
- descriptor->mali_mapping.addr = mali_addr;
- descriptor->size = size;
- descriptor->cpu_mapping.addr = (void __user *)vma->vm_start;
- descriptor->cpu_mapping.ref = 1;
-
- if (VM_SHARED == (VM_SHARED & vma->vm_flags)) {
- descriptor->mali_mapping.properties = MALI_MMU_FLAGS_DEFAULT;
- } else {
- /* Cached Mali memory mapping */
- descriptor->mali_mapping.properties = MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE;
- vma->vm_flags |= VM_SHARED;
- }
-
- err = mali_mem_os_alloc_pages(descriptor, size); /* Allocate pages */
- if (0 != err) goto alloc_failed;
-
- /* Take session memory lock */
- _mali_osk_mutex_wait(session->memory_lock);
-
- err = mali_mem_os_mali_map(descriptor, session); /* Map on Mali */
- if (0 != err) goto mali_map_failed;
-
- err = mali_mem_os_cpu_map(descriptor, vma); /* Map on CPU */
- if (0 != err) goto cpu_map_failed;
-
- _mali_osk_mutex_signal(session->memory_lock);
- return descriptor;
-
-cpu_map_failed:
- mali_mem_os_mali_unmap(session, descriptor);
-mali_map_failed:
- _mali_osk_mutex_signal(session->memory_lock);
- mali_mem_os_free(descriptor);
-alloc_failed:
- mali_mem_descriptor_destroy(descriptor);
- MALI_DEBUG_PRINT(2, ("OS allocator: Failed to allocate memory (%d)\n", err));
- return NULL;
-}
-
-void mali_mem_os_release(mali_mem_allocation *descriptor)
-{
- struct mali_session_data *session = descriptor->session;
+ alloc = mem_bkend->mali_allocation;
+ MALI_DEBUG_ASSERT_POINTER(alloc);
/* Unmap the memory from the mali virtual address space. */
- mali_mem_os_mali_unmap(session, descriptor);
+ mali_mem_os_mali_unmap(alloc);
/* Free pages */
- mali_mem_os_free(descriptor);
+ mali_mem_os_free(&mem_bkend->os_mem);
}
}
}
-static void mali_mem_os_free_page(struct page *page)
+static void mali_mem_os_free_page(struct mali_page_node *m_page)
{
+ struct page *page = m_page->page;
BUG_ON(page_count(page) != 1);
dma_unmap_page(&mali_platform_device->dev, page_private(page),
ClearPagePrivate(page);
__free_page(page);
+ kfree(m_page);
}
/* The maximum number of page table pool pages to free in one go. */
#endif /* Linux < 3.12.0 */
#endif /* Linux < 3.0.0 */
{
- struct page *page, *tmp;
+ struct mali_page_node *m_page, *m_tmp;
unsigned long flags;
struct list_head *le, pages;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
list_cut_position(&pages, &mali_mem_os_allocator.pool_pages, le);
spin_unlock_irqrestore(&mali_mem_os_allocator.pool_lock, flags);
- list_for_each_entry_safe(page, tmp, &pages, lru) {
- mali_mem_os_free_page(page);
+ list_for_each_entry_safe(m_page, m_tmp, &pages, list) {
+ mali_mem_os_free_page(m_page);
}
if (MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_PAGES > mali_mem_os_allocator.pool_count) {
static void mali_mem_os_trim_pool(struct work_struct *data)
{
- struct page *page, *tmp;
+ struct mali_page_node *m_page, *m_tmp;
struct list_head *le;
LIST_HEAD(pages);
size_t nr_to_free;
}
spin_unlock(&mali_mem_os_allocator.pool_lock);
- list_for_each_entry_safe(page, tmp, &pages, lru) {
- mali_mem_os_free_page(page);
+ list_for_each_entry_safe(m_page, m_tmp, &pages, list) {
+ mali_mem_os_free_page(m_page);
}
/* Release some pages from page table page pool */
void mali_mem_os_term(void)
{
- struct page *page, *tmp;
-
+ struct mali_page_node *m_page, *m_tmp;
unregister_shrinker(&mali_mem_os_allocator.shrinker);
cancel_delayed_work_sync(&mali_mem_os_allocator.timed_shrinker);
}
spin_lock(&mali_mem_os_allocator.pool_lock);
- list_for_each_entry_safe(page, tmp, &mali_mem_os_allocator.pool_pages, lru) {
- mali_mem_os_free_page(page);
+ list_for_each_entry_safe(m_page, m_tmp, &mali_mem_os_allocator.pool_pages, list) {
+ mali_mem_os_free_page(m_page);
--mali_mem_os_allocator.pool_count;
}
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#define __MALI_MEMORY_OS_ALLOC_H__
#include "mali_osk.h"
-#include "mali_session.h"
-
#include "mali_memory_types.h"
-/* OS memory allocator */
-/** @brief Allocate memory from OS
- *
- * This function will create a descriptor, allocate pages and map these on the CPU and Mali.
- *
- * @param mali_addr Mali virtual address to use for Mali mapping
- * @param size Size to allocate
- * @param vma Pointer to vma for CPU mapping
- * @param session Pointer to session doing the allocation
- */
-mali_mem_allocation *mali_mem_os_alloc(u32 mali_addr, u32 size, struct vm_area_struct *vma, struct mali_session_data *session);
-
/** @brief Release Mali OS memory
*
* The session memory_lock must be held when calling this function.
*
- * @param descriptor Pointer to the descriptor to release
+ * @param mem_bkend Pointer to the mali_mem_backend to release
*/
-void mali_mem_os_release(mali_mem_allocation *descriptor);
+void mali_mem_os_release(mali_mem_backend *mem_bkend);
_mali_osk_errcode_t mali_mem_os_get_table_page(mali_dma_addr *phys, mali_io_address *mapping);
void mali_mem_os_term(void);
u32 mali_mem_os_stat(void);
+int mali_mem_os_alloc_pages(mali_mem_os_mem *os_mem, u32 size);
+void mali_mem_os_free(mali_mem_os_mem *os_mem);
+void mali_mem_os_mali_map(mali_mem_backend *mem_bkend, u32 vaddr, u32 props);
+int mali_mem_os_cpu_map(mali_mem_os_mem *os_mem, struct vm_area_struct *vma);
+
+
#endif /* __MALI_MEMORY_OS_ALLOC_H__ */
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
MALI_MEM_TYPE_MAX,
} mali_mem_type;
+typedef struct mali_block_item {
+ /* for block type, the block_phy is alway page size align
+ * so use low 12bit used for ref_cout.
+ */
+ unsigned long phy_addr;
+} mali_block_item;
+
+typedef enum mali_page_node_type {
+ MALI_PAGE_NODE_OS,
+ MALI_PAGE_NODE_BLOCK,
+} mali_page_node_type;
+
+typedef struct mali_block_node {
+ struct list_head list;
+ mali_block_item *blk_it; /*pointer to block item*/
+ u32 type;
+} mali_block_node;
+
+typedef struct mali_page_node {
+ struct list_head list;
+ struct page *page;
+} mali_page_node;
+
typedef struct mali_mem_os_mem {
struct list_head pages;
u32 count;
} block_allocator_allocation;
typedef struct mali_mem_block_mem {
- block_allocator_allocation mem;
+ struct list_head pfns;
+ u32 count;
} mali_mem_block_mem;
typedef struct mali_mem_virt_mali_mapping {
#define MALI_MEM_ALLOCATION_VALID_MAGIC 0xdeda110c
#define MALI_MEM_ALLOCATION_FREED_MAGIC 0x10101010
+typedef struct mali_mm_node {
+ /* MALI GPU vaddr start, use u32 for mmu only support 32bit address*/
+ uint32_t start; /* GPU vaddr */
+ uint32_t size; /* GPU allocation virtual size */
+ unsigned allocated : 1;
+} mali_mm_node;
+
+typedef struct mali_vma_node {
+ struct mali_mm_node vm_node;
+ struct rb_node vm_rb;
+} mali_vma_node;
+
+
typedef struct mali_mem_allocation {
MALI_DEBUG_CODE(u32 magic);
mali_mem_type type; /**< Type of memory */
mali_mem_virt_cpu_mapping cpu_mapping; /**< CPU mapping */
mali_mem_virt_mali_mapping mali_mapping; /**< Mali mapping */
+
+ /* add for new memory system */
+ struct mali_vma_node mali_vma_node;
+ u32 vsize; /* virtual size*/
+ u32 psize; /* physical backend memory size*/
+ struct list_head list;
+ s32 backend_handle; /* idr for mem_backend */
+ struct kref ref;
} mali_mem_allocation;
+
+/* COW backend memory type */
+typedef struct mali_mem_cow {
+ struct list_head pages; /**< all pages for this cow backend allocation,
+ including new allocated pages for modified range*/
+ u32 count; /**< number of pages */
+} mali_mem_cow;
+
+typedef struct mali_mem_backend {
+ mali_mem_type type; /**< Type of backend memory */
+ u32 flags; /**< Flags for this allocation */
+ u32 size;
+ /* Union selected by type. */
+ union {
+ mali_mem_os_mem os_mem; /**< MALI_MEM_OS */
+ mali_mem_external ext_mem; /**< MALI_MEM_EXTERNAL */
+ mali_mem_dma_buf dma_buf; /**< MALI_MEM_DMA_BUF */
+ mali_mem_ump ump_mem; /**< MALI_MEM_UMP */
+ mali_mem_block_mem block_mem; /**< MALI_MEM_BLOCK */
+ mali_mem_cow cow_mem;
+ };
+ mali_mem_allocation *mali_allocation;
+} mali_mem_backend;
+
#define MALI_MEM_FLAG_MALI_GUARD_PAGE (1 << 0)
#define MALI_MEM_FLAG_DONT_CPU_MAP (1 << 1)
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
- *
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
+ *
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
- *
+ *
* A copy of the licence is included with the program, and can also be obtained from Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "mali_kernel_common.h"
#include "mali_session.h"
#include "mali_kernel_linux.h"
-
#include "mali_memory.h"
-
#include "ump_kernel_interface.h"
-static int mali_ump_map(struct mali_session_data *session, mali_mem_allocation *descriptor)
+static int mali_mem_ump_map(mali_mem_backend *mem_backend)
{
ump_dd_handle ump_mem;
+ mali_mem_allocation *alloc;
+ struct mali_session_data *session;
u32 nr_blocks;
u32 i;
ump_dd_physical_block *ump_blocks;
struct mali_page_directory *pagedir;
u32 offset = 0;
- u32 prop;
_mali_osk_errcode_t err;
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+ MALI_DEBUG_ASSERT(MALI_MEM_UMP == mem_backend->type);
+
+ alloc = mem_backend->mali_allocation;
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+
+ session = alloc->session;
MALI_DEBUG_ASSERT_POINTER(session);
- MALI_DEBUG_ASSERT_POINTER(descriptor);
- MALI_DEBUG_ASSERT(MALI_MEM_UMP == descriptor->type);
- ump_mem = descriptor->ump_mem.handle;
+ ump_mem = mem_backend->ump_mem.handle;
MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID != ump_mem);
nr_blocks = ump_dd_phys_block_count_get(ump_mem);
}
pagedir = session->page_directory;
- prop = descriptor->mali_mapping.properties;
- err = mali_mem_mali_map_prepare(descriptor);
+ mali_session_memory_lock(session);
+
+ err = mali_mem_mali_map_prepare(alloc);
if (_MALI_OSK_ERR_OK != err) {
MALI_DEBUG_PRINT(1, ("Mapping of UMP memory failed\n"));
_mali_osk_free(ump_blocks);
+ mali_session_memory_unlock(session);
return -ENOMEM;
}
for (i = 0; i < nr_blocks; ++i) {
- u32 virt = descriptor->mali_mapping.addr + offset;
+ u32 virt = alloc->mali_vma_node.vm_node.start + offset;
MALI_DEBUG_PRINT(7, ("Mapping in 0x%08x size %d\n", ump_blocks[i].addr , ump_blocks[i].size));
mali_mmu_pagedir_update(pagedir, virt, ump_blocks[i].addr,
- ump_blocks[i].size, prop);
+ ump_blocks[i].size, MALI_MMU_FLAGS_DEFAULT);
offset += ump_blocks[i].size;
}
- if (descriptor->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
- u32 virt = descriptor->mali_mapping.addr + offset;
+ if (alloc->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
+ u32 virt = alloc->mali_vma_node.vm_node.start + offset;
/* Map in an extra virtual guard page at the end of the VMA */
MALI_DEBUG_PRINT(6, ("Mapping in extra guard page\n"));
- mali_mmu_pagedir_update(pagedir, virt, ump_blocks[0].addr, _MALI_OSK_MALI_PAGE_SIZE, prop);
+ mali_mmu_pagedir_update(pagedir, virt, ump_blocks[0].addr, _MALI_OSK_MALI_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT);
offset += _MALI_OSK_MALI_PAGE_SIZE;
}
-
+ session->mali_mem_array[mem_backend->type] += mem_backend->size;
+ mali_session_memory_unlock(session);
_mali_osk_free(ump_blocks);
-
return 0;
}
-void mali_ump_unmap(struct mali_session_data *session, mali_mem_allocation *descriptor)
+static void mali_mem_ump_unmap(mali_mem_allocation *alloc)
{
- ump_dd_handle ump_mem;
- struct mali_page_directory *pagedir;
-
- ump_mem = descriptor->ump_mem.handle;
- pagedir = session->page_directory;
-
- MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID != ump_mem);
-
- mali_mem_mali_map_free(descriptor);
+ struct mali_session_data *session;
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+ session = alloc->session;
+ MALI_DEBUG_ASSERT_POINTER(session);
+ mali_session_memory_lock(session);
+ mali_mem_mali_map_free(session, alloc->psize, alloc->mali_vma_node.vm_node.start,
+ alloc->flags);
- ump_dd_reference_release(ump_mem);
- return;
+ session->mali_mem_array[alloc->type] -= alloc->psize;
+ mali_session_memory_unlock(session);
}
-_mali_osk_errcode_t _mali_ukk_attach_ump_mem(_mali_uk_attach_ump_mem_s *args)
+int mali_memory_bind_ump_buf(mali_mem_allocation *alloc, mali_mem_backend *mem_backend, u32 secure_id, u32 flags)
{
ump_dd_handle ump_mem;
- struct mali_session_data *session;
- mali_mem_allocation *descriptor;
- int md, ret;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
-
- session = (struct mali_session_data *)(uintptr_t)args->ctx;
-
- /* check arguments */
- /* NULL might be a valid Mali address */
- if (!args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
-
- /* size must be a multiple of the system page size */
- if (args->size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+ int ret;
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+ MALI_DEBUG_ASSERT(MALI_MEM_UMP == mem_backend->type);
MALI_DEBUG_PRINT(3,
("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n",
- args->secure_id, args->mali_address, args->size));
-
- ump_mem = ump_dd_handle_create_from_secure_id((int)args->secure_id);
+ secure_id, alloc->mali_vma_node.vm_node.start, alloc->mali_vma_node.vm_node.size));
+ ump_mem = ump_dd_handle_create_from_secure_id(secure_id);
if (UMP_DD_HANDLE_INVALID == ump_mem) MALI_ERROR(_MALI_OSK_ERR_FAULT);
-
- descriptor = mali_mem_descriptor_create(session, MALI_MEM_UMP);
- if (NULL == descriptor) {
- ump_dd_reference_release(ump_mem);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ alloc->flags |= MALI_MEM_FLAG_DONT_CPU_MAP;
+ if (flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
+ alloc->flags |= MALI_MEM_FLAG_MALI_GUARD_PAGE;
}
- descriptor->ump_mem.handle = ump_mem;
- descriptor->mali_mapping.addr = args->mali_address;
- descriptor->size = args->size;
- descriptor->mali_mapping.properties = MALI_MMU_FLAGS_DEFAULT;
- descriptor->flags |= MALI_MEM_FLAG_DONT_CPU_MAP;
+ mem_backend->ump_mem.handle = ump_mem;
- if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE) {
- descriptor->flags = MALI_MEM_FLAG_MALI_GUARD_PAGE;
- }
-
- _mali_osk_mutex_wait(session->memory_lock);
-
- ret = mali_ump_map(session, descriptor);
+ ret = mali_mem_ump_map(mem_backend);
if (0 != ret) {
- _mali_osk_mutex_signal(session->memory_lock);
ump_dd_reference_release(ump_mem);
- mali_mem_descriptor_destroy(descriptor);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ return _MALI_OSK_ERR_FAULT;
}
-
- _mali_osk_mutex_signal(session->memory_lock);
-
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md)) {
- ump_dd_reference_release(ump_mem);
- mali_mem_descriptor_destroy(descriptor);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- args->cookie = md;
-
- MALI_DEBUG_PRINT(5, ("Returning from UMP attach\n"));
-
- MALI_SUCCESS;
+ MALI_DEBUG_PRINT(3, ("Returning from UMP bind\n"));
+ return _MALI_OSK_ERR_OK;
}
-void mali_mem_ump_release(mali_mem_allocation *descriptor)
+void mali_mem_ump_release(mali_mem_backend *mem_backend)
{
- struct mali_session_data *session = descriptor->session;
-
- MALI_DEBUG_ASSERT(MALI_MEM_UMP == descriptor->type);
+ ump_dd_handle ump_mem;
+ mali_mem_allocation *alloc;
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+ MALI_DEBUG_ASSERT(MALI_MEM_UMP == mem_backend->type);
+ ump_mem = mem_backend->ump_mem.handle;
+ MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID != ump_mem);
- mali_ump_unmap(session, descriptor);
+ alloc = mem_backend->mali_allocation;
+ MALI_DEBUG_ASSERT_POINTER(alloc);
+ mali_mem_ump_unmap(alloc);
+ ump_dd_reference_release(ump_mem);
}
-_mali_osk_errcode_t _mali_ukk_release_ump_mem(_mali_uk_release_ump_mem_s *args)
+int mali_memory_unbind_ump_buf(mali_mem_backend *mem_backend)
{
- mali_mem_allocation *descriptor;
- struct mali_session_data *session;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_DEBUG_ASSERT(NULL != (void *)(uintptr_t)args->ctx);
-
- session = (struct mali_session_data *)(uintptr_t)args->ctx;
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session->descriptor_mapping, args->cookie, (void **)&descriptor)) {
- MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release ump memory\n", args->cookie));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- descriptor = mali_descriptor_mapping_free(session->descriptor_mapping, args->cookie);
-
- if (NULL != descriptor) {
- _mali_osk_mutex_wait(session->memory_lock);
- mali_mem_ump_release(descriptor);
- _mali_osk_mutex_signal(session->memory_lock);
-
- mali_mem_descriptor_destroy(descriptor);
- }
-
- MALI_SUCCESS;
+ MALI_DEBUG_ASSERT_POINTER(mem_backend);
+ mali_mem_ump_release(mem_backend);
+ return _MALI_OSK_ERR_OK;
}
+
--- /dev/null
+/*
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_MEMORY_UMP_BUF_H__
+#define __MALI_MEMORY_UMP_BUF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mali_uk_types.h"
+#include "mali_osk.h"
+#include "mali_memory.h"
+
+int mali_memory_bind_ump_buf(mali_mem_allocation *alloc, mali_mem_backend *mem_backend, u32 secure_id, u32 flags);
+int mali_memory_unbind_ump_buf(mali_mem_backend *mem_backend);
+void mali_mem_ump_release(mali_mem_backend *mem_backend);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_MEMORY_DMA_BUF_H__ */
--- /dev/null
+/*
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/mm_types.h>
+#include <linux/fs.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_kernel_linux.h"
+#include "mali_scheduler.h"
+
+#include "mali_memory.h"
+#include "mali_memory_os_alloc.h"
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+#include "mali_memory_dma_buf.h"
+#endif
+#if defined(CONFIG_MALI400_UMP)
+#include "mali_memory_ump.h"
+#endif
+#include "mali_memory_external.h"
+#include "mali_memory_manager.h"
+#include "mali_memory_virtual.h"
+#include "mali_memory_block_alloc.h"
+
+/**
+*function @_mali_free_allocation_mem - free a memory allocation
+* support backend type:
+* MALI_MEM_OS
+* maybe COW later?
+*/
+static void _mali_free_allocation_mem(struct kref *kref)
+{
+ mali_mem_backend *mem_bkend = NULL;
+
+ mali_mem_allocation *mali_alloc = container_of(kref, struct mali_mem_allocation, ref);
+
+ struct mali_session_data *session = mali_alloc->session;
+ MALI_DEBUG_PRINT(4, (" _mali_free_allocation_mem, psize =0x%x! \n", mali_alloc->psize));
+ if (0 == mali_alloc->psize)
+ goto out;
+
+ /* Get backend memory & Map on CPU */
+ mutex_lock(&mali_idr_mutex);
+ mem_bkend = idr_find(&mali_backend_idr, mali_alloc->backend_handle);
+ mutex_unlock(&mali_idr_mutex);
+
+ MALI_DEBUG_ASSERT(NULL != mem_bkend);
+
+ switch (mem_bkend->type) {
+ case MALI_MEM_OS:
+ mali_mem_os_release(mem_bkend);
+ break;
+ case MALI_MEM_UMP:
+#if defined(CONFIG_MALI400_UMP)
+ mali_mem_ump_release(mem_bkend);
+#else
+ MALI_DEBUG_PRINT(2, ("DMA not supported\n"));
+#endif
+ break;
+ case MALI_MEM_DMA_BUF:
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+ mali_mem_dma_buf_release(mem_bkend);
+#else
+ MALI_DEBUG_PRINT(2, ("DMA not supported\n"));
+#endif
+ break;
+ case MALI_MEM_EXTERNAL:
+ mali_mem_external_release(mem_bkend);
+ break;
+ case MALI_MEM_BLOCK:
+ mali_mem_block_release(mem_bkend);
+ break;
+ default:
+ MALI_DEBUG_PRINT(1, ("mem type %d is not in the mali_mem_type enum.\n", mem_bkend->type));
+ break;
+ }
+
+ /* remove backend memory idex */
+ mutex_lock(&mali_idr_mutex);
+ idr_remove(&mali_backend_idr, mali_alloc->backend_handle);
+ mutex_unlock(&mali_idr_mutex);
+ kfree(mem_bkend);
+out:
+ /* remove memory allocation */
+ mali_vma_offset_remove(&session->allocation_mgr, &mali_alloc->mali_vma_node);
+ mali_mem_allocation_struct_destory(mali_alloc);
+
+}
+
+
+
+/**
+* ref_count for allocation
+*/
+void mali_allocation_unref(struct mali_mem_allocation **alloc)
+{
+ mali_mem_allocation *mali_alloc = *alloc;
+ *alloc = NULL;
+ kref_put(&mali_alloc->ref, _mali_free_allocation_mem);
+}
+
+void mali_allocation_ref(struct mali_mem_allocation *alloc)
+{
+ kref_get(&alloc->ref);
+}
+
+void mali_free_session_allocations(struct mali_session_data *session)
+{
+
+ struct mali_mem_allocation *entry, *next;
+
+ MALI_DEBUG_PRINT(4, (" mali_free_session_allocations! \n"));
+
+ list_for_each_entry_safe(entry, next, &session->allocation_mgr.head, list) {
+ mali_allocation_unref(&entry);
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+void mali_allocation_unref(struct mali_mem_allocation **alloc);
+
+void mali_allocation_ref(struct mali_mem_allocation *alloc);
+
+void mali_free_session_allocations(struct mali_session_data *session);
+
--- /dev/null
+/*
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/mm_types.h>
+#include <linux/fs.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_kernel_linux.h"
+#include "mali_scheduler.h"
+#include "mali_memory_os_alloc.h"
+#include "mali_memory_manager.h"
+#include "mali_memory_virtual.h"
+
+
+/**
+*internal helper to link node into the rb-tree
+*/
+static inline void _mali_vma_offset_add_rb(struct mali_allocation_manager *mgr,
+ struct mali_vma_node *node)
+{
+ struct rb_node **iter = &mgr->allocation_mgr_rb.rb_node;
+ struct rb_node *parent = NULL;
+ struct mali_vma_node *iter_node;
+
+ while (likely(*iter)) {
+ parent = *iter;
+ iter_node = rb_entry(*iter, struct mali_vma_node, vm_rb);
+
+ if (node->vm_node.start < iter_node->vm_node.start)
+ iter = &(*iter)->rb_left;
+ else if (node->vm_node.start > iter_node->vm_node.start)
+ iter = &(*iter)->rb_right;
+ else
+ /* Not support yet */
+ MALI_DEBUG_ASSERT(0);
+ }
+
+ rb_link_node(&node->vm_rb, parent, iter);
+ rb_insert_color(&node->vm_rb, &mgr->allocation_mgr_rb);
+}
+
+/**
+ * mali_vma_offset_add() - Add offset node to RB Tree
+ */
+int mali_vma_offset_add(struct mali_allocation_manager *mgr,
+ struct mali_vma_node *node)
+{
+ int ret = 0;
+ write_lock(&mgr->vm_lock);
+
+ if (node->vm_node.allocated) {
+ goto out;
+ }
+
+ _mali_vma_offset_add_rb(mgr, node);
+ /* set to allocated */
+ node->vm_node.allocated = 1;
+
+out:
+ write_unlock(&mgr->vm_lock);
+ return ret;
+}
+
+/**
+ * mali_vma_offset_remove() - Remove offset node from RB tree
+ */
+void mali_vma_offset_remove(struct mali_allocation_manager *mgr,
+ struct mali_vma_node *node)
+{
+ write_lock(&mgr->vm_lock);
+
+ if (node->vm_node.allocated) {
+ rb_erase(&node->vm_rb, &mgr->allocation_mgr_rb);
+ memset(&node->vm_node, 0, sizeof(node->vm_node));
+ }
+ write_unlock(&mgr->vm_lock);
+}
+
+/**
+* mali_vma_offset_search - Search the node in RB tree
+*/
+struct mali_vma_node *mali_vma_offset_search(struct mali_allocation_manager *mgr,
+ unsigned long start, unsigned long pages)
+{
+ struct mali_vma_node *node, *best;
+ struct rb_node *iter;
+ unsigned long offset;
+ read_lock(&mgr->vm_lock);
+
+ iter = mgr->allocation_mgr_rb.rb_node;
+ best = NULL;
+
+ while (likely(iter)) {
+ node = rb_entry(iter, struct mali_vma_node, vm_rb);
+ offset = node->vm_node.start;
+ if (start >= offset) {
+ iter = iter->rb_right;
+ best = node;
+ if (start == offset)
+ break;
+ } else {
+ iter = iter->rb_left;
+ }
+ }
+
+ if (best) {
+ offset = best->vm_node.start + best->vm_node.size;
+ if (offset <= start + pages)
+ best = NULL;
+ }
+ read_unlock(&mgr->vm_lock);
+
+ return best;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef __MALI_GPU_VMEM_H__
+#define __MALI_GPU_VMEM_H__
+
+#include "mali_osk.h"
+#include "mali_session.h"
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/rbtree.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include "mali_memory_types.h"
+#include "mali_memory_os_alloc.h"
+#include "mali_memory_manager.h"
+
+
+
+int mali_vma_offset_add(struct mali_allocation_manager *mgr,
+ struct mali_vma_node *node);
+
+void mali_vma_offset_remove(struct mali_allocation_manager *mgr,
+ struct mali_vma_node *node);
+
+struct mali_vma_node *mali_vma_offset_search(struct mali_allocation_manager *mgr,
+ unsigned long start, unsigned long pages);
+
+#endif
/*
- * Copyright (C) 2010, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#define MALI_OSK_RESOURCE_l2_LOCATION_END 22
static _mali_osk_resource_t mali_osk_resource_bank[MALI_OSK_MAX_RESOURCE_NUMBER] = {
-{.description = "Mali_GP", .base = MALI_OFFSET_GP, .irq_name = "IRQGP",},
-{.description = "Mali_GP_MMU", .base = MALI_OFFSET_GP_MMU, .irq_name = "IRQGPMMU",},
-{.description = "Mali_PP0", .base = MALI_OFFSET_PP0, .irq_name = "IRQPP0",},
-{.description = "Mali_PP0_MMU", .base = MALI_OFFSET_PP0_MMU, .irq_name = "IRQPPMMU0",},
-{.description = "Mali_PP1", .base = MALI_OFFSET_PP1, .irq_name = "IRQPP1",},
-{.description = "Mali_PP1_MMU", .base = MALI_OFFSET_PP1_MMU, .irq_name = "IRQPPMMU1",},
-{.description = "Mali_PP2", .base = MALI_OFFSET_PP2, .irq_name = "IRQPP2",},
-{.description = "Mali_PP2_MMU", .base = MALI_OFFSET_PP2_MMU, .irq_name = "IRQPPMMU2",},
-{.description = "Mali_PP3", .base = MALI_OFFSET_PP3, .irq_name = "IRQPP3",},
-{.description = "Mali_PP3_MMU", .base = MALI_OFFSET_PP3_MMU, .irq_name = "IRQPPMMU3",},
-{.description = "Mali_PP4", .base = MALI_OFFSET_PP4, .irq_name = "IRQPP4",},
-{.description = "Mali_PP4_MMU", .base = MALI_OFFSET_PP4_MMU, .irq_name = "IRQPPMMU4",},
-{.description = "Mali_PP5", .base = MALI_OFFSET_PP5, .irq_name = "IRQPP5",},
-{.description = "Mali_PP5_MMU", .base = MALI_OFFSET_PP5_MMU, .irq_name = "IRQPPMMU5",},
-{.description = "Mali_PP6", .base = MALI_OFFSET_PP6, .irq_name = "IRQPP6",},
-{.description = "Mali_PP6_MMU", .base = MALI_OFFSET_PP6_MMU, .irq_name = "IRQPPMMU6",},
-{.description = "Mali_PP7", .base = MALI_OFFSET_PP7, .irq_name = "IRQPP7",},
-{.description = "Mali_PP7_MMU", .base = MALI_OFFSET_PP7_MMU, .irq_name = "IRQPPMMU",},
-{.description = "Mali_PP_Broadcast", .base = MALI_OFFSET_PP_BCAST, .irq_name = "IRQPP",},
-{.description = "Mali_PMU", .base = MALI_OFFSET_PMU, .irq_name = "IRQPMU",},
-{.description = "Mali_L2", .base = MALI_OFFSET_L2_RESOURCE0,},
-{.description = "Mali_L2", .base = MALI_OFFSET_L2_RESOURCE1,},
-{.description = "Mali_L2", .base = MALI_OFFSET_L2_RESOURCE2,},
-{.description = "Mali_PP_MMU_Broadcast", .base = MALI_OFFSET_PP_BCAST_MMU,},
-{.description = "Mali_Broadcast", .base = MALI_OFFSET_BCAST,},
-{.description = "Mali_DLBU", .base = MALI_OFFSET_DLBU,},
-{.description = "Mali_DMA", .base = MALI_OFFSET_DMA,},
+ {.description = "Mali_GP", .base = MALI_OFFSET_GP, .irq_name = "IRQGP",},
+ {.description = "Mali_GP_MMU", .base = MALI_OFFSET_GP_MMU, .irq_name = "IRQGPMMU",},
+ {.description = "Mali_PP0", .base = MALI_OFFSET_PP0, .irq_name = "IRQPP0",},
+ {.description = "Mali_PP0_MMU", .base = MALI_OFFSET_PP0_MMU, .irq_name = "IRQPPMMU0",},
+ {.description = "Mali_PP1", .base = MALI_OFFSET_PP1, .irq_name = "IRQPP1",},
+ {.description = "Mali_PP1_MMU", .base = MALI_OFFSET_PP1_MMU, .irq_name = "IRQPPMMU1",},
+ {.description = "Mali_PP2", .base = MALI_OFFSET_PP2, .irq_name = "IRQPP2",},
+ {.description = "Mali_PP2_MMU", .base = MALI_OFFSET_PP2_MMU, .irq_name = "IRQPPMMU2",},
+ {.description = "Mali_PP3", .base = MALI_OFFSET_PP3, .irq_name = "IRQPP3",},
+ {.description = "Mali_PP3_MMU", .base = MALI_OFFSET_PP3_MMU, .irq_name = "IRQPPMMU3",},
+ {.description = "Mali_PP4", .base = MALI_OFFSET_PP4, .irq_name = "IRQPP4",},
+ {.description = "Mali_PP4_MMU", .base = MALI_OFFSET_PP4_MMU, .irq_name = "IRQPPMMU4",},
+ {.description = "Mali_PP5", .base = MALI_OFFSET_PP5, .irq_name = "IRQPP5",},
+ {.description = "Mali_PP5_MMU", .base = MALI_OFFSET_PP5_MMU, .irq_name = "IRQPPMMU5",},
+ {.description = "Mali_PP6", .base = MALI_OFFSET_PP6, .irq_name = "IRQPP6",},
+ {.description = "Mali_PP6_MMU", .base = MALI_OFFSET_PP6_MMU, .irq_name = "IRQPPMMU6",},
+ {.description = "Mali_PP7", .base = MALI_OFFSET_PP7, .irq_name = "IRQPP7",},
+ {.description = "Mali_PP7_MMU", .base = MALI_OFFSET_PP7_MMU, .irq_name = "IRQPPMMU",},
+ {.description = "Mali_PP_Broadcast", .base = MALI_OFFSET_PP_BCAST, .irq_name = "IRQPP",},
+ {.description = "Mali_PMU", .base = MALI_OFFSET_PMU, .irq_name = "IRQPMU",},
+ {.description = "Mali_L2", .base = MALI_OFFSET_L2_RESOURCE0,},
+ {.description = "Mali_L2", .base = MALI_OFFSET_L2_RESOURCE1,},
+ {.description = "Mali_L2", .base = MALI_OFFSET_L2_RESOURCE2,},
+ {.description = "Mali_PP_MMU_Broadcast", .base = MALI_OFFSET_PP_BCAST_MMU,},
+ {.description = "Mali_Broadcast", .base = MALI_OFFSET_BCAST,},
+ {.description = "Mali_DLBU", .base = MALI_OFFSET_DLBU,},
+ {.description = "Mali_DMA", .base = MALI_OFFSET_DMA,},
};
_mali_osk_errcode_t _mali_osk_resource_initialize(void)
if (res) {
mali_osk_resource_bank[i].irq = res->start;
if (0 == strncmp("Mali_PP_Broadcast", mali_osk_resource_bank[i].description,
- strlen(mali_osk_resource_bank[i].description))) {
+ strlen(mali_osk_resource_bank[i].description))) {
mali_is_450 = MALI_TRUE;
}
} else {
int length = 0, i = 0;
u32 u;
+ MALI_DEBUG_PRINT(2, ("Get pmu config from device tree configuration.\n"));
+
MALI_DEBUG_ASSERT(NULL != node);
if (!of_get_property(node, "pmu_domain_config", &length)) {
return;
}
- if (array_size != length/sizeof(u32)) {
+ if (array_size != length / sizeof(u32)) {
MALI_PRINT_ERROR(("Wrong pmu domain config in device tree."));
return;
}
{
_mali_osk_device_data data = { 0, };
+ MALI_DEBUG_PRINT(2, ("Get pmu config from platform device data.\n"));
if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data)) {
/* Copy the custom customer power domain config */
_mali_osk_memcpy(domain_config_array, data.pmu_domain_config, sizeof(data.pmu_domain_config));
/*
- * Copyright (C) 2010, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/**
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/**
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012, 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
if (NULL != mali_sync_tl->timeline) {
_mali_osk_snprintf(str, size, "oldest (%u) next (%u)\n", mali_sync_tl->timeline->point_oldest,
- mali_sync_tl->timeline->point_next);
+ mali_sync_tl->timeline->point_next);
}
}
#endif
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012, 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#include "mali_session.h"
#include "mali_ukk_wrappers.h"
-int mem_write_safe_wrapper(struct mali_session_data *session_data, _mali_uk_mem_write_safe_s __user *uargs)
+int mem_alloc_wrapper(struct mali_session_data *session_data, _mali_uk_alloc_mem_s __user *uargs)
{
- _mali_uk_mem_write_safe_s kargs;
+ _mali_uk_alloc_mem_s kargs;
_mali_osk_errcode_t err;
MALI_CHECK_NON_NULL(uargs, -EINVAL);
MALI_CHECK_NON_NULL(session_data, -EINVAL);
- if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_mem_write_safe_s))) {
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_alloc_mem_s))) {
return -EFAULT;
}
-
kargs.ctx = (uintptr_t)session_data;
- /* Check if we can access the buffers */
- if (!access_ok(VERIFY_WRITE, kargs.dest, kargs.size)
- || !access_ok(VERIFY_READ, kargs.src, kargs.size)) {
- return -EINVAL;
- }
-
- /* Check if size wraps */
- if ((kargs.size + kargs.dest) <= kargs.dest
- || (kargs.size + kargs.src) <= kargs.src) {
- return -EINVAL;
- }
+ err = _mali_ukk_mem_allocate(&kargs);
- err = _mali_ukk_mem_write_safe(&kargs);
if (_MALI_OSK_ERR_OK != err) {
return map_errcode(err);
}
- if (0 != put_user(kargs.size, &uargs->size)) {
+ if (0 != put_user(kargs.backend_handle, &uargs->backend_handle)) {
return -EFAULT;
}
return 0;
}
-int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user *argument)
+int mem_free_wrapper(struct mali_session_data *session_data, _mali_uk_free_mem_s __user *uargs)
{
- _mali_uk_map_external_mem_s uk_args;
- _mali_osk_errcode_t err_code;
+ _mali_uk_free_mem_s kargs;
+ _mali_osk_errcode_t err;
- /* validate input */
- /* the session_data pointer was validated by caller */
- MALI_CHECK_NON_NULL(argument, -EINVAL);
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
- /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
- if (0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_map_external_mem_s))) {
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_free_mem_s))) {
return -EFAULT;
}
+ kargs.ctx = (uintptr_t)session_data;
- uk_args.ctx = (uintptr_t)session_data;
- err_code = _mali_ukk_map_external_mem(&uk_args);
-
- if (0 != put_user(uk_args.cookie, &argument->cookie)) {
- if (_MALI_OSK_ERR_OK == err_code) {
- /* Rollback */
- _mali_uk_unmap_external_mem_s uk_args_unmap;
+ err = _mali_ukk_mem_free(&kargs);
- uk_args_unmap.ctx = (uintptr_t)session_data;
- uk_args_unmap.cookie = uk_args.cookie;
- err_code = _mali_ukk_unmap_external_mem(&uk_args_unmap);
- if (_MALI_OSK_ERR_OK != err_code) {
- MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_unmap_external_mem, as a result of failing put_user(), failed\n"));
- }
- }
- return -EFAULT;
+ if (_MALI_OSK_ERR_OK != err) {
+ return map_errcode(err);
}
- /* Return the error that _mali_ukk_free_big_block produced */
- return map_errcode(err_code);
+ return 0;
}
-int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user *argument)
+int mem_bind_wrapper(struct mali_session_data *session_data, _mali_uk_bind_mem_s __user *uargs)
{
- _mali_uk_unmap_external_mem_s uk_args;
- _mali_osk_errcode_t err_code;
+ _mali_uk_bind_mem_s kargs;
+ _mali_osk_errcode_t err;
- /* validate input */
- /* the session_data pointer was validated by caller */
- MALI_CHECK_NON_NULL(argument, -EINVAL);
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
- /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
- if (0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_unmap_external_mem_s))) {
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_bind_mem_s))) {
return -EFAULT;
}
+ kargs.ctx = (uintptr_t)session_data;
+
+ err = _mali_ukk_mem_bind(&kargs);
- uk_args.ctx = (uintptr_t)session_data;
- err_code = _mali_ukk_unmap_external_mem(&uk_args);
+ if (_MALI_OSK_ERR_OK != err) {
+ return map_errcode(err);
+ }
- /* Return the error that _mali_ukk_free_big_block produced */
- return map_errcode(err_code);
+ return 0;
}
-#if defined(CONFIG_MALI400_UMP)
-int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user *argument)
+int mem_unbind_wrapper(struct mali_session_data *session_data, _mali_uk_unbind_mem_s __user *uargs)
{
- _mali_uk_release_ump_mem_s uk_args;
- _mali_osk_errcode_t err_code;
+ _mali_uk_unbind_mem_s kargs;
+ _mali_osk_errcode_t err;
- /* validate input */
- /* the session_data pointer was validated by caller */
- MALI_CHECK_NON_NULL(argument, -EINVAL);
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
- /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
- if (0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_release_ump_mem_s))) {
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_unbind_mem_s))) {
return -EFAULT;
}
+ kargs.ctx = (uintptr_t)session_data;
- uk_args.ctx = (uintptr_t)session_data;
- err_code = _mali_ukk_release_ump_mem(&uk_args);
+ err = _mali_ukk_mem_unbind(&kargs);
- /* Return the error that _mali_ukk_free_big_block produced */
- return map_errcode(err_code);
+ if (_MALI_OSK_ERR_OK != err) {
+ return map_errcode(err);
+ }
+
+ return 0;
}
-int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user *argument)
+
+int mem_write_safe_wrapper(struct mali_session_data *session_data, _mali_uk_mem_write_safe_s __user *uargs)
{
- _mali_uk_attach_ump_mem_s uk_args;
- _mali_osk_errcode_t err_code;
+ _mali_uk_mem_write_safe_s kargs;
+ _mali_osk_errcode_t err;
- /* validate input */
- /* the session_data pointer was validated by caller */
- MALI_CHECK_NON_NULL(argument, -EINVAL);
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
- /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
- if (0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_attach_ump_mem_s))) {
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_mem_write_safe_s))) {
return -EFAULT;
}
- uk_args.ctx = (uintptr_t)session_data;
- err_code = _mali_ukk_attach_ump_mem(&uk_args);
+ kargs.ctx = (uintptr_t)session_data;
+
+ /* Check if we can access the buffers */
+ if (!access_ok(VERIFY_WRITE, kargs.dest, kargs.size)
+ || !access_ok(VERIFY_READ, kargs.src, kargs.size)) {
+ return -EINVAL;
+ }
+
+ /* Check if size wraps */
+ if ((kargs.size + kargs.dest) <= kargs.dest
+ || (kargs.size + kargs.src) <= kargs.src) {
+ return -EINVAL;
+ }
- if (0 != put_user(uk_args.cookie, &argument->cookie)) {
- if (_MALI_OSK_ERR_OK == err_code) {
- /* Rollback */
- _mali_uk_release_ump_mem_s uk_args_unmap;
+ err = _mali_ukk_mem_write_safe(&kargs);
+ if (_MALI_OSK_ERR_OK != err) {
+ return map_errcode(err);
+ }
- uk_args_unmap.ctx = (uintptr_t)session_data;
- uk_args_unmap.cookie = uk_args.cookie;
- err_code = _mali_ukk_release_ump_mem(&uk_args_unmap);
- if (_MALI_OSK_ERR_OK != err_code) {
- MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_attach_mem, as a result of failing put_user(), failed\n"));
- }
- }
+ if (0 != put_user(kargs.size, &uargs->size)) {
return -EFAULT;
}
- /* Return the error that _mali_ukk_map_external_ump_mem produced */
- return map_errcode(err_code);
+ return 0;
}
-#endif /* CONFIG_MALI400_UMP */
+
+
int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user *uargs)
{
/*
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2011-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2011-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs);
int request_high_priority_wrapper(struct mali_session_data *session_data, _mali_uk_request_high_priority_s __user *uargs);
+int mem_alloc_wrapper(struct mali_session_data *session_data, _mali_uk_alloc_mem_s __user *uargs);
+int mem_free_wrapper(struct mali_session_data *session_data, _mali_uk_free_mem_s __user *uargs);
+int mem_bind_wrapper(struct mali_session_data *session_data, _mali_uk_bind_mem_s __user *uargs);
+int mem_unbind_wrapper(struct mali_session_data *session_data, _mali_uk_unbind_mem_s __user *uargs);
+
int mem_write_safe_wrapper(struct mali_session_data *session_data, _mali_uk_mem_write_safe_s __user *uargs);
-int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user *argument);
-int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user *argument);
int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user *uargs);
int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user *uargs);
int timeline_create_sync_fence_wrapper(struct mali_session_data *session, _mali_uk_timeline_create_sync_fence_s __user *uargs);
int soft_job_start_wrapper(struct mali_session_data *session, _mali_uk_soft_job_start_s __user *uargs);
int soft_job_signal_wrapper(struct mali_session_data *session, _mali_uk_soft_job_signal_s __user *uargs);
-
-#if defined(CONFIG_MALI400_UMP)
-int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user *argument);
-int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user *argument);
-#endif
-
int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs);
int pp_and_gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_and_gp_start_job_s __user *uargs);
int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs);
return ret;
}
-#ifdef CONFIG_AM_VDEC_H264_4K2K
-static u32 grd_pp_bk = CFG_PP;
-static void mali_4k2k_enter(void)
-{
- if (mali_plat_data.limit_on == 0)
- return;
- grd_pp_bk = mali_plat_data.scale_info.maxpp;
- set_limit_pp_num(mali_plat_data.scale_info.minpp);
-}
-
-static void mali_4k2k_exit(void)
-{
- if (mali_plat_data.limit_on == 0)
- return;
- set_limit_pp_num(grd_pp_bk);
-}
-
-void vh264_4k2k_register_module_callback(void(*enter_func)(void), void(*remove_func)(void));
-#endif /* CONFIG_AM_VDEC_H264_4K2K */
-
void mali_gpu_utilization_callback(struct mali_gpu_utilization_data *data);
#if 0
printk("gpu core cooling register okay with err=%d\n",err);
}
#endif
-#ifdef CONFIG_AM_VDEC_H264_4K2K
- vh264_4k2k_register_module_callback(mali_4k2k_enter, mali_4k2k_exit);
-#endif /* CONFIG_AM_VDEC_H264_4K2K */
}
.shared_mem_size = 1024 * 1024 * 1024,
.max_job_runtime = 60000, /* 60 seconds */
.pmu_switch_delay = 0xFFFF, /* do not have to be this high on FPGA, but it is good for testing to have a delay */
+#if defined(CONFIG_ARCH_MESON8B)||defined(CONFIG_ARCH_MESONG9BB)
+ .pmu_domain_config = {0x1, 0x2, 0x4, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x1, 0x2, 0x0},
+#else
.pmu_domain_config = {0x1, 0x2, 0x4, 0x4,
0x0, 0x8, 0x8, 0x8,
0x0, 0x1, 0x2, 0x8},
+#endif
};
static void mali_platform_device_release(struct device *device);
/*
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
-r4p0-00rel0
+r5p1-01rel0
# Set default configuration to use, if Makefile didn't provide one.
# Change this to use a different config.h
+TARGET_PLATFORM ?= aml-meson
CONFIG ?= aml-meson-m400-1
-ifneq ($(KBUILD_SRC),)
- ifneq ($(wildcard $(KBUILD_SRC)/$(src)),)
- TOP_KBUILD_SRC := $(KBUILD_SRC)/
- endif
-endif
# Validate selected config
-ifneq ($(shell [ -d $(TOP_KBUILD_SRC)$(src)/arch-$(CONFIG) ] && [ -f $(TOP_KBUILD_SRC)$(src)/arch-$(CONFIG)/config.h ] && echo "OK"), OK)
+ifneq ($(shell [ -d $(src)/arch-$(CONFIG) ] && [ -f $(src)/arch-$(CONFIG)/config.h ] && echo "OK"), OK)
$(warning Current directory is $(src))
$(error No configuration found for config $(CONFIG). Check that arch-$(CONFIG)/config.h exists)
else
# Link arch to the selected arch-config directory
-$(shell [ -L $(TOP_KBUILD_SRC)$(src)/arch ] && rm $(TOP_KBUILD_SRC)$(src)/arch)
-$(shell ln -sf arch-$(CONFIG) $(TOP_KBUILD_SRC)$(src)/arch)
-$(shell touch $(TOP_KBUILD_SRC)$(src)/arch/config.h)
+$(shell [ -L $(src)/arch ] && rm $(src)/arch)
+$(shell ln -sf arch-$(CONFIG) $(src)/arch)
+$(shell touch $(src)/arch/config.h)
endif
UDD_FILE_PREFIX = ../mali/
# Get subversion revision number, fall back to 0000 if no svn info is available
-SVN_REV := $(shell ((svnversion | grep -qv exported && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //')
-
+SVN_INFO = (cd $(src); svn info 2>/dev/null)
+
+ifneq ($(shell $(SVN_INFO) 2>/dev/null),)
+# SVN detected
+SVN_REV := $(shell $(SVN_INFO) | grep '^Revision: '| sed -e 's/^Revision: //' 2>/dev/null)
+DRIVER_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV)
+CHANGE_DATE := $(shell $(SVN_INFO) | grep '^Last Changed Date: ' | cut -d: -f2- | cut -b2-)
+CHANGED_REVISION := $(shell $(SVN_INFO) | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-)
+REPO_URL := $(shell $(SVN_INFO) | grep '^URL: ' | cut -d: -f2- | cut -b2-)
+else # SVN
+GIT_REV := $(shell cd $(src); git describe --always 2>/dev/null)
+ifneq ($(GIT_REV),)
+# Git detected
+DRIVER_REV := $(MALI_RELEASE_NAME)-$(GIT_REV)
+CHANGE_DATE := $(shell cd $(src); git log -1 --format="%ci")
+CHANGED_REVISION := $(GIT_REV)
+REPO_URL := $(shell cd $(src); git describe --all --always 2>/dev/null)
+else # Git
+# No Git or SVN detected
+DRIVER_REV := $(MALI_RELEASE_NAME)
+CHANGE_DATE := $(MALI_RELEASE_NAME)
+CHANGED_REVISION := $(MALI_RELEASE_NAME)
+endif
+endif
ccflags-y += -DSVN_REV=$(SVN_REV)
-ccflags-y += -DSVN_REV_STRING=\"$(SVN_REV)\"
+ccflags-y += -DSVN_REV_STRING=\"$(DRIVER_REV)\"
-ccflags-y += -I$(src) -I$(TOP_KBUILD_SRC)$(src)/common -I$(TOP_KBUILD_SRC)$(src)/linux -I$(TOP_KBUILD_SRC)$(src)/../mali/common -I$(src)/../mali/linux -I$(src)/../ump/include/ump
-ccflags-y += -I$(srctree)/drivers/staging/android
+ccflags-y += -I$(src) -I$(src)/common -I$(src)/linux -I$(src)/../mali/common -I$(src)/../mali/linux -I$(src)/../../ump/include/ump
ccflags-y += -DMALI_STATE_TRACKING=0
ccflags-y += -DMALI_ENABLE_CPU_CYCLES=0
ccflags-$(CONFIG_UMP_DEBUG) += -DDEBUG
# The ARM proprietary product will only include the license/proprietary directory
# The GPL product will only include the license/gpl directory
-ifeq ($(wildcard $(TOP_KBUILD_SRC)$(src)/linux/license/gpl/*),)
-ccflags-y += -I$(TOP_KBUILD_SRC)$(src)/linux/license/proprietary
+ifeq ($(wildcard $(src)/linux/license/gpl/*),)
+ccflags-y += -I$(src)/linux/license/proprietary -I$(src)/../mali/linux/license/proprietary
else
-ccflags-y += -I$(TOP_KBUILD_SRC)$(src)/linux/license/gpl
-ccflags-y += -I$(TOP_KBUILD_SRC)$(src)/../mali/linux/license/gpl
+ccflags-y += -I$(src)/linux/license/gpl -I$(src)/../mali/linux/license/gpl
endif
-$(obj)/__mali_osk_atomics.c : $(src)/$(UDD_FILE_PREFIX)linux/mali_osk_atomics.c
- @cp -f $< $@
-$(obj)/__mali_osk_locks.c : $(src)/$(UDD_FILE_PREFIX)linux/mali_osk_locks.c
- @cp -f $< $@
-$(obj)/__mali_osk_memory.c : $(src)/$(UDD_FILE_PREFIX)linux/mali_osk_memory.c
- @cp -f $< $@
-$(obj)/__mali_osk_math.c : $(src)/$(UDD_FILE_PREFIX)linux/mali_osk_math.c
- @cp -f $< $@
-$(obj)/__mali_osk_misc.c : $(src)/$(UDD_FILE_PREFIX)linux/mali_osk_misc.c
- @cp -f $< $@
ump-y = common/ump_kernel_common.o \
common/ump_kernel_descriptor_mapping.o \
linux/ump_osk_low_level_mem.o \
linux/ump_osk_misc.o \
linux/ump_kernel_random_mapping.o \
- __mali_osk_locks.o \
- __mali_osk_memory.o \
- __mali_osk_atomics.o \
- __mali_osk_math.o \
- __mali_osk_misc.o
-# $(UDD_FILE_PREFIX)linux/mali_osk_atomics.o \
-# $(UDD_FILE_PREFIX)linux/mali_osk_locks.o \
-# $(UDD_FILE_PREFIX)linux/mali_osk_memory.o \
-# $(UDD_FILE_PREFIX)linux/mali_osk_math.o \
-# $(UDD_FILE_PREFIX)linux/mali_osk_misc.o
+ $(UDD_FILE_PREFIX)linux/mali_osk_atomics.o \
+ $(UDD_FILE_PREFIX)linux/mali_osk_locks.o \
+ $(UDD_FILE_PREFIX)linux/mali_osk_memory.o \
+ $(UDD_FILE_PREFIX)linux/mali_osk_math.o \
+ $(UDD_FILE_PREFIX)linux/mali_osk_misc.o
-clean-files := __mali_osk*.c
obj-$(CONFIG_UMP) := ump.o
menu "Mali 400 UMP device driver"
config UMP
tristate "UMP support"
- depends on m
+ depends on ARM
default n
---help---
This enables support for the UMP memory allocation and sharing API.
#
-# Copyright (C) 2010-2012, 2014 ARM Limited. All rights reserved.
+# Copyright (C) 2010-2012, 2014-2015 ARM Limited. All rights reserved.
#
# This program is free software and is provided to you under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
# Skip this Makefile when included from modpost
ifeq ($(KBUILD_EXTMOD),)
+TARGET_PLATFORM ?= aml-meson
+CONFIG ?= aml-meson-m400-1
+
# For each arch check: CROSS_COMPILE , KDIR , CFLAGS += -DARCH
export ARCH ?= arm
BUILD ?= debug
-TARGET_PLATFORM ?= aml-meson
-CONFIG ?= aml-meson-m400-1
-BUILD ?= debug
+check_cc2 = \
+ $(shell if $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \
+ then \
+ echo "$(2)"; \
+ else \
+ echo "$(3)"; \
+ fi ;)
# Check that required parameters are supplied.
ifeq ($(CONFIG),)
-$(error "CONFIG must be specified.")
+CONFIG := default
endif
ifeq ($(CPU)$(KDIR),)
$(error "KDIR or CPU must be specified.")
ifeq ($(ARCH), arm)
# when compiling for ARM we're cross compiling
- export CROSS_COMPILE ?= arm-none-linux-gnueabi-
+export CROSS_COMPILE ?= $(call check_cc2, arm-linux-gnueabi-gcc, arm-linux-gnueabi-, arm-none-linux-gnueabi-)
endif
# look up KDIR based om CPU selection
#
-# Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+# Copyright (C) 2010-2011, 2013, 2015 ARM Limited. All rights reserved.
#
# This program is free software and is provided to you under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2014-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2014-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2011, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2011, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2014-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
}
if (size < block->size - offset) {
- end_p = start_p + size - 1;
+ end_p = start_p + size;
size = 0;
} else {
if (offset) {
- end_p = start_p + (block->size - offset - 1);
+ end_p = start_p + (block->size - offset);
size -= block->size - offset;
offset = 0;
} else {
- end_p = start_p + block->size - 1;
+ end_p = start_p + block->size;
size -= block->size;
}
}
/*
- * Copyright (C) 2010, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2013-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2010, 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2010, 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
#
-# Copyright (C) 2012, 2014 ARM Limited. All rights reserved.
+# Copyright (C) 2012, 2015 ARM Limited. All rights reserved.
#
# This program is free software and is provided to you under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
typedef struct lock_ref {
int ref_count;
u32 pid;
+ u32 down_count;
} _lock_ref;
typedef struct umplock_item {
if (ref_index < MAX_PIDS) {
device.items[i_index].references[ref_index].pid = lock_cmd->pid;
device.items[i_index].references[ref_index].ref_count = 0;
+ device.items[i_index].references[ref_index].down_count = 0;
} else {
PERROR("whoops, item ran out of available reference slots\n");
return -EINVAL;
device.items[i_index].usage = lock_item->usage;
device.items[i_index].references[0].pid = lock_cmd->pid;
device.items[i_index].references[0].ref_count = 0;
+ device.items[i_index].references[0].down_count = 0;
sema_init(&device.items[i_index].item_lock, 1);
} else {
PERROR("whoops, ran out of available slots\n");
return 0;
}
+ device.items[i_index].references[ref_index].down_count++;
mutex_unlock(&device.item_list_lock);
if (down_interruptible(&device.items[i_index].item_lock)) {
/*wait up without hold the umplock. restore previous state and return*/
mutex_lock(&device.item_list_lock);
device.items[i_index].references[ref_index].ref_count--;
device.items[i_index].id_ref_count--;
+ device.items[i_index].references[ref_index].down_count--;
if (0 == device.items[i_index].references[ref_index].ref_count) {
device.items[i_index].references[ref_index].pid = 0;
if (0 == device.items[i_index].id_ref_count) {
static int do_umplock_release(_lock_cmd_priv *lock_cmd)
{
- int ret, i_index, ref_index;
+ int ret, i_index, ref_index, call_up;
_lock_item_s *lock_item = (_lock_item_s *)&lock_cmd->msg;
mutex_lock(&device.item_list_lock);
device.items[i_index].id_ref_count--;
PDEBUG(1, "unlock, pid: %d, secure_id: 0x%x, ref_count: %d\n", lock_cmd->pid, lock_item->secure_id, device.items[i_index].references[ref_index].ref_count);
+ call_up = 0;
+ if (device.items[i_index].references[ref_index].down_count > 1) {
+ call_up = 1;
+ device.items[i_index].references[ref_index].down_count--;
+ }
if (0 == device.items[i_index].references[ref_index].ref_count) {
device.items[i_index].references[ref_index].pid = 0;
if (0 == device.items[i_index].id_ref_count) {
device.items[i_index].secure_id = 0;
}
device.items[i_index].owner = 0;
+ call_up = 1;
+ }
+ if (call_up) {
+ PDEBUG(1, "call up, pid: %d, secure_id: 0x%x\n", lock_cmd->pid, lock_item->secure_id);
up(&device.items[i_index].item_lock);
}
mutex_unlock(&device.item_list_lock);
/*
- * Copyright (C) 2012-2014 ARM Limited. All rights reserved.
+ * Copyright (C) 2012-2013, 2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.