Skip to content

Commit 1d7c71a

Browse files
author
Ben Skeggs
committed
drm/nouveau/disp: port vblank handling to event interface
This removes the nastiness with the interactions between display and software engines when handling vblank semaphore release interrupts. Now, all the semantics are handled in one place (sw) \o/. Signed-off-by: Ben Skeggs <[email protected]>
1 parent 21a5ace commit 1d7c71a

File tree

19 files changed

+226
-216
lines changed

19 files changed

+226
-216
lines changed

drivers/gpu/drm/nouveau/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ nouveau-y += core/engine/copy/nvc0.o
143143
nouveau-y += core/engine/copy/nve0.o
144144
nouveau-y += core/engine/crypt/nv84.o
145145
nouveau-y += core/engine/crypt/nv98.o
146+
nouveau-y += core/engine/disp/base.o
146147
nouveau-y += core/engine/disp/nv04.o
147148
nouveau-y += core/engine/disp/nv50.o
148149
nouveau-y += core/engine/disp/nv84.o
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2013 Red Hat Inc.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+
* OTHER DEALINGS IN THE SOFTWARE.
21+
*
22+
* Authors: Ben Skeggs
23+
*/
24+
25+
#include <engine/disp.h>
26+
27+
void
28+
_nouveau_disp_dtor(struct nouveau_object *object)
29+
{
30+
struct nouveau_disp *disp = (void *)object;
31+
nouveau_event_destroy(&disp->vblank);
32+
nouveau_engine_destroy(&disp->base);
33+
}
34+
35+
int
36+
nouveau_disp_create_(struct nouveau_object *parent,
37+
struct nouveau_object *engine,
38+
struct nouveau_oclass *oclass, int heads,
39+
const char *intname, const char *extname,
40+
int length, void **pobject)
41+
{
42+
struct nouveau_disp *disp;
43+
int ret;
44+
45+
ret = nouveau_engine_create_(parent, engine, oclass, true,
46+
intname, extname, length, pobject);
47+
disp = *pobject;
48+
if (ret)
49+
return ret;
50+
51+
return nouveau_event_create(heads, &disp->vblank);
52+
}

drivers/gpu/drm/nouveau/core/engine/disp/nv04.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*/
2424

2525
#include <engine/disp.h>
26+
27+
#include <core/event.h>
2628
#include <core/class.h>
2729

2830
struct nv04_disp_priv {
@@ -35,12 +37,20 @@ nv04_disp_sclass[] = {
3537
{},
3638
};
3739

40+
/*******************************************************************************
41+
* Display engine implementation
42+
******************************************************************************/
43+
44+
static void
45+
nv04_disp_vblank_enable(struct nouveau_event *event, int head)
46+
{
47+
nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000001);
48+
}
49+
3850
static void
39-
nv04_disp_intr_vblank(struct nv04_disp_priv *priv, int crtc)
51+
nv04_disp_vblank_disable(struct nouveau_event *event, int head)
4052
{
41-
struct nouveau_disp *disp = &priv->base;
42-
if (disp->vblank.notify)
43-
disp->vblank.notify(disp->vblank.data, crtc);
53+
nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000000);
4454
}
4555

4656
static void
@@ -51,32 +61,35 @@ nv04_disp_intr(struct nouveau_subdev *subdev)
5161
u32 crtc1 = nv_rd32(priv, 0x602100);
5262

5363
if (crtc0 & 0x00000001) {
54-
nv04_disp_intr_vblank(priv, 0);
64+
nouveau_event_trigger(priv->base.vblank, 0);
5565
nv_wr32(priv, 0x600100, 0x00000001);
5666
}
5767

5868
if (crtc1 & 0x00000001) {
59-
nv04_disp_intr_vblank(priv, 1);
69+
nouveau_event_trigger(priv->base.vblank, 1);
6070
nv_wr32(priv, 0x602100, 0x00000001);
6171
}
6272
}
6373

