From 5024c54b5cc6e93a8e2713f53981423d0deb60d7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 3 Aug 2011 08:52:39 +1000 Subject: drm/nva3/backlight: add suppport for newer style backlight regs Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_backlight.c | 67 +++++++++++++++++++++++++---- drivers/gpu/drm/nouveau/nouveau_reg.h | 9 ++-- 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 757a6f8..fa22b28 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -103,7 +103,8 @@ nv50_get_intensity(struct backlight_device *bd) u32 div = 1025; u32 val; - val = nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800)); + val = nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(or)); + val &= NV50_PDISP_SOR_PWM_CTL_VAL; return ((val * 100) + (div / 2)) / div; } @@ -116,8 +117,8 @@ nv50_set_intensity(struct backlight_device *bd) u32 div = 1025; u32 val = (bd->props.brightness * div) / 100; - nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800), - val | NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE); + nv_wr32(dev, NV50_PDISP_SOR_PWM_CTL(or), + NV50_PDISP_SOR_PWM_CTL_NEW | val); return 0; } @@ -128,6 +129,49 @@ static const struct backlight_ops nv50_bl_ops = { }; static int +nva3_get_intensity(struct backlight_device *bd) +{ + struct nouveau_encoder *nv_encoder = bl_get_data(bd); + struct drm_device *dev = nv_encoder->base.base.dev; + int or = nv_encoder->or; + u32 div, val; + + div = nv_rd32(dev, NV50_PDISP_SOR_PWM_DIV(or)); + val = nv_rd32(dev, 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; +} + +static int +nva3_set_intensity(struct backlight_device *bd) +{ + struct nouveau_encoder *nv_encoder = bl_get_data(bd); + struct drm_device *dev = nv_encoder->base.base.dev; + int or = nv_encoder->or; + u32 div, val; + + div = nv_rd32(dev, NV50_PDISP_SOR_PWM_DIV(or)); + val = (bd->props.brightness * div) / 100; + if (div) { + nv_wr32(dev, NV50_PDISP_SOR_PWM_CTL(or), val | + NV50_PDISP_SOR_PWM_CTL_NEW | + NVA3_PDISP_SOR_PWM_CTL_UNK); + return 0; + } + + return -EINVAL; +} + +static const struct backlight_ops nva3_bl_ops = { + .options = BL_CORE_SUSPENDRESUME, + .get_brightness = nva3_get_intensity, + .update_status = nva3_set_intensity, +}; + +static int nv50_backlight_init(struct drm_connector *connector) { struct drm_device *dev = connector->dev; @@ -135,7 +179,7 @@ nv50_backlight_init(struct drm_connector *connector) struct nouveau_encoder *nv_encoder; struct backlight_properties props; struct backlight_device *bd; - int or; + const struct backlight_ops *ops; nv_encoder = find_encoder(connector, OUTPUT_LVDS); if (!nv_encoder) { @@ -144,21 +188,26 @@ nv50_backlight_init(struct drm_connector *connector) return -ENODEV; } - or = nv_encoder->or; - - if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800))) + if (!nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(nv_encoder->or))) return 0; + if (dev_priv->chipset <= 0xa0 || + dev_priv->chipset == 0xaa || + dev_priv->chipset == 0xac) + ops = &nv50_bl_ops; + else + ops = &nva3_bl_ops; + memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = 100; bd = backlight_device_register("nv_backlight", &connector->kdev, - nv_encoder, &nv50_bl_ops, &props); + nv_encoder, ops, &props); if (IS_ERR(bd)) return PTR_ERR(bd); dev_priv->backlight = bd; - bd->props.brightness = nv50_get_intensity(bd); + bd->props.brightness = bd->ops->get_brightness(bd); backlight_update_status(bd); return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index d9632ae..43a96b9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -826,9 +826,12 @@ #define NV50_PDISPLAY_SOR_DPMS_STATE_ACTIVE 0x00030000 #define NV50_PDISPLAY_SOR_DPMS_STATE_BLANKED 0x00080000 #define NV50_PDISPLAY_SOR_DPMS_STATE_WAIT 0x10000000 -#define NV50_PDISPLAY_SOR_BACKLIGHT 0x0061c084 -#define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 -#define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff +#define NV50_PDISP_SOR_PWM_DIV(i) (0x0061c080 + (i) * 0x800) +#define NV50_PDISP_SOR_PWM_CTL(i) (0x0061c084 + (i) * 0x800) +#define NV50_PDISP_SOR_PWM_CTL_NEW 0x80000000 +#define NVA3_PDISP_SOR_PWM_CTL_UNK 0x40000000 +#define NV50_PDISP_SOR_PWM_CTL_VAL 0x000007ff +#define NVA3_PDISP_SOR_PWM_CTL_VAL 0x00ffffff #define NV50_SOR_DP_CTRL(i, l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) #define NV50_SOR_DP_CTRL_ENABLED 0x00000001 #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 -- cgit v1.1