Patches goes to sun4i too

https://github.com/igorpecovnik/lib/pull/287
This commit is contained in:
Igor Pecovnik 2016-05-04 09:00:33 +02:00
parent addf46f028
commit dbdad655de
4 changed files with 785 additions and 0 deletions

View file

@ -0,0 +1,35 @@
From ef19ae19f876d9cb04fac10141d23c8ae500f9e7 Mon Sep 17 00:00:00 2001
From: Andreas Baierl <ichgeh@imkreisrum.de>
Date: Tue, 26 May 2015 09:18:46 -0400
Subject: [PATCH 1/9] arm:sunxi:disp: Fix division by zero
---
drivers/video/sunxi/disp/disp_video.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/video/sunxi/disp/disp_video.c b/drivers/video/sunxi/disp/disp_video.c
index aa07364..765f6ec 100644
--- a/drivers/video/sunxi/disp/disp_video.c
+++ b/drivers/video/sunxi/disp/disp_video.c
@@ -71,10 +71,14 @@ static __s32 video_enhancement_start(__u32 sel, __u32 id)
/* !!! assume open HDMI before video start */
if (gdisp.screen[sel].output_type == DISP_OUTPUT_TYPE_HDMI) {
scaler_index = gdisp.screen[sel].layer_manage[id].scaler_index;
- scaleuprate =
- gdisp.screen[sel].layer_manage[id].para.scn_win.width *
- 2 /
- gdisp.screen[sel].layer_manage[id].para.src_win.width;
+
+ if ((gdisp.screen[sel].layer_manage[id].para.scn_win.width ==
+ gdisp.screen[sel].layer_manage[id].para.src_win.width) ||
+ (gdisp.screen[sel].layer_manage[id].para.src_win.width < 1280))
+ scaleuprate = 0;
+ else
+ scaleuprate = gdisp.screen[sel].layer_manage[id].para.scn_win.width * 2 /
+ gdisp.screen[sel].layer_manage[id].para.src_win.width;
switch (scaleuprate) {
case 0: /* scale down, do noting */
--
2.7.0

View file

@ -0,0 +1,87 @@
From 3526df71cb2d2f9416a1a007da66ce88d3c70af9 Mon Sep 17 00:00:00 2001
From: Andreas Baierl <ichgeh@imkreisrum.de>
Date: Tue, 26 May 2015 09:20:10 -0400
Subject: [PATCH 2/9] arm:sunxi:g2d: Fix: handle noop blits
Zero area blits are technically valid noops and are requested by
libvdpau. Return 0 when blit area is zero without performing bogus
calculations.
---
drivers/char/sunxi_g2d/g2d.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/drivers/char/sunxi_g2d/g2d.c b/drivers/char/sunxi_g2d/g2d.c
index 539c726..02bc83c 100644
--- a/drivers/char/sunxi_g2d/g2d.c
+++ b/drivers/char/sunxi_g2d/g2d.c
@@ -142,8 +142,7 @@ int g2d_blit(g2d_blt * para)
__s32 err = 0;
/* check the parameter valid */
- if(para->src_rect.w == 0 || para->src_rect.h == 0 ||
- ((para->src_rect.x < 0)&&((-para->src_rect.x) > para->src_rect.w)) ||
+ if(((para->src_rect.x < 0)&&((-para->src_rect.x) > para->src_rect.w)) ||
((para->src_rect.y < 0)&&((-para->src_rect.y) > para->src_rect.h)) ||
((para->dst_x < 0)&&((-para->dst_x) > para->src_rect.w)) ||
((para->dst_y < 0)&&((-para->dst_y) > para->src_rect.h)) ||
@@ -157,6 +156,11 @@ int g2d_blit(g2d_blt * para)
}
else
{
+ if((para->src_rect.w == 0) || (para->src_rect.h == 0))
+ {
+ printk(KERN_DEBUG "User requested g2d blit on zero region\n");
+ return err;
+ }
if(((para->src_rect.x < 0)&&((-para->src_rect.x) < para->src_rect.w)))
{
para->src_rect.w = para->src_rect.w + para->src_rect.x;
@@ -209,8 +213,7 @@ int g2d_fill(g2d_fillrect * para)
__s32 err = 0;
/* check the parameter valid */
- if(para->dst_rect.w == 0 || para->dst_rect.h == 0 ||
- ((para->dst_rect.x < 0)&&((-para->dst_rect.x)>para->dst_rect.w)) ||
+ if(((para->dst_rect.x < 0)&&((-para->dst_rect.x)>para->dst_rect.w)) ||
((para->dst_rect.y < 0)&&((-para->dst_rect.y)>para->dst_rect.h)) ||
((para->dst_rect.x > 0)&&(para->dst_rect.x > para->dst_image.w - 1)) ||
((para->dst_rect.y > 0)&&(para->dst_rect.y > para->dst_image.h - 1)))
@@ -220,6 +223,11 @@ int g2d_fill(g2d_fillrect * para)
}
else
{
+ if((para->dst_rect.w == 0) || (para->dst_rect.h == 0))
+ {
+ printk(KERN_DEBUG "User requested g2d fill on zero region\n");
+ return err;
+ }
if(((para->dst_rect.x < 0)&&((-para->dst_rect.x) < para->dst_rect.w)))
{
para->dst_rect.w = para->dst_rect.w + para->dst_rect.x;
@@ -251,9 +259,7 @@ int g2d_stretchblit(g2d_stretchblt * para)
__s32 err = 0;
/* check the parameter valid */
- if(para->src_rect.w == 0 || para->src_rect.h == 0 ||
- para->dst_rect.w == 0 || para->dst_rect.h == 0 ||
- ((para->src_rect.x < 0)&&((-para->src_rect.x) > para->src_rect.w)) ||
+ if(((para->src_rect.x < 0)&&((-para->src_rect.x) > para->src_rect.w)) ||
((para->src_rect.y < 0)&&((-para->src_rect.y) > para->src_rect.h)) ||
((para->dst_rect.x < 0)&&((-para->dst_rect.x) > para->dst_rect.w)) ||
((para->dst_rect.y < 0)&&((-para->dst_rect.y) > para->dst_rect.h)) ||
@@ -267,6 +273,12 @@ int g2d_stretchblit(g2d_stretchblt * para)
}
else
{
+ if((para->dst_rect.w == 0) || (para->dst_rect.h == 0) ||
+ (para->src_rect.w == 0) || (para->src_rect.h == 0))
+ {
+ printk(KERN_DEBUG "User requested g2d stretchblit on zero region\n");
+ return err;
+ }
if(((para->src_rect.x < 0)&&((-para->src_rect.x) < para->src_rect.w)))
{
para->src_rect.w = para->src_rect.w + para->src_rect.x;
--
2.7.0

View file

@ -0,0 +1,31 @@
From c92d32e1adc7ee2fcf014a9abf35039b59478bf3 Mon Sep 17 00:00:00 2001
From: Andreas Baierl <ichgeh@imkreisrum.de>
Date: Tue, 26 May 2015 09:23:00 -0400
Subject: [PATCH 3/9] arm:sunxi:disp: Fix csc calculations.
---
drivers/video/sunxi/disp/de_fe.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/video/sunxi/disp/de_fe.c b/drivers/video/sunxi/disp/de_fe.c
index 92799a0..54dfe7f 100644
--- a/drivers/video/sunxi/disp/de_fe.c
+++ b/drivers/video/sunxi/disp/de_fe.c
@@ -1382,10 +1382,10 @@ __s32 DE_SCAL_Set_CSC_Coef_Enhance(__u8 sel, __u8 in_csc_mode,
__u32 i;
__s32 sinv, cosv; /* sin_tab: 7 bit fractional */
- bright = bright * 64 / 100;
- bright = saturation * 64 / 100;
- bright = contrast * 64 / 100;
- bright = hue * 64 / 100;
+ bright = DIV_ROUND_CLOSEST((clamp(bright, 0, 100) * 63), 100);
+ saturation = DIV_ROUND_CLOSEST((clamp(saturation, 0, 100) * 63), 100);
+ contrast = DIV_ROUND_CLOSEST((clamp(contrast, 0, 100) * 63), 100);
+ hue = DIV_ROUND_CLOSEST((clamp(hue, 0, 100) * 63), 100);
sinv = image_enhance_tab[8 * 12 + (hue & 0x3f)];
cosv = image_enhance_tab[8 * 12 + 8 * 8 + (hue & 0x3f)];
--
2.7.0

View file

@ -0,0 +1,632 @@
From 16ad799b917a761b1b3c269a1063e5f0e991d35c Mon Sep 17 00:00:00 2001
From: Martin Ostertag <martin.ostertag@gmx.de>
Date: Tue, 29 Dec 2015 23:37:47 +0100
Subject: [PATCH 9/9] Added new backend based on CMA for the Mali UMP memory
block allocator.
This one is necesary for a zero-copy interworking between Cedarx and Mali hardware
---
drivers/gpu/mali/ump/Kbuild | 1 +
.../mali/ump/arch-ca7-virtex820-m400-2/config.h | 4 +-
.../mali/ump/arch-ca8-virtex820-m400-1/config.h | 4 +-
drivers/gpu/mali/ump/common/ump_kernel_api.c | 27 ++-
drivers/gpu/mali/ump/common/ump_kernel_types.h | 13 +-
drivers/gpu/mali/ump/common/ump_uk_types.h | 11 ++
drivers/gpu/mali/ump/common/ump_ukk.h | 2 +
drivers/gpu/mali/ump/linux/ump_ioctl.h | 1 +
drivers/gpu/mali/ump/linux/ump_kernel_linux.c | 29 +--
.../mali/ump/linux/ump_kernel_memory_backend_cma.c | 209 +++++++++++++++++++++
.../mali/ump/linux/ump_kernel_memory_backend_cma.h | 27 +++
drivers/gpu/mali/ump/linux/ump_memory_backend.c | 8 +-
drivers/gpu/mali/ump/linux/ump_ukk_wrappers.c | 40 ++++
drivers/gpu/mali/ump/linux/ump_ukk_wrappers.h | 1 +
14 files changed, 358 insertions(+), 19 deletions(-)
create mode 100644 drivers/gpu/mali/ump/linux/ump_kernel_memory_backend_cma.c
create mode 100644 drivers/gpu/mali/ump/linux/ump_kernel_memory_backend_cma.h
diff --git a/drivers/gpu/mali/ump/Kbuild b/drivers/gpu/mali/ump/Kbuild
index 62380fa..a581a27 100644
--- a/drivers/gpu/mali/ump/Kbuild
+++ b/drivers/gpu/mali/ump/Kbuild
@@ -43,6 +43,7 @@ ump-y = common/ump_kernel_common.o \
linux/ump_kernel_linux.o \
linux/ump_kernel_memory_backend_os.o \
linux/ump_kernel_memory_backend_dedicated.o \
+ linux/ump_kernel_memory_backend_cma.o \
linux/ump_memory_backend.o \
linux/ump_ukk_wrappers.o \
linux/ump_ukk_ref_wrappers.o \
diff --git a/drivers/gpu/mali/ump/arch-ca7-virtex820-m400-2/config.h b/drivers/gpu/mali/ump/arch-ca7-virtex820-m400-2/config.h
index 9560e96..9199061 100644
--- a/drivers/gpu/mali/ump/arch-ca7-virtex820-m400-2/config.h
+++ b/drivers/gpu/mali/ump/arch-ca7-virtex820-m400-2/config.h
@@ -1,8 +1,8 @@
#ifndef __ARCH_CONFIG_H__
#define __ARCH_CONFIG_H__
-#define ARCH_UMP_BACKEND_DEFAULT 1
+#define ARCH_UMP_BACKEND_DEFAULT 2
#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x5E000000
#define ARCH_UMP_MEMORY_SIZE_DEFAULT 128UL * 1024UL * 1024UL
-#endif /* __ARCH_CONFIG_H__ */
\ No newline at end of file
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/gpu/mali/ump/arch-ca8-virtex820-m400-1/config.h b/drivers/gpu/mali/ump/arch-ca8-virtex820-m400-1/config.h
index 9560e96..9199061 100644
--- a/drivers/gpu/mali/ump/arch-ca8-virtex820-m400-1/config.h
+++ b/drivers/gpu/mali/ump/arch-ca8-virtex820-m400-1/config.h
@@ -1,8 +1,8 @@
#ifndef __ARCH_CONFIG_H__
#define __ARCH_CONFIG_H__
-#define ARCH_UMP_BACKEND_DEFAULT 1
+#define ARCH_UMP_BACKEND_DEFAULT 2
#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x5E000000
#define ARCH_UMP_MEMORY_SIZE_DEFAULT 128UL * 1024UL * 1024UL
-#endif /* __ARCH_CONFIG_H__ */
\ No newline at end of file
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/gpu/mali/ump/common/ump_kernel_api.c b/drivers/gpu/mali/ump/common/ump_kernel_api.c
index e86bc33..e5ce026 100644
--- a/drivers/gpu/mali/ump/common/ump_kernel_api.c
+++ b/drivers/gpu/mali/ump/common/ump_kernel_api.c
@@ -7,6 +7,8 @@
* 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 <asm/memory.h>
+#include <mach/memory.h>
#include "mali_osk.h"
#include "mali_osk_list.h"
@@ -16,7 +18,6 @@
#include "ump_kernel_common.h"
-
/* ---------------- UMP kernel space API functions follows ---------------- */
@@ -291,6 +292,30 @@ _mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction )
return ret;
}
+_mali_osk_errcode_t _ump_ukk_phys_addr_get( _ump_uk_phys_addr_get_s *user_interaction )
+{
+ ump_dd_mem * mem;
+ _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT;
+
+ DEBUG_ASSERT_POINTER( user_interaction );
+
+ /* We lock the mappings so things don't get removed while we are looking for the memory */
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)user_interaction->secure_id, (void**)&mem))
+ {
+ user_interaction->phys_addr = __phys_to_bus(mem->block_array[0].addr);
+ DBG_MSG(4, ("Returning physical address. ID: %u, phys_addr: 0x%x ", (ump_secure_id)user_interaction->secure_id, (unsigned long)user_interaction->phys_addr));
+ ret = _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ user_interaction->phys_addr = 0;
+ DBG_MSG(1, ("Failed to look up mapping in ump_ioctl_phys_addr_get(). ID: %u\n", (ump_secure_id)user_interaction->secure_id));
+ }
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ return ret;
+}
void _ump_ukk_msync( _ump_uk_msync_s *args )
diff --git a/drivers/gpu/mali/ump/common/ump_kernel_types.h b/drivers/gpu/mali/ump/common/ump_kernel_types.h
index fdacd86..45d4939 100644
--- a/drivers/gpu/mali/ump/common/ump_kernel_types.h
+++ b/drivers/gpu/mali/ump/common/ump_kernel_types.h
@@ -13,7 +13,10 @@
#include "ump_kernel_interface.h"
#include "mali_osk.h"
+#include <linux/cdev.h>
+#include <linux/device.h>
+#define UMP_LICENSE_IS_GPL 1
typedef enum
{
@@ -40,6 +43,7 @@ typedef struct ump_dd_mem
unsigned long size_bytes;
unsigned long nr_blocks;
ump_dd_physical_block * block_array;
+ void * cpu_addr;
void (*release_func)(void * ctx, struct ump_dd_mem * descriptor);
void * ctx;
void * backend_info;
@@ -48,6 +52,13 @@ typedef struct ump_dd_mem
ump_lock_usage lock_usage;
} ump_dd_mem;
-
+struct ump_device
+{
+ struct cdev cdev;
+#if UMP_LICENSE_IS_GPL
+ struct class * ump_class;
+ struct device *mdev;
+#endif
+};
#endif /* __UMP_KERNEL_TYPES_H__ */
diff --git a/drivers/gpu/mali/ump/common/ump_uk_types.h b/drivers/gpu/mali/ump/common/ump_uk_types.h
index 24f4596..bd0cc8d 100644
--- a/drivers/gpu/mali/ump/common/ump_uk_types.h
+++ b/drivers/gpu/mali/ump/common/ump_uk_types.h
@@ -49,6 +49,7 @@ typedef enum
_UMP_IOC_SWITCH_HW_USAGE,
_UMP_IOC_LOCK,
_UMP_IOC_UNLOCK,
+ _UMP_IOC_PHYS_ADDR_GET,
}_ump_uk_functions;
typedef enum
@@ -118,6 +119,16 @@ typedef struct _ump_uk_size_get_s
} _ump_uk_size_get_s;
/**
+ * PHYS_ADDR_GET ([in] u32 secure_id, [out]phys_addr )
+ */
+typedef struct _ump_uk_phys_addr_get_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 secure_id; /**< Input to DD */
+ void *phys_addr; /**< Returned physical address; output */
+} _ump_uk_phys_addr_get_s;
+
+/**
* Release ([in] u32 secure_id)
*/
typedef struct _ump_uk_release_s
diff --git a/drivers/gpu/mali/ump/common/ump_ukk.h b/drivers/gpu/mali/ump/common/ump_ukk.h
index 4e6bb86..926a286 100644
--- a/drivers/gpu/mali/ump/common/ump_ukk.h
+++ b/drivers/gpu/mali/ump/common/ump_ukk.h
@@ -36,6 +36,8 @@ _mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info );
_mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction );
+_mali_osk_errcode_t _ump_ukk_phys_addr_get( _ump_uk_phys_addr_get_s *user_interaction );
+
_mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args );
_mali_osk_errcode_t _ump_uku_get_api_version( _ump_uk_api_version_s *args );
diff --git a/drivers/gpu/mali/ump/linux/ump_ioctl.h b/drivers/gpu/mali/ump/linux/ump_ioctl.h
index 675e36e..6778b67 100644
--- a/drivers/gpu/mali/ump/linux/ump_ioctl.h
+++ b/drivers/gpu/mali/ump/linux/ump_ioctl.h
@@ -46,6 +46,7 @@ extern "C"
#define UMP_IOC_LOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_LOCK, _ump_uk_lock_s)
#define UMP_IOC_UNLOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_UNLOCK, _ump_uk_unlock_s)
+#define UMP_IOC_PHYS_ADDR_GET _IOWR(UMP_IOCTL_NR, _UMP_IOC_PHYS_ADDR_GET, _ump_uk_phys_addr_get_s)
#ifdef __cplusplus
}
diff --git a/drivers/gpu/mali/ump/linux/ump_kernel_linux.c b/drivers/gpu/mali/ump/linux/ump_kernel_linux.c
index 40514fe..02b12b4 100644
--- a/drivers/gpu/mali/ump/linux/ump_kernel_linux.c
+++ b/drivers/gpu/mali/ump/linux/ump_kernel_linux.c
@@ -17,6 +17,7 @@
#include <asm/atomic.h>
#include <linux/device.h>
#include <linux/debugfs.h>
+#include <linux/dma-mapping.h>
#include "config.h" /* Configuration for current platform. The symlinc for arch is set by Makefile */
#include "ump_ioctl.h"
@@ -65,16 +66,10 @@ typedef struct ump_vma_usage_tracker
ump_dd_handle handle;
} ump_vma_usage_tracker;
-struct ump_device
-{
- struct cdev cdev;
-#if UMP_LICENSE_IS_GPL
- struct class * ump_class;
-#endif
-};
+
/* The global variable containing the global device data */
-static struct ump_device ump_device;
+struct ump_device ump_device;
/* Forward declare static functions */
@@ -207,14 +202,19 @@ int ump_kernel_device_initialize(void)
}
else
{
- struct device * mdev;
- mdev = device_create(ump_device.ump_class, NULL, dev, NULL, ump_dev_name);
- if (!IS_ERR(mdev))
+ ump_device.mdev = device_create(ump_device.ump_class, NULL, dev, NULL, ump_dev_name);
+ if (!IS_ERR(ump_device.mdev))
{
+ DBG_MSG(2, ("dma_set_mask_and_coherent calling\n"));
+ err = dma_set_coherent_mask(ump_device.mdev, DMA_BIT_MASK(28));
+ DBG_MSG(2, ("dma_set_mask_and_coherent result=%d\n", err));
+ if(err < 0)
+ DBG_MSG(2, ("dma_set_mask_and_coherent failed\n"));
+
return 0;
}
- err = PTR_ERR(mdev);
+ err = PTR_ERR(ump_device.mdev);
}
cdev_del(&ump_device.cdev);
#else
@@ -367,6 +367,10 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c
case UMP_IOC_UNLOCK:
err = ump_unlock_wrapper((u32 __user *)argument, session_data);
break;
+
+ case UMP_IOC_PHYS_ADDR_GET:
+ err = ump_phys_addr_get_wrapper((u32 __user *)argument, session_data);
+ break;
default:
DBG_MSG(1, ("No handler for IOCTL. cmd: 0x%08x, arg: 0x%08lx\n", cmd, arg));
@@ -449,6 +453,7 @@ EXPORT_SYMBOL(ump_dd_phys_blocks_get);
EXPORT_SYMBOL(ump_dd_size_get);
EXPORT_SYMBOL(ump_dd_reference_add);
EXPORT_SYMBOL(ump_dd_reference_release);
+EXPORT_SYMBOL(ump_device);
/* Export our own extended kernel space allocator */
EXPORT_SYMBOL(ump_dd_handle_create_from_phys_blocks);
diff --git a/drivers/gpu/mali/ump/linux/ump_kernel_memory_backend_cma.c b/drivers/gpu/mali/ump/linux/ump_kernel_memory_backend_cma.c
new file mode 100644
index 0000000..84021cd
--- /dev/null
+++ b/drivers/gpu/mali/ump/linux/ump_kernel_memory_backend_cma.c
@@ -0,0 +1,209 @@
+/*
+ * Based on code originally written by ARM Limited.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright 2015 Martin Ostertag Martin.Ostertag@gmx.de
+ *
+ *
+ * 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.
+ */
+
+/* needed to detect kernel version specific code */
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#include <linux/semaphore.h>
+#else /* pre 2.6.26 the file was in the arch specific location */
+#include <asm/semaphore.h>
+#endif
+
+#include <linux/dma-mapping.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/atomic.h>
+#include <linux/vmalloc.h>
+#include <asm/cacheflush.h>
+#include "ump_kernel_common.h"
+#include "ump_kernel_memory_backend.h"
+
+
+extern struct ump_device ump_device;
+
+typedef struct os_allocator
+{
+ struct semaphore mutex;
+ u32 mem_maximum; /**< Maximum number of pages to allocate from the CMA */
+ u32 mem_allocated; /**< Number of pages allocated from the CMA */
+} cma_allocator;
+
+
+
+static void cma_free(void* ctx, ump_dd_mem * descriptor);
+static int cma_allocate(void* ctx, ump_dd_mem * descriptor);
+static void cma_memory_backend_destroy(ump_memory_backend * backend);
+static u32 cma_stat(struct ump_memory_backend *backend);
+
+
+
+/*
+ * Create CMA memory backend
+ */
+ump_memory_backend * ump_cma_memory_backend_create(const int max_allocation)
+{
+ ump_memory_backend * backend;
+ cma_allocator * info;
+
+ info = kmalloc(sizeof(cma_allocator), GFP_KERNEL);
+ if (NULL == info)
+ {
+ return NULL;
+ }
+
+ info->mem_maximum = max_allocation;
+ info->mem_allocated = 0;
+
+ sema_init(&info->mutex, 1);
+
+ backend = kmalloc(sizeof(ump_memory_backend), GFP_KERNEL);
+ if (NULL == backend)
+ {
+ kfree(info);
+ return NULL;
+ }
+
+ backend->ctx = info;
+ backend->allocate = cma_allocate;
+ backend->release = cma_free;
+ backend->shutdown = cma_memory_backend_destroy;
+ backend->stat = cma_stat;
+ backend->pre_allocate_physical_check = NULL;
+ backend->adjust_to_mali_phys = NULL;
+
+ return backend;
+}
+
+
+
+/*
+ * Destroy specified OS memory backend
+ */
+static void cma_memory_backend_destroy(ump_memory_backend * backend)
+{
+ cma_allocator * info = (cma_allocator*)backend->ctx;
+
+ DBG_MSG_IF(1, 0 != info->mem_allocated, ("%d bytes still in use during shutdown\n", info->mem_allocated));
+
+ kfree(info);
+ kfree(backend);
+}
+
+
+
+/*
+ * Allocate UMP memory
+ */
+static int cma_allocate(void* ctx, ump_dd_mem * descriptor)
+{
+ u32 left;
+ cma_allocator * info;
+ int pages_allocated = 0;
+ int is_cached;
+ dma_addr_t paddr;
+
+ BUG_ON(!descriptor);
+ BUG_ON(!ctx);
+
+ info = (cma_allocator*)ctx;
+ left = descriptor->size_bytes;
+ is_cached = descriptor->is_cached;
+
+ if (down_interruptible(&info->mutex))
+ {
+ DBG_MSG(1, ("Failed to get mutex in os_free\n"));
+ return 0; /* failure */
+ }
+
+ descriptor->backend_info = NULL;
+ descriptor->nr_blocks = ((left + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) >> PAGE_SHIFT;
+
+ DBG_MSG(5, ("Allocating page array. Size: %lu\n", descriptor->nr_blocks * sizeof(ump_dd_physical_block)));
+
+ descriptor->block_array = (ump_dd_physical_block *)vmalloc(sizeof(ump_dd_physical_block) * descriptor->nr_blocks);
+ if (NULL == descriptor->block_array)
+ {
+ up(&info->mutex);
+ DBG_MSG(1, ("Block array could not be allocated\n"));
+ return 0; /* failure */
+ }
+
+ descriptor->cpu_addr = dma_alloc_coherent(/* ump_device.mdev */ NULL, descriptor->size_bytes, &paddr, GFP_KERNEL | GFP_DMA);
+ if(! descriptor->cpu_addr)
+ {
+ up(&info->mutex);
+ DBG_MSG(1, ("Failed to allocate needed CMA memory %d bytes\n", descriptor->size_bytes));
+ return 0; /* failure */
+ }
+
+ if(is_cached)
+ DBG_MSG(1, ("caching not supported\n"));
+
+ for (; pages_allocated < descriptor->nr_blocks; pages_allocated++)
+ {
+ descriptor->block_array[pages_allocated].addr = ((char*)paddr) + (PAGE_SIZE * pages_allocated);
+ descriptor->block_array[pages_allocated].size = PAGE_SIZE;
+ }
+
+ DBG_MSG(5, ("Alloce for ID:%2d got %d pages\n", descriptor->secure_id, pages_allocated));
+
+ info->mem_allocated += descriptor->size_bytes;
+
+ DBG_MSG(6, ("%d out of %d bytes now allocated\n", info->mem_allocated, info->mem_maximum));
+
+ up(&info->mutex);
+
+ return 1; /* success*/
+}
+
+
+/*
+ * Free specified UMP memory
+ */
+static void cma_free(void* ctx, ump_dd_mem * descriptor)
+{
+ cma_allocator * info;
+ int i;
+
+ BUG_ON(!ctx);
+ BUG_ON(!descriptor);
+
+ info = (cma_allocator*)ctx;
+
+ BUG_ON(descriptor->nr_blocks * PAGE_SIZE > info->mem_allocated);
+
+ if (down_interruptible(&info->mutex))
+ {
+ DBG_MSG(1, ("Failed to get mutex in cma_free\n"));
+ return;
+ }
+
+ DBG_MSG(5, ("Releasing %lu OS pages\n", descriptor->nr_blocks));
+
+ info->mem_allocated -= descriptor->nr_blocks * PAGE_SIZE;
+
+ up(&info->mutex);
+
+ dma_free_coherent(ump_device.mdev, descriptor->nr_blocks * PAGE_SIZE,
+ descriptor->cpu_addr, descriptor->block_array[0].addr);
+ vfree(descriptor->block_array);
+}
+
+
+static u32 cma_stat(struct ump_memory_backend *backend)
+{
+ cma_allocator *info;
+ info = (cma_allocator*)backend->ctx;
+ return info->mem_allocated;
+}
diff --git a/drivers/gpu/mali/ump/linux/ump_kernel_memory_backend_cma.h b/drivers/gpu/mali/ump/linux/ump_kernel_memory_backend_cma.h
new file mode 100644
index 0000000..7687b58
--- /dev/null
+++ b/drivers/gpu/mali/ump/linux/ump_kernel_memory_backend_cma.h
@@ -0,0 +1,27 @@
+/*
+ * Based on code originally written by ARM Limited.
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ * Copyright 2015 Martin Ostertag Martin.Ostertag@gmx.de
+ *
+ * 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.
+ *
+ * Modified 2015: Martin Ostertag <martin.ostertag@gmx.de>
+ */
+
+/**
+ * @file ump_kernel_memory_backend_CMA.h
+ */
+
+#ifndef __UMP_KERNEL_MEMORY_BACKEND_CMA_H__
+#define __UMP_KERNEL_MEMORY_BACKEND_CMA_H__
+
+#include "ump_kernel_memory_backend.h"
+
+ump_memory_backend * ump_cma_memory_backend_create(const int max_allocation);
+
+#endif /* __UMP_KERNEL_MEMORY_BACKEND_CMA_H__ */
+
diff --git a/drivers/gpu/mali/ump/linux/ump_memory_backend.c b/drivers/gpu/mali/ump/linux/ump_memory_backend.c
index 9242819..76c5c96 100644
--- a/drivers/gpu/mali/ump/linux/ump_memory_backend.c
+++ b/drivers/gpu/mali/ump/linux/ump_memory_backend.c
@@ -17,11 +17,12 @@
#include "ump_kernel_common.h"
#include "ump_kernel_memory_backend_os.h"
#include "ump_kernel_memory_backend_dedicated.h"
+#include "ump_kernel_memory_backend_cma.h"
/* Configure which dynamic memory allocator to use */
int ump_backend = ARCH_UMP_BACKEND_DEFAULT;
module_param(ump_backend, int, S_IRUGO); /* r--r--r-- */
-MODULE_PARM_DESC(ump_backend, "0 = dedicated memory backend (default), 1 = OS memory backend");
+MODULE_PARM_DESC(ump_backend, "0 = dedicated memory backend (default), 1 = OS memory backend, 2 = CMA based backend");
/* The base address of the memory block for the dedicated memory backend */
unsigned int ump_memory_address = ARCH_UMP_MEMORY_ADDRESS_DEFAULT;
@@ -56,6 +57,11 @@ ump_memory_backend* ump_memory_backend_create ( void )
DBG_MSG(2, ("Using OS memory backend, allocation limit: %d\n", ump_memory_size));
backend = ump_os_memory_backend_create(ump_memory_size);
}
+ else if (2 == ump_backend)
+ {
+ DBG_MSG(2, ("Using CMA memory backend, allocation limit: %d\n", ump_memory_size));
+ backend = ump_cma_memory_backend_create(ump_memory_size);
+ }
return backend;
}
diff --git a/drivers/gpu/mali/ump/linux/ump_ukk_wrappers.c b/drivers/gpu/mali/ump/linux/ump_ukk_wrappers.c
index e5c5903..1f06242 100644
--- a/drivers/gpu/mali/ump/linux/ump_ukk_wrappers.c
+++ b/drivers/gpu/mali/ump/linux/ump_ukk_wrappers.c
@@ -138,6 +138,46 @@ int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * sessi
}
/*
+ * IOCTL operation; Return physical address for specified UMP memory.
+ */
+int ump_phys_addr_get_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_phys_addr_get_s user_interaction;
+ _mali_osk_errcode_t err;
+
+ /* Sanity check input parameters */
+ if (NULL == argument || NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
+ return -ENOTTY;
+ }
+
+ if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_size_get()\n"));
+ return -EFAULT;
+ }
+
+ user_interaction.ctx = (void *) session_data;
+ err = _ump_ukk_phys_addr_get( &user_interaction );
+ if( _MALI_OSK_ERR_OK != err )
+ {
+ MSG_ERR(("_ump_ukk_size_get() failed in ump_ioctl_size_get()\n"));
+ return map_errcode(err);
+ }
+
+ user_interaction.ctx = NULL;
+
+ if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_to_user() failed in ump_ioctl_size_get()\n"));
+ return -EFAULT;
+ }
+
+ return 0; /* success */
+}
+
+/*
* IOCTL operation; Do cache maintenance on specified UMP memory.
*/
int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data)
diff --git a/drivers/gpu/mali/ump/linux/ump_ukk_wrappers.h b/drivers/gpu/mali/ump/linux/ump_ukk_wrappers.h
index 1cbacf7..acb3505 100644
--- a/drivers/gpu/mali/ump/linux/ump_ukk_wrappers.h
+++ b/drivers/gpu/mali/ump/linux/ump_ukk_wrappers.h
@@ -34,6 +34,7 @@ int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_sessi
int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data * session_data);
int ump_lock_wrapper(u32 __user * argument, struct ump_session_data * session_data);
int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+int ump_phys_addr_get_wrapper(u32 __user * argument, struct ump_session_data * session_data);
--
2.7.0