summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2020-06-03 12:51:03 +1000
committerBen Skeggs <bskeggs@redhat.com>2020-06-04 14:23:21 +1000
commit9b5ca547bb8fc26c251d457ac55cc8e3d9baa6bf (patch)
tree272bf5f1a5503483783e4735719c1eb8ac55672b /drivers/gpu/drm/nouveau
parent9f9f54e887adef3dc9b62f372002c421ef4f1921 (diff)
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 <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c32
4 files changed, 135 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
index cf2075db742a..4dd7f382968e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
@@ -89,7 +89,7 @@ gm200_sor_route_get(struct nvkm_outp *outp, int *link)
}
static const struct nvkm_ior_func
-gm200_sor = {
+gm200_sor_hda = {
.route = {
.get = gm200_sor_route_get,
.set = gm200_sor_route_set,
@@ -119,8 +119,42 @@ gm200_sor = {
},
};
+static const struct nvkm_ior_func
+gm200_sor = {
+ .route = {
+ .get = gm200_sor_route_get,
+ .set = gm200_sor_route_set,
+ },
+ .state = gf119_sor_state,
+ .power = nv50_sor_power,
+ .clock = gf119_sor_clock,
+ .hdmi = {
+ .ctrl = gk104_hdmi_ctrl,
+ .scdc = gm200_hdmi_scdc,
+ },
+ .dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .vcpi = gf119_sor_dp_vcpi,
+ .audio = gf119_sor_dp_audio,
+ .audio_sym = gf119_sor_dp_audio_sym,
+ .watermark = gf119_sor_dp_watermark,
+ },
+};
+
int
gm200_sor_new(struct nvkm_disp *disp, int id)
{
+ struct nvkm_device *device = disp->engine.subdev.device;
+ u32 hda;
+
+ if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
+ hda = nvkm_rd32(device, 0x101034);
+
+ if (hda & BIT(id))
+ return nvkm_ior_new_(&gm200_sor_hda, disp, SOR, id);
return nvkm_ior_new_(&gm200_sor, disp, SOR, id);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c
index 94feb91b16d5..c54f88317a07 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgp100.c
@@ -22,7 +22,7 @@
#include "ior.h"
static const struct nvkm_ior_func
-gp100_sor = {
+gp100_sor_hda = {
.route = {
.get = gm200_sor_route_get,
.set = gm200_sor_route_set,
@@ -52,8 +52,42 @@ gp100_sor = {
},
};
+static const struct nvkm_ior_func
+gp100_sor = {
+ .route = {
+ .get = gm200_sor_route_get,
+ .set = gm200_sor_route_set,
+ },
+ .state = gf119_sor_state,
+ .power = nv50_sor_power,
+ .clock = gf119_sor_clock,
+ .hdmi = {
+ .ctrl = gk104_hdmi_ctrl,
+ .scdc = gm200_hdmi_scdc,
+ },
+ .dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .vcpi = gf119_sor_dp_vcpi,
+ .audio = gf119_sor_dp_audio,
+ .audio_sym = gf119_sor_dp_audio_sym,
+ .watermark = gf119_sor_dp_watermark,
+ },
+};
+
int
gp100_sor_new(struct nvkm_disp *disp, int id)
{
+ struct nvkm_device *device = disp->engine.subdev.device;
+ u32 hda;
+
+ if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
+ hda = nvkm_rd32(device, 0x10ebb0) >> 8;
+
+ if (hda & BIT(id))
+ return nvkm_ior_new_(&gp100_sor_hda, disp, SOR, id);
return nvkm_ior_new_(&gp100_sor, disp, SOR, id);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c
index d11a0dff10c6..4441187e8ec9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgv100.c
@@ -78,7 +78,7 @@ gv100_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
}
static const struct nvkm_ior_func
-gv100_sor = {
+gv100_sor_hda = {
.route = {
.get = gm200_sor_route_get,
.set = gm200_sor_route_set,
@@ -107,9 +107,42 @@ gv100_sor = {
},
};
+static const struct nvkm_ior_func
+gv100_sor = {
+ .route = {
+ .get = gm200_sor_route_get,
+ .set = gm200_sor_route_set,
+ },
+ .state = gv100_sor_state,
+ .power = nv50_sor_power,
+ .clock = gf119_sor_clock,
+ .hdmi = {
+ .ctrl = gv100_hdmi_ctrl,
+ .scdc = gm200_hdmi_scdc,
+ },
+ .dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .audio = gv100_sor_dp_audio,
+ .audio_sym = gv100_sor_dp_audio_sym,
+ .watermark = gv100_sor_dp_watermark,
+ },
+};
+
int
gv100_sor_new(struct nvkm_disp *disp, int id)
{
+ struct nvkm_device *device = disp->engine.subdev.device;
+ u32 hda;
+
+ if (!((hda = nvkm_rd32(device, 0x08a15c)) & 0x40000000))
+ hda = nvkm_rd32(device, 0x118fb0) >> 8;
+
+ if (hda & BIT(id))
+ return nvkm_ior_new_(&gv100_sor_hda, disp, SOR, id);
return nvkm_ior_new_(&gv100_sor, disp, SOR, id);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c
index fa6d74251237..59865a934c4b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sortu102.c
@@ -62,7 +62,7 @@ tu102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
}
static const struct nvkm_ior_func
-tu102_sor = {
+tu102_sor_hda = {
.route = {
.get = gm200_sor_route_get,
.set = gm200_sor_route_set,
@@ -92,8 +92,38 @@ tu102_sor = {
},
};
+static const struct nvkm_ior_func
+tu102_sor = {
+ .route = {
+ .get = gm200_sor_route_get,
+ .set = gm200_sor_route_set,
+ },
+ .state = gv100_sor_state,
+ .power = nv50_sor_power,
+ .clock = gf119_sor_clock,
+ .hdmi = {
+ .ctrl = gv100_hdmi_ctrl,
+ .scdc = gm200_hdmi_scdc,
+ },
+ .dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = tu102_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .vcpi = tu102_sor_dp_vcpi,
+ .audio = gv100_sor_dp_audio,
+ .audio_sym = gv100_sor_dp_audio_sym,
+ .watermark = gv100_sor_dp_watermark,
+ },
+};
+
int
tu102_sor_new(struct nvkm_disp *disp, int id)
{
+ struct nvkm_device *device = disp->engine.subdev.device;
+ u32 hda = nvkm_rd32(device, 0x08a15c);
+ if (hda & BIT(id))
+ return nvkm_ior_new_(&tu102_sor_hda, disp, SOR, id);
return nvkm_ior_new_(&tu102_sor, disp, SOR, id);
}