drm/nouveau/disp: add output backlight control methods
authorBen Skeggs <bskeggs@redhat.com>
Tue, 19 Sep 2023 21:56:18 +0000 (17:56 -0400)
committerLyude Paul <lyude@redhat.com>
Tue, 19 Sep 2023 22:22:06 +0000 (18:22 -0400)
- preparation for GSP-RM

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Acked-by: Danilo Krummrich <me@dakr.org>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230919220442.202488-24-lyude@redhat.com
22 files changed:
drivers/gpu/drm/nouveau/include/nvif/if0012.h
drivers/gpu/drm/nouveau/include/nvif/outp.h
drivers/gpu/drm/nouveau/nouveau_backlight.c
drivers/gpu/drm/nouveau/nvif/outp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.h
drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c

index 230084d..f878784 100644 (file)
@@ -21,6 +21,9 @@ union nvif_outp_args {
 
 #define NVIF_OUTP_V0_LOAD_DETECT   0x20
 
+#define NVIF_OUTP_V0_BL_GET        0x30
+#define NVIF_OUTP_V0_BL_SET        0x31
+
 #define NVIF_OUTP_V0_HDMI          0x50
 
 #define NVIF_OUTP_V0_INFOFRAME     0x60
@@ -118,6 +121,20 @@ union nvif_outp_release_args {
        } vn;
 };
 
