Skip to content

Commit

Permalink
drm/nv50/backlight: take the sor into account when bashing regs
Browse files Browse the repository at this point in the history
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: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Sep 20, 2011
1 parent 7307648 commit 10b461e
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 31 deletions.
58 changes: 40 additions & 18 deletions drivers/gpu/drm/nouveau/nouveau_backlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);

Expand All @@ -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()) {
Expand All @@ -157,22 +173,28 @@ nouveau_backlight_init(struct drm_connector *connector)
}
#endif

switch (dev_priv->card_type) {
case NV_40:
return nv40_backlight_init(connector);
case NV_50:
return nv50_backlight_init(connector);
default:
break;
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);
case NV_50:
return nv50_backlight_init(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) {
Expand Down
10 changes: 1 addition & 9 deletions drivers/gpu/drm/nouveau/nouveau_connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down
8 changes: 4 additions & 4 deletions drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit 10b461e

Please sign in to comment.