From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-by2nam01on0099.outbound.protection.outlook.com ([104.47.34.99]:20832 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726616AbeJAHOG (ORCPT ); Mon, 1 Oct 2018 03:14:06 -0400 From: Sasha Levin To: "stable@vger.kernel.org" , "linux-kernel@vger.kernel.org" CC: Ben Skeggs , Sasha Levin Subject: [PATCH AUTOSEL 4.18 34/65] drm/nouveau/disp/gm200-: enforce identity-mapped SOR assignment for LVDS/eDP panels Date: Mon, 1 Oct 2018 00:38:24 +0000 Message-ID: <20181001003754.146961-34-alexander.levin@microsoft.com> References: <20181001003754.146961-1-alexander.levin@microsoft.com> In-Reply-To: <20181001003754.146961-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Ben Skeggs [ Upstream commit 53b0cc46f27cfc2cadca609b503a7d92b5185a47 ] Fixes eDP backlight issues on more recent laptops. Signed-off-by: Ben Skeggs Signed-off-by: Sasha Levin --- drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c | 14 ++++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c | 15 ++++++++++++--- drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h | 1 + 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/= drm/nouveau/nvkm/engine/disp/base.c index 32fa94a9773f..cbd33e87b799 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c @@ -275,6 +275,7 @@ nvkm_disp_oneinit(struct nvkm_engine *engine) struct nvkm_outp *outp, *outt, *pair; struct nvkm_conn *conn; struct nvkm_head *head; + struct nvkm_ior *ior; struct nvbios_connE connE; struct dcb_output dcbE; u8 hpd =3D 0, ver, hdr; @@ -399,6 +400,19 @@ nvkm_disp_oneinit(struct nvkm_engine *engine) return ret; } =20 + /* Enforce identity-mapped SOR assignment for panels, which have + * certain bits (ie. backlight controls) wired to a specific SOR. + */ + list_for_each_entry(outp, &disp->outp, head) { + if (outp->conn->info.type =3D=3D DCB_CONNECTOR_LVDS || + outp->conn->info.type =3D=3D DCB_CONNECTOR_eDP) { + ior =3D nvkm_ior_find(disp, SOR, ffs(outp->info.or) - 1); + if (!WARN_ON(!ior)) + ior->identity =3D true; + outp->identity =3D true; + } + } + i =3D 0; list_for_each_entry(head, &disp->head, head) i =3D max(i, head->id + 1); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/d= rm/nouveau/nvkm/engine/disp/ior.h index e0b4e0c5704e..19911211a12a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h @@ -16,6 +16,7 @@ struct nvkm_ior { char name[8]; =20 struct list_head head; + bool identity; =20 struct nvkm_ior_state { struct nvkm_outp *outp; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c b/drivers/gpu/= drm/nouveau/nvkm/engine/disp/outp.c index bbba77ff9385..44df835e5473 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c @@ -129,17 +129,26 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user) if (proto =3D=3D UNKNOWN) return -ENOSYS; =20 + /* Deal with panels requiring identity-mapped SOR assignment. */ + if (outp->identity) { + ior =3D nvkm_ior_find(outp->disp, SOR, ffs(outp->info.or) - 1); + if (WARN_ON(!ior)) + return -ENOSPC; + return nvkm_outp_acquire_ior(outp, user, ior); + } + /* First preference is to reuse the OR that is currently armed * on HW, if any, in order to prevent unnecessary switching. */ list_for_each_entry(ior, &outp->disp->ior, head) { - if (!ior->asy.outp && ior->arm.outp =3D=3D outp) + if (!ior->identity && !ior->asy.outp && ior->arm.outp =3D=3D outp) return nvkm_outp_acquire_ior(outp, user, ior); } =20 /* Failing that, a completely unused OR is the next best thing. */ list_for_each_entry(ior, &outp->disp->ior, head) { - if (!ior->asy.outp && ior->type =3D=3D type && !ior->arm.outp && + if (!ior->identity && + !ior->asy.outp && ior->type =3D=3D type && !ior->arm.outp && (ior->func->route.set || ior->id =3D=3D __ffs(outp->info.or))) return nvkm_outp_acquire_ior(outp, user, ior); } @@ -148,7 +157,7 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user) * but will be released during the next modeset. */ list_for_each_entry(ior, &outp->disp->ior, head) { - if (!ior->asy.outp && ior->type =3D=3D type && + if (!ior->identity && !ior->asy.outp && ior->type =3D=3D type && (ior->func->route.set || ior->id =3D=3D __ffs(outp->info.or))) return nvkm_outp_acquire_ior(outp, user, ior); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h b/drivers/gpu/= drm/nouveau/nvkm/engine/disp/outp.h index 97196f802924..3f932fb39c94 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h @@ -17,6 +17,7 @@ struct nvkm_outp { =20 struct list_head head; struct nvkm_conn *conn; + bool identity; =20 /* Assembly state. */ #define NVKM_OUTP_PRIV 1 --=20 2.17.1