+union nvif_outp_bl_get_args {
+       struct nvif_outp_bl_get_v0 {
+               __u8  version;
+               __u8  level;
+       } v0;
+};
+
+union nvif_outp_bl_set_args {
+       struct nvif_outp_bl_set_v0 {
+               __u8  version;
+               __u8  level;
+       } v0;
+};
+
 union nvif_outp_hdmi_args {
        struct nvif_outp_hdmi_v0 {
                __u8 version;
index ea60d41..ef63d22 100644 (file)
@@ -47,6 +47,9 @@ nvif_outp_acquired(struct nvif_outp *outp)
        return outp->or.id >= 0;
 }
 
+int nvif_outp_bl_get(struct nvif_outp *);
+int nvif_outp_bl_set(struct nvif_outp *, int level);
+
 int nvif_outp_hdmi(struct nvif_outp *, int head, bool enable, u8 max_ac_packet, u8 rekey, u32 khz,
                   bool scdc, bool scdc_scrambling, bool scdc_low_rates);
 
index 91b5ecc..d474421 100644 (file)
@@ -109,42 +109,6 @@ nv40_backlight_init(struct nouveau_encoder *encoder,
        return 0;
 }
 
-static int
-nv50_get_intensity(struct backlight_device *bd)
-{
-       struct nouveau_encoder *nv_encoder = bl_get_data(bd);
-       struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
-       struct nvif_object *device = &drm->client.device.object;
-       int or = ffs(nv_encoder->dcb->or) - 1;
-       u32 div = 1025;
-       u32 val;
-
-       val  = nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(or));
-       val &= NV50_PDISP_SOR_PWM_CTL_VAL;
-       return ((val * 100) + (div / 2)) / div;
-}
-
-static int
-nv50_set_intensity(struct backlight_device *bd)
-{
-       struct nouveau_encoder *nv_encoder = bl_get_data(bd);
-       struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
-       struct nvif_object *device = &drm->client.device.object;
-       int or = ffs(nv_encoder->dcb->or) - 1;
-       u32 div = 1025;
-       u32 val = (bd->props.brightness * div) / 100;
-
-       nvif_wr32(device, NV50_PDISP_SOR_PWM_CTL(or),
-                 NV50_PDISP_SOR_PWM_CTL_NEW | val);
-       return 0;
-}
-
-static const struct backlight_ops nv50_bl_ops = {
-       .options = BL_CORE_SUSPENDRESUME,
-       .get_brightness = nv50_get_intensity,
-       .update_status = nv50_set_intensity,
-};
-
 /*
  * eDP brightness callbacks need to happen under lock, since we need to
  * enable/disable the backlight ourselves for modesets
@@ -238,53 +202,25 @@ static const struct backlight_ops nv50_edp_bl_ops = {
 };
 
 static int
-nva3_get_intensity(struct backlight_device *bd)
+nv50_get_intensity(struct backlight_device *bd)
 {
        struct nouveau_encoder *nv_encoder = bl_get_data(bd);
-       struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
-       struct nvif_object *device = &drm->client.device.object;
-       int or = ffs(nv_encoder->dcb->or) - 1;
-       u32 div, val;
 
-       div  = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
-       val  = nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(or));
-       val &= NVA3_PDISP_SOR_PWM_CTL_VAL;
-       if (div && div >= val)
-               return ((val * 100) + (div / 2)) / div;
-
-       return 100;
+       return nvif_outp_bl_get(&nv_encoder->outp);
 }
 
 static int
-nva3_set_intensity(struct backlight_device *bd)
+nv50_set_intensity(struct backlight_device *bd)
 {
        struct nouveau_encoder *nv_encoder = bl_get_data(bd);
-       struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
-       struct nvif_object *device = &drm->client.device.object;
-       int or = ffs(nv_encoder->dcb->or) - 1;
-       u32 div, val;
-
-       div = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or));
 
-       val = backlight_get_brightness(bd);
-       if (val)
-               val = (val * div) / 100;
-
-       if (div) {
-               nvif_wr32(device, NV50_PDISP_SOR_PWM_CTL(or),
-                         val |
-                         NV50_PDISP_SOR_PWM_CTL_NEW |
-                         NVA3_PDISP_SOR_PWM_CTL_UNK);
-               return 0;
-       }
-
-       return -EINVAL;
+       return nvif_outp_bl_set(&nv_encoder->outp, backlight_get_brightness(bd));
 }
 
-static const struct backlight_ops nva3_bl_ops = {
+static const struct backlight_ops nv50_bl_ops = {
        .options = BL_CORE_SUSPENDRESUME,
-       .get_brightness = nva3_get_intensity,
-       .update_status = nva3_set_intensity,
+       .get_brightness = nv50_get_intensity,
+       .update_status = nv50_set_intensity,
 };
 
 /* FIXME: perform backlight probing for eDP _before_ this, this only gets called after connector
@@ -298,13 +234,12 @@ nv50_backlight_init(struct nouveau_backlight *bl,
                    const struct backlight_ops **ops)
 {
        struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev);
-       struct nvif_object *device = &drm->client.device.object;
 
        /*
         * Note when this runs the connectors have not been probed yet,
         * so nv_conn->base.status is not set yet.
         */
-       if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(ffs(nv_encoder->dcb->or) - 1)) ||
+       if (nvif_outp_bl_get(&nv_encoder->outp) < 0 ||
            drm_helper_probe_detect(&nv_conn->base, NULL, false) != connector_status_connected)
                return -ENODEV;
 
@@ -346,15 +281,8 @@ nv50_backlight_init(struct nouveau_backlight *bl,
                }
        }
 
-       if (drm->client.device.info.chipset <= 0xa0 ||
-           drm->client.device.info.chipset == 0xaa ||
-           drm->client.device.info.chipset == 0xac)
-               *ops = &nv50_bl_ops;
-       else
-               *ops = &nva3_bl_ops;
-
+       *ops = &nv50_bl_ops;
        props->max_brightness = 100;
-
        return 0;
 }
 
index 6e1bcc2..5a3c0dd 100644 (file)
@@ -165,6 +165,33 @@ nvif_outp_acquire_lvds(struct nvif_outp *outp, bool dual, bool bpc8)
        return ret;
 }
 
