Commit 361863ce authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/disp: move head scanoutpos method

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent a2b7eadf
......@@ -46,7 +46,6 @@
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/cl5070.h>
#include <nvif/event.h>
#include <nvif/if0012.h>
#include <nvif/if0014.h>
......
......@@ -4,26 +4,4 @@
#define NV04_DISP_NTFY_VBLANK 0x00
#define NV04_DISP_NTFY_CONN 0x01
struct nv04_disp_mthd_v0 {
__u8 version;
#define NV04_DISP_SCANOUTPOS 0x00
__u8 method;
__u8 head;
__u8 pad03[5];
};
struct nv04_disp_scanoutpos_v0 {
__u8 version;
__u8 pad01[7];
__s64 time[2];
__u16 vblanks;
__u16 vblanke;
__u16 vtotal;
__u16 vline;
__u16 hblanks;
__u16 hblanke;
__u16 htotal;
__u16 hline;
};
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_CL5070_H__
#define __NVIF_CL5070_H__
#define NV50_DISP_MTHD 0x00
struct nv50_disp_mthd_v0 {
__u8 version;
#define NV50_DISP_SCANOUTPOS 0x00
__u8 method;
__u8 head;
__u8 pad03[5];
};
struct nv50_disp_scanoutpos_v0 {
__u8 version;
__u8 pad01[7];
__s64 time[2];
__u16 vblanks;
__u16 vblanke;
__u16 vtotal;
__u16 vline;
__u16 hblanks;
__u16 hblanke;
__u16 htotal;
__u16 hline;
};
#endif
......@@ -9,4 +9,22 @@ union nvif_head_args {
__u8 pad02[6];
} v0;
};
#define NVIF_HEAD_V0_SCANOUTPOS 0x00
union nvif_head_scanoutpos_args {
struct nvif_head_scanoutpos_v0 {
__u8 version;
__u8 pad01[7];
__s64 time[2];
__u16 vblanks;
__u16 vblanke;
__u16 vtotal;
__u16 vline;
__u16 hblanks;
__u16 hblanke;
__u16 htotal;
__u16 hline;
} v0;
};
#endif
......@@ -42,7 +42,7 @@
#include "nv50_display.h"
#include <nvif/class.h>
#include <nvif/cl0046.h>
#include <nvif/if0013.h>
#include <nvif/event.h>
#include <dispnv50/crc.h>
......@@ -84,24 +84,20 @@ static bool
nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
ktime_t *stime, ktime_t *etime)
{
struct {
struct nv04_disp_mthd_v0 base;
struct nv04_disp_scanoutpos_v0 scan;
} args = {
.base.method = NV04_DISP_SCANOUTPOS,
.base.head = nouveau_crtc(crtc)->index,
};
struct nouveau_display *disp = nouveau_display(crtc->dev);
struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)];
struct nvif_head *head = &nouveau_crtc(crtc)->head;
struct nvif_head_scanoutpos_v0 args;
int retry = 20;
bool ret = false;
args.version = 0;
do {
ret = nvif_mthd(&disp->disp.object, 0, &args, sizeof(args));
ret = nvif_mthd(&head->object, NVIF_HEAD_V0_SCANOUTPOS, &args, sizeof(args));
if (ret != 0)
return false;
if (args.scan.vline) {
if (args.vline) {
ret = true;
break;
}
......@@ -109,11 +105,10 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
if (retry) ndelay(vblank->linedur_ns);
} while (retry--);
*hpos = args.scan.hline;
*vpos = calc(args.scan.vblanks, args.scan.vblanke,
args.scan.vtotal, args.scan.vline);
if (stime) *stime = ns_to_ktime(args.scan.time[0]);
if (etime) *etime = ns_to_ktime(args.scan.time[1]);
*hpos = args.hline;
*vpos = calc(args.vblanks, args.vblanke, args.vtotal, args.vline);
if (stime) *stime = ns_to_ktime(args.time[0]);
if (etime) *etime = ns_to_ktime(args.time[1]);
return ret;
}
......
......@@ -28,9 +28,6 @@ nvkm-y += nvkm/engine/disp/gv100.o
nvkm-y += nvkm/engine/disp/tu102.o
nvkm-y += nvkm/engine/disp/ga102.o
nvkm-y += nvkm/engine/disp/rootnv04.o
nvkm-y += nvkm/engine/disp/rootnv50.o
nvkm-y += nvkm/engine/disp/udisp.o
nvkm-y += nvkm/engine/disp/uconn.o
nvkm-y += nvkm/engine/disp/uoutp.o
......
......@@ -39,44 +39,6 @@ nvkm_head_find(struct nvkm_disp *disp, int id)
return NULL;
}
int
nvkm_head_mthd_scanoutpos(struct nvkm_object *object,
struct nvkm_head *head, void *data, u32 size)
{
union {
struct nv04_disp_scanoutpos_v0 v0;
} *args = data;
int ret = -ENOSYS;
nvif_ioctl(object, "head scanoutpos size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "head scanoutpos vers %d\n",
args->v0.version);
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());
} else
return ret;
return 0;
}
void
nvkm_head_del(struct nvkm_head **phead)
{
......
......@@ -33,8 +33,6 @@ struct nvkm_head {
int nvkm_head_new_(const struct nvkm_head_func *, struct nvkm_disp *, int id);
void nvkm_head_del(struct nvkm_head **);
int nvkm_head_mthd_scanoutpos(struct nvkm_object *,
struct nvkm_head *, void *, u32);
struct nvkm_head *nvkm_head_find(struct nvkm_disp *, int id);
struct nvkm_head_func {
......
......@@ -43,8 +43,6 @@ struct nvkm_disp_func {
};
int nvkm_disp_ntfy(struct nvkm_object *, u32, struct nvkm_event **);
int nv04_disp_mthd(struct nvkm_object *, u32, void *, u32);
int nv50_disp_root_mthd_(struct nvkm_object *, u32, void *, u32);
int nv50_disp_oneinit(struct nvkm_disp *);
int nv50_disp_init(struct nvkm_disp *);
......
/*
* Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include "priv.h"
#include "head.h"
#include <core/client.h>
#include <nvif/cl0046.h>
#include <nvif/unpack.h>
int
nv04_disp_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
struct nvkm_disp *disp = nvkm_disp(object->engine);
union {
struct nv04_disp_mthd_v0 v0;
} *args = data;
struct nvkm_head *head;
int id, ret = -ENOSYS;
nvif_ioctl(object, "disp mthd size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object, "disp mthd vers %d mthd %02x head %d\n",
args->v0.version, args->v0.method, args->v0.head);
mthd = args->v0.method;
id = args->v0.head;
} else
return ret;
if (!(head = nvkm_head_find(disp, id)))
return -ENXIO;
switch (mthd) {
case NV04_DISP_SCANOUTPOS:
return nvkm_head_mthd_scanoutpos(object, head, data, size);
default:
break;
}
return -EINVAL;
}
/*
* Copyright 2012 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/
#include "chan.h"
#include "head.h"
#include "ior.h"
#include "outp.h"
#include <core/client.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
union {
struct nv50_disp_mthd_v0 v0;
} *args = data;
struct nvkm_disp *disp = nvkm_udisp(object);
struct nvkm_outp *temp, *outp = NULL;
struct nvkm_head *head;
u16 type, mask = 0;
int hidx, ret = -ENOSYS;
if (mthd != NV50_DISP_MTHD)
return -EINVAL;
nvif_ioctl(object, "disp mthd size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object, "disp mthd vers %d mthd %02x head %d\n",
args->v0.version, args->v0.method, args->v0.head);
mthd = args->v0.method;
hidx = args->v0.head;
} else
return ret;
if (!(head = nvkm_head_find(disp, hidx)))
return -ENXIO;
if (mask) {
list_for_each_entry(temp, &disp->outps, head) {
if ((temp->info.hasht == type) &&
(temp->info.hashm & mask) == mask) {
outp = temp;
break;
}
}
if (outp == NULL)
return -ENXIO;
}
switch (mthd) {
case NV50_DISP_SCANOUTPOS: {
return nvkm_head_mthd_scanoutpos(object, head, data, size);
}
default:
break;
}
return -EINVAL;
}
......@@ -59,17 +59,6 @@ nvkm_udisp_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *scl
return -EINVAL;
}
static int
nvkm_udisp_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
{
struct nvkm_disp *disp = nvkm_udisp(object);
if (disp->engine.subdev.device->card_type >= NV_50)
return nv50_disp_root_mthd_(object, mthd, argv, argc);
return nv04_disp_mthd(object, mthd, argv, argc);
}
static void *
nvkm_udisp_dtor(struct nvkm_object *object)
{
......@@ -85,7 +74,6 @@ nvkm_udisp_dtor(struct nvkm_object *object)
static const struct nvkm_object_func
nvkm_udisp = {
.dtor = nvkm_udisp_dtor,
.mthd = nvkm_udisp_mthd,
.ntfy = nvkm_disp_ntfy,
.sclass = nvkm_udisp_sclass,
};
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment