aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/dispnv50/head.c
diff options
context:
space:
mode:
authorLyude Paul <lyude@redhat.com>2019-09-13 18:03:52 -0400
committerBen Skeggs <bskeggs@redhat.com>2020-01-15 10:49:58 +1000
commit5ff0cb1ce2536321045b5bc33ab8fb2467750f33 (patch)
treedf1c5f88793c4242765a0786e857f7cc564d313f /drivers/gpu/drm/nouveau/dispnv50/head.c
parentdrm/nouveau/kms/nv50-: Remove nv50_mstc_best_encoder() (diff)
downloadlinux-dev-5ff0cb1ce2536321045b5bc33ab8fb2467750f33.tar.xz
linux-dev-5ff0cb1ce2536321045b5bc33ab8fb2467750f33.zip
drm/nouveau/kms/nv50-: Use less encoders by making mstos per-head
Currently, for every single MST capable DRM connector we create a set of fake encoders, one for each possible head. Unfortunately this ends up being a huge waste of encoders. While this currently isn't causing us any problems, it's extremely close to doing so. The ThinkPad P71 is a good example of this. Originally when trying to figure out why nouveau was failing to load on this laptop, I discovered it was because nouveau was creating too many encoders. This ended up being because we were mistakenly creating MST encoders for the eDP port, however we are still extremely close to hitting the encoder limit on this machine as it exposes 1 eDP port and 5 DP ports, resulting in 31 encoders. So while this fix didn't end up being necessary to fix the P71, we still need to implement this so that we avoid hitting the encoder limit for valid display configurations in the event that some machine with more connectors then this becomes available. Plus, we don't want to let good code go to waste :) So, use less encoders by only creating one MSTO per head. Then, attach each new MSTC to each MSTO which corresponds to a head that it's parent DP port is capable of using. This brings the number of encoders we register on the ThinkPad P71 from 31, down to just 15. Yay! Signed-off-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/dispnv50/head.c')
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/head.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c
index f64c87dfc1d0..d9d64602947d 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/head.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/head.c
@@ -483,7 +483,7 @@ nv50_head_func = {
.atomic_destroy_state = nv50_head_atomic_destroy_state,
};
-int
+struct nv50_head *
nv50_head_create(struct drm_device *dev, int index)
{
struct nouveau_drm *drm = nouveau_drm(dev);
@@ -495,7 +495,7 @@ nv50_head_create(struct drm_device *dev, int index)
head = kzalloc(sizeof(*head), GFP_KERNEL);
if (!head)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
head->func = disp->core->func->head;
head->base.index = index;
@@ -513,7 +513,7 @@ nv50_head_create(struct drm_device *dev, int index)
ret = nv50_curs_new(drm, head->base.index, &curs);
if (ret) {
kfree(head);
- return ret;
+ return ERR_PTR(ret);
}
crtc = &head->base.base;
@@ -528,12 +528,11 @@ nv50_head_create(struct drm_device *dev, int index)
if (head->func->olut_set) {
ret = nv50_lut_init(disp, &drm->client.mmu, &head->olut);
- if (ret)
- goto out;
+ if (ret) {
+ nv50_head_destroy(crtc);
+ return ERR_PTR(ret);
+ }
}
-out:
- if (ret)
- nv50_head_destroy(crtc);
- return ret;
+ return head;
}