6474
static int
6575
nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
66-
struct nouveau_oclass *oclass, void *data, u32 size,
67-
struct nouveau_object **pobject)
76+
struct nouveau_oclass *oclass, void *data, u32 size,
77+
struct nouveau_object **pobject)
6878
{
6979
struct nv04_disp_priv *priv;
7080
int ret;
7181

72-
ret = nouveau_disp_create(parent, engine, oclass, "DISPLAY",
82+
ret = nouveau_disp_create(parent, engine, oclass, 2, "DISPLAY",
7383
"display", &priv);
7484
*pobject = nv_object(priv);
7585
if (ret)
7686
return ret;
7787

7888
nv_engine(priv)->sclass = nv04_disp_sclass;
7989
nv_subdev(priv)->intr = nv04_disp_intr;
90+
priv->base.vblank->priv = priv;
91+
priv->base.vblank->enable = nv04_disp_vblank_enable;
92+
priv->base.vblank->disable = nv04_disp_vblank_disable;
8093
return 0;
8194
}
8295

drivers/gpu/drm/nouveau/core/engine/disp/nv50.c

Lines changed: 18 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <core/handle.h>
2828
#include <core/class.h>
2929

30-
#include <engine/software.h>
3130
#include <engine/disp.h>
3231

3332
#include <subdev/bios.h>
@@ -37,7 +36,6 @@
3736
#include <subdev/bios/pll.h>
3837
#include <subdev/timer.h>
3938
#include <subdev/fb.h>
40-
#include <subdev/bar.h>
4139
#include <subdev/clock.h>
4240

4341
#include "nv50.h"
@@ -543,6 +541,18 @@ nv50_disp_curs_ofuncs = {
543541
* Base display object
544542
******************************************************************************/
545543

544+
static void
545+
nv50_disp_base_vblank_enable(struct nouveau_event *event, int head)
546+
{
547+
nv_mask(event->priv, 0x61002c, (1 << head), (1 << head));
548+
}
549+
550+
static void
551+
nv50_disp_base_vblank_disable(struct nouveau_event *event, int head)
552+
{
553+
nv_mask(event->priv, 0x61002c, (1 << head), (0 << head));
554+
}
555+
546556
static int
547557
nv50_disp_base_ctor(struct nouveau_object *parent,
548558
struct nouveau_object *engine,
@@ -559,6 +569,9 @@ nv50_disp_base_ctor(struct nouveau_object *parent,
559569
if (ret)
560570
return ret;
561571

572+
priv->base.vblank->priv = priv;
573+
priv->base.vblank->enable = nv50_disp_base_vblank_enable;
574+
priv->base.vblank->disable = nv50_disp_base_vblank_disable;
562575
return nouveau_ramht_new(parent, parent, 0x1000, 0, &base->ramht);
563576
}
564577

@@ -756,50 +769,6 @@ nv50_disp_intr_error(struct nv50_disp_priv *priv)
756769
}
757770
}
758771

759-
static void
760-
nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
761-
{
762-
struct nouveau_bar *bar = nouveau_bar(priv);
763-
struct nouveau_disp *disp = &priv->base;
764-
struct nouveau_software_chan *chan, *temp;
765-
unsigned long flags;
766-
767-
spin_lock_irqsave(&disp->vblank.lock, flags);
768-
list_for_each_entry_safe(chan, temp, &disp->vblank.list, vblank.head) {
769-
if (chan->vblank.crtc != crtc)
770-
continue;
771-
772-
if (nv_device(priv)->chipset >= 0xc0) {
773-
nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
774-
bar->flush(bar);
775-
nv_wr32(priv, 0x06000c,
776-
upper_32_bits(chan->vblank.offset));
777-
nv_wr32(priv, 0x060010,
778-
lower_32_bits(chan->vblank.offset));
779-
nv_wr32(priv, 0x060014, chan->vblank.value);
780-
} else {
781-
nv_wr32(priv, 0x001704, chan->vblank.channel);
782-
nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
783-
bar->flush(bar);
784-
if (nv_device(priv)->chipset == 0x50) {
785-
nv_wr32(priv, 0x001570, chan->vblank.offset);
786-
nv_wr32(priv, 0x001574, chan->vblank.value);
787-
} else {
788-
nv_wr32(priv, 0x060010, chan->vblank.offset);
789-
nv_wr32(priv, 0x060014, chan->vblank.value);
790-
}
791-
}
792-
793-
list_del(&chan->vblank.head);
794-
if (disp->vblank.put)
795-
disp->vblank.put(disp->vblank.data, crtc);
796-
}
797-
spin_unlock_irqrestore(&disp->vblank.lock, flags);
798-
799-
if (disp->vblank.notify)
800-
disp->vblank.notify(disp->vblank.data, crtc);
801-
}
802-
803772
static u16
804773
exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl,
805774
struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
@@ -1201,13 +1170,13 @@ nv50_disp_intr(struct nouveau_subdev *subdev)
12011170
}
12021171

12031172
if (intr1 & 0x00000004) {
1204-
nv50_disp_intr_vblank(priv, 0);
1173+
nouveau_event_trigger(priv->base.vblank, 0);
12051174
nv_wr32(priv, 0x610024, 0x00000004);
12061175
intr1 &= ~0x00000004;
12071176
}
12081177

