Skip to contentSkip to conversation

drm/nouveau/disp/r535: Add scanline position support + head state support

PATCH In review Lyude Paul 2 participants 2 messages Apr 29 – May 9

Subsystems (4)
lore
Share & tools
lore

Lyude Paul

author maintainer
#0 lore raw

PATCH 1/1 drm/nouveau/disp/r535: Add scanline position support + head state support

That's right! It looks like this never actually got finished, something which I just noticed today when I saw this fun message spamming one of my test machine's kernel logs when enabling display debug output for nouveau:

[drm:drm_crtc_vblank_helper_get_vblank_timestamp_internal] crtc 0 : scanoutpos query failed.

So it looks like we've been falling back to DRM's core fallback for a while now, whoops.

So, while it seems that we do have the option of doing this through GSP - that doesn't seem like a great idea. Mainly because reading this from GSP would involve a lot more latency then we should have for vblank handling due to the RPC communication. So instead of implementing that, just use gv100_head_state and gv100_head_rgpos for implementing .state and .rgpos. It seems to work perfectly fine!

Fixes 9e9944449023 ("drm/nouveau/disp/r535: initial support")
Cc Ben Skeggs <[email protected]>
Cc Dave Airlie <[email protected]>
Cc Timur Tabi <[email protected]>
Cc Ben Skeggs <[email protected]>
Cc James Jones <[email protected]>
Cc Faith Ekstrand <[email protected]>
Cc Suraj Kandpal <[email protected]>
Cc Lyude Paul <[email protected]>
Cc Aaron Kling <[email protected]>
Cc Danilo Krummrich <[email protected]>
Cc Zhang Enpei <[email protected]>
Cc <[email protected]> # v6.7+
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c       | 4 ++--
 drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h        | 2 ++
 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 8 ++------
 3 files changed, 6 insertions(+), 8 deletions(-)
drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c +2 -2
index dbd984da75014..0608266188d3e 100644
@@ -253,7 +253,7 @@ gv100_head_vblank_get(struct nvkm_head *head)
 	nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000004, 0x00000004);
 }
 
-static void
+void
 gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
 {
 	struct nvkm_device *device = head->disp->engine.subdev.device;
@@ -263,7 +263,7 @@ gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
 	*hline = nvkm_rd32(device, 0x616334 + hoff) & 0x0000ffff;
 }
 
-static void
+void
 gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
 {
 	struct nvkm_device *device = head->disp->engine.subdev.device;
drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h +2 -0
index 856252bf559a4..b642729c254fe 100644
@@ -53,6 +53,8 @@ void gf119_head_rgclk(struct nvkm_head *, int);
 
 int gv100_head_cnt(struct nvkm_disp *, unsigned long *);
 int gv100_head_new(struct nvkm_disp *, int id);
+void gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state);
+void gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline);
 
 #define HEAD_MSG(h,l,f,a...) do {                                              \
 	struct nvkm_head *_h = (h);                                            \
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +2 -6
index 6e63df816d855..49a1eef9bdf14 100644
@@ -625,14 +625,10 @@ r535_head_vblank_get(struct nvkm_head *head)
 	nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000002);
 }
 
-static void
-r535_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
-{
-}
-
 static const struct nvkm_head_func
 r535_head = {
-	.state = r535_head_state,
+	.state = gv100_head_state,
+	.rgpos = gv100_head_rgpos,
 	.vblank_get = r535_head_vblank_get,
 	.vblank_put = r535_head_vblank_put,
 };

base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731

Signature · 1 line
2.54.0
maintainer Reviewed-by on v1 1/1
#1 lore raw
Quoted 10 lines · Lyude Paul

That's right! It looks like this never actually got finished, something which I just noticed today when I saw this fun message spamming one of my test machine's kernel logs when enabling display debug output for nouveau:

[drm:drm_crtc_vblank_helper_get_vblank_timestamp_internal] crtc 0 : scanoutpos query failed.

So it looks like we've been falling back to DRM's core fallback for a while now, whoops.

Quoted 6 lines

So, while it seems that we do have the option of doing this through GSP - that doesn't seem like a great idea. Mainly because reading this from GSP would involve a lot more latency then we should have for vblank handling due to the RPC communication. So instead of implementing that, just use gv100_head_state and gv100_head_rgpos for implementing .state and .rgpos. It seems to work perfectly fine!

Does the open gpu module do this at all, I'm just mildly worried that blackwell might have moved stuff,

If you can confirm by looking at open-gpu.

Dave.

Quoted 82 lines
Fixes 9e9944449023 ("drm/nouveau/disp/r535: initial support")
Cc Ben Skeggs <[email protected]>
Cc Dave Airlie <[email protected]>
Cc Timur Tabi <[email protected]>
Cc Ben Skeggs <[email protected]>
Cc James Jones <[email protected]>
Cc Faith Ekstrand <[email protected]>
Cc Suraj Kandpal <[email protected]>
Cc Lyude Paul <[email protected]>
Cc Aaron Kling <[email protected]>
Cc Danilo Krummrich <[email protected]>
Cc Zhang Enpei <[email protected]>
Cc <[email protected]> # v6.7+
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c       | 4 ++--
 drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h        | 2 ++
 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c | 8 ++------
 3 files changed, 6 insertions(+), 8 deletions(-)
drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c +2 -2
index dbd984da75014..0608266188d3e 100644
@@ -253,7 +253,7 @@ gv100_head_vblank_get(struct nvkm_head *head)
        nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000004, 0x00000004);
 }
 
-static void
+void
 gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
 {
        struct nvkm_device *device = head->disp->engine.subdev.device;
@@ -263,7 +263,7 @@ gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
        *hline = nvkm_rd32(device, 0x616334 + hoff) & 0x0000ffff;
 }
 
-static void
+void
 gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
 {
        struct nvkm_device *device = head->disp->engine.subdev.device;
drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h +2 -0
index 856252bf559a4..b642729c254fe 100644
@@ -53,6 +53,8 @@ void gf119_head_rgclk(struct nvkm_head *, int);
 
 int gv100_head_cnt(struct nvkm_disp *, unsigned long *);
 int gv100_head_new(struct nvkm_disp *, int id);
+void gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state);
+void gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline);
 
 #define HEAD_MSG(h,l,f,a...) do {                                              \
        struct nvkm_head *_h = (h);                                            \
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c +2 -6
index 6e63df816d855..49a1eef9bdf14 100644
@@ -625,14 +625,10 @@ r535_head_vblank_get(struct nvkm_head *head)
        nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000002);
 }
 
-static void
-r535_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
-{
-}
-
 static const struct nvkm_head_func
 r535_head = {
-       .state = r535_head_state,
+       .state = gv100_head_state,
+       .rgpos = gv100_head_rgpos,
        .vblank_get = r535_head_vblank_get,
        .vblank_put = r535_head_vblank_put,
 };

base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731 --
2.54.0