aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier Martin <javier.martin@arm.com>2013-08-21 16:48:07 +0100
committerJavier Martin <javier.martin@arm.com>2013-08-22 14:55:13 +0100
commit981264db4a324eb2e5804daa10965a99a37b365a (patch)
tree19223b4028ff38410c8f3b84c0248255d464530c
parent1ce856713af2319e22488207c9823a9d85a0ffba (diff)
downloadxf86-video-armsoc-981264db4a324eb2e5804daa10965a99a37b365a.tar.gz
Provide a new hook to allocate GEM objects in a device specific way.
DUMB_CREATE ioctl() should not be used to create buffers for rendering. Instead of that each device is responsible to provide that kind of facility in a specific way. This implements GEM object creation for both exynos and pl111. Change-Id: Idf9961e112f5f36b2fd0a66cab5d3a928fab096f
-rw-r--r--src/armsoc_driver.c3
-rw-r--r--src/armsoc_dumb.c47
-rw-r--r--src/armsoc_dumb.h20
-rw-r--r--src/drmmode_driver.h28
-rw-r--r--src/drmmode_exynos/drmmode_exynos.c39
-rw-r--r--src/drmmode_pl111/drmmode_pl111.c56
-rw-r--r--src/drmmode_template/drmmode_template.c12
7 files changed, 152 insertions, 53 deletions
diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c
index c5208ee..41e43e8 100644
--- a/src/armsoc_driver.c
+++ b/src/armsoc_driver.c
@@ -678,8 +678,7 @@ ARMSOCPreInit(ScrnInfoPtr pScrn, int flags)
/* create DRM device instance: */
pARMSOC->dev = armsoc_device_new(pARMSOC->drmFD,
- pARMSOC->drmmode_interface->dumb_scanout_flags,
- pARMSOC->drmmode_interface->dumb_no_scanout_flags);
+ pARMSOC->drmmode_interface->create_custom_gem);
/* find matching chipset name: */
for (i = 0; ARMSOCChipsets[i].name; i++) {
diff --git a/src/armsoc_dumb.c b/src/armsoc_dumb.c
index a1fd800..ba92d00 100644
--- a/src/armsoc_dumb.c
+++ b/src/armsoc_dumb.c
@@ -38,8 +38,7 @@
struct armsoc_device {
int fd;
- uint32_t dumb_scanout_flags;
- uint32_t dumb_no_scanout_flags;
+ int (*create_custom_gem)(int fd, struct armsoc_create_gem *create_gem);
};
struct armsoc_bo {
@@ -65,16 +64,16 @@ struct armsoc_bo {
/* device related functions:
*/
-struct armsoc_device *armsoc_device_new(int fd, uint32_t dumb_scanout_flags,
- uint32_t dumb_no_scanout_flags)
+struct armsoc_device *armsoc_device_new(int fd,
+ int (*create_custom_gem)(int fd,
+ struct armsoc_create_gem *create_gem))
{
struct armsoc_device *new_dev = malloc(sizeof(*new_dev));
if (!new_dev)
return NULL;
new_dev->fd = fd;
- new_dev->dumb_scanout_flags = dumb_scanout_flags;
- new_dev->dumb_no_scanout_flags = dumb_no_scanout_flags;
+ new_dev->create_custom_gem = create_custom_gem;
return new_dev;
}
@@ -126,7 +125,7 @@ struct armsoc_bo *armsoc_bo_new_with_dim(struct armsoc_device *dev,
uint32_t width, uint32_t height, uint8_t depth,
uint8_t bpp, enum armsoc_buf_type buf_type)
{
- struct drm_mode_create_dumb create_dumb;
+ struct armsoc_create_gem create_gem;
struct armsoc_bo *new_buf;
int res;
@@ -134,36 +133,30 @@ struct armsoc_bo *armsoc_bo_new_with_dim(struct armsoc_device *dev,
if (!new_buf)
return NULL;
- create_dumb.height = height;
- create_dumb.width = width;
- create_dumb.bpp = bpp;
- assert((ARMSOC_BO_SCANOUT == buf_type) ||
- (ARMSOC_BO_NON_SCANOUT == buf_type));
- if (ARMSOC_BO_SCANOUT == buf_type)
- create_dumb.flags = dev->dumb_scanout_flags;
- else
- create_dumb.flags = dev->dumb_no_scanout_flags;
-
- res = drmIoctl(dev->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
+ create_gem.buf_type = buf_type;
+ create_gem.height = height;
+ create_gem.width = width;
+ create_gem.bpp = bpp;
+ res = dev->create_custom_gem(dev->fd, &create_gem);
if (res) {
free(new_buf);
xf86DrvMsg(-1, X_ERROR,
- "_CREATE_DUMB({height: 0x%X, width: 0x%X, bpp: 0x%X, flags: 0x%X}) failed. errno:0x%X\n",
- height, width, bpp, create_dumb.flags, errno);
+ "_CREATE_GEM({height: 0x%X, width: 0x%X, bpp: 0x%X, buf_type: 0x%X}) failed. errno:0x%X\n",
+ height, width, bpp, buf_type, errno);
return NULL;
}
new_buf->dev = dev;
- new_buf->handle = create_dumb.handle;
- new_buf->size = create_dumb.size;
+ new_buf->handle = create_gem.handle;
+ new_buf->size = create_gem.size;
new_buf->map_addr = NULL;
new_buf->fb_id = 0;
- new_buf->pitch = create_dumb.pitch;
- new_buf->width = create_dumb.width;
- new_buf->height = create_dumb.height;
- new_buf->original_size = create_dumb.size;
+ new_buf->pitch = create_gem.pitch;
+ new_buf->width = create_gem.width;
+ new_buf->height = create_gem.height;
+ new_buf->original_size = create_gem.size;
new_buf->depth = depth;
- new_buf->bpp = create_dumb.bpp;
+ new_buf->bpp = create_gem.bpp;
new_buf->refcnt = 1;
new_buf->dmabuf = -1;
new_buf->name = 0;
diff --git a/src/armsoc_dumb.h b/src/armsoc_dumb.h
index 660c455..c510c18 100644
--- a/src/armsoc_dumb.h
+++ b/src/armsoc_dumb.h
@@ -40,8 +40,24 @@ enum armsoc_buf_type {
ARMSOC_BO_NON_SCANOUT
};
-struct armsoc_device *armsoc_device_new(int fd, uint32_t dumb_scanout_flags,
- uint32_t dumb_no_scanout_flags);
+/*
+ * Generic GEM object information used to abstract custom GEM creation
+ * for every DRM driver.
+ */
+struct armsoc_create_gem {
+ /* parameters that will be provided */
+ uint32_t height;
+ uint32_t width;
+ uint32_t bpp;
+ enum armsoc_buf_type buf_type;
+ /* handle, pitch, size will be returned */
+ uint32_t handle;
+ uint32_t pitch;
+ uint64_t size;
+};
+
+struct armsoc_device *armsoc_device_new(int fd,
+ int (*create_custom_gem)(int fd, struct armsoc_create_gem *create_gem));
void armsoc_device_del(struct armsoc_device *dev);
int armsoc_bo_get_name(struct armsoc_bo *bo, uint32_t *name);
uint32_t armsoc_bo_handle(struct armsoc_bo *bo);
diff --git a/src/drmmode_driver.h b/src/drmmode_driver.h
index eb49483..b568218 100644
--- a/src/drmmode_driver.h
+++ b/src/drmmode_driver.h
@@ -29,24 +29,9 @@
#include "xorg-server.h"
#include "xf86Crtc.h"
+#include "armsoc_dumb.h"
struct drmmode_interface {
-
- /* Flags value to pass to DRM_IOCTL_MODE_CREATE_DUMB to allocate
- * a scanout-capable buffer. A buffer allocated with these flags
- * must be able to be wrapped in a DRM framebuffer (via
- * DRM_IOCTL_MODE_ADDFB or DRM_IOCTL_MODE_ADDFB2).
- */
- uint32_t dumb_scanout_flags;
-
- /* Flags value to pass to DRM_IOCTL_MODE_CREATE_DUMB to allocate a
- * non-scanout-capable buffer. It is acceptable for the driver to
- * create a scanout-capable buffer when given this flag, this flag
- * is used to give the option of preserving scarce scanout-capable
- * memory if applicable.
- */
- uint32_t dumb_no_scanout_flags;
-
/* Boolean value indicating whether DRM page flip events should
* be requested and waited for during DRM_IOCTL_MODE_PAGE_FLIP.
*/
@@ -90,6 +75,17 @@ struct drmmode_interface {
* vblank timestamp query
*/
int vblank_query_supported;
+
+ /* (Mandatory) Create new gem object
+ *
+ * A driver specific ioctl() is usually needed to create GEM objects
+ * with particular features such as contiguous memory, uncached, etc...
+ *
+ * @param fd DRM device file descriptor
+ * @param create_gem generic GEM description
+ * @return 0 on success, non-zero on failure
+ */
+ int (*create_custom_gem)(int fd, struct armsoc_create_gem *create_gem);
};
struct drmmode_interface *drmmode_interface_get_implementation(int drm_fd);
diff --git a/src/drmmode_exynos/drmmode_exynos.c b/src/drmmode_exynos/drmmode_exynos.c
index 70d7ba2..bfba25d 100644
--- a/src/drmmode_exynos/drmmode_exynos.c
+++ b/src/drmmode_exynos/drmmode_exynos.c
@@ -25,6 +25,7 @@
#include "../drmmode_driver.h"
#include <stddef.h>
#include <xf86drmMode.h>
+#include <xf86drm.h>
#include <sys/ioctl.h>
struct drm_exynos_plane_set_zpos {
@@ -46,6 +47,9 @@ struct drm_exynos_plane_set_zpos {
#define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
+#define EXYNOS_SCANOUT_FLAGS 0x00000000
+#define EXYNOS_NON_SCANOUT_FLAGS 0x00000001
+
static int init_plane_for_cursor(int drm_fd, uint32_t plane_id)
{
int res = -1;
@@ -117,9 +121,39 @@ static void set_cursor_image(xf86CrtcPtr crtc, uint32_t *d, CARD32 *s)
}
}
+static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem)
+{
+ struct drm_mode_create_dumb create_dumb;
+ int ret;
+
+ memset(&create_dumb, 0, sizeof(create_dumb));
+ create_dumb.height = create_gem->height;
+ create_dumb.width = create_gem->width;
+ create_dumb.bpp = create_gem->bpp;
+
+ assert((create_gem->buf_type == ARMSOC_BO_SCANOUT) ||
+ (create_gem->buf_type == ARMSOC_BO_NON_SCANOUT));
+ if (create_gem->buf_type == ARMSOC_BO_SCANOUT)
+ create_dumb.flags = EXYNOS_SCANOUT_FLAGS;
+ else
+ create_dumb.flags = EXYNOS_NON_SCANOUT_FLAGS;
+
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
+ if (ret)
+ return ret;
+
+ /* Convert custom create_dumb to generic create_gem */
+ create_gem->height = create_dumb.height;
+ create_gem->width = create_dumb.width;
+ create_gem->bpp = create_dumb.bpp;
+ create_gem->handle = create_dumb.handle;
+ create_gem->pitch = create_dumb.pitch;
+ create_gem->size = create_dumb.size;
+
+ return 0;
+}
+
struct drmmode_interface exynos_interface = {
- 0x00000000 /* dumb_scanout_flags */,
- 0x00000001 /* dumb_no_scanout_flags */,
1 /* use_page_flip_events */,
CURSORW /* cursor width */,
CURSORH /* cursor_height */,
@@ -127,6 +161,7 @@ struct drmmode_interface exynos_interface = {
init_plane_for_cursor /* init_plane_for_cursor */,
set_cursor_image /* set cursor image */,
0 /* vblank_query_supported */,
+ create_custom_gem /* create_custom_gem */,
};
struct drmmode_interface *drmmode_interface_get_implementation(int drm_fd)
diff --git a/src/drmmode_pl111/drmmode_pl111.c b/src/drmmode_pl111/drmmode_pl111.c
index 2cd5e4a..2346112 100644
--- a/src/drmmode_pl111/drmmode_pl111.c
+++ b/src/drmmode_pl111/drmmode_pl111.c
@@ -24,6 +24,7 @@
#include "../drmmode_driver.h"
#include <stddef.h>
+#include <xf86drm.h>
/* Cursor dimensions
* Technically we probably don't have any size limit.. since we
@@ -50,6 +51,9 @@
#define LBBP_WORDS_PER_LINE (4)
#define LBBP_PIXELS_PER_WORD (16)
+#define PL111_SCANOUT_FLAGS 0x00000001
+#define PL111_NON_SCANOUT_FLAGS 0x00000000
+
/* shift required to locate pixel into the correct position in
* a cursor LBBP word, indexed by x mod 16.
*/
@@ -132,9 +136,56 @@ static void set_cursor_image(xf86CrtcPtr crtc, uint32_t *d, CARD32 *s)
}
}
+/* TODO MIDEGL-1718: this should be included from kernel headers when pl111 is mainline */
+struct drm_pl111_gem_create {
+ uint32_t height;
+ uint32_t width;
+ uint32_t bpp;
+ uint32_t flags;
+ /* handle, pitch, size will be returned */
+ uint32_t handle;
+ uint32_t pitch;
+ uint64_t size;
+};
+
+#define DRM_PL111_GEM_CREATE 0x00
+#define DRM_IOCTL_PL111_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_PL111_GEM_CREATE, struct drm_pl111_gem_create)
+/***************************************************************************/
+
+static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem)
+{
+ struct drm_pl111_gem_create create_pl111;
+ int ret;
+
+ memset(&create_pl111, 0, sizeof(create_pl111));
+ create_pl111.height = create_gem->height;
+ create_pl111.width = create_gem->width;
+ create_pl111.bpp = create_gem->bpp;
+
+ assert((create_gem->buf_type == ARMSOC_BO_SCANOUT) ||
+ (create_gem->buf_type == ARMSOC_BO_NON_SCANOUT));
+ if (create_gem->buf_type == ARMSOC_BO_SCANOUT)
+ create_pl111.flags = PL111_SCANOUT_FLAGS;
+ else
+ create_pl111.flags = PL111_NON_SCANOUT_FLAGS;
+
+ ret = drmIoctl(fd, DRM_IOCTL_PL111_GEM_CREATE, &create_pl111);
+ if (ret)
+ return ret;
+
+ /* Convert custom create_pl111 to generic create_gem */
+ create_gem->height = create_pl111.height;
+ create_gem->width = create_pl111.width;
+ create_gem->bpp = create_pl111.bpp;
+ create_gem->handle = create_pl111.handle;
+ create_gem->pitch = create_pl111.pitch;
+ create_gem->size = create_pl111.size;
+
+ return 0;
+}
+
struct drmmode_interface pl111_interface = {
- 0x00000001 /* dumb_scanout_flags */,
- 0x00000000 /* dumb_no_scanout_flags */,
0 /* use_page_flip_events */,
CURSORW /* cursor width */,
CURSORH /* cursor_height */,
@@ -142,6 +193,7 @@ struct drmmode_interface pl111_interface = {
NULL /* init_plane_for_cursor */,
set_cursor_image /* set cursor image */,
0 /* vblank_query_supported */,
+ create_custom_gem /* create_custom_gem */,
};
struct drmmode_interface *drmmode_interface_get_implementation(int drm_fd)
diff --git a/src/drmmode_template/drmmode_template.c b/src/drmmode_template/drmmode_template.c
index 550848c..237dae5 100644
--- a/src/drmmode_template/drmmode_template.c
+++ b/src/drmmode_template/drmmode_template.c
@@ -48,9 +48,16 @@ static void set_cursor_image(xf86CrtcPtr crtc, uint32_t *d, CARD32 *s)
/* provide a method of setting the cursor image here */
}
+static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem)
+{
+ /*
+ * provide a method of creating both scanout and non-scanout GEM
+ * objects here. This method is usually a custom ioctl() call to
+ * the DRM driver.
+ */
+}
+
struct drmmode_interface template_interface = {
- 0x00000000 /* dumb_scanout_flags */,
- 0x00000000 /* dumb_no_scanout_flags */,
1 /* use_page_flip_events */,
CURSORW /* cursor width */,
CURSORH /* cursor_height */,
@@ -58,6 +65,7 @@ struct drmmode_interface template_interface = {
init_plane_for_cursor /* init_plane_for_cursor */,
set_cursor_image /* set cursor image */,
0 /* vblank_query_supported */,
+ create_custom_gem /* create_custom_gem */,
};
struct drmmode_interface *drmmode_interface_get_implementation(int drm_fd)