OSDN Git Service

configure/freedreno: make KGSL support optional
[android-x86/external-libdrm.git] / freedreno / kgsl / kgsl_bo.c
index 0d019cb..fab3350 100644 (file)
  *    Rob Clark <robclark@freedesktop.org>
  */
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 #include "kgsl_priv.h"
 
 #include <linux/fb.h>
@@ -80,9 +84,31 @@ static int kgsl_bo_offset(struct fd_bo *bo, uint64_t *offset)
 static int kgsl_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
 {
        uint32_t timestamp = kgsl_bo_get_timestamp(to_kgsl_bo(bo));
-       if (timestamp) {
-               fd_pipe_wait(pipe, timestamp);
+
+       if (op & DRM_FREEDRENO_PREP_NOSYNC) {
+               uint32_t current;
+               int ret;
+
+               /* special case for is_idle().. we can't really handle that
+                * properly in kgsl (perhaps we need a way to just disable
+                * the bo-cache for kgsl?)
+                */
+               if (!pipe)
+                       return -EBUSY;
+
+               ret = kgsl_pipe_timestamp(to_kgsl_pipe(pipe), &current);
+               if (ret)
+                       return ret;
+
+               if (timestamp > current)
+                       return -EBUSY;
+
+               return 0;
        }
+
+       if (timestamp)
+               fd_pipe_wait(pipe, timestamp);
+
        return 0;
 }
 
@@ -149,32 +175,22 @@ struct fd_bo * kgsl_bo_from_handle(struct fd_device *dev,
        return bo;
 }
 
-struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe,
-               int fbfd, uint32_t size)
+drm_public struct fd_bo *
+fd_bo_from_fbdev(struct fd_pipe *pipe, int fbfd, uint32_t size)
 {
-       struct drm_kgsl_gem_create_fd req = {
-                       .fd = fbfd,
-       };
        struct fd_bo *bo;
-       struct kgsl_bo *kgsl_bo;
 
        if (!is_kgsl_pipe(pipe))
                return NULL;
 
-       if (drmCommandWriteRead(pipe->dev->fd, DRM_KGSL_GEM_CREATE_FD,
-                       &req, sizeof(req))) {
-               return NULL;
-       }
-
-       bo = fd_bo_from_handle(pipe->dev, req.handle, size);
-       kgsl_bo = to_kgsl_bo(bo);
+       bo = fd_bo_new(pipe->dev, 1, 0);
 
        /* this is fugly, but works around a bug in the kernel..
         * priv->memdesc.size never gets set, so getbufinfo ioctl
         * thinks the buffer hasn't be allocate and fails
         */
-       if (bo && !kgsl_bo_gpuaddr(kgsl_bo, 0)) {
-               void *fbmem = mmap(NULL, size, PROT_READ | PROT_WRITE,
+       if (bo) {
+               void *fbmem = drm_mmap(NULL, size, PROT_READ | PROT_WRITE,
                                MAP_SHARED, fbfd, 0);
                struct kgsl_map_user_mem req = {
                                .memtype = KGSL_USER_MEM_TYPE_ADDR,
@@ -182,7 +198,9 @@ struct fd_bo * fd_bo_from_fbdev(struct fd_pipe *pipe,
                                .offset  = 0,
                                .hostptr = (unsigned long)fbmem,
                };
+               struct kgsl_bo *kgsl_bo = to_kgsl_bo(bo);
                int ret;
+
                ret = ioctl(to_kgsl_pipe(pipe)->fd, IOCTL_KGSL_MAP_USER_MEM, &req);
                if (ret) {
                        ERROR_MSG("mapping user mem failed: %s",
@@ -200,7 +218,6 @@ fail:
        return NULL;
 }
 
-
 uint32_t kgsl_bo_gpuaddr(struct kgsl_bo *kgsl_bo, uint32_t offset)
 {
        struct fd_bo *bo = &kgsl_bo->base;