Skip to content

Commit

Permalink
drm/nouveau/disp: add output backlight control methods
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
Ben Skeggs authored and Lyude Paul committed Sep 19, 2023
1 parent 422f6d8 commit 2274ce7
Show file tree
Hide file tree
Showing 22 changed files with 233 additions and 81 deletions.
17 changes: 17 additions & 0 deletions drivers/gpu/drm/nouveau/include/nvif/if0012.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/nouveau/include/nvif/outp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
90 changes: 9 additions & 81 deletions drivers/gpu/drm/nouveau/nouveau_backlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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;

Expand Down Expand Up @@ -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;
}

Expand Down
27 changes: 27 additions & 0 deletions drivers/gpu/drm/nouveau/nvif/outp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/g84.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/g94.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/gk104.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/gm200.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/gp100.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
38 changes: 38 additions & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/gt215.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp89.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 2274ce7

Please sign in to comment.