Skip to content

Commit 9b5ca54

Browse files
author
Ben Skeggs
committed
drm/nouveau/disp/gm200-: detect and potentially disable HDA support on some SORs
Some HDA pin widgets may be disabled by BIOS, and unavailable from a SOR. Our SOR allocation policy uses this information to allocate an appropriate SOR when HDA is supported by a display. Thank you to NVIDIA for providing the information to determine this. Signed-off-by: Ben Skeggs <[email protected]>
1 parent 9f9f54e commit 9b5ca54

File tree

4 files changed

+135
-4
lines changed

4 files changed

+135
-4
lines changed

drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ gm200_sor_route_get(struct nvkm_outp *outp, int *link)
8989
}
9090

9191
static const struct nvkm_ior_func
92-
gm200_sor = {
92+
gm200_sor_hda = {
9393
.route = {
9494
.get = gm200_sor_route_get,
9595
.set = gm200_sor_route_set,
@@ -119,8 +119,42 @@ gm200_sor = {
119119
},
120120
};
121121

122+
static const struct nvkm_ior_func
123+
gm200_sor = {
124+
.route = {
125+
.get = gm200_sor_route_get,
126+
.set = gm200_sor_route_set,
127+
},
128+
.state = gf119_sor_state,
129+
.power = nv50_sor_power,
130+
.clock = gf119_sor_clock,
131+
.hdmi = {
132+
.ctrl = gk104_hdmi_ctrl,
133+
.scdc = gm200_hdmi_scdc,
134+
},
135+
.dp = {
136+
.lanes = { 0, 1, 2, 3 },
137+
.links = gf119_sor_dp_links,
138+
.power = g94_sor_dp_power,
139+
.pattern = gm107_sor_dp_pattern,
140+
.drive = gm200_sor_dp_drive,
141+
.vcpi = gf119_sor_dp_vcpi,
142+
.audio = gf119_sor_dp_audio,
143+
.audio_sym = gf119_sor_dp_audio_sym,
144+
.watermark = gf119_sor_dp_watermark,
145+
},
146+
};
147+
122148
int
123149
gm200_sor_new(struct nvkm_disp *disp, int id)
124150
{
151+
struct nvkm_device *device = disp->engine.subdev.device;
152+
u32 hda;
153+
154+
if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
155+
hda = nvkm_rd32(device, 0x101034);
156+
157+
if (hda & BIT(id))
158+
return nvkm_ior_new_(&gm200_sor_hda, disp, SOR, id);
125159
return nvkm_ior_new_(&gm200_sor, disp, SOR, id);
126160
}

drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include "ior.h"
2323

2424
static const struct nvkm_ior_func
25-
gp100_sor = {
25+
gp100_sor_hda = {
2626
.route = {
2727
.get = gm200_sor_route_get,
2828
.set = gm200_sor_route_set,
@@ -52,8 +52,42 @@ gp100_sor = {
5252
},
5353
};
5454

55+
static const struct nvkm_ior_func
56+
gp100_sor = {
57+
.route = {
58+
.get = gm200_sor_route_get,
59+
.set = gm200_sor_route_set,
60+
},
61+
.state = gf119_sor_state,
62+
.power = nv50_sor_power,
63+
.clock = gf119_sor_clock,
64+
.hdmi = {
65+
.ctrl = gk104_hdmi_ctrl,
66+
.scdc = gm200_hdmi_scdc,
67+
},
68+
.dp = {
69+
.lanes = { 0, 1, 2, 3 },
70+
.links = gf119_sor_dp_links,
71+
.power = g94_sor_dp_power,
72+
.pattern = gm107_sor_dp_pattern,
73+
.drive = gm200_sor_dp_drive,
74+
.vcpi = gf119_sor_dp_vcpi,
75+
.audio = gf119_sor_dp_audio,
76+
.audio_sym = gf119_sor_dp_audio_sym,
77+
.watermark = gf119_sor_dp_watermark,
78+
},
79+
};
80+
5581
int
5682
gp100_sor_new(struct nvkm_disp *disp, int id)
5783
{
84+
struct nvkm_device *device = disp->engine.subdev.device;
85+
u32 hda;
86+
87+
if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
88+
hda = nvkm_rd32(device, 0x10ebb0) >> 8;
89+
90+
if (hda & BIT(id))
91+
return nvkm_ior_new_(&gp100_sor_hda, disp, SOR, id);
5892
return nvkm_ior_new_(&gp100_sor, disp, SOR, id);
5993
}

drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ gv100_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
7878
}
7979

8080
static const struct nvkm_ior_func
81-
gv100_sor = {
81+
gv100_sor_hda = {
8282
.route = {
8383
.get = gm200_sor_route_get,
8484
.set = gm200_sor_route_set,
@@ -107,9 +107,42 @@ gv100_sor = {
107107
},
108108
};
109109

110+
static const struct nvkm_ior_func
111+
gv100_sor = {
112+
.route = {
113+
.get = gm200_sor_route_get,
114+
.set = gm200_sor_route_set,
115+
},
116+
.state = gv100_sor_state,
117+
.power = nv50_sor_power,
118+
.clock = gf119_sor_clock,
119+
.hdmi = {
120+
.ctrl = gv100_hdmi_ctrl,
121+
.scdc = gm200_hdmi_scdc,
122+
},
123+
.dp = {
124+
.lanes = { 0, 1, 2, 3 },
125+
.links = gf119_sor_dp_links,
126+
.power = g94_sor_dp_power,
127+
.pattern = gm107_sor_dp_pattern,
128+
.drive = gm200_sor_dp_drive,
129+
.audio = gv100_sor_dp_audio,
130+
.audio_sym = gv100_sor_dp_audio_sym,
131+
.watermark = gv100_sor_dp_watermark,
132+
},
133+
};
134+
110135
int
111136
gv100_sor_new(struct nvkm_disp *disp, int id)
112137
{
138+
struct nvkm_device *device = disp->engine.subdev.device;
139+
u32 hda;
140+
141+
if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
142+
hda = nvkm_rd32(device, 0x118fb0) >> 8;
143+
144+
if (hda & BIT(id))
145+
return nvkm_ior_new_(&gv100_sor_hda, disp, SOR, id);
113146
return nvkm_ior_new_(&gv100_sor, disp, SOR, id);
114147
}
115148

drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ tu102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
6262
}
6363

6464
static const struct nvkm_ior_func
65-
tu102_sor = {
65+
tu102_sor_hda = {
6666
.route = {
6767
.get = gm200_sor_route_get,
6868
.set = gm200_sor_route_set,
@@ -92,8 +92,38 @@ tu102_sor = {
9292
},
9393
};
9494

95+
static const struct nvkm_ior_func
96+
tu102_sor = {
97+
.route = {
98+
.get = gm200_sor_route_get,
99+
.set = gm200_sor_route_set,
100+
},
101+
.state = gv100_sor_state,
102+
.power = nv50_sor_power,
103+
.clock = gf119_sor_clock,
104+
.hdmi = {
105+
.ctrl = gv100_hdmi_ctrl,
106+
.scdc = gm200_hdmi_scdc,
107+
},
108+
.dp = {
109+
.lanes = { 0, 1, 2, 3 },
110+
.links = tu102_sor_dp_links,
111+
.power = g94_sor_dp_power,
112+
.pattern = gm107_sor_dp_pattern,
113+
.drive = gm200_sor_dp_drive,
114+
.vcpi = tu102_sor_dp_vcpi,
115+
.audio = gv100_sor_dp_audio,
116+
.audio_sym = gv100_sor_dp_audio_sym,
117+
.watermark = gv100_sor_dp_watermark,
118+
},
119+
};
120+
95121
int
96122
tu102_sor_new(struct nvkm_disp *disp, int id)
97123
{
124+
struct nvkm_device *device = disp->engine.subdev.device;
125+
u32 hda = nvkm_rd32(device, 0x08a15c);
126+
if (hda & BIT(id))
127+
return nvkm_ior_new_(&tu102_sor_hda, disp, SOR, id);
98128
return nvkm_ior_new_(&tu102_sor, disp, SOR, id);
99129
}

0 commit comments

Comments
 (0)