drm/nouveau/disp: add output backlight control methods
- 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
This commit is contained in:
parent
422f6d8a24
commit
2274ce7e36
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -105,6 +105,7 @@ ga102_sor = {
|
||||
.state = gv100_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = ga102_sor_clock,
|
||||
.bl = >215_sor_bl,
|
||||
.hdmi = &gv100_sor_hdmi,
|
||||
.dp = &ga102_sor_dp,
|
||||
.hda = &gv100_sor_hda,
|
||||
|
@ -328,6 +328,7 @@ gf119_sor = {
|
||||
.state = gf119_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = gf119_sor_clock,
|
||||
.bl = >215_sor_bl,
|
||||
.hdmi = &gf119_sor_hdmi,
|
||||
.dp = &gf119_sor_dp,
|
||||
.hda = &gf119_sor_hda,
|
||||
|
@ -115,6 +115,7 @@ gk104_sor = {
|
||||
.state = gf119_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = gf119_sor_clock,
|
||||
.bl = >215_sor_bl,
|
||||
.hdmi = &gk104_sor_hdmi,
|
||||
.dp = &gf119_sor_dp,
|
||||
.hda = &gf119_sor_hda,
|
||||
|
@ -70,6 +70,7 @@ gm107_sor = {
|
||||
.state = gf119_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = gf119_sor_clock,
|
||||
.bl = >215_sor_bl,
|
||||
.hdmi = &gk104_sor_hdmi,
|
||||
.dp = &gm107_sor_dp,
|
||||
.hda = &gf119_sor_hda,
|
||||
|
@ -147,6 +147,7 @@ gm200_sor = {
|
||||
.state = gf119_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = gf119_sor_clock,
|
||||
.bl = >215_sor_bl,
|
||||
.hdmi = &gm200_sor_hdmi,
|
||||
.dp = &gm200_sor_dp,
|
||||
.hda = &gf119_sor_hda,
|
||||
|
@ -37,6 +37,7 @@ gp100_sor = {
|
||||
.state = gf119_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = gf119_sor_clock,
|
||||
.bl = >215_sor_bl,
|
||||
.hdmi = &gm200_sor_hdmi,
|
||||
.dp = &gm200_sor_dp,
|
||||
.hda = &gf119_sor_hda,
|
||||
|
@ -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 = >215_sor_bl,
|
||||
.hdmi = >215_sor_hdmi,
|
||||
.dp = >215_sor_dp,
|
||||
.hda = >215_sor_hda,
|
||||
|
@ -212,6 +212,7 @@ gv100_sor = {
|
||||
.state = gv100_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = gf119_sor_clock,
|
||||
.bl = >215_sor_bl,
|
||||
.hdmi = &gv100_sor_hdmi,
|
||||
.dp = &gv100_sor_dp,
|
||||
.hda = &gv100_sor_hda,
|
||||
|
@ -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;
|
||||
|
@ -44,6 +44,7 @@ mcp89_sor = {
|
||||
.state = g94_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = nv50_sor_clock,
|
||||
.bl = >215_sor_bl,
|
||||
.hdmi = >215_sor_hdmi,
|
||||
.dp = &mcp89_sor_dp,
|
||||
.hda = >215_sor_hda,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 { \
|
||||
|
@ -88,6 +88,7 @@ tu102_sor = {
|
||||
.state = gv100_sor_state,
|
||||
.power = nv50_sor_power,
|
||||
.clock = gf119_sor_clock,
|
||||
.bl = >215_sor_bl,
|
||||
.hdmi = &gv100_sor_hdmi,
|
||||
.dp = &tu102_sor_dp,
|
||||
.hda = &gv100_sor_hda,
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user