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 @@ ...@@ -46,7 +46,6 @@
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/cl0002.h> #include <nvif/cl0002.h>
#include <nvif/cl5070.h>
#include <nvif/event.h> #include <nvif/event.h>
#include <nvif/if0012.h> #include <nvif/if0012.h>
#include <nvif/if0014.h> #include <nvif/if0014.h>
......
...@@ -4,26 +4,4 @@ ...@@ -4,26 +4,4 @@
#define NV04_DISP_NTFY_VBLANK 0x00 #define NV04_DISP_NTFY_VBLANK 0x00
#define NV04_DISP_NTFY_CONN 0x01 #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 #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 { ...@@ -9,4 +9,22 @@ union nvif_head_args {
__u8 pad02[6]; __u8 pad02[6];
} v0; } 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 #endif
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#include "nv50_display.h" #include "nv50_display.h"
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/cl0046.h> #include <nvif/if0013.h>
#include <nvif/event.h> #include <nvif/event.h>
#include <dispnv50/crc.h> #include <dispnv50/crc.h>
...@@ -84,24 +84,20 @@ static bool ...@@ -84,24 +84,20 @@ static bool
nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
ktime_t *stime, ktime_t *etime) 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 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; int retry = 20;
bool ret = false; bool ret = false;
args.version = 0;
do { 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) if (ret != 0)
return false; return false;
if (args.scan.vline) { if (args.vline) {
ret = true; ret = true;
break; break;
} }
...@@ -109,11 +105,10 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, ...@@ -109,11 +105,10 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
if (retry) ndelay(vblank->linedur_ns); if (retry) ndelay(vblank->linedur_ns);
} while (retry--); } while (retry--);
*hpos = args.scan.hline; *hpos = args.hline;
*vpos = calc(args.scan.vblanks, args.scan.vblanke, *vpos = calc(args.vblanks, args.vblanke, args.vtotal, args.vline);
args.scan.vtotal, args.scan.vline); if (stime) *stime = ns_to_ktime(args.time[0]);
if (stime) *stime = ns_to_ktime(args.scan.time[0]); if (etime) *etime = ns_to_ktime(args.time[1]);
if (etime) *etime = ns_to_ktime(args.scan.time[1]);
return ret; return ret;
} }
......
...@@ -28,9 +28,6 @@ nvkm-y += nvkm/engine/disp/gv100.o ...@@ -28,9 +28,6 @@ nvkm-y += nvkm/engine/disp/gv100.o
nvkm-y += nvkm/engine/disp/tu102.o nvkm-y += nvkm/engine/disp/tu102.o
nvkm-y += nvkm/engine/disp/ga102.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/udisp.o
nvkm-y += nvkm/engine/disp/uconn.o nvkm-y += nvkm/engine/disp/uconn.o
nvkm-y += nvkm/engine/disp/uoutp.o nvkm-y += nvkm/engine/disp/uoutp.o
......
...@@ -39,44 +39,6 @@ nvkm_head_find(struct nvkm_disp *disp, int id) ...@@ -39,44 +39,6 @@ nvkm_head_find(struct nvkm_disp *disp, int id)
return NULL; 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 void
nvkm_head_del(struct nvkm_head **phead) nvkm_head_del(struct nvkm_head **phead)
{ {
......
...@@ -33,8 +33,6 @@ struct nvkm_head { ...@@ -33,8 +33,6 @@ struct nvkm_head {
int nvkm_head_new_(const struct nvkm_head_func *, struct nvkm_disp *, int id); int nvkm_head_new_(const struct nvkm_head_func *, struct nvkm_disp *, int id);
void nvkm_head_del(struct nvkm_head **); 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 *nvkm_head_find(struct nvkm_disp *, int id);
struct nvkm_head_func { struct nvkm_head_func {
......
...@@ -43,8 +43,6 @@ struct nvkm_disp_func { ...@@ -43,8 +43,6 @@ struct nvkm_disp_func {
}; };
int nvkm_disp_ntfy(struct nvkm_object *, u32, struct nvkm_event **); 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_oneinit(struct nvkm_disp *);
int nv50_disp_init(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 ...@@ -59,17 +59,6 @@ nvkm_udisp_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *scl
return -EINVAL; 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 * static void *
nvkm_udisp_dtor(struct nvkm_object *object) nvkm_udisp_dtor(struct nvkm_object *object)
{ {
...@@ -85,7 +74,6 @@ nvkm_udisp_dtor(struct nvkm_object *object) ...@@ -85,7 +74,6 @@ nvkm_udisp_dtor(struct nvkm_object *object)
static const struct nvkm_object_func static const struct nvkm_object_func
nvkm_udisp = { nvkm_udisp = {
.dtor = nvkm_udisp_dtor, .dtor = nvkm_udisp_dtor,
.mthd = nvkm_udisp_mthd,
.ntfy = nvkm_disp_ntfy, .ntfy = nvkm_disp_ntfy,
.sclass = nvkm_udisp_sclass, .sclass = nvkm_udisp_sclass,
}; };
......
...@@ -24,6 +24,47 @@ ...@@ -24,6 +24,47 @@
#include <nvif/if0013.h> #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 * static void *
nvkm_uhead_dtor(struct nvkm_object *object) nvkm_uhead_dtor(struct nvkm_object *object)
{ {
...@@ -39,6 +80,7 @@ nvkm_uhead_dtor(struct nvkm_object *object) ...@@ -39,6 +80,7 @@ nvkm_uhead_dtor(struct nvkm_object *object)
static const struct nvkm_object_func static const struct nvkm_object_func
nvkm_uhead = { nvkm_uhead = {
.dtor = nvkm_uhead_dtor, .dtor = nvkm_uhead_dtor,
.mthd = nvkm_uhead_mthd,
}; };
int 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