summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2022-06-01 13:46:36 +0300
committerBen Skeggs <bskeggs@redhat.com>2022-11-09 03:43:10 +0300
commit361863ceab1eaa171a304bda84636f2ff0a1d820 (patch)
tree5aaafffb354d8965b245ee9b159e758efcd3d5a2 /drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c
parenta2b7eadfef5963138a5aeaba90c4f513414823c2 (diff)
downloadlinux-361863ceab1eaa171a304bda84636f2ff0a1d820.tar.xz
drm/nouveau/disp: move head scanoutpos method
Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c
index a58f4b5fcd01..5f3c4b7dbb75 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c
@@ -24,6 +24,47 @@
#include <nvif/if0013.h>
+static int
+nvkm_uhead_mthd_scanoutpos(struct nvkm_head *head, void *argv, u32 argc)
+{
+ union nvif_head_scanoutpos_args *args = argv;
+
+ if (argc != sizeof(args->v0) || args->v0.version != 0)
+ return -ENOSYS;
+
+ head->func->state(head, &head->arm);
+ args->v0.vtotal = head->arm.vtotal;
+ args->v0.vblanks = head->arm.vblanks;
+ args->v0.vblanke = head->arm.vblanke;
+ args->v0.htotal = head->arm.htotal;
+ args->v0.hblanks = head->arm.hblanks;
+ args->v0.hblanke = head->arm.hblanke;
+
+ /* We don't support reading htotal/vtotal on pre-NV50 VGA,
+ * so we have to give up and trigger the timestamping
+ * fallback in the drm core.
+ */
+ if (!args->v0.vtotal || !args->v0.htotal)
+ return -ENOTSUPP;
+
+ args->v0.time[0] = ktime_to_ns(ktime_get());
+ head->func->rgpos(head, &args->v0.hline, &args->v0.vline);
+ args->v0.time[1] = ktime_to_ns(ktime_get());
+ return 0;
+}
+
+static int
+nvkm_uhead_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
+{
+ struct nvkm_head *head = nvkm_uhead(object);
+
+ switch (mthd) {
+ case NVIF_HEAD_V0_SCANOUTPOS: return nvkm_uhead_mthd_scanoutpos(head, argv, argc);
+ default:
+ return -EINVAL;
+ }
+}
+
static void *
nvkm_uhead_dtor(struct nvkm_object *object)
{
@@ -39,6 +80,7 @@ nvkm_uhead_dtor(struct nvkm_object *object)
static const struct nvkm_object_func
nvkm_uhead = {
.dtor = nvkm_uhead_dtor,
+ .mthd = nvkm_uhead_mthd,
};
int