+int
+nvif_outp_bl_set(struct nvif_outp *outp, int level)
+{
+       struct nvif_outp_bl_set_v0 args;
+       int ret;
+
+       args.version = 0;
+       args.level = level;
+
+       ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_BL_SET, &args, sizeof(args));
+       NVIF_ERRON(ret, &outp->object, "[BL_SET level:%d]", args.level);
+       return ret;
+}
+
+int
+nvif_outp_bl_get(struct nvif_outp *outp)
+{
+       struct nvif_outp_bl_get_v0 args;
+       int ret;
+
+       args.version = 0;
+
+       ret = nvif_object_mthd(&outp->object, NVIF_OUTP_V0_BL_GET, &args, sizeof(args));
+       NVIF_ERRON(ret, &outp->object, "[BL_GET level:%d]", args.level);
+       return ret ? ret : args.level;
+}
+
 void
 nvif_outp_release(struct nvif_outp *outp)
 {
index 3b6d58c..0e6e388 100644 (file)
@@ -812,6 +812,8 @@ nvkm_dp_func = {
        .acquire = nvkm_dp_acquire,
        .release = nvkm_dp_release,
        .disable = nvkm_dp_disable,
+       .bl.get = nvkm_outp_bl_get,
+       .bl.set = nvkm_outp_bl_set,
 };
 
 int
index 23ae451..1be97a6 100644 (file)
@@ -124,6 +124,7 @@ g84_sor = {
        .state = nv50_sor_state,
        .power = nv50_sor_power,
        .clock = nv50_sor_clock,
+       .bl = &nv50_sor_bl,
        .hdmi = &g84_sor_hdmi,
 };
 
index 67ef889..843a266 100644 (file)
@@ -295,6 +295,7 @@ g94_sor = {
        .clock = nv50_sor_clock,
        .war_2 = g94_sor_war_2,
        .war_3 = g94_sor_war_3,
+       .bl = &nv50_sor_bl,
        .hdmi = &g84_sor_hdmi,
        .dp = &g94_sor_dp,
 };
index 52099b7..efe66ba 100644 (file)
@@ -105,6 +105,7 @@ ga102_sor = {
        .state = gv100_sor_state,
        .power = nv50_sor_power,
        .clock = ga102_sor_clock,
+       .bl = &gt215_sor_bl,
        .hdmi = &gv100_sor_hdmi,
        .dp = &ga102_sor_dp,
        .hda = &gv100_sor_hda,
index 937baae..b48ead3 100644 (file)
@@ -328,6 +328,7 @@ gf119_sor = {
        .state = gf119_sor_state,
        .power = nv50_sor_power,
        .clock = gf119_sor_clock,
+       .bl = &gt215_sor_bl,
        .hdmi = &gf119_sor_hdmi,
        .dp = &gf119_sor_dp,
        .hda = &gf119_sor_hda,
index 876a21a..a3e2fba 100644 (file)
@@ -115,6 +115,7 @@ gk104_sor = {
        .state = gf119_sor_state,
        .power = nv50_sor_power,
        .clock = gf119_sor_clock,
+       .bl = &gt215_sor_bl,
        .hdmi = &gk104_sor_hdmi,
        .dp = &gf119_sor_dp,
        .hda = &gf119_sor_hda,
index b4d8e86..688e123 100644 (file)
@@ -70,6 +70,7 @@ gm107_sor = {
        .state = gf119_sor_state,
        .power = nv50_sor_power,
        .clock = gf119_sor_clock,
+       .bl = &gt215_sor_bl,
        .hdmi = &gk104_sor_hdmi,
        .dp = &gm107_sor_dp,
        .hda = &gf119_sor_hda,
index 126a908..511e783 100644 (file)
@@ -147,6 +147,7 @@ gm200_sor = {
        .state = gf119_sor_state,
        .power = nv50_sor_power,
        .clock = gf119_sor_clock,
+       .bl = &gt215_sor_bl,
        .hdmi = &gm200_sor_hdmi,
        .dp = &gm200_sor_dp,
        .hda = &gf119_sor_hda,
index 7f1eb43..4070447 100644 (file)
@@ -37,6 +37,7 @@ gp100_sor = {
        .state = gf119_sor_state,
        .power = nv50_sor_power,
        .clock = gf119_sor_clock,
+       .bl = &gt215_sor_bl,
        .hdmi = &gm200_sor_hdmi,
        .dp = &gm200_sor_dp,
        .hda = &gf119_sor_hda,
index 506ffbe..6318721 100644 (file)
@@ -182,11 +182,49 @@ gt215_sor_hdmi = {
        .infoframe_vsi = gt215_sor_hdmi_infoframe_vsi,
 };
 
+static int
+gt215_sor_bl_set(struct nvkm_ior *ior, int lvl)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(ior);
+       u32 div, val;
+
+       div = nvkm_rd32(device, 0x61c080 + soff);
+       val = (lvl * div) / 100;
+       if (div)
+               nvkm_wr32(device, 0x61c084 + soff, 0xc0000000 | val);
+
+       return 0;
+}
+
+static int
+gt215_sor_bl_get(struct nvkm_ior *ior)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(ior);
+       u32 div, val;
+
+       div  = nvkm_rd32(device, 0x61c080 + soff);
+       val  = nvkm_rd32(device, 0x61c084 + soff);
+       val &= 0x00ffffff;
+       if (div && div >= val)
+               return ((val * 100) + (div / 2)) / div;
+
+       return 100;
+}
+
+const struct nvkm_ior_func_bl
+gt215_sor_bl = {
+       .get = gt215_sor_bl_get,
+       .set = gt215_sor_bl_set,
+};
+
 static const struct nvkm_ior_func
 gt215_sor = {
        .state = g94_sor_state,
        .power = nv50_sor_power,
        .clock = nv50_sor_clock,
+       .bl = &gt215_sor_bl,
        .hdmi = &gt215_sor_hdmi,
        .dp = &gt215_sor_dp,
        .hda = &gt215_sor_hda,
index 7ac59ba..e1634f7 100644 (file)
@@ -212,6 +212,7 @@ gv100_sor = {
        .state = gv100_sor_state,
        .power = nv50_sor_power,
        .clock = gf119_sor_clock,
+       .bl = &gt215_sor_bl,
        .hdmi = &gv100_sor_hdmi,
        .dp = &gv100_sor_dp,
        .hda = &gv100_sor_hda,
index f8b9d16..6e75089 100644 (file)
@@ -63,6 +63,11 @@ struct nvkm_ior_func {
        void (*war_2)(struct nvkm_ior *);
        void (*war_3)(struct nvkm_ior *);
 
+       const struct nvkm_ior_func_bl {
+               int (*get)(struct nvkm_ior *);
+               int (*set)(struct nvkm_ior *, int lvl);
+       } *bl;
+
        const struct nvkm_ior_func_hdmi {
                void (*ctrl)(struct nvkm_ior *, int head, bool enable, u8 max_ac_packet, u8 rekey);
                void (*scdc)(struct nvkm_ior *, u32 khz, bool support, bool scrambling,
@@ -123,6 +128,7 @@ int nv50_sor_cnt(struct nvkm_disp *, unsigned long *);
 void nv50_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
 void nv50_sor_power(struct nvkm_ior *, bool, bool, bool, bool, bool);
 void nv50_sor_clock(struct nvkm_ior *);
+extern const struct nvkm_ior_func_bl nv50_sor_bl;
 
 int g84_sor_new(struct nvkm_disp *, int);
 extern const struct nvkm_ior_func_hdmi g84_sor_hdmi;
@@ -139,6 +145,7 @@ void g94_sor_dp_audio_sym(struct nvkm_ior *, int, u16, u32);
 void g94_sor_dp_activesym(struct nvkm_ior *, int, u8, u8, u8, u8);
 void g94_sor_dp_watermark(struct nvkm_ior *, int, u8);
 
+extern const struct nvkm_ior_func_bl gt215_sor_bl;
 extern const struct nvkm_ior_func_hdmi gt215_sor_hdmi;
 void gt215_sor_dp_audio(struct nvkm_ior *, int, bool);
 extern const struct nvkm_ior_func_hda gt215_sor_hda;
index f96ba47..e0c5fb6 100644 (file)
@@ -44,6 +44,7 @@ mcp89_sor = {
        .state = g94_sor_state,
        .power = nv50_sor_power,
        .clock = nv50_sor_clock,
+       .bl = &gt215_sor_bl,
        .hdmi = &gt215_sor_hdmi,
        .dp = &mcp89_sor_dp,
        .hda = &gt215_sor_hda,
index a4ce605..948a46f 100644 (file)
@@ -156,6 +156,37 @@ nv50_pior_cnt(struct nvkm_disp *disp, unsigned long *pmask)
        return 3;
 }
 
+static int
+nv50_sor_bl_set(struct nvkm_ior *ior, int lvl)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(ior);
+       u32 div = 1025;
+       u32 val = (lvl * div) / 100;
+
+       nvkm_wr32(device, 0x61c084 + soff, 0x80000000 | val);
+       return 0;
+}
+
+static int
+nv50_sor_bl_get(struct nvkm_ior *ior)
+{
+       struct nvkm_device *device = ior->disp->engine.subdev.device;
+       const u32 soff = nv50_ior_base(ior);
+       u32 div = 1025;
+       u32 val;
+
+       val  = nvkm_rd32(device, 0x61c084 + soff);
+       val &= 0x000007ff;
+       return ((val * 100) + (div / 2)) / div;
+}
+
+const struct nvkm_ior_func_bl
+nv50_sor_bl = {
+       .get = nv50_sor_bl_get,
+       .set = nv50_sor_bl_set,
+};
+
 void
 nv50_sor_clock(struct nvkm_ior *sor)
 {
@@ -220,6 +251,7 @@ nv50_sor = {
        .state = nv50_sor_state,
        .power = nv50_sor_power,
        .clock = nv50_sor_clock,
+       .bl = &nv50_sor_bl,
 };
 
 static int
index 20a013f..28ec7b3 100644 (file)
@@ -209,6 +209,42 @@ nvkm_outp_acquire_or(struct nvkm_outp *outp, u8 user, bool hda)
        return nvkm_outp_acquire_hda(outp, type, user, false);
 }
 
+int
+nvkm_outp_bl_set(struct nvkm_outp *outp, int level)
+{
+       int ret;
+
+       ret = nvkm_outp_acquire_or(outp, NVKM_OUTP_PRIV, false);
+       if (ret)
+               return ret;
+
+       if (outp->ior->func->bl)
+               ret = outp->ior->func->bl->set(outp->ior, level);
+       else
+               ret = -EINVAL;
+
+       nvkm_outp_release_or(outp, NVKM_OUTP_PRIV);
+       return ret;
+}
+
+int
+nvkm_outp_bl_get(struct nvkm_outp *outp)
+{
+       int ret;
+
+       ret = nvkm_outp_acquire_or(outp, NVKM_OUTP_PRIV, false);
+       if (ret)
+               return ret;
+
+       if (outp->ior->func->bl)
+               ret = outp->ior->func->bl->get(outp->ior);
+       else
+               ret = -EINVAL;
+
+       nvkm_outp_release_or(outp, NVKM_OUTP_PRIV);
+       return ret;
+}
+
 int
 nvkm_outp_detect(struct nvkm_outp *outp)
 {
@@ -376,6 +412,8 @@ static const struct nvkm_outp_func
 nvkm_outp = {
        .detect = nvkm_outp_detect,
        .inherit = nvkm_outp_inherit,
+       .bl.get = nvkm_outp_bl_get,
+       .bl.set = nvkm_outp_bl_set,
 };
 
 int
index ab1699b..38b6b43 100644 (file)
@@ -84,6 +84,9 @@ void nvkm_outp_release(struct nvkm_outp *);
 void nvkm_outp_release_or(struct nvkm_outp *, u8 user);
 void nvkm_outp_route(struct nvkm_disp *);
 
+int nvkm_outp_bl_get(struct nvkm_outp *);
+int nvkm_outp_bl_set(struct nvkm_outp *, int level);
+
 struct nvkm_outp_func {
        void *(*dtor)(struct nvkm_outp *);
        void (*init)(struct nvkm_outp *);
@@ -96,6 +99,11 @@ struct nvkm_outp_func {
        int (*acquire)(struct nvkm_outp *);
        void (*release)(struct nvkm_outp *);
        void (*disable)(struct nvkm_outp *, struct nvkm_ior *);
+
+       struct {
+               int (*get)(struct nvkm_outp *);
+               int (*set)(struct nvkm_outp *, int level);
+       } bl;
 };
 
 #define OUTP_MSG(o,l,f,a...) do {                                              \
index f5242a6..19f5d3a 100644 (file)
@@ -88,6 +88,7 @@ tu102_sor = {
        .state = gv100_sor_state,
        .power = nv50_sor_power,
        .clock = gf119_sor_clock,
+       .bl = &gt215_sor_bl,
        .hdmi = &gv100_sor_hdmi,
        .dp = &tu102_sor_dp,
        .hda = &gv100_sor_hda,
index 40cbb4d..c177552 100644 (file)
@@ -181,6 +181,45 @@ nvkm_uoutp_mthd_acquire_lvds(struct nvkm_outp *outp, bool dual, bool bpc8)
        return 0;
 }
 
+static int
+nvkm_uoutp_mthd_bl_set(struct nvkm_outp *outp, void *argv, u32 argc)
+{
+       union nvif_outp_bl_get_args *args = argv;
+       int ret;
+
+       if (argc != sizeof(args->v0) || args->v0.version != 0)
+               return -ENOSYS;
+
+       if (outp->func->bl.set)
+               ret = outp->func->bl.set(outp, args->v0.level);
+       else
+               ret = -EINVAL;
+
+       return ret;
+}
+
+static int
+nvkm_uoutp_mthd_bl_get(struct nvkm_outp *outp, void *argv, u32 argc)
+{
+       union nvif_outp_bl_get_args *args = argv;
+       int ret;
+
+       if (argc != sizeof(args->v0) || args->v0.version != 0)
+               return -ENOSYS;
+
+       if (outp->func->bl.get) {
+               ret = outp->func->bl.get(outp);
+               if (ret >= 0) {
+                       args->v0.level = ret;
+                       ret = 0;
+               }
+       } else {
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
 static int
 nvkm_uoutp_mthd_release(struct nvkm_outp *outp, void *argv, u32 argc)
 {
@@ -388,6 +427,8 @@ nvkm_uoutp_mthd_noacquire(struct nvkm_outp *outp, u32 mthd, void *argv, u32 argc
        case NVIF_OUTP_V0_INHERIT    : return nvkm_uoutp_mthd_inherit    (outp, argv, argc);
        case NVIF_OUTP_V0_ACQUIRE    : return nvkm_uoutp_mthd_acquire    (outp, argv, argc);
        case NVIF_OUTP_V0_LOAD_DETECT: return nvkm_uoutp_mthd_load_detect(outp, argv, argc);
+       case NVIF_OUTP_V0_BL_GET     : return nvkm_uoutp_mthd_bl_get     (outp, argv, argc);
+       case NVIF_OUTP_V0_BL_SET     : return nvkm_uoutp_mthd_bl_set     (outp, argv, argc);
        case NVIF_OUTP_V0_DP_AUX_PWR : return nvkm_uoutp_mthd_dp_aux_pwr (outp, argv, argc);
        default:
                break;