Commit 2274ce7e authored by Ben Skeggs's avatar Ben Skeggs Committed by Lyude Paul
Browse files

drm/nouveau/disp: add output backlight control methods

parent 422f6d8a
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -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);

+9 −81
Original line number Diff line number Diff line
@@ -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;

	props->max_brightness = 100;

	return 0;
}

+27 −0
Original line number Diff line number Diff line
@@ -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)
{
+2 −0
Original line number Diff line number Diff line
@@ -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
Loading