drm/nouveau/kms/gk104-: support additional cursor sizes
authorBen Skeggs <bskeggs@redhat.com>
Tue, 8 May 2018 10:39:47 +0000 (20:39 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 18 May 2018 05:01:30 +0000 (15:01 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/dispnv50/atom.h
drivers/gpu/drm/nouveau/dispnv50/curs507a.c
drivers/gpu/drm/nouveau/dispnv50/head.h
drivers/gpu/drm/nouveau/dispnv50/head507d.c
drivers/gpu/drm/nouveau/dispnv50/head827d.c
drivers/gpu/drm/nouveau/dispnv50/head907d.c
drivers/gpu/drm/nouveau/dispnv50/head917d.c

index 0409947bf196259165e3a2d63e1c292f70f31aab..3d059df78322b98ea38084314c8a713d62ba73e2 100644 (file)
@@ -76,7 +76,7 @@ struct nv50_head_atom {
                bool visible;
                u32 handle;
                u64 offset:40;
-               u8  layout:1;
+               u8  layout:2;
                u8  format:1;
        } curs;
 
index ba05bcb13ae794767a5656483ff3b8429baab775..291c08117ab65337f7a9d8567cec08207cd555db 100644 (file)
@@ -21,6 +21,7 @@
  */
 #include "curs.h"
 #include "core.h"
+#include "head.h"
 
 #include <nvif/cl507a.h>
 
@@ -70,6 +71,7 @@ static int
 curs507a_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
                 struct nv50_head_atom *asyh)
 {
+       struct nv50_head *head = nv50_head(asyw->state.crtc);
        int ret;
 
        ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
@@ -80,24 +82,14 @@ curs507a_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
        if (ret || !asyh->curs.visible)
                return ret;
 
-       switch (asyw->state.fb->width) {
-       case 32: asyh->curs.layout = 0; break;
-       case 64: asyh->curs.layout = 1; break;
-       default:
-               return -EINVAL;
-       }
-
-       if (asyw->state.fb->width != asyw->state.fb->height)
+       if (asyw->image.w != asyw->image.h)
                return -EINVAL;
 
-       switch (asyw->image.format) {
-       case 0xcf: asyh->curs.format = 1; break;
-       default:
-               WARN_ON(1);
-               return -EINVAL;
-       }
+       ret = head->func->curs_layout(head, asyw, asyh);
+       if (ret)
+               return ret;
 
-       return 0;
+       return head->func->curs_format(head, asyw, asyh);
 }
 
 static const u32
index 0802271bc90ccb2b30cb0805c907650f00bd82f5..8f2c3ffa4e610ddd93f914b93f8b2ab28755c0f0 100644 (file)
@@ -26,6 +26,10 @@ struct nv50_head_func {
        void (*core_calc)(struct nv50_head *, struct nv50_head_atom *);
        void (*core_set)(struct nv50_head *, struct nv50_head_atom *);
        void (*core_clr)(struct nv50_head *);
+       int (*curs_layout)(struct nv50_head *, struct nv50_wndw_atom *,
+                          struct nv50_head_atom *);
+       int (*curs_format)(struct nv50_head *, struct nv50_wndw_atom *,
+                          struct nv50_head_atom *);
        void (*curs_set)(struct nv50_head *, struct nv50_head_atom *);
        void (*curs_clr)(struct nv50_head *);
        void (*base)(struct nv50_head *, struct nv50_head_atom *);
@@ -41,6 +45,10 @@ void head507d_mode(struct nv50_head *, struct nv50_head_atom *);
 void head507d_olut(struct nv50_head *, struct nv50_head_atom *);
 void head507d_core_calc(struct nv50_head *, struct nv50_head_atom *);
 void head507d_core_clr(struct nv50_head *);
+int head507d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *,
+                        struct nv50_head_atom *);
+int head507d_curs_format(struct nv50_head *, struct nv50_wndw_atom *,
+                        struct nv50_head_atom *);
 void head507d_base(struct nv50_head *, struct nv50_head_atom *);
 void head507d_ovly(struct nv50_head *, struct nv50_head_atom *);
 void head507d_dither(struct nv50_head *, struct nv50_head_atom *);
index 8a8aa9b69ef8334a710ab0c51db1b1d0d670c859..5b6a280ab804c9b501111f04a2ac25da7097d747 100644 (file)
@@ -128,6 +128,32 @@ head507d_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh)
        }
 }
 
+int
+head507d_curs_format(struct nv50_head *head, struct nv50_wndw_atom *asyw,
+                    struct nv50_head_atom *asyh)
+{
+       switch (asyw->image.format) {
+       case 0xcf: asyh->curs.format = 1; break;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+int
+head507d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw,
+                    struct nv50_head_atom *asyh)
+{
+       switch (asyw->image.w) {
+       case 32: asyh->curs.layout = 0; break;
+       case 64: asyh->curs.layout = 1; break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
 void
 head507d_core_clr(struct nv50_head *head)
 {
@@ -287,6 +313,8 @@ head507d = {
        .core_calc = head507d_core_calc,
        .core_set = head507d_core_set,
        .core_clr = head507d_core_clr,
+       .curs_layout = head507d_curs_layout,
+       .curs_format = head507d_curs_format,
        .curs_set = head507d_curs_set,
        .curs_clr = head507d_curs_clr,
        .base = head507d_base,
index ae33e21790ee7b4605fcef838bf1a81ab5d25a6c..af5e7bd5978bf4ff848e11cc8852de8e16240a30 100644 (file)
@@ -113,6 +113,8 @@ head827d = {
        .core_calc = head507d_core_calc,
        .core_set = head827d_core_set,
        .core_clr = head507d_core_clr,
+       .curs_layout = head507d_curs_layout,
+       .curs_format = head507d_curs_format,
        .curs_set = head827d_curs_set,
        .curs_clr = head827d_curs_clr,
        .base = head507d_base,
index a05dfccadcfa6178b42733c0d98be3939a0a93ee..c09620f540f9febf74e8849d9a54c1db193d21d1 100644 (file)
@@ -270,6 +270,8 @@ head907d = {
        .core_calc = head507d_core_calc,
        .core_set = head907d_core_set,
        .core_clr = head907d_core_clr,
+       .curs_layout = head507d_curs_layout,
+       .curs_format = head507d_curs_format,
        .curs_set = head907d_curs_set,
        .curs_clr = head907d_curs_clr,
        .base = head907d_base,
index 5f654512c8c268cede60fc0208b5b75f8c0f0159..4c019a4417ea1c067fde7ff4183b8ea76068f007 100644 (file)
@@ -63,6 +63,21 @@ head917d_base(struct nv50_head *head, struct nv50_head_atom *asyh)
        }
 }
 
+static int
+head917d_curs_layout(struct nv50_head *head, struct nv50_wndw_atom *asyw,
+                    struct nv50_head_atom *asyh)
+{
+       switch (asyw->state.fb->width) {
+       case  32: asyh->curs.layout = 0; break;
+       case  64: asyh->curs.layout = 1; break;
+       case 128: asyh->curs.layout = 2; break;
+       case 256: asyh->curs.layout = 3; break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
 const struct nv50_head_func
 head917d = {
        .view = head907d_view,
@@ -73,6 +88,8 @@ head917d = {
        .core_calc = head507d_core_calc,
        .core_set = head907d_core_set,
        .core_clr = head907d_core_clr,
+       .curs_layout = head917d_curs_layout,
+       .curs_format = head507d_curs_format,
        .curs_set = head907d_curs_set,
        .curs_clr = head907d_curs_clr,
        .base = head917d_base,