Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10b461e4 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv50/backlight: take the sor into account when bashing regs



I'm sure that out there somewhere, someone will need this.  We currently
haven't seen an example of LVDS being on a non-0 SOR so far though.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 73076481
Loading
Loading
Loading
Loading
+40 −18
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "nouveau_drv.h"
#include "nouveau_drm.h"
#include "nouveau_reg.h"
#include "nouveau_encoder.h"

static int
nv40_get_intensity(struct backlight_device *bd)
@@ -96,18 +97,22 @@ nv40_backlight_init(struct drm_connector *connector)
static int
nv50_get_intensity(struct backlight_device *bd)
{
	struct drm_device *dev = bl_get_data(bd);
	struct nouveau_encoder *nv_encoder = bl_get_data(bd);
	struct drm_device *dev = nv_encoder->base.base.dev;
	int or = nv_encoder->or;

	return nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT);
	return nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800));
}

static int
nv50_set_intensity(struct backlight_device *bd)
{
	struct drm_device *dev = bl_get_data(bd);
	struct nouveau_encoder *nv_encoder = bl_get_data(bd);
	struct drm_device *dev = nv_encoder->base.base.dev;
	int val = bd->props.brightness;
	int or = nv_encoder->or;

	nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT,
	nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800),
		val | NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE);
	return 0;
}
@@ -123,17 +128,28 @@ nv50_backlight_init(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_encoder *nv_encoder;
	struct backlight_properties props;
	struct backlight_device *bd;
	int or;

	nv_encoder = find_encoder(connector, OUTPUT_LVDS);
	if (!nv_encoder) {
		nv_encoder = find_encoder(connector, OUTPUT_DP);
		if (!nv_encoder)
			return -ENODEV;
	}

	or = nv_encoder->or;

	if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT))
	if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800)))
		return 0;

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_RAW;
	props.max_brightness = 1025;
	bd = backlight_device_register("nv_backlight", &connector->kdev, dev,
				       &nv50_bl_ops, &props);
	bd = backlight_device_register("nv_backlight", &connector->kdev,
				       nv_encoder, &nv50_bl_ops, &props);
	if (IS_ERR(bd))
		return PTR_ERR(bd);

@@ -144,10 +160,10 @@ nv50_backlight_init(struct drm_connector *connector)
}

int
nouveau_backlight_init(struct drm_connector *connector)
nouveau_backlight_init(struct drm_device *dev)
{
	struct drm_device *dev = connector->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct drm_connector *connector;

#ifdef CONFIG_ACPI
	if (acpi_video_backlight_support()) {
@@ -157,6 +173,11 @@ nouveau_backlight_init(struct drm_connector *connector)
	}
#endif

	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
		    connector->connector_type != DRM_MODE_CONNECTOR_eDP)
			continue;

		switch (dev_priv->card_type) {
		case NV_40:
			return nv40_backlight_init(connector);
@@ -165,14 +186,15 @@ nouveau_backlight_init(struct drm_connector *connector)
		default:
			break;
		}
	}


	return 0;
}

void
nouveau_backlight_exit(struct drm_connector *connector)
nouveau_backlight_exit(struct drm_device *dev)
{
	struct drm_device *dev = connector->dev;
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	if (dev_priv->backlight) {
+1 −9
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@

static void nouveau_connector_hotplug(void *, int);

static struct nouveau_encoder *
struct nouveau_encoder *
find_encoder(struct drm_connector *connector, int type)
{
	struct drm_device *dev = connector->dev;
@@ -116,10 +116,6 @@ nouveau_connector_destroy(struct drm_connector *connector)
				      nouveau_connector_hotplug, connector);
	}

	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
	    connector->connector_type == DRM_MODE_CONNECTOR_eDP)
		nouveau_backlight_exit(connector);

	kfree(nv_connector->edid);
	drm_sysfs_connector_remove(connector);
	drm_connector_cleanup(connector);
@@ -901,10 +897,6 @@ nouveau_connector_create(struct drm_device *dev, int index)

	drm_sysfs_connector_add(connector);

	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
	    connector->connector_type == DRM_MODE_CONNECTOR_eDP)
		nouveau_backlight_init(connector);

	dcb->drm = connector;
	return dcb->drm;

+4 −4
Original line number Diff line number Diff line
@@ -1054,15 +1054,15 @@ static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector

/* nouveau_backlight.c */
#ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT
extern int nouveau_backlight_init(struct drm_connector *);
extern void nouveau_backlight_exit(struct drm_connector *);
extern int nouveau_backlight_init(struct drm_device *);
extern void nouveau_backlight_exit(struct drm_device *);
#else
static inline int nouveau_backlight_init(struct drm_connector *dev)
static inline int nouveau_backlight_init(struct drm_device *dev)
{
	return 0;
}

static inline void nouveau_backlight_exit(struct drm_connector *dev) { }
static inline void nouveau_backlight_exit(struct drm_device *dev) { }
#endif

/* nouveau_bios.c */
+3 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ struct nouveau_encoder {
	};
};

struct nouveau_encoder *
find_encoder(struct drm_connector *connector, int type);

static inline struct nouveau_encoder *nouveau_encoder(struct drm_encoder *enc)
{
	struct drm_encoder_slave *slave = to_encoder_slave(enc);
+4 −0
Original line number Diff line number Diff line
@@ -728,6 +728,8 @@ nouveau_card_init(struct drm_device *dev)
	if (ret)
		goto out_irq;

	nouveau_backlight_init(dev);

	if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
		ret = nouveau_fence_init(dev);
		if (ret)
@@ -757,6 +759,7 @@ nouveau_card_init(struct drm_device *dev)
out_fence:
	nouveau_fence_fini(dev);
out_disp:
	nouveau_backlight_exit(dev);
	engine->display.destroy(dev);
out_irq:
	nouveau_irq_fini(dev);
@@ -817,6 +820,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
		nouveau_fence_fini(dev);
	}

	nouveau_backlight_exit(dev);
	engine->display.destroy(dev);
	drm_mode_config_cleanup(dev);