12091178
if (intr1 & 0x00000008) {
1210-
nv50_disp_intr_vblank(priv, 1);
1179+
nouveau_event_trigger(priv->base.vblank, 1);
12111180
nv_wr32(priv, 0x610024, 0x00000008);
12121181
intr1 &= ~0x00000008;
12131182
}
@@ -1226,7 +1195,7 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
12261195
struct nv50_disp_priv *priv;
12271196
int ret;
12281197

1229-
ret = nouveau_disp_create(parent, engine, oclass, "PDISP",
1198+
ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
12301199
"display", &priv);
12311200
*pobject = nv_object(priv);
12321201
if (ret)
@@ -1242,9 +1211,6 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
12421211
priv->dac.power = nv50_dac_power;
12431212
priv->dac.sense = nv50_dac_sense;
12441213
priv->sor.power = nv50_sor_power;
1245-
1246-
INIT_LIST_HEAD(&priv->base.vblank.list);
1247-
spin_lock_init(&priv->base.vblank.lock);
12481214
return 0;
12491215
}
12501216

drivers/gpu/drm/nouveau/core/engine/disp/nv50.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
#include <core/parent.h>
55
#include <core/namedb.h>
6+
#include <core/engctx.h>
67
#include <core/ramht.h>
8+
#include <core/event.h>
79

810
#include <engine/dmaobj.h>
911
#include <engine/disp.h>

drivers/gpu/drm/nouveau/core/engine/disp/nv84.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
6363
struct nv50_disp_priv *priv;
6464
int ret;
6565

66-
ret = nouveau_disp_create(parent, engine, oclass, "PDISP",
66+
ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
6767
"display", &priv);
6868
*pobject = nv_object(priv);
6969
if (ret)
@@ -80,9 +80,6 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
8080
priv->dac.sense = nv50_dac_sense;
8181
priv->sor.power = nv50_sor_power;
8282
priv->sor.hdmi = nv84_hdmi_ctrl;
83-
84-
INIT_LIST_HEAD(&priv->base.vblank.list);
85-
spin_lock_init(&priv->base.vblank.lock);
8683
return 0;
8784
}
8885

drivers/gpu/drm/nouveau/core/engine/disp/nv94.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
6969
struct nv50_disp_priv *priv;
7070
int ret;
7171

72-
ret = nouveau_disp_create(parent, engine, oclass, "PDISP",
72+
ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
7373
"display", &priv);
7474
*pobject = nv_object(priv);
7575
if (ret)
@@ -91,9 +91,6 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
9191
priv->sor.dp_train_fini = nv94_sor_dp_train_fini;
9292
priv->sor.dp_lnkctl = nv94_sor_dp_lnkctl;
9393
priv->sor.dp_drvctl = nv94_sor_dp_drvctl;
94-
95-
INIT_LIST_HEAD(&priv->base.vblank.list);
96-
spin_lock_init(&priv->base.vblank.lock);
9794
return 0;
9895
}
9996

drivers/gpu/drm/nouveau/core/engine/disp/nva0.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
5353
struct nv50_disp_priv *priv;
5454
int ret;
5555

56-
ret = nouveau_disp_create(parent, engine, oclass, "PDISP",
56+
ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
5757
"display", &priv);
5858
*pobject = nv_object(priv);
5959
if (ret)
@@ -70,9 +70,6 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
7070
priv->dac.sense = nv50_dac_sense;
7171
priv->sor.power = nv50_sor_power;
7272
priv->sor.hdmi = nv84_hdmi_ctrl;
73-
74-
INIT_LIST_HEAD(&priv->base.vblank.list);
75-
spin_lock_init(&priv->base.vblank.lock);
7673
return 0;
7774
}
7875

drivers/gpu/drm/nouveau/core/engine/disp/nva3.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
7070
struct nv50_disp_priv *priv;
7171
int ret;
7272

73-
ret = nouveau_disp_create(parent, engine, oclass, "PDISP",
73+
ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
7474
"display", &priv);
7575
*pobject = nv_object(priv);
7676
if (ret)
@@ -93,9 +93,6 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
9393
priv->sor.dp_train_fini = nv94_sor_dp_train_fini;
9494
priv->sor.dp_lnkctl = nv94_sor_dp_lnkctl;
9595
priv->sor.dp_drvctl = nv94_sor_dp_drvctl;
96-
97-
INIT_LIST_HEAD(&priv->base.vblank.list);
98-
spin_lock_init(&priv->base.vblank.lock);
9996
return 0;
10097
}
10198

0 commit comments

Comments
 (0)