drm/msm: fb prepare/cleanup
authorRob Clark <robdclark@gmail.com>
Sat, 8 Nov 2014 14:13:37 +0000 (09:13 -0500)
committerRob Clark <robdclark@gmail.com>
Sun, 16 Nov 2014 19:27:36 +0000 (14:27 -0500)
Atomic wants to split the prepare/pin from where we actually program the
scanout address (so that any part that can fail is done synchronously).
Add some fb/gem apis to make this easier to use from the kms parts.

Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/msm_drv.h
drivers/gpu/drm/msm/msm_fb.c
drivers/gpu/drm/msm/msm_gem.c

index 5ab6c3dff3c090897cac6f3b4eeffa5128c20f49..4a7e8b8ff6492567e1679fd1059c578b2a5f0145 100644 (file)
@@ -160,6 +160,7 @@ uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
 int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
                uint32_t *iova);
 int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova);
+uint32_t msm_gem_iova(struct drm_gem_object *obj, int id);
 struct page **msm_gem_get_pages(struct drm_gem_object *obj);
 void msm_gem_put_pages(struct drm_gem_object *obj);
 void msm_gem_put_iova(struct drm_gem_object *obj, int id);
@@ -193,6 +194,9 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev,
 struct drm_gem_object *msm_gem_import(struct drm_device *dev,
                uint32_t size, struct sg_table *sgt);
 
+int msm_framebuffer_prepare(struct drm_framebuffer *fb, int id);
+void msm_framebuffer_cleanup(struct drm_framebuffer *fb, int id);
+uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane);
 struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane);
 const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb);
 struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
index 81bafdf19ab39fc32428e6f5be692c597a6a8276..acf34ec80a7584c717984f2b2a541b78cab031ff 100644 (file)
@@ -87,6 +87,42 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
 }
 #endif
 
+/* prepare/pin all the fb's bo's for scanout.  Note that it is not valid
+ * to prepare an fb more multiple different initiator 'id's.  But that
+ * should be fine, since only the scanout (mdpN) side of things needs
+ * this, the gpu doesn't care about fb's.
+ */
+int msm_framebuffer_prepare(struct drm_framebuffer *fb, int id)
+{
+       struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+       int ret, i, n = drm_format_num_planes(fb->pixel_format);
+       uint32_t iova;
+
+       for (i = 0; i < n; i++) {
+               ret = msm_gem_get_iova(msm_fb->planes[i], id, &iova);
+               DBG("FB[%u]: iova[%d]: %08x (%d)", fb->base.id, i, iova, ret);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+void msm_framebuffer_cleanup(struct drm_framebuffer *fb, int id)
+{
+       struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+       int i, n = drm_format_num_planes(fb->pixel_format);
+
+       for (i = 0; i < n; i++)
+               msm_gem_put_iova(msm_fb->planes[i], id);
+}
+
+uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane)
+{
+       struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+       return msm_gem_iova(msm_fb->planes[plane], id);
+}
+
 struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane)
 {
        struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
index 8207862b70d19823b9ec9908591e94d92ce282ee..aaa7898b0b6dc6755d1cc42da95571b8cbac0888 100644 (file)
@@ -309,6 +309,7 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
        return ret;
 }
 
+/* get iova, taking a reference.  Should have a matching put */
 int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova)
 {
        struct msm_gem_object *msm_obj = to_msm_bo(obj);
@@ -328,6 +329,16 @@ int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova)
        return ret;
 }
 
+/* get iova without taking a reference, used in places where you have
+ * already done a 'msm_gem_get_iova()'.
+ */
+uint32_t msm_gem_iova(struct drm_gem_object *obj, int id)
+{
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+       WARN_ON(!msm_obj->domain[id].iova);
+       return msm_obj->domain[id].iova;
+}
+
 void msm_gem_put_iova(struct drm_gem_object *obj, int id)
 {
        // XXX TODO ..