[PATCH 3/3] drm/amd/powerplay: enable dkms build

2015-11-24 Thread Jammy Zhou
Signed-off-by: Jammy Zhou 
Reviewed-by: Alex Deucher 
---
 drivers/gpu/drm/amd/powerplay/Makefile | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/powerplay/Makefile 
b/drivers/gpu/drm/amd/powerplay/Makefile
index e195bf5..043e6eb 100644
--- a/drivers/gpu/drm/amd/powerplay/Makefile
+++ b/drivers/gpu/drm/amd/powerplay/Makefile
@@ -1,17 +1,17 @@

 subdir-ccflags-y += -Iinclude/drm  \
-   -Idrivers/gpu/drm/amd/powerplay/inc/  \
-   -Idrivers/gpu/drm/amd/include/asic_reg  \
-   -Idrivers/gpu/drm/amd/include  \
-   -Idrivers/gpu/drm/amd/powerplay/smumgr\
-   -Idrivers/gpu/drm/amd/powerplay/hwmgr \
-   -Idrivers/gpu/drm/amd/powerplay/eventmgr
+   -I$(FULL_AMD_PATH)/powerplay/inc/  \
+   -I$(FULL_AMD_PATH)/include/asic_reg  \
+   -I$(FULL_AMD_PATH)/include  \
+   -I$(FULL_AMD_PATH)/powerplay/smumgr\
+   -I$(FULL_AMD_PATH)/powerplay/hwmgr \
+   -I$(FULL_AMD_PATH)/powerplay/eventmgr

 AMD_PP_PATH = ../powerplay

 PP_LIBS = smumgr hwmgr eventmgr

-AMD_POWERPLAY = $(addsuffix /Makefile,$(addprefix 
drivers/gpu/drm/amd/powerplay/,$(PP_LIBS)))
+AMD_POWERPLAY = $(addsuffix /Makefile,$(addprefix 
$(FULL_AMD_PATH)/powerplay/,$(PP_LIBS)))

 include $(AMD_POWERPLAY)

-- 
1.9.1



[PATCH 2/3] drm/amd/acp: use $(src) in Makefile

2015-11-24 Thread Jammy Zhou
Signed-off-by: Jammy Zhou 
---
 drivers/gpu/drm/amd/acp/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/acp/Makefile b/drivers/gpu/drm/amd/acp/Makefile
index c8c3303..b33bbd6 100644
--- a/drivers/gpu/drm/amd/acp/Makefile
+++ b/drivers/gpu/drm/amd/acp/Makefile
@@ -3,7 +3,7 @@
 # of AMDSOC/AMDGPU drm driver.
 # It provides the HW control for ACP related functionalities.

-ccflags-y += -Idrivers/gpu/drm/amd/include/asic_reg/acp
+ccflags-y += -I$(src)/../include/asic_reg/acp
 subdir-ccflags-y += -I$(AMDACPPATH)/ -I$(AMDACPPATH)/include

 AMD_ACP_FILES := $(AMDACPPATH)/acp_hw.o
-- 
1.9.1



[PATCH 1/3] drm/amdgpu: use $(src) in Makefile

2015-11-24 Thread Jammy Zhou
This can solve the path problem when compile amdgpu with DKMS.

Signed-off-by: Jammy Zhou 
Acked-by: Alex Deucher 
---
 drivers/gpu/drm/amd/amdgpu/Makefile | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
b/drivers/gpu/drm/amd/amdgpu/Makefile
index 156b726..0540a20 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -2,12 +2,14 @@
 # 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 -Idrivers/gpu/drm/amd/include/asic_reg \
-   -Idrivers/gpu/drm/amd/include \
-   -Idrivers/gpu/drm/amd/amdgpu \
-   -Idrivers/gpu/drm/amd/scheduler \
-   -Idrivers/gpu/drm/amd/powerplay/inc \
-   -Idrivers/gpu/drm/amd/acp/include
+FULL_AMD_PATH=$(src)/..
+
+ccflags-y := -Iinclude/drm -I$(FULL_AMD_PATH)/include/asic_reg \
+   -I$(FULL_AMD_PATH)/include \
+   -I$(FULL_AMD_PATH)/amdgpu \
+   -I$(FULL_AMD_PATH)/scheduler \
+   -I$(FULL_AMD_PATH)/powerplay/inc \
+   -I$(FULL_AMD_PATH)/acp/include

 amdgpu-y := amdgpu_drv.o

-- 
1.9.1



[PATCH 0/3] drm/amdgpu: enable DKMS build

2015-11-24 Thread Jammy Zhou
This series enable the DKMS build of amdgpu driver.

Jammy Zhou (3):
  drm/amdgpu: use $(src) in Makefile
  drm/amd/acp: use $(src) in Makefile
  drm/amd/powerplay: enable dkms build

 drivers/gpu/drm/amd/acp/Makefile   |  2 +-
 drivers/gpu/drm/amd/amdgpu/Makefile| 14 --
 drivers/gpu/drm/amd/powerplay/Makefile | 14 +++---
 3 files changed, 16 insertions(+), 14 deletions(-)

-- 
1.9.1



[PATCH] drm: fix the usage after free

2015-08-24 Thread Jammy Zhou
From: Mathias Tillman <master.ho...@gmail.com>

For readdir_r(), the next directory entry is returned in caller-allocted
buffer (pointered by pent here).

https://bugs.freedesktop.org/show_bug.cgi?id=91704

Signed-off-by: Jammy Zhou 
---
 xf86drm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/xf86drm.c b/xf86drm.c
index 5e02969..a7cc643 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -2803,11 +2803,12 @@ static char *drmGetMinorNameForFD(int fd, int type)

while (readdir_r(sysdir, pent, ) == 0 && ent != NULL) {
if (strncmp(ent->d_name, name, len) == 0) {
+   snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
+ent->d_name);
+
free(pent);
closedir(sysdir);

-   snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
-ent->d_name);
return strdup(dev_name);
}
}
-- 
1.9.1



[PATCH 4/4] amdgpu: make vamgr per device v2

2015-08-17 Thread Jammy Zhou
Each device can have its own vamgr, so make it per device now.
This can fix the failure with multiple GPUs used in one single
process.

v2: rebase

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
---
 amdgpu/amdgpu_device.c   | 13 +++--
 amdgpu/amdgpu_internal.h |  5 -
 amdgpu/amdgpu_vamgr.c| 24 +---
 3 files changed, 12 insertions(+), 30 deletions(-)

diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index 0ef1d31..d5f65e5 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -131,7 +131,8 @@ static int amdgpu_get_auth(int fd, int *auth)

 static void amdgpu_device_free_internal(amdgpu_device_handle dev)
 {
-   amdgpu_vamgr_reference(>vamgr, NULL);
+   amdgpu_vamgr_deinit(dev->vamgr);
+   free(dev->vamgr);
util_hash_table_destroy(dev->bo_flink_names);
util_hash_table_destroy(dev->bo_handles);
pthread_mutex_destroy(>bo_table_mutex);
@@ -252,7 +253,13 @@ int amdgpu_device_initialize(int fd,
if (r)
goto cleanup;

-   dev->vamgr = amdgpu_vamgr_get_global(dev);
+   dev->vamgr = calloc(1, sizeof(struct amdgpu_bo_va_mgr));
+   if (dev->vamgr == NULL)
+   goto cleanup;
+
+   amdgpu_vamgr_init(dev->vamgr, dev->dev_info.virtual_address_offset,
+ dev->dev_info.virtual_address_max,
+ dev->dev_info.virtual_address_alignment);

max = MIN2(dev->dev_info.virtual_address_max, 0x);
start = amdgpu_vamgr_find_va(dev->vamgr,
@@ -279,6 +286,8 @@ free_va:
r = -ENOMEM;
amdgpu_vamgr_free_va(dev->vamgr, start,
 max - dev->dev_info.virtual_address_offset);
+   amdgpu_vamgr_deinit(dev->vamgr);
+   free(dev->vamgr);

 cleanup:
if (dev->fd >= 0)
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index ca155be..cb06dbf 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -51,7 +51,6 @@ struct amdgpu_bo_va_hole {
 };

 struct amdgpu_bo_va_mgr {
-   atomic_t refcount;
/* the start virtual address */
uint64_t va_offset;
uint64_t va_max;
@@ -124,10 +123,6 @@ struct amdgpu_context {

 drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo);

-drm_private struct amdgpu_bo_va_mgr* amdgpu_vamgr_get_global(struct 
amdgpu_device *dev);
-
-drm_private void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst, struct 
amdgpu_bo_va_mgr *src);
-
 drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t 
start,
   uint64_t max, uint64_t alignment);

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 698826d..659e6c8 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -33,8 +33,6 @@
 #include "amdgpu_internal.h"
 #include "util_math.h"

-static struct amdgpu_bo_va_mgr vamgr = {{0}};
-
 int amdgpu_va_range_query(amdgpu_device_handle dev,
  enum amdgpu_gpu_va_range type, uint64_t *start, 
uint64_t *end)
 {
@@ -67,26 +65,6 @@ drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr 
*mgr)
pthread_mutex_destroy(>bo_va_mutex);
 }

-drm_private struct amdgpu_bo_va_mgr * amdgpu_vamgr_get_global(struct 
amdgpu_device *dev)
-{
-   int ref;
-   ref = atomic_inc_return();
-
-   if (ref == 1)
-   amdgpu_vamgr_init(, dev->dev_info.virtual_address_offset,
- dev->dev_info.virtual_address_max,
- dev->dev_info.virtual_address_alignment);
-   return 
-}
-
-drm_private void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst,
-   struct amdgpu_bo_va_mgr *src)
-{
-   if (update_references(&(*dst)->refcount, NULL))
-   amdgpu_vamgr_deinit(*dst);
-   *dst = src;
-}
-
 drm_private uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, 
