summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-08-02 19:29:37 +1000
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 16:09:56 +1000
commit10b461e40a5a5522fe996805a0625c9cd4e5c1a7 (patch)
tree4000f3922cb3218950fa8cc89cb85bfe1869f3c3
parent730764812ded8b53643670131219b3abbdab52c8 (diff)
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: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_backlight.c58
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c10
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c4
5 files changed, 52 insertions, 31 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index d412adc6740..4f3d1ff3e47 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -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,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) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 561d4c6677e..5308024ce56 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -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;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index ee0f0d129d3..3e9e7cc09a7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -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 */
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index 2bb316d2421..70f0232558f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -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);
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index baaecf10a58..50df52da3aa 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -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 @@ out_chan:
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);