uint64_t size,
uint64_t alignment, uint64_t base_required)
 {
@@ -102,7 +80,7 @@ drm_private uint64_t amdgpu_vamgr_find_va(struct 
amdgpu_bo_va_mgr *mgr, uint64_t
pthread_mutex_lock(>bo_va_mutex);
/* TODO: using more appropriate way to track the holes */
/* first look for a hole */
-   LIST_FOR_EACH_ENTRY_SAFE(hole, n, _holes, list) {
+   LIST_FOR_EACH_ENTRY_SAFE(hole, n, >va_holes, list) {
if (base_required) {
if(hole->offset > base_required ||
(hole->offset + hole->size) < (base_required + 
size))
-- 
1.9.1



[PATCH 3/4] amdgpu: add flag to support 32bit VA address v4

2015-08-17 Thread Jammy Zhou
The AMDGPU_VA_RANGE_32_BIT flag is added to request VA range in the
32bit address space for amdgpu_va_range_alloc.

The 32bit address space is reserved at initialization time, and managed
with a separate VAMGR as part of the global VAMGR. And if no enough VA
space available in range above 4GB, this reserved range can be used as
fallback.

v2: add comment for AMDGPU_VA_RANGE_32_BIT, and add vamgr to va_range
v3: rebase to Emil's drm_private series
v4: fix one warning

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
---
 amdgpu/amdgpu.h  |  5 +
 amdgpu/amdgpu_device.c   | 20 
 amdgpu/amdgpu_internal.h |  9 +
 amdgpu/amdgpu_vamgr.c| 32 +---
 4 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index a90c1ac..1e633e3 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1075,6 +1075,11 @@ int amdgpu_read_mm_registers(amdgpu_device_handle dev, 
unsigned dword_offset,
 uint32_t *values);

 /**
+ * Flag to request VA address range in the 32bit address space
+*/
+#define AMDGPU_VA_RANGE_32_BIT 0x1
+
+/**
  * Allocate virtual address range
  *
  * \param dev - [in] Device handle. See #amdgpu_device_initialize()
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index b977847..0ef1d31 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -44,6 +44,7 @@
 #include "amdgpu_drm.h"
 #include "amdgpu_internal.h"
 #include "util_hash_table.h"
+#include "util_math.h"

 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
 #define UINT_TO_PTR(x) ((void *)((intptr_t)(x)))
@@ -174,6 +175,7 @@ int amdgpu_device_initialize(int fd,
int flag_auth = 0;
int flag_authexist=0;
uint32_t accel_working = 0;
+   uint64_t start, max;

*device_handle = NULL;

@@ -252,6 +254,19 @@ int amdgpu_device_initialize(int fd,

dev->vamgr = amdgpu_vamgr_get_global(dev);

+   max = MIN2(dev->dev_info.virtual_address_max, 0x);
+   start = amdgpu_vamgr_find_va(dev->vamgr,
+max - dev->dev_info.virtual_address_offset,
+dev->dev_info.virtual_address_alignment, 
0);
+   if (start > 0x)
+   goto free_va; /* shouldn't get here */
+
+   dev->vamgr_32 =  calloc(1, sizeof(struct amdgpu_bo_va_mgr));
+   if (dev->vamgr_32 == NULL)
+   goto free_va;
+   amdgpu_vamgr_init(dev->vamgr_32, start, max,
+ dev->dev_info.virtual_address_alignment);
+
*major_version = dev->major_version;
*minor_version = dev->minor_version;
*device_handle = dev;
@@ -260,6 +275,11 @@ int amdgpu_device_initialize(int fd,

return 0;

+free_va:
+   r = -ENOMEM;
+   amdgpu_vamgr_free_va(dev->vamgr, start,
+max - dev->dev_info.virtual_address_offset);
+
 cleanup:
if (dev->fd >= 0)
close(dev->fd);
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index 92eb5ec..ca155be 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -65,6 +65,7 @@ struct amdgpu_va {
uint64_t address;
uint64_t size;
enum amdgpu_gpu_va_range range;
+   struct amdgpu_bo_va_mgr *vamgr;
 };

 struct amdgpu_device {
@@ -82,7 +83,10 @@ struct amdgpu_device {
pthread_mutex_t bo_table_mutex;
struct drm_amdgpu_info_device dev_info;
struct amdgpu_gpu_info info;
+   /** The global VA manager for the whole virtual address space */
struct amdgpu_bo_va_mgr *vamgr;
+   /** The VA manager for the 32bit address space */
+   struct amdgpu_bo_va_mgr *vamgr_32;
 };

 struct amdgpu_bo {
@@ -124,6 +128,11 @@ drm_private struct amdgpu_bo_va_mgr* 
amdgpu_vamgr_get_global(struct amdgpu_devic

 drm_private void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst, struct 
amdgpu_bo_va_mgr *src);

+drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t 
start,
+  uint64_t max, uint64_t alignment);
+
+drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr);
+
 drm_private uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, 
uint64_t size,
uint64_t alignment, uint64_t base_required);

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 71fd2b1..698826d 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -46,7 +46,7 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
return -EINVAL;
 }

-static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t 
start,
  uint64_t max, uint64_t alignment)
 {
mgr->va_offset = start;

[PATCH 2/4] amdgpu: improve amdgpu_vamgr_init

2015-08-17 Thread Jammy Zhou
Make it a generic function independent of the device info.

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
---
 amdgpu/amdgpu_vamgr.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index cc4a1c4..71fd2b1 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -46,11 +46,12 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
return -EINVAL;
 }

-static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, struct 
amdgpu_device *dev)
+static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+ uint64_t max, uint64_t alignment)
 {
-   mgr->va_offset = dev->dev_info.virtual_address_offset;
-   mgr->va_max = dev->dev_info.virtual_address_max;
-   mgr->va_alignment = dev->dev_info.virtual_address_alignment;
+   mgr->va_offset = start;
+   mgr->va_max = max;
+   mgr->va_alignment = alignment;

list_inithead(>va_holes);
pthread_mutex_init(>bo_va_mutex, NULL);
@@ -72,7 +73,9 @@ drm_private struct amdgpu_bo_va_mgr * 
amdgpu_vamgr_get_global(struct amdgpu_devi
ref = atomic_inc_return();

if (ref == 1)
-   amdgpu_vamgr_init(, dev);
+   amdgpu_vamgr_init(, dev->dev_info.virtual_address_offset,
+ dev->dev_info.virtual_address_max,
+ dev->dev_info.virtual_address_alignment);
return 
 }

-- 
1.9.1



[PATCH 1/4] drm: add interface to get drm devices on the system v3

2015-08-17 Thread Jammy Zhou
From: Emil Velikov <emil.l.veli...@gmail.com>

For mutiple GPU support, the devices on the system should be enumerated
to get necessary information about each device, and the drmGetDevices
interface is added for this. Currently only PCI devices are supported for
the enumeration.

Typical usage:
int count;
drmDevicePtr *foo;
count = drmGetDevices(NULL, 0);
foo = calloc(count, sizeof(drmDevicePtr));
count = drmGetDevices(foo, count);
/* find proper device, open correct device node, etc */
drmFreeDevices(foo, count);
free(foo);

v2: change according to feedback from Emil
v3: fix the signed extension for PCI device info

Signed-off-by: Jammy Zhou 
---
 xf86drm.c | 351 ++
 xf86drm.h |  34 ++
 2 files changed, 385 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 5e02969..7d9e5f9 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -55,6 +55,7 @@
 #ifdef HAVE_SYS_MKDEV_H
 # include  /* defines major(), minor(), and makedev() on Solaris 
*/
 #endif
+#include 

 /* Not all systems have MAP_FAILED defined */
 #ifndef MAP_FAILED
@@ -2829,3 +2830,353 @@ char *drmGetRenderDeviceNameFromFd(int fd)
 {
return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
 }
+
+#ifdef __linux__
+static int drmParseSubsystemType(const char *str)
+{
+char link[PATH_MAX + 1] = "";
+char *name;
+
+if (readlink(str, link, PATH_MAX) < 0)
+return -EINVAL;
+
+name = strrchr(link, '/');
+if (!name)
+return -EINVAL;
+
+name++;
+
+if (strncmp(name, "pci", 3) == 0)
+return DRM_BUS_PCI;
+
+return -EINVAL;
+}
+
+static int drmParsePciBusInfo(const char *str, drmPciBusInfoPtr info)
+{
+int domain, bus, dev, func;
+char *value;
+
+if (str == NULL)
+return -EINVAL;
+
+value = strstr(str, "PCI_SLOT_NAME=");
+if (value == NULL)
+return -EINVAL;
+
+value += strlen("PCI_SLOT_NAME=");
+
+if (sscanf(value, "%04x:%02x:%02x.%1u",
+   , , , ) != 4)
+return -EINVAL;
+
+info->domain = domain;
+info->bus = bus;
+info->dev = dev;
+info->func = func;
+
+return 0;
+}
+
+static int drmSameDevice(drmDevicePtr a, drmDevicePtr b)
+{
+if (a->bustype != b->bustype)
+return 0;
+
+switch (a->bustype) {
+case DRM_BUS_PCI:
+if (memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo)) == 0)
+return 1;
+default:
+break;
+}
+
+return 0;
+}
+
+static int drmGetNodeType(const char *name)
+{
+if (strncmp(name, DRM_PRIMARY_MINOR_NAME,
+sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0)
+return DRM_NODE_PRIMARY;
+
+if (strncmp(name, DRM_CONTROL_MINOR_NAME,
+sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0)
+return DRM_NODE_CONTROL;
+
+if (strncmp(name, DRM_RENDER_MINOR_NAME,
+sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0)
+return DRM_NODE_RENDER;
+
+return -EINVAL;
+}
+
+static int drmParsePciDeviceInfo(const unsigned char *config,
+ drmPciDeviceInfoPtr device)
+{
+if (config == NULL)
+return -EINVAL;
+
+device->vendor_id = config[0] | (config[1] << 8);
+device->device_id = config[2] | (config[3] << 8);
+device->revision_id = config[8];
+device->subvendor_id = config[44] | (config[45] << 8);
+device->subdevice_id = config[46] | (config[47] << 8);
+
+return 0;
+}
+
+static void drmFreeDevice(drmDevicePtr device)
+{
+int i;
+
+if (device == NULL)
+return;
+
+if (device->nodes != NULL)
+for (i = 0; i < DRM_NODE_MAX; i++)
+free(device->nodes[i]);
+
+free(device->nodes);
+free(device->businfo.pci);
+free(device->deviceinfo.pci);
+}
+
+void drmFreeDevices(drmDevicePtr devices[], int count)
+{
+int i;
+
+if (devices == NULL)
+return;
+
+for (i = 0; i < count; i++) {
+drmFreeDevice(devices[i]);
+free(devices[i]);
+devices[i] = NULL;
+}
+}
+
+/**
+ * Get drm devices on the system
+ *
+ * \param devices the array of devices with drmDevicePtr elements
+ *can be NULL to get the device number first
+ * \param max_devices the maximum number of devices for the array
+ *
+ * \return on error - negative error code,
+ * if devices is NULL - total number of devices available on the 
system,
+ * alternatively the number of devices stored in devices[], which is
+ * capped by the max_devices.
+ */
+int drmGetDevices(drmDevicePtr devices[], int max_devices)
+{
+drmDevicePtr devs = NULL;
+drmPciBusInfoPtr pcibus = NULL;
+drmPciDeviceInfoPtr pcidevice = NULL;
+DIR *sysdir = NULL;
+struct dirent *dent = NULL;
+struct stat sbuf = {0};
+char node[PATH_MAX + 1] = "";
+char path[PATH_MAX + 1] = "";
+char da

[PATCH 5/5] amdgpu: make vamgr per device v2

2015-08-13 Thread Jammy Zhou
Each device can have its own vamgr, so make it per device now.
This can fix the failure with multiple GPUs used in one single
process.

v2: rebase

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
---
 amdgpu/amdgpu_device.c   | 13 +++--
 amdgpu/amdgpu_internal.h |  5 -
 amdgpu/amdgpu_vamgr.c| 24 +---
 3 files changed, 12 insertions(+), 30 deletions(-)

diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index 0ef1d31..d5f65e5 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -131,7 +131,8 @@ static int amdgpu_get_auth(int fd, int *auth)

 static void amdgpu_device_free_internal(amdgpu_device_handle dev)
 {
-   amdgpu_vamgr_reference(>vamgr, NULL);
+   amdgpu_vamgr_deinit(dev->vamgr);
+   free(dev->vamgr);
util_hash_table_destroy(dev->bo_flink_names);
util_hash_table_destroy(dev->bo_handles);
pthread_mutex_destroy(>bo_table_mutex);
@@ -252,7 +253,13 @@ int amdgpu_device_initialize(int fd,
if (r)
goto cleanup;

-   dev->vamgr = amdgpu_vamgr_get_global(dev);
+   dev->vamgr = calloc(1, sizeof(struct amdgpu_bo_va_mgr));
+   if (dev->vamgr == NULL)
+   goto cleanup;
+
+   amdgpu_vamgr_init(dev->vamgr, dev->dev_info.virtual_address_offset,
+ dev->dev_info.virtual_address_max,
+ dev->dev_info.virtual_address_alignment);

max = MIN2(dev->dev_info.virtual_address_max, 0x);
start = amdgpu_vamgr_find_va(dev->vamgr,
@@ -279,6 +286,8 @@ free_va:
r = -ENOMEM;
amdgpu_vamgr_free_va(dev->vamgr, start,
 max - dev->dev_info.virtual_address_offset);
+   amdgpu_vamgr_deinit(dev->vamgr);
+   free(dev->vamgr);

 cleanup:
if (dev->fd >= 0)
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index ca155be..cb06dbf 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -51,7 +51,6 @@ struct amdgpu_bo_va_hole {
 };

 struct amdgpu_bo_va_mgr {
-   atomic_t refcount;
/* the start virtual address */
uint64_t va_offset;
uint64_t va_max;
@@ -124,10 +123,6 @@ struct amdgpu_context {

 drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo);

-drm_private struct amdgpu_bo_va_mgr* amdgpu_vamgr_get_global(struct 
amdgpu_device *dev);
-
-drm_private void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst, struct 
amdgpu_bo_va_mgr *src);
-
 drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t 
start,
   uint64_t max, uint64_t alignment);

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 698826d..659e6c8 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -33,8 +33,6 @@
 #include "amdgpu_internal.h"
 #include "util_math.h"

-static struct amdgpu_bo_va_mgr vamgr = {{0}};
-
 int amdgpu_va_range_query(amdgpu_device_handle dev,
  enum amdgpu_gpu_va_range type, uint64_t *start, 
uint64_t *end)
 {
@@ -67,26 +65,6 @@ drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr 
*mgr)
pthread_mutex_destroy(>bo_va_mutex);
 }

-drm_private struct amdgpu_bo_va_mgr * amdgpu_vamgr_get_global(struct 
amdgpu_device *dev)
-{
-   int ref;
-   ref = atomic_inc_return();
-
-   if (ref == 1)
-   amdgpu_vamgr_init(, dev->dev_info.virtual_address_offset,
- dev->dev_info.virtual_address_max,
- dev->dev_info.virtual_address_alignment);
-   return 
-}
-
-drm_private void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst,
-   struct amdgpu_bo_va_mgr *src)
-{
-   if (update_references(&(*dst)->refcount, NULL))
-   amdgpu_vamgr_deinit(*dst);
-   *dst = src;
-}
-
 drm_private uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, 
uint64_t size,
uint64_t alignment, uint64_t base_required)
 {
@@ -102,7 +80,7 @@ drm_private uint64_t amdgpu_vamgr_find_va(struct 
amdgpu_bo_va_mgr *mgr, uint64_t
pthread_mutex_lock(>bo_va_mutex);
/* TODO: using more appropriate way to track the holes */
/* first look for a hole */
-   LIST_FOR_EACH_ENTRY_SAFE(hole, n, _holes, list) {
+   LIST_FOR_EACH_ENTRY_SAFE(hole, n, >va_holes, list) {
if (base_required) {
if(hole->offset > base_required ||
(hole->offset + hole->size) < (base_required + 
size))
-- 
1.9.1



[PATCH 4/5] amdgpu: fix one warning from previous commit

2015-08-13 Thread Jammy Zhou
The local variable 'vamgr' is unused in amdgpu_va_range_free.

Signed-off-by: Jammy Zhou 
Reviewed-by: Alex Deucher 
---
 amdgpu/amdgpu_vamgr.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 91aad4e..698826d 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -295,8 +295,6 @@ int amdgpu_va_range_alloc(amdgpu_device_handle dev,

 int amdgpu_va_range_free(amdgpu_va_handle va_range_handle)
 {
-   struct amdgpu_bo_va_mgr *vamgr;
-
if(!va_range_handle || !va_range_handle->address)
return 0;

-- 
1.9.1



[PATCH 3/5] amdgpu: add flag to support 32bit VA address v3

2015-08-13 Thread Jammy Zhou
The AMDGPU_VA_RANGE_32_BIT flag is added to request VA range in the
32bit address space for amdgpu_va_range_alloc.

The 32bit address space is reserved at initialization time, and managed
with a separate VAMGR as part of the global VAMGR. And if no enough VA
space available in range above 4GB, this reserved range can be used as
fallback.

v2: add comment for AMDGPU_VA_RANGE_32_BIT, and add vamgr to va_range
v3: rebase to Emil's drm_private series

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
---
 amdgpu/amdgpu.h  |  5 +
 amdgpu/amdgpu_device.c   | 20 
 amdgpu/amdgpu_internal.h |  9 +
 amdgpu/amdgpu_vamgr.c| 34 +++---
 4 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index a90c1ac..1e633e3 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1075,6 +1075,11 @@ int amdgpu_read_mm_registers(amdgpu_device_handle dev, 
unsigned dword_offset,
 uint32_t *values);

 /**
+ * Flag to request VA address range in the 32bit address space
+*/
+#define AMDGPU_VA_RANGE_32_BIT 0x1
+
+/**
  * Allocate virtual address range
  *
  * \param dev - [in] Device handle. See #amdgpu_device_initialize()
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index b977847..0ef1d31 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -44,6 +44,7 @@
 #include "amdgpu_drm.h"
 #include "amdgpu_internal.h"
 #include "util_hash_table.h"
+#include "util_math.h"

 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
 #define UINT_TO_PTR(x) ((void *)((intptr_t)(x)))
@@ -174,6 +175,7 @@ int amdgpu_device_initialize(int fd,
int flag_auth = 0;
int flag_authexist=0;
uint32_t accel_working = 0;
+   uint64_t start, max;

*device_handle = NULL;

@@ -252,6 +254,19 @@ int amdgpu_device_initialize(int fd,

dev->vamgr = amdgpu_vamgr_get_global(dev);

+   max = MIN2(dev->dev_info.virtual_address_max, 0x);
+   start = amdgpu_vamgr_find_va(dev->vamgr,
+max - dev->dev_info.virtual_address_offset,
+dev->dev_info.virtual_address_alignment, 
0);
+   if (start > 0x)
+   goto free_va; /* shouldn't get here */
+
+   dev->vamgr_32 =  calloc(1, sizeof(struct amdgpu_bo_va_mgr));
+   if (dev->vamgr_32 == NULL)
+   goto free_va;
+   amdgpu_vamgr_init(dev->vamgr_32, start, max,
+ dev->dev_info.virtual_address_alignment);
+
*major_version = dev->major_version;
*minor_version = dev->minor_version;
*device_handle = dev;
@@ -260,6 +275,11 @@ int amdgpu_device_initialize(int fd,

return 0;

+free_va:
+   r = -ENOMEM;
+   amdgpu_vamgr_free_va(dev->vamgr, start,
+max - dev->dev_info.virtual_address_offset);
+
 cleanup:
if (dev->fd >= 0)
close(dev->fd);
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index 92eb5ec..ca155be 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -65,6 +65,7 @@ struct amdgpu_va {
uint64_t address;
uint64_t size;
enum amdgpu_gpu_va_range range;
+   struct amdgpu_bo_va_mgr *vamgr;
 };

 struct amdgpu_device {
@@ -82,7 +83,10 @@ struct amdgpu_device {
pthread_mutex_t bo_table_mutex;
struct drm_amdgpu_info_device dev_info;
struct amdgpu_gpu_info info;
+   /** The global VA manager for the whole virtual address space */
struct amdgpu_bo_va_mgr *vamgr;
+   /** The VA manager for the 32bit address space */
+   struct amdgpu_bo_va_mgr *vamgr_32;
 };

 struct amdgpu_bo {
@@ -124,6 +128,11 @@ drm_private struct amdgpu_bo_va_mgr* 
amdgpu_vamgr_get_global(struct amdgpu_devic

 drm_private void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst, struct 
amdgpu_bo_va_mgr *src);

+drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t 
start,
+  uint64_t max, uint64_t alignment);
+
+drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr);
+
 drm_private uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, 
uint64_t size,
uint64_t alignment, uint64_t base_required);

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 71fd2b1..91aad4e 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -46,7 +46,7 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
return -EINVAL;
 }

-static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t 
start,
  uint64_t max, uint64_t alignment)
 {
mgr->va_offset = start;
@@ -57,7 +57,7 @@ static vo

[PATCH 2/5] amdgpu: improve amdgpu_vamgr_init

2015-08-13 Thread Jammy Zhou
Make it a generic function independent of the device info.

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
---
 amdgpu/amdgpu_vamgr.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index cc4a1c4..71fd2b1 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -46,11 +46,12 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
return -EINVAL;
 }

-static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, struct 
amdgpu_device *dev)
+static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+ uint64_t max, uint64_t alignment)
 {
-   mgr->va_offset = dev->dev_info.virtual_address_offset;
-   mgr->va_max = dev->dev_info.virtual_address_max;
-   mgr->va_alignment = dev->dev_info.virtual_address_alignment;
+   mgr->va_offset = start;
+   mgr->va_max = max;
+   mgr->va_alignment = alignment;

list_inithead(>va_holes);
pthread_mutex_init(>bo_va_mutex, NULL);
@@ -72,7 +73,9 @@ drm_private struct amdgpu_bo_va_mgr * 
amdgpu_vamgr_get_global(struct amdgpu_devi
ref = atomic_inc_return();

if (ref == 1)
-   amdgpu_vamgr_init(, dev);
+   amdgpu_vamgr_init(, dev->dev_info.virtual_address_offset,
+ dev->dev_info.virtual_address_max,
+ dev->dev_info.virtual_address_alignment);
return 
 }

-- 
1.9.1



[PATCH 1/5] drm: add interface to get drm devices on the system v2

2015-08-13 Thread Jammy Zhou
From: Emil Velikov <emil.l.veli...@gmail.com>

For mutiple GPU support, the devices on the system should be enumerated
to get necessary information about each device, and the drmGetDevices
interface is added for this. Currently only PCI devices are supported for
the enumeration.

Typical usage:
int count;
drmDevicePtr *foo;
count = drmGetDevices(NULL, 0);
foo = calloc(count, sizeof(drmDevicePtr));
count = drmGetDevices(foo, count);
/* find proper device, open correct device node, etc */
drmFreeDevices(foo, count);
free(foo);

v2: change according to feedback from Emil

Signed-off-by: Jammy Zhou 
---
 xf86drm.c | 351 ++
 xf86drm.h |  34 ++
 2 files changed, 385 insertions(+)

diff --git a/xf86drm.c b/xf86drm.c
index 5e02969..237663b 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -55,6 +55,7 @@
 #ifdef HAVE_SYS_MKDEV_H
 # include  /* defines major(), minor(), and makedev() on Solaris 
*/
 #endif
+#include 

 /* Not all systems have MAP_FAILED defined */
 #ifndef MAP_FAILED
@@ -2829,3 +2830,353 @@ char *drmGetRenderDeviceNameFromFd(int fd)
 {
return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
 }
+
+#ifdef __linux__
+static int drmParseSubsystemType(const char *str)
+{
+char link[PATH_MAX + 1] = "";
+char *name;
+
+if (readlink(str, link, PATH_MAX) < 0)
+return -EINVAL;
+
+name = strrchr(link, '/');
+if (!name)
+return -EINVAL;
+
+name++;
+
+if (strncmp(name, "pci", 3) == 0)
+return DRM_BUS_PCI;
+
+return -EINVAL;
+}
+
+static int drmParsePciBusInfo(const char *str, drmPciBusInfoPtr info)
+{
+int domain, bus, dev, func;
+char *value;
+
+if (str == NULL)
+return -EINVAL;
+
+value = strstr(str, "PCI_SLOT_NAME=");
+if (value == NULL)
+return -EINVAL;
+
+value += strlen("PCI_SLOT_NAME=");
+
+if (sscanf(value, "%04x:%02x:%02x.%1u",
+   , , , ) != 4)
+return -EINVAL;
+
+info->domain = domain;
+info->bus = bus;
+info->dev = dev;
+info->func = func;
+
+return 0;
+}
+
+static int drmSameDevice(drmDevicePtr a, drmDevicePtr b)
+{
+if (a->bustype != b->bustype)
+return 0;
+
+switch (a->bustype) {
+case DRM_BUS_PCI:
+if (memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo)) == 0)
+return 1;
+default:
+break;
+}
+
+return 0;
+}
+
+static int drmGetNodeType(const char *name)
+{
+if (strncmp(name, DRM_PRIMARY_MINOR_NAME,
+sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0)
+return DRM_NODE_PRIMARY;
+
+if (strncmp(name, DRM_CONTROL_MINOR_NAME,
+sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0)
+return DRM_NODE_CONTROL;
+
+if (strncmp(name, DRM_RENDER_MINOR_NAME,
+sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0)
+return DRM_NODE_RENDER;
+
+return -EINVAL;
+}
+
+static int drmParsePciDeviceInfo(const char *config,
+ drmPciDeviceInfoPtr device)
+{
+if (config == NULL)
+return -EINVAL;
+
+device->vendor_id = config[0] | (config[1] << 8);
+device->device_id = config[2] | (config[3] << 8);
+device->revision_id = config[8];
+device->subvendor_id = config[44] | (config[45] << 8);
+device->subdevice_id = config[46] | (config[47] << 8);
+
+return 0;
+}
+
+static void drmFreeDevice(drmDevicePtr device)
+{
+int i;
+
+if (device == NULL)
+return;
+
+if (device->nodes != NULL)
+for (i = 0; i < DRM_NODE_MAX; i++)
+free(device->nodes[i]);
+
+free(device->nodes);
+free(device->businfo.pci);
+free(device->deviceinfo.pci);
+}
+
+void drmFreeDevices(drmDevicePtr devices[], int count)
+{
+int i;
+
+if (devices == NULL)
+return;
+
+for (i = 0; i < count; i++) {
+drmFreeDevice(devices[i]);
+free(devices[i]);
+devices[i] = NULL;
+}
+}
+
+/**
+ * Get drm devices on the system
+ *
+ * \param devices the array of devices with drmDevicePtr elements
+ *can be NULL to get the device number first
+ * \param max_devices the maximum number of devices for the array
+ *
+ * \return on error - negative error code,
+ * if devices is NULL - total number of devices available on the 
system,
+ * alternatively the number of devices stored in devices[], which is
+ * capped by the max_devices.
+ */
+int drmGetDevices(drmDevicePtr devices[], int max_devices)
+{
+drmDevicePtr devs = NULL;
+drmPciBusInfoPtr pcibus = NULL;
+drmPciDeviceInfoPtr pcidevice = NULL;
+DIR *sysdir = NULL;
+struct dirent *dent = NULL;
+struct stat sbuf = {0};
+char node[PATH_MAX + 1] = "";
+char path[PATH_MAX + 1] = "";
+char data[128] = "";
+char config[64] = &q

[PATCH 0/5] some drm and amdgpu patches

2015-08-13 Thread Jammy Zhou
This series is a set of patches in my side pending for merge. And I rebased it
with the drm_private series from Emil.

Emil Velikov (1):
  drm: add interface to get drm devices on the system v2

Jammy Zhou (4):
  amdgpu: improve amdgpu_vamgr_init
  amdgpu: add flag to support 32bit VA address v3
  amdgpu: fix one warning from previous commit
  amdgpu: make vamgr per device v2

 amdgpu/amdgpu.h  |   5 +
 amdgpu/amdgpu_device.c   |  33 -
 amdgpu/amdgpu_internal.h |  10 +-
 amdgpu/amdgpu_vamgr.c|  61 
 xf86drm.c| 351 +++
 xf86drm.h|  34 +
 6 files changed, 458 insertions(+), 36 deletions(-)

-- 
1.9.1



[PATCH 2/2] amdgpu: add flag to support 32bit VA address v2

2015-08-10 Thread Jammy Zhou
The AMDGPU_VA_RANGE_32_BIT flag is added to request VA range in the
32bit address space for amdgpu_va_range_alloc.

The 32bit address space is reserved at initialization time, and managed
with a separate VAMGR as part of the global VAMGR. And if no enough VA
space available in range above 4GB, this reserved range can be used as
fallback.

v2: add comment for AMDGPU_VA_RANGE_32_BIT, and add vamgr to va_range

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
---
 amdgpu/amdgpu.h  |  5 +
 amdgpu/amdgpu_device.c   | 22 ++
 amdgpu/amdgpu_internal.h |  9 +
 amdgpu/amdgpu_vamgr.c| 35 ---
 4 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index a90c1ac..1e633e3 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1075,6 +1075,11 @@ int amdgpu_read_mm_registers(amdgpu_device_handle dev, 
unsigned dword_offset,
 uint32_t *values);

 /**
+ * Flag to request VA address range in the 32bit address space
+*/
+#define AMDGPU_VA_RANGE_32_BIT 0x1
+
+/**
  * Allocate virtual address range
  *
  * \param dev - [in] Device handle. See #amdgpu_device_initialize()
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index ba75db0..067ef64 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -40,6 +40,7 @@
 #include "amdgpu_drm.h"
 #include "amdgpu_internal.h"
 #include "util_hash_table.h"
+#include "util_math.h"

 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
 #define UINT_TO_PTR(x) ((void *)((intptr_t)(x)))
@@ -126,6 +127,7 @@ int amdgpu_device_initialize(int fd,
int flag_auth = 0;
int flag_authexist=0;
uint32_t accel_working = 0;
+   uint64_t start, max;

*device_handle = NULL;

@@ -204,6 +206,19 @@ int amdgpu_device_initialize(int fd,

dev->vamgr = amdgpu_vamgr_get_global(dev);

+   max = MIN2(dev->dev_info.virtual_address_max, 0x);
+   start = amdgpu_vamgr_find_va(dev->vamgr,
+max - dev->dev_info.virtual_address_offset,
+dev->dev_info.virtual_address_alignment, 
0);
+   if (start > 0x)
+   goto free_va; /* shouldn't get here */
+
+   dev->vamgr_32 =  calloc(1, sizeof(struct amdgpu_bo_va_mgr));
+   if (dev->vamgr_32 == NULL)
+   goto free_va;
+   amdgpu_vamgr_init(dev->vamgr_32, start, max,
+ dev->dev_info.virtual_address_alignment);
+
*major_version = dev->major_version;
*minor_version = dev->minor_version;
*device_handle = dev;
@@ -212,6 +227,11 @@ int amdgpu_device_initialize(int fd,

return 0;

+free_va:
+   r = -ENOMEM;
+   amdgpu_vamgr_free_va(dev->vamgr, start,
+max - dev->dev_info.virtual_address_offset);
+
 cleanup:
if (dev->fd >= 0)
close(dev->fd);
@@ -222,6 +242,8 @@ cleanup:

 void amdgpu_device_free_internal(amdgpu_device_handle dev)
 {
+   amdgpu_vamgr_deinit(dev->vamgr_32);
+   free(dev->vamgr_32);
amdgpu_vamgr_reference(>vamgr, NULL);
util_hash_table_destroy(dev->bo_flink_names);
util_hash_table_destroy(dev->bo_handles);
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index 526a93f..6e65642 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -63,6 +63,7 @@ struct amdgpu_va {
uint64_t address;
uint64_t size;
enum amdgpu_gpu_va_range range;
+   struct amdgpu_bo_va_mgr *vamgr;
 };

 struct amdgpu_device {
@@ -80,7 +81,10 @@ struct amdgpu_device {
pthread_mutex_t bo_table_mutex;
struct drm_amdgpu_info_device dev_info;
struct amdgpu_gpu_info info;
+   /** The global VA manager for the whole virtual address space */
struct amdgpu_bo_va_mgr *vamgr;
+   /** The VA manager for the 32bit address space */
+   struct amdgpu_bo_va_mgr *vamgr_32;
 };

 struct amdgpu_bo {
@@ -124,6 +128,11 @@ struct amdgpu_bo_va_mgr* amdgpu_vamgr_get_global(struct 
amdgpu_device *dev);

 void amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst, struct 
amdgpu_bo_va_mgr *src);

+void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+  uint64_t max, uint64_t alignment);
+
+void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr);
+
 uint64_t amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
uint64_t alignment, uint64_t base_required);

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index e044dfa..04e09e2 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -42,7 +42,7 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
return -EINVAL;
 }

-static void amdgpu_vamgr_init(struct a

[PATCH 1/2] amdgpu: improve amdgpu_vamgr_init

2015-08-10 Thread Jammy Zhou
Make it a generic function independent of the device info.

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
---
 amdgpu/amdgpu_vamgr.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index ced4f4f..e044dfa 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -42,11 +42,12 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
return -EINVAL;
 }

-static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, struct 
amdgpu_device *dev)
+static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+ uint64_t max, uint64_t alignment)
 {
-   mgr->va_offset = dev->dev_info.virtual_address_offset;
-   mgr->va_max = dev->dev_info.virtual_address_max;
-   mgr->va_alignment = dev->dev_info.virtual_address_alignment;
+   mgr->va_offset = start;
+   mgr->va_max = max;
+   mgr->va_alignment = alignment;

list_inithead(>va_holes);
pthread_mutex_init(>bo_va_mutex, NULL);
@@ -68,7 +69,9 @@ struct amdgpu_bo_va_mgr * amdgpu_vamgr_get_global(struct 
amdgpu_device *dev)
ref = atomic_inc_return();

if (ref == 1)
-   amdgpu_vamgr_init(, dev);
+   amdgpu_vamgr_init(, dev->dev_info.virtual_address_offset,
+ dev->dev_info.virtual_address_max,
+ dev->dev_info.virtual_address_alignment);
return 
 }

-- 
1.9.1



[PATCH 01/25] drm: add generic lock-free queue implementation

2015-06-04 Thread Jammy Zhou
Signed-off-by: Jammy Zhou 
Signed-off-by: Shaoyun Liu 
Reviewed-by: Christian K?nig 
---
 drivers/gpu/drm/Makefile|   3 +-
 drivers/gpu/drm/drm_queue.c | 208 
 include/drm/drm_queue.h |  47 ++
 3 files changed, 257 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/drm_queue.c
 create mode 100644 include/drm/drm_queue.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 20f81fd..173d2b6 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -14,7 +14,8 @@ drm-y   :=drm_auth.o drm_bufs.o drm_cache.o \
drm_info.o drm_debugfs.o drm_encoder_slave.o \
drm_trace_points.o drm_global.o drm_prime.o \
drm_rect.o drm_vma_manager.o drm_flip_work.o \
-   drm_modeset_lock.o drm_atomic.o drm_bridge.o
+   drm_modeset_lock.o drm_atomic.o drm_bridge.o \
+   drm_queue.o

 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
diff --git a/drivers/gpu/drm/drm_queue.c b/drivers/gpu/drm/drm_queue.c
new file mode 100644
index 000..00cd649
--- /dev/null
+++ b/drivers/gpu/drm/drm_queue.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * This file implement a generic circular array queue.
+ * It's lock free for single producer and single consumer.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define QUEUE_IDX(_X_)  ((_X_)&(queue->size-1))
+
+/**
+ * drm_queue_create - create the queue
+ *
+ * @size  total number of elements for this queue
+ * @element_size the memory size of each element entry
+ *
+ * return pointer to the drm_queue structure if succeed, NULL if failed
+ */
+struct drm_queue * drm_queue_create(uint32_t size, uint32_t element_size)
+{
+   struct drm_queue *queue;
+
+   /* check whether the size is power of 2*/
+   BUG_ON(size & (size - 1));
+
+   queue = kzalloc(sizeof(struct drm_queue), GFP_KERNEL);
+   if (!queue)
+   return NULL;
+
+   queue->size = size;
+   queue->element_size = element_size;
+   atomic_set(>count, 0);
+   mutex_init(>lock);
+   queue->data = kzalloc(size * element_size, GFP_KERNEL);
+   if (!queue->data) {
+   kfree(queue);
+   return NULL;
+   }
+
+   return queue;
+}
+
+EXPORT_SYMBOL(drm_queue_create);
+
+/**
+ * drm_queue_free - free the queue storage
+ *
+ * @queue pointer to the queue need to be destroied
+ *
+ * return 0 if succeed. -1 if failed.
+ */
+int drm_queue_free(struct drm_queue *queue)
+{
+   BUG_ON(queue == NULL);
+
+   kfree(queue->data);
+   kfree(queue);
+
+   return 0;
+}
+
+EXPORT_SYMBOL(drm_queue_free);
+
+/**
+ * drm_queue_get_count - Get active count of elements in the queue
+ *
+ * @queue pointer to the queue.
+ *
+ * return current occuptied count of the queue.
+ *
+ */
+int drm_queue_get_count(struct drm_queue *queue)
+{
+   BUG_ON(queue == NULL);
+   return atomic_read(>count);
+}
+
+EXPORT_SYMBOL(drm_queue_get_count);
+
+/**
+ * drm_queue_push - push one element into the queue
+ *
+ * @queue pointer to the queue
+ * @data  pointer to the element.
+ *
+ * return 0 if succeed.
+ *-EINVAL if the queue is not valid
+ *-ENOSPC if the queue is full.
+ *
+ * Only one producer is allowed.
+ */
+int drm_queue_push(struct drm_queue *queue, void *data)
+{
+   uint32_t index;
+
+   if (!(queue && queue->data))
+   return -EINVAL;
+
+   if (atomic_read(>count) >= queue->size)
+   return -ENOSPC;
+
+   index = QUEUE_IDX(queue->w_idx++);
+   memcpy(queue->data + index * queue->element_size,
+  data, queue->element_size);
+   barr

[PATCH] Add device enumeration interface (v3)

2015-05-20 Thread Jammy Zhou
From: frank <frank@amd.com>

v3: switch to udev/sysfs for the enumeration

Signed-off-by: Frank Min 
Reviewed-by: Christian König 
Reviewed-by: Alex Deucher 
Reviewed-by: Jammy Zhou 
---
 Makefile.am |   7 +++--
 xf86drm.c   | 103 
 xf86drm.h   |  19 +++
 3 files changed, 127 insertions(+), 2 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 13df80c..ffd334a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -95,12 +95,15 @@ SUBDIRS = \
 libdrm_la_LTLIBRARIES = libdrm.la
 libdrm_ladir = $(libdir)
 libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined
-libdrm_la_LIBADD = @CLOCK_LIB@
+libdrm_la_LIBADD = \
+   @CLOCK_LIB@ \
+   @LIBUDEV_LIBS@

 libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm
 AM_CFLAGS = \
$(WARN_CFLAGS) \
-   $(VALGRIND_CFLAGS)
+   $(VALGRIND_CFLAGS) \
+   $(LIBUDEV_CFLAGS)

 libdrm_la_SOURCES = $(LIBDRM_FILES)

diff --git a/xf86drm.c b/xf86drm.c
index f7c45f8..d2704de 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -63,6 +63,7 @@

 #include "xf86drm.h"
 #include "libdrm_macros.h"
+#include "libudev.h"

 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || 
defined(__DragonFly__)
 #define DRM_MAJOR 145
@@ -2817,3 +2818,105 @@ char *drmGetRenderDeviceNameFromFd(int fd)
 {
return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
 }
+
+/**
+* Enumerate the GPU devices on the system
+*
+* \param devs device array set to return the device information
+* (if NULL, the number of device is returned)
+* \param vendor the vendor ID for GPU devices to list
+* (optional, if not specified, all GPU devices are returned)
+*
+* \return the number of GPU devices
+*/
+int drmGetPciDevices(drmPciDevicePtr devSet, uint16_t vendorId)
+{
+   struct udev *udev = NULL;
+   struct udev_enumerate *udev_enumerate;
+   struct udev_list_entry *list_entry;
+   struct udev_device *device;
+   int drmDevCount = 0;
+   int vendor = 0;
+   int devid = 0;
+   int devclass = 0;
+   int subvendor = 0;
+   int subdevid = 0;
+   int revid = 0xff;
+   int domain = 0;
+   int bus = 0;
+   int dev = 0;
+   int func = 0;
+   char config[64] = {0};
+   char node[128] = {'\0'};
+   char slot[] = ":00:00.0";
+   char *info = NULL;
+   int minor = 0xff;
+   int fd = 0;
+   int ret = 0;
+
+   udev = udev_new();
+   if (udev == NULL) {
+   fprintf(stderr, "no context\n");
+   return -EINVAL;
+   }
+   udev_enumerate = udev_enumerate_new(udev);
+   if (udev_enumerate == NULL)
+   return -EINVAL;
+   udev_enumerate_add_match_subsystem(udev_enumerate, "drm");
+   udev_enumerate_add_match_property(udev_enumerate, "DEVTYPE", 
"drm_minor");
+
+   udev_enumerate_scan_devices(udev_enumerate);
+
+   udev_list_entry_foreach(list_entry, 
udev_enumerate_get_list_entry(udev_enumerate)) {
+   device = 
udev_device_new_from_syspath(udev_enumerate_get_udev(udev_enumerate),
+ 
udev_list_entry_get_name(list_entry));
+   if (device != NULL) {
+   info = udev_device_get_property_value(device, "MINOR");
+   if (!strcmp(info, "0")) {
+   strcpy(node, udev_device_get_syspath(device));
+   info = strstr(node, "/drm");
+   strncpy(slot, info - strlen(slot), strlen(slot));
+   if (sscanf(slot, "%4x:%2x:%2x.%1x", , , 
, ) != 4) {
+   domain = 0;
+   bus = 0;
+   dev = 0;
+   func = 0;
+   }
+   strcpy(node + strlen(node), "/device/config");
+
+   fd = open(node, O_RDONLY);
+   if (fd >= 0) {
+   ret = read(fd, config, 64);
+   if (ret == 64) {
+   vendor = config[0] + (config[1] << 8);
+   devid = config[2] + (config[3] << 8);
+   revid = config[8];
+   devclass = config[9] + (config[10] << 
8) + (config[11] << 16);
+   subdevid = config[44] + (config[45] << 
8);
+   }
+   close(fd);
+   }
+
+   if((vendorId == 0) || (vendorId == vendor)) {
+   if(devSet != NULL) {
+   devSet[drmDevCount].domain = domain;
+

[PATCH 2/2] Fix one warning (v2)

2015-04-27 Thread Jammy Zhou
xf86drm.c:356:2: warning: comparison of unsigned expression >= 0 is always true 
[-Wtype-limits]
  group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
  ^

v2: do 'int' cast to fix the warning

Signed-off-by: Jammy Zhou 
---
 xf86drm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xf86drm.c b/xf86drm.c
index 4d67861..4ecb24f 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -353,7 +353,7 @@ static int drmOpenDevice(dev_t dev, int minor, int type)
 }

 if (drm_server_info) {
-   group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
+   group = ((int)serv_group >= 0) ? serv_group : DRM_DEV_GID;
chown_check_return(buf, user, group);
chmod(buf, devmode);
 }
-- 
1.9.1



[PATCH 1/2] Add device enumeration interface (v2)

2015-04-24 Thread Jammy Zhou
drmGetDevices interface is added to enumernate GPU devices on the system

v2: rebase the code and some improvement for the coding style

Signed-off-by: Frank Min 
Signed-off-by: Jammy Zhou  (v2)
---
 Makefile.am |  3 ++-
 xf86drm.c   | 48 
 xf86drm.h   | 18 ++
 3 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index 42d3d7f..8236ed8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -89,7 +89,8 @@ SUBDIRS = \
 libdrm_la_LTLIBRARIES = libdrm.la
 libdrm_ladir = $(libdir)
 libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined
-libdrm_la_LIBADD = @CLOCK_LIB@
+libdrm_la_LIBADD = @CLOCK_LIB@ \
+   @PCIACCESS_LIBS@

 libdrm_la_CPPFLAGS = -I$(top_srcdir)/include/drm
 AM_CFLAGS = \
diff --git a/xf86drm.c b/xf86drm.c
index ffc53b8..4d67861 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -63,6 +63,7 @@

 #include "xf86drm.h"
 #include "libdrm.h"
+#include 

 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || 
defined(__DragonFly__)
 #define DRM_MAJOR 145
@@ -2817,3 +2818,50 @@ char *drmGetRenderDeviceNameFromFd(int fd)
 {
return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
 }
+
+/**
+ * Enumerate the GPU devices on the system
+ *
+ * \param devs device array set to return the device information
+ * (if NULL, the number of device is returned)
+ * \param vendor the vendor ID for GPU devices to list
+ * (optional, if not specified, all GPU devices are returned)
+ *
+ * \return the number of GPU devices
+ */
+int drmGetDevices(drmDevicePtr devs, uint16_t vendor)
+{
+   struct pci_device_iterator * iter;
+   struct pci_device * dev;
+   uint32_t count = 0;
+
+   if (pci_system_init())
+   return -EINVAL;
+
+   iter = pci_slot_match_iterator_create(NULL);
+   if (!iter)
+   return -EINVAL;
+
+   while ((dev = pci_device_next(iter))) {
+   if (((dev->device_class == 0x3) ||
+   (dev->device_class == 0x38000)) &&
+   ((vendor == 0) || (dev->vendor_id == vendor))){
+   if (devs) {
+   devs[count].domain = dev->domain;
+   devs[count].bus = dev->bus;
+   devs[count].dev = dev->dev;
+   devs[count].func = dev->func;
+   devs[count].vendor_id = dev->vendor_id;
+   devs[count].device_id = dev->device_id;
+   devs[count].subvendor_id = dev->subvendor_id;
+   devs[count].subdevice_id = dev->subdevice_id;
+   devs[count].revision_id = dev->revision;
+   }
+   count++;
+   }
+   }
+
+   pci_iterator_destroy(iter);
+   pci_system_cleanup();
+   return count;
+}
diff --git a/xf86drm.h b/xf86drm.h
index 40c55c9..6150e71 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -752,6 +752,24 @@ extern int drmPrimeFDToHandle(int fd, int prime_fd, 
uint32_t *handle);
 extern char *drmGetPrimaryDeviceNameFromFd(int fd);
 extern char *drmGetRenderDeviceNameFromFd(int fd);

+/**
+ * Structure for a general pcie gpu device
+ */
+typedef struct _drmDevice {
+   uint16_t domain;
+   uint8_t bus;
+   uint8_t dev;
+   uint8_t func;
+   uint8_t revision_id;
+   uint16_t vendor_id;
+   uint16_t device_id;
+   uint16_t subvendor_id;
+   uint16_t subdevice_id;
+} drmDevice, *drmDevicePtr;
+
+
+extern int drmGetDevices(drmDevicePtr devs, uint16_t vendor);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
-- 
1.9.1



[PATCH 1/2] Add new drmOpenWithType function (v4)

2015-02-11 Thread Jammy Zhou
v2: Add drmGetMinorBase, and call drmOpenWithType in drmOpen
v3: Pass 'type' to drmOpenByBusid and drmOpenDevice in drmOpenByName
v4: Renumber node type definitions, and return -1 for unsupported type

Signed-off-by: Jammy Zhou 
Reviewed-by: Alex Deucher  (v3)
---
 xf86drm.c | 70 +--
 xf86drm.h |  9 +++-
 2 files changed, 63 insertions(+), 16 deletions(-)

diff --git a/xf86drm.c b/xf86drm.c
index 345325a..998f010 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -85,10 +85,6 @@

 #define DRM_MSG_VERBOSITY 3

-#define DRM_NODE_CONTROL 0
-#define DRM_NODE_PRIMARY 1
-#define DRM_NODE_RENDER 2
-
 static drmServerInfoPtr drm_server_info;

 void drmSetServerInfo(drmServerInfoPtr info)
@@ -493,11 +489,25 @@ int drmAvailable(void)
 return retval;
 }

+static int drmGetMinorBase(int type)
+{
+switch (type) {
+case DRM_NODE_PRIMARY:
+return 0;
+case DRM_NODE_CONTROL:
+return 64;
+case DRM_NODE_RENDER:
+return 128;
+default:
+return -1;
+};
+}

 /**
  * Open the device by bus ID.
  *
  * \param busid bus ID.
+ * \param type device node type.
  *
  * \return a file descriptor on success, or a negative value on error.
  *
@@ -507,16 +517,20 @@ int drmAvailable(void)
  *
  * \sa drmOpenMinor() and drmGetBusid().
  */
-static int drmOpenByBusid(const char *busid)
+static int drmOpenByBusid(const char *busid, int type)
 {
 inti, pci_domain_ok = 1;
 intfd;
 const char *buf;
 drmSetVersion sv;
+intbase = drmGetMinorBase(type);
+
+if (base < 0)
+return -1;

 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
-for (i = 0; i < DRM_MAX_MINOR; i++) {
-   fd = drmOpenMinor(i, 1, DRM_NODE_PRIMARY);
+for (i = base; i < base + DRM_MAX_MINOR; i++) {
+   fd = drmOpenMinor(i, 1, type);
drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
if (fd >= 0) {
/* We need to try for 1.4 first for proper PCI domain support
@@ -556,6 +570,7 @@ static int drmOpenByBusid(const char *busid)
  * Open the device by name.
  *
  * \param name driver name.
+ * \param type the device node type.
  * 
  * \return a file descriptor on success, or a negative value on error.
  * 
@@ -566,19 +581,23 @@ static int drmOpenByBusid(const char *busid)
  * 
  * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
  */
-static int drmOpenByName(const char *name)
+static int drmOpenByName(const char *name, int type)
 {
 int   i;
 int   fd;
 drmVersionPtr version;
 char *id;
+int   base = drmGetMinorBase(type);
+
+if (base < 0)
+return -1;

 /*
  * Open the first minor number that matches the driver name and isn't
  * already in use.  If it's in use it will have a busid assigned already.
  */
-for (i = 0; i < DRM_MAX_MINOR; i++) {
-   if ((fd = drmOpenMinor(i, 1, DRM_NODE_PRIMARY)) >= 0) {
+for (i = base; i < base + DRM_MAX_MINOR; i++) {
+   if ((fd = drmOpenMinor(i, 1, type)) >= 0) {
if ((version = drmGetVersion(fd))) {
if (!strcmp(version->name, name)) {
drmFreeVersion(version);
@@ -620,9 +639,9 @@ static int drmOpenByName(const char *name)
for (devstring = ++pt; *pt && *pt != ' '; ++pt)
;
if (*pt) { /* Found busid */
-   return drmOpenByBusid(++pt);
+   return drmOpenByBusid(++pt, type);
} else { /* No busid */
-   return drmOpenDevice(strtol(devstring, NULL, 0),i, 
DRM_NODE_PRIMARY);
+   return drmOpenDevice(strtol(devstring, NULL, 0),i, 
type);
}
}
}
@@ -652,8 +671,29 @@ static int drmOpenByName(const char *name)
  */
 int drmOpen(const char *name, const char *busid)
 {
+return drmOpenWithType(name, busid, DRM_NODE_PRIMARY);
+}
+
+/**
+ * Open the DRM device with specified type.
+ *
+ * Looks up the specified name and bus ID, and opens the device found.  The
+ * entry in /dev/dri is created if necessary and if called by root.
+ *
+ * \param name driver name. Not referenced if bus ID is supplied.
+ * \param busid bus ID. Zero if not known.
+ * \param type the device node type to open, PRIMARY, CONTROL or RENDER
+ *
+ * \return a file descriptor on success, or a negative value on error.
+ *
+ * \internal
+ * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
+ * otherwise.
+ */
+int drmOpenWithType(const char *name, const char *busid, int type)
+{
 if (!drmAvailable() && name != NULL && drm_server_info) {
-   /* try to load the kernel */
+   /* try to load the kernel module */
if (!drm_server_info->load_module(na

[PATCH 2/2] Add new drmOpenOnceWithType function (v2)

2015-02-02 Thread Jammy Zhou
v2: call drmOpenOnceWithType in drmOpenOnce, and drop unused param
for drmOpenOnceWithType

Signed-off-by: Jammy Zhou 
---
 xf86drm.c | 12 ++--
 xf86drm.h |  1 +
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/xf86drm.c b/xf86drm.c
index 810edfa..b5d7686 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -2518,6 +2518,7 @@ static struct {
 char *BusID;
 int fd;
 int refcount;
+int type;
 } connection[DRM_MAX_FDS];

 static int nr_fds = 0;
@@ -2526,23 +2527,30 @@ int drmOpenOnce(void *unused,
const char *BusID,
int *newlyopened)
 {
+return drmOpenOnceWithType(BusID, newlyopened, DRM_NODE_PRIMARY);
+}
+
+int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type)
+{
 int i;
 int fd;

 for (i = 0; i < nr_fds; i++)
-   if (strcmp(BusID, connection[i].BusID) == 0) {
+   if ((strcmp(BusID, connection[i].BusID) == 0) &&
+   (connection[i].type == type)) {
connection[i].refcount++;
*newlyopened = 0;
return connection[i].fd;
}

-fd = drmOpen(unused, BusID);
+fd = drmOpenWithType(NULL, BusID, type);
 if (fd <= 0 || nr_fds == DRM_MAX_FDS)
return fd;

 connection[nr_fds].BusID = strdup(BusID);
 connection[nr_fds].fd = fd;
 connection[nr_fds].refcount = 1;
+connection[nr_fds].type = type;
 *newlyopened = 1;

 if (0)
diff --git a/xf86drm.h b/xf86drm.h
index f145d42..54a56ef 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -712,6 +712,7 @@ extern int  drmSLLookupNeighbors(void *l, unsigned long key,
 unsigned long *next_key, void **next_value);

 extern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened);
+extern int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type);
 extern void drmCloseOnce(int fd);
 extern void drmMsg(const char *format, ...) DRM_PRINTFLIKE(1, 2);

-- 
1.9.1



[PATCH 1/2] Add new drmOpenWithType function (v3)

2015-02-02 Thread Jammy Zhou
v2: Add drmGetMinorBase, and call drmOpenWithType in drmOpen
v3: Pass 'type' to drmOpenByBusid and drmOpenDevice in drmOpenByName

Signed-off-by: Jammy Zhou 
---
 xf86drm.c | 63 ---
 xf86drm.h |  9 -
 2 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/xf86drm.c b/xf86drm.c
index 345325a..810edfa 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -85,10 +85,6 @@

 #define DRM_MSG_VERBOSITY 3

-#define DRM_NODE_CONTROL 0
-#define DRM_NODE_PRIMARY 1
-#define DRM_NODE_RENDER 2
-
 static drmServerInfoPtr drm_server_info;

 void drmSetServerInfo(drmServerInfoPtr info)
@@ -493,11 +489,24 @@ int drmAvailable(void)
 return retval;
 }

+static int drmGetMinorBase(int type)
+{
+switch (type) {
+case DRM_NODE_PRIMARY:
+default:
+return 0;
+case DRM_NODE_CONTROL:
+return 64;
+case DRM_NODE_RENDER:
+return 128;
+};
+}

 /**
  * Open the device by bus ID.
  *
  * \param busid bus ID.
+ * \param type device node type.
  *
  * \return a file descriptor on success, or a negative value on error.
  *
@@ -507,16 +516,17 @@ int drmAvailable(void)
  *
  * \sa drmOpenMinor() and drmGetBusid().
  */
-static int drmOpenByBusid(const char *busid)
+static int drmOpenByBusid(const char *busid, int type)
 {
 inti, pci_domain_ok = 1;
 intfd;
 const char *buf;
 drmSetVersion sv;
+intbase = drmGetMinorBase(type);

 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
-for (i = 0; i < DRM_MAX_MINOR; i++) {
-   fd = drmOpenMinor(i, 1, DRM_NODE_PRIMARY);
+for (i = base; i < base + DRM_MAX_MINOR; i++) {
+   fd = drmOpenMinor(i, 1, type);
drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
if (fd >= 0) {
/* We need to try for 1.4 first for proper PCI domain support
@@ -556,6 +566,7 @@ static int drmOpenByBusid(const char *busid)
  * Open the device by name.
  *
  * \param name driver name.
+ * \param type the device node type.
  * 
  * \return a file descriptor on success, or a negative value on error.
  * 
@@ -566,19 +577,20 @@ static int drmOpenByBusid(const char *busid)
  * 
  * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
  */
-static int drmOpenByName(const char *name)
+static int drmOpenByName(const char *name, int type)
 {
 int   i;
 int   fd;
 drmVersionPtr version;
 char *id;
+int   base = drmGetMinorBase(type);

 /*
  * Open the first minor number that matches the driver name and isn't
  * already in use.  If it's in use it will have a busid assigned already.
  */
-for (i = 0; i < DRM_MAX_MINOR; i++) {
-   if ((fd = drmOpenMinor(i, 1, DRM_NODE_PRIMARY)) >= 0) {
+for (i = base; i < base + DRM_MAX_MINOR; i++) {
+   if ((fd = drmOpenMinor(i, 1, type)) >= 0) {
if ((version = drmGetVersion(fd))) {
if (!strcmp(version->name, name)) {
drmFreeVersion(version);
@@ -620,9 +632,9 @@ static int drmOpenByName(const char *name)
for (devstring = ++pt; *pt && *pt != ' '; ++pt)
;
if (*pt) { /* Found busid */
-   return drmOpenByBusid(++pt);
+   return drmOpenByBusid(++pt, type);
} else { /* No busid */
-   return drmOpenDevice(strtol(devstring, NULL, 0),i, 
DRM_NODE_PRIMARY);
+   return drmOpenDevice(strtol(devstring, NULL, 0),i, 
type);
}
}
}
@@ -652,8 +664,29 @@ static int drmOpenByName(const char *name)
  */
 int drmOpen(const char *name, const char *busid)
 {
+return drmOpenWithType(name, busid, DRM_NODE_PRIMARY);
+}
+
+/**
+ * Open the DRM device with specified type.
+ *
+ * Looks up the specified name and bus ID, and opens the device found.  The
+ * entry in /dev/dri is created if necessary and if called by root.
+ *
+ * \param name driver name. Not referenced if bus ID is supplied.
+ * \param busid bus ID. Zero if not known.
+ * \param type the device node type to open, PRIMARY, CONTROL or RENDER
+ *
+ * \return a file descriptor on success, or a negative value on error.
+ *
+ * \internal
+ * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
+ * otherwise.
+ */
+int drmOpenWithType(const char *name, const char *busid, int type)
+{
 if (!drmAvailable() && name != NULL && drm_server_info) {
-   /* try to load the kernel */
+   /* try to load the kernel module */
if (!drm_server_info->load_module(name)) {
drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
return -1;
@@ -661,13 +694,13 @@ int drmOpen(const char *name, const char *busid)
 }

 if (b

[RFC PATCH 0/2] Add drmOpenWithType and drmOpenOnceWithType

2015-02-02 Thread Jammy Zhou
For DRM render nodes, they are opened with the 'open' system call directly by
components such as mesa, etc now, and the minor number should be specified with 
the
new drmOpenRender function.

The following two patches add two new functions to open DRM device with the 
specified
node type, and the minor number is transparent to the callers.

Jammy Zhou (2):
  Add new drmOpenWithType function (v3)
  Add new drmOpenOnceWithType function (v2)

 xf86drm.c | 75 ---
 xf86drm.h | 10 -
 2 files changed, 67 insertions(+), 18 deletions(-)

-- 
1.9.1



[PATCH 2/2] dma-buf/fence: don't wait when specified timeout is zero

2015-01-21 Thread Jammy Zhou
When specified timeout is zero for fence_wait_timeout, just check if the fence
is signaled or not without wait.

Signed-off-by: Jammy Zhou 
---
 drivers/dma-buf/fence.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index e554111..50ef8bd 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -159,6 +159,9 @@ fence_wait_timeout(struct fence *fence, bool intr, signed 
long timeout)
if (WARN_ON(timeout < 0))
return -EINVAL;

+   if (timeout == 0)
+   return fence_is_signaled(fence);
+
trace_fence_wait_start(fence);
ret = fence->ops->wait(fence, intr, timeout);
trace_fence_wait_end(fence);
-- 
1.9.1



[PATCH 1/2] reservation: wait only with non-zero timeout specified (v3)

2015-01-21 Thread Jammy Zhou
When the timeout value passed to reservation_object_wait_timeout_rcu
is zero, no wait should be done if the fences are not signaled.

Return '1' for idle and '0' for busy if the specified timeout is '0'
to keep consistent with the case of non-zero timeout.

v2: call fence_put if not signaled in the case of timeout==0

v3: switch to reservation_object_test_signaled_rcu

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
Reviewed-by: Alex Deucher 
---
 drivers/dma-buf/reservation.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index 3c97c8f..807ef15 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -327,6 +327,9 @@ long reservation_object_wait_timeout_rcu(struct 
reservation_object *obj,
unsigned seq, shared_count, i = 0;
long ret = timeout;

+   if (!timeout)
+   return reservation_object_test_signaled_rcu(obj, wait_all);
+
 retry:
fence = NULL;
shared_count = 0;
-- 
1.9.1



[PATCH] reservation: wait only with non-zero timeout specified (v3)

2015-01-13 Thread Jammy Zhou
When the timeout value passed to reservation_object_wait_timeout_rcu
is zero, no wait should be done if the fences are not signaled.

Return '1' for idle and '0' for busy if the specified timeout is '0'
to keep consistent with the case of non-zero timeout.

v2: call fence_put if not signaled in the case of timeout==0

v3: switch to reservation_object_test_signaled_rcu

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
Reviewed-by: Alex Deucher 
---
 drivers/dma-buf/reservation.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index 3c97c8f..807ef15 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -327,6 +327,9 @@ long reservation_object_wait_timeout_rcu(struct 
reservation_object *obj,
unsigned seq, shared_count, i = 0;
long ret = timeout;

+   if (!timeout)
+   return reservation_object_test_signaled_rcu(obj, wait_all);
+
 retry:
fence = NULL;
shared_count = 0;
-- 
1.9.1



[PATCH 1/1] reservation: wait only with non-zero timeout specified (v2)

2015-01-13 Thread Jammy Zhou
When the timeout value passed to reservation_object_wait_timeout_rcu
is zero, no wait should be done if the fences are not signaled.

Return '1' for idle and '0' for busy if the specified timeout is '0'
to keep consistent with the case of non-zero timeout.

v2: call fence_put if not signaled in the case of timeout==0

Signed-off-by: Jammy Zhou 
Reviewed-by: Christian König 
Reviewed-by: Alex Deucher 
---
 drivers/dma-buf/reservation.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index 3c97c8f..b1d554f 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -380,12 +380,19 @@ retry:
}

rcu_read_unlock();
-   if (fence) {
+   if (fence && timeout) {
ret = fence_wait_timeout(fence, intr, ret);
fence_put(fence);
if (ret > 0 && wait_all && (i + 1 < shared_count))
goto retry;
}
+
+   if (fence && !timeout)
+   fence_put(fence);
+
+   if (!fence && !timeout)
+   ret = 1;
+
return ret;

 unlock_retry:
-- 
1.9.1



[PATCH] i.MX23/28 framebuffer driver

2011-02-18 Thread Jammy Zhou
To accommodate the fact of independent display controller and GPU components
in ARM SOC, it will be better if we can separate KMS from DRM both in kernel
space and user space (i.e, create a new drivers/video/kms directory for
kernel side, move KMS related code in libdrm to libkms in user space). Then
we can build xrandr1.2+ support based on KMS for ARM platforms, even if DRM
is still not supported. Besides, for buffer management part (GEM) in DRM, if
possible, we can also make it an independent module leaving DRM just a
wrapper, so that the GEM stuff can be used more flexibly.

Regards,
Jammy

On Fri, Feb 18, 2011 at 12:14 AM, James Simmons wrote:

>
> > I'm still in the learning-as-I-go phase here, so definitely not ready
> > to propose a solution, but it does seem to me like there is room for
> > some sort of kms-helper library here to handle more of the boilerplate
> > xf86-video-* stuff..  I guess I'll have a better picture once I have a
> > chance to add support for the various multi-monitor configurations.
> > But certainly would be interested if anyone already has some ideas.
>
> I have been thinking about this as well. One of the short coming for DRM
> on embedded platforms is the lack of a small well defined library that one
> could use. Right now libkms only handles buffer allocation. The mode
> setting is currently tied to the libdrm library. It would be nice to
> seperate the two out more. Move the mode setting code to libkms and then
> have libdrm be a wrapper around this. This way libdrm can both support
> the legacy drm drivers and the new kms drivers at the same time. It also
> makes a clear seperation. Jakob if you are willing to take this work I
> will gladly seen you patches.
>
> ___
> linaro-dev mailing list
> linaro-dev at lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/linaro-dev
>
-- next part --
An HTML attachment was scrubbed...
URL: 



Re: [PATCH] i.MX23/28 framebuffer driver

2011-02-18 Thread Jammy Zhou
To accommodate the fact of independent display controller and GPU components
in ARM SOC, it will be better if we can separate KMS from DRM both in kernel
space and user space (i.e, create a new drivers/video/kms directory for
kernel side, move KMS related code in libdrm to libkms in user space). Then
we can build xrandr1.2+ support based on KMS for ARM platforms, even if DRM
is still not supported. Besides, for buffer management part (GEM) in DRM, if
possible, we can also make it an independent module leaving DRM just a
wrapper, so that the GEM stuff can be used more flexibly.

Regards,
Jammy

On Fri, Feb 18, 2011 at 12:14 AM, James Simmons jsimm...@infradead.orgwrote:


  I'm still in the learning-as-I-go phase here, so definitely not ready
  to propose a solution, but it does seem to me like there is room for
  some sort of kms-helper library here to handle more of the boilerplate
  xf86-video-* stuff..  I guess I'll have a better picture once I have a
  chance to add support for the various multi-monitor configurations.
  But certainly would be interested if anyone already has some ideas.

 I have been thinking about this as well. One of the short coming for DRM
 on embedded platforms is the lack of a small well defined library that one
 could use. Right now libkms only handles buffer allocation. The mode
 setting is currently tied to the libdrm library. It would be nice to
 seperate the two out more. Move the mode setting code to libkms and then
 have libdrm be a wrapper around this. This way libdrm can both support
 the legacy drm drivers and the new kms drivers at the same time. It also
 makes a clear seperation. Jakob if you are willing to take this work I
 will gladly seen you patches.

 ___
 linaro-dev mailing list
 linaro-...@lists.linaro.org
 http://lists.linaro.org/mailman/listinfo/linaro-dev

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Freescale Linux BSP review

2010-12-14 Thread Jammy Zhou
On Tue, Dec 14, 2010 at 10:06 AM, Jerome Glisse  wrote:

> On Mon, Dec 13, 2010 at 9:04 PM, Jammy Zhou  wrote:
> >
> >
> > On Tue, Dec 14, 2010 at 12:11 AM, Jerome Glisse 
> wrote:
> >>
> >> On Mon, Dec 13, 2010 at 10:18 AM, Arnd Bergmann  wrote:
> >> > On Monday 13 December 2010, Jammy Zhou wrote:
> >> >> On Mon, Dec 13, 2010 at 4:45 AM, Linus Walleij
> >> >> wrote:
> >> >>
> >> >> > On 11 December 2010 22:41, Arnd Bergmann  wrote:
> >> >> >
> >> >> > * amd-gpu -- a single but huge driver for the GPU. As is normally
> the
> >> >> >> case with GPU drivers, we can expect long discussions
> >> >> >> before it will get considered for mainline
> >> >> >>  4 patches
> >> >> >>  98 files changed, 278321 insertions(+), 0 deletions(-)
> >> >> >>
> >> >> >
> >> >> > Just out of curiosity, following the discussion between Dave Airlie
> >> >> > and Codeaurora this summer re GPU driver shims.
> >> >> >
> >> >> > Is the AMD GPU exposing all functionality in its kernel driver or
> >> >> > is there some userspace blob somewhere with lots of e.g. GL
> >> >> > goodies?
> >> >> >
> >> >> All the functionality for the kernel driver of AMD GPU Z430/Z160 (now
> >> >> belongs to Qualcom) is exposed. But we need accompanied userspace
> >> >> library to
> >> >> call these functionality (buffer management, command submission,
> ...).
> >> >
> >> > Who owns these components? If it's closed source, the only options we
> >> > have are lobbying for complete release of the specs for a
> >> > reimplementation
> >> > or reverse-engineering the drivers, which may at least get easier with
> >> > a user space driver than it would be with a kernel driver.
> >> >
> >> > Until there is a solution with an open source user space part, I would
> >> > suggest that the driver better be dropped from the Freescale BSP and
> >> > we should at least not waste time reviewing it.
> >> >
> >> >Arnd
> >>
> >> From a quick look it also seems that the API exposed to userspace
> >> would allow easy abuse of the GPU to access any system ram. There is a
> >> reason we do expensive command checking in the other amd gpu driver
> >> (drivers/gpu/drm/radeon/*cs.c files)
> >
> > No, the memory used by the GPU is reserved at boot time, so I think there
> is
> > no such a problem.
> >
> >>
> >> Cheers,
> >> Jerome
> >
> >
>
> This isn't about what's reserved, this is about GPU capacity, if the
> GPU is isolated through an IOMMU and the GPU can't reprogram it then
> fine. But if not, then it's easy to abuse packet to reprogram the GPU
> GART (either by reprogramming GART register or by overwritting GART
> table) to point to any system ram.
>

For non-PCI GPU in embedded world, there is no GART concept. Besides, the
GPU MMU is disabled currently for some hardware problem.


>
> Cheers,
> Jerome
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20101214/a3bbbfdd/attachment-0001.htm>


Freescale Linux BSP review

2010-12-14 Thread Jammy Zhou
On Tue, Dec 14, 2010 at 12:11 AM, Jerome Glisse  wrote:

> On Mon, Dec 13, 2010 at 10:18 AM, Arnd Bergmann  wrote:
> > On Monday 13 December 2010, Jammy Zhou wrote:
> >> On Mon, Dec 13, 2010 at 4:45 AM, Linus Walleij <
> linus.walleij at linaro.org>wrote:
> >>
> >> > On 11 December 2010 22:41, Arnd Bergmann  wrote:
> >> >
> >> > * amd-gpu -- a single but huge driver for the GPU. As is normally the
> >> >> case with GPU drivers, we can expect long discussions
> >> >> before it will get considered for mainline
> >> >>  4 patches
> >> >>  98 files changed, 278321 insertions(+), 0 deletions(-)
> >> >>
> >> >
> >> > Just out of curiosity, following the discussion between Dave Airlie
> >> > and Codeaurora this summer re GPU driver shims.
> >> >
> >> > Is the AMD GPU exposing all functionality in its kernel driver or
> >> > is there some userspace blob somewhere with lots of e.g. GL
> >> > goodies?
> >> >
> >> All the functionality for the kernel driver of AMD GPU Z430/Z160 (now
> >> belongs to Qualcom) is exposed. But we need accompanied userspace
> library to
> >> call these functionality (buffer management, command submission, ...).
> >
> > Who owns these components? If it's closed source, the only options we
> > have are lobbying for complete release of the specs for a
> reimplementation
> > or reverse-engineering the drivers, which may at least get easier with
> > a user space driver than it would be with a kernel driver.
> >
> > Until there is a solution with an open source user space part, I would
> > suggest that the driver better be dropped from the Freescale BSP and
> > we should at least not waste time reviewing it.
> >
> >Arnd
>
> From a quick look it also seems that the API exposed to userspace
> would allow easy abuse of the GPU to access any system ram. There is a
> reason we do expensive command checking in the other amd gpu driver
> (drivers/gpu/drm/radeon/*cs.c files)
>

No, the memory used by the GPU is reserved at boot time, so I think there is
no such a problem.


>
> Cheers,
> Jerome
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20101214/8e45590c/attachment-0001.htm>


Freescale Linux BSP review

2010-12-14 Thread Jammy Zhou
On Mon, Dec 13, 2010 at 11:18 PM, Arnd Bergmann  wrote:

> On Monday 13 December 2010, Jammy Zhou wrote:
> > On Mon, Dec 13, 2010 at 4:45 AM, Linus Walleij  >wrote:
> >
> > > On 11 December 2010 22:41, Arnd Bergmann  wrote:
> > >
> > > * amd-gpu -- a single but huge driver for the GPU. As is normally the
> > >> case with GPU drivers, we can expect long discussions
> > >> before it will get considered for mainline
> > >>  4 patches
> > >>  98 files changed, 278321 insertions(+), 0 deletions(-)
> > >>
> > >
> > > Just out of curiosity, following the discussion between Dave Airlie
> > > and Codeaurora this summer re GPU driver shims.
> > >
> > > Is the AMD GPU exposing all functionality in its kernel driver or
> > > is there some userspace blob somewhere with lots of e.g. GL
> > > goodies?
> > >
> > All the functionality for the kernel driver of AMD GPU Z430/Z160 (now
> > belongs to Qualcom) is exposed. But we need accompanied userspace library
> to
> > call these functionality (buffer management, command submission, ...).
>
> Who owns these components? If it's closed source, the only options we
> have are lobbying for complete release of the specs for a reimplementation
> or reverse-engineering the drivers, which may at least get easier with
> a user space driver than it would be with a kernel driver.
>

The user space library is closed source, and it is owned by Qualcomm.


>
> Until there is a solution with an open source user space part, I would
> suggest that the driver better be dropped from the Freescale BSP and
> we should at least not waste time reviewing it.
>

I think it is beneficial for us to integrate the kernel part into our Linaro
tree, so that we can build/use it together with the kernel image. As for the
user space libraries, how about adding them into the hwpack? (Is there any
legal issue for this?)


>
>Arnd
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://lists.freedesktop.org/archives/dri-devel/attachments/20101214/773319b4/attachment.htm>


Re: Freescale Linux BSP review

2010-12-13 Thread Jammy Zhou
On Mon, Dec 13, 2010 at 11:18 PM, Arnd Bergmann a...@arndb.de wrote:

 On Monday 13 December 2010, Jammy Zhou wrote:
  On Mon, Dec 13, 2010 at 4:45 AM, Linus Walleij linus.wall...@linaro.org
 wrote:
 
   On 11 December 2010 22:41, Arnd Bergmann a...@arndb.de wrote:
  
   * amd-gpu -- a single but huge driver for the GPU. As is normally the
   case with GPU drivers, we can expect long discussions
   before it will get considered for mainline
4 patches
98 files changed, 278321 insertions(+), 0 deletions(-)
  
  
   Just out of curiosity, following the discussion between Dave Airlie
   and Codeaurora this summer re GPU driver shims.
  
   Is the AMD GPU exposing all functionality in its kernel driver or
   is there some userspace blob somewhere with lots of e.g. GL
   goodies?
  
  All the functionality for the kernel driver of AMD GPU Z430/Z160 (now
  belongs to Qualcom) is exposed. But we need accompanied userspace library
 to
  call these functionality (buffer management, command submission, ...).

 Who owns these components? If it's closed source, the only options we
 have are lobbying for complete release of the specs for a reimplementation
 or reverse-engineering the drivers, which may at least get easier with
 a user space driver than it would be with a kernel driver.


The user space library is closed source, and it is owned by Qualcomm.



 Until there is a solution with an open source user space part, I would
 suggest that the driver better be dropped from the Freescale BSP and
 we should at least not waste time reviewing it.


I think it is beneficial for us to integrate the kernel part into our Linaro
tree, so that we can build/use it together with the kernel image. As for the
user space libraries, how about adding them into the hwpack? (Is there any
legal issue for this?)



Arnd

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: Freescale Linux BSP review

2010-12-13 Thread Jammy Zhou
On Tue, Dec 14, 2010 at 12:11 AM, Jerome Glisse j.gli...@gmail.com wrote:

 On Mon, Dec 13, 2010 at 10:18 AM, Arnd Bergmann a...@arndb.de wrote:
  On Monday 13 December 2010, Jammy Zhou wrote:
  On Mon, Dec 13, 2010 at 4:45 AM, Linus Walleij 
 linus.wall...@linaro.orgwrote:
 
   On 11 December 2010 22:41, Arnd Bergmann a...@arndb.de wrote:
  
   * amd-gpu -- a single but huge driver for the GPU. As is normally the
   case with GPU drivers, we can expect long discussions
   before it will get considered for mainline
4 patches
98 files changed, 278321 insertions(+), 0 deletions(-)
  
  
   Just out of curiosity, following the discussion between Dave Airlie
   and Codeaurora this summer re GPU driver shims.
  
   Is the AMD GPU exposing all functionality in its kernel driver or
   is there some userspace blob somewhere with lots of e.g. GL
   goodies?
  
  All the functionality for the kernel driver of AMD GPU Z430/Z160 (now
  belongs to Qualcom) is exposed. But we need accompanied userspace
 library to
  call these functionality (buffer management, command submission, ...).
 
  Who owns these components? If it's closed source, the only options we
  have are lobbying for complete release of the specs for a
 reimplementation
  or reverse-engineering the drivers, which may at least get easier with
  a user space driver than it would be with a kernel driver.
 
  Until there is a solution with an open source user space part, I would
  suggest that the driver better be dropped from the Freescale BSP and
  we should at least not waste time reviewing it.
 
 Arnd

 From a quick look it also seems that the API exposed to userspace
 would allow easy abuse of the GPU to access any system ram. There is a
 reason we do expensive command checking in the other amd gpu driver
 (drivers/gpu/drm/radeon/*cs.c files)


No, the memory used by the GPU is reserved at boot time, so I think there is
no such a problem.



 Cheers,
 Jerome

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: Freescale Linux BSP review

2010-12-13 Thread Jammy Zhou
On Tue, Dec 14, 2010 at 10:06 AM, Jerome Glisse j.gli...@gmail.com wrote:

 On Mon, Dec 13, 2010 at 9:04 PM, Jammy Zhou jammy.z...@linaro.org wrote:
 
 
  On Tue, Dec 14, 2010 at 12:11 AM, Jerome Glisse j.gli...@gmail.com
 wrote:
 
  On Mon, Dec 13, 2010 at 10:18 AM, Arnd Bergmann a...@arndb.de wrote:
   On Monday 13 December 2010, Jammy Zhou wrote:
   On Mon, Dec 13, 2010 at 4:45 AM, Linus Walleij
   linus.wall...@linaro.orgwrote:
  
On 11 December 2010 22:41, Arnd Bergmann a...@arndb.de wrote:
   
* amd-gpu -- a single but huge driver for the GPU. As is normally
 the
case with GPU drivers, we can expect long discussions
before it will get considered for mainline
 4 patches
 98 files changed, 278321 insertions(+), 0 deletions(-)
   
   
Just out of curiosity, following the discussion between Dave Airlie
and Codeaurora this summer re GPU driver shims.
   
Is the AMD GPU exposing all functionality in its kernel driver or
is there some userspace blob somewhere with lots of e.g. GL
goodies?
   
   All the functionality for the kernel driver of AMD GPU Z430/Z160 (now
   belongs to Qualcom) is exposed. But we need accompanied userspace
   library to
   call these functionality (buffer management, command submission,
 ...).
  
   Who owns these components? If it's closed source, the only options we
   have are lobbying for complete release of the specs for a
   reimplementation
   or reverse-engineering the drivers, which may at least get easier with
   a user space driver than it would be with a kernel driver.
  
   Until there is a solution with an open source user space part, I would
   suggest that the driver better be dropped from the Freescale BSP and
   we should at least not waste time reviewing it.
  
  Arnd
 
  From a quick look it also seems that the API exposed to userspace
  would allow easy abuse of the GPU to access any system ram. There is a
  reason we do expensive command checking in the other amd gpu driver
  (drivers/gpu/drm/radeon/*cs.c files)
 
  No, the memory used by the GPU is reserved at boot time, so I think there
 is
  no such a problem.
 
 
  Cheers,
  Jerome
 
 

 This isn't about what's reserved, this is about GPU capacity, if the
 GPU is isolated through an IOMMU and the GPU can't reprogram it then
 fine. But if not, then it's easy to abuse packet to reprogram the GPU
 GART (either by reprogramming GART register or by overwritting GART
 table) to point to any system ram.


For non-PCI GPU in embedded world, there is no GART concept. Besides, the
GPU MMU is disabled currently for some hardware problem.



 Cheers,
 Jerome

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel