diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-08-02 18:52:39 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 02:10:06 -0400 |
commit | 5024c54b5cc6e93a8e2713f53981423d0deb60d7 (patch) | |
tree | 98fd9f44cfe76b4565bd5a17563bfdec21384ef8 /drivers/gpu | |
parent | 09461459e12019375dbda88f81d1fe8926ce139c (diff) |
drm/nva3/backlight: add suppport for newer style backlight regs
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_backlight.c | 67 | ||||
-rw-r--r-- | 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 757a6f87edf2..fa22b28e8777 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) | |||
103 | u32 div = 1025; | 103 | u32 div = 1025; |
104 | u32 val; | 104 | u32 val; |
105 | 105 | ||
106 | val = nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800)); | 106 | val = nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(or)); |
107 | val &= NV50_PDISP_SOR_PWM_CTL_VAL; | ||
107 | return ((val * 100) + (div / 2)) / div; | 108 | return ((val * 100) + (div / 2)) / div; |
108 | } | 109 | } |
109 | 110 | ||
@@ -116,8 +117,8 @@ nv50_set_intensity(struct backlight_device *bd) | |||
116 | u32 div = 1025; | 117 | u32 div = 1025; |
117 | u32 val = (bd->props.brightness * div) / 100; | 118 | u32 val = (bd->props.brightness * div) / 100; |
118 | 119 | ||
119 | nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800), | 120 | nv_wr32(dev, NV50_PDISP_SOR_PWM_CTL(or), |
120 | val | NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE); | 121 | NV50_PDISP_SOR_PWM_CTL_NEW | val); |
121 | return 0; | 122 | return 0; |
122 | } | 123 | } |
123 | 124 | ||
@@ -128,6 +129,49 @@ static const struct backlight_ops nv50_bl_ops = { | |||
128 | }; | 129 | }; |
129 | 130 | ||
130 | static int | 131 | static int |
132 | nva3_get_intensity(struct backlight_device *bd) | ||
133 | { | ||
134 | struct nouveau_encoder *nv_encoder = bl_get_data(bd); | ||
135 | struct drm_device *dev = nv_encoder->base.base.dev; | ||
136 | int or = nv_encoder->or; | ||
137 | u32 div, val; | ||
138 | |||
139 | div = nv_rd32(dev, NV50_PDISP_SOR_PWM_DIV(or)); | ||
140 | val = nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(or)); | ||
141 | val &= NVA3_PDISP_SOR_PWM_CTL_VAL; | ||
142 | if (div && div >= val) | ||
143 | return ((val * 100) + (div / 2)) / div; | ||
144 | |||
145 | return 100; | ||
146 | } | ||
147 | |||
148 | static int | ||
149 | nva3_set_intensity(struct backlight_device *bd) | ||
150 | { | ||
151 | struct nouveau_encoder *nv_encoder = bl_get_data(bd); | ||
152 | struct drm_device *dev = nv_encoder->base.base.dev; | ||
153 | int or = nv_encoder->or; | ||
154 | u32 div, val; | ||
155 | |||
156 | div = nv_rd32(dev, NV50_PDISP_SOR_PWM_DIV(or)); | ||
157 | val = (bd->props.brightness * div) / 100; | ||
158 | if (div) { | ||
159 | nv_wr32(dev, NV50_PDISP_SOR_PWM_CTL(or), val | | ||
160 | NV50_PDISP_SOR_PWM_CTL_NEW | | ||
161 | NVA3_PDISP_SOR_PWM_CTL_UNK); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | return -EINVAL; | ||
166 | } | ||
167 | |||
168 | static const struct backlight_ops nva3_bl_ops = { | ||
169 | .options = BL_CORE_SUSPENDRESUME, | ||
170 | .get_brightness = nva3_get_intensity, | ||
171 | .update_status = nva3_set_intensity, | ||
172 | }; | ||
173 | |||
174 | static int | ||
131 | nv50_backlight_init(struct drm_connector *connector) | 175 | nv50_backlight_init(struct drm_connector *connector) |
132 | { | 176 | { |
133 | struct drm_device *dev = connector->dev; | 177 | struct drm_device *dev = connector->dev; |
@@ -135,7 +179,7 @@ nv50_backlight_init(struct drm_connector *connector) | |||
135 | struct nouveau_encoder *nv_encoder; | 179 | struct nouveau_encoder *nv_encoder; |
136 | struct backlight_properties props; | 180 | struct backlight_properties props; |
137 | struct backlight_device *bd; | 181 | struct backlight_device *bd; |
138 | int or; | 182 | const struct backlight_ops *ops; |
139 | 183 | ||
140 | nv_encoder = find_encoder(connector, OUTPUT_LVDS); | 184 | nv_encoder = find_encoder(connector, OUTPUT_LVDS); |
141 | if (!nv_encoder) { | 185 | if (!nv_encoder) { |
@@ -144,21 +188,26 @@ nv50_backlight_init(struct drm_connector *connector) | |||
144 | return -ENODEV; | 188 | return -ENODEV; |
145 | } | 189 | } |
146 | 190 | ||
147 | or = nv_encoder->or; | 191 | if (!nv_rd32(dev, NV50_PDISP_SOR_PWM_CTL(nv_encoder->or))) |
148 | |||
149 | if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800))) | ||
150 | return 0; | 192 | return 0; |
151 | 193 | ||
194 | if (dev_priv->chipset <= 0xa0 || | ||
195 | dev_priv->chipset == 0xaa || | ||
196 | dev_priv->chipset == 0xac) | ||
197 | ops = &nv50_bl_ops; | ||
198 | else | ||
199 | ops = &nva3_bl_ops; | ||
200 | |||
152 | memset(&props, 0, sizeof(struct backlight_properties)); | 201 | memset(&props, 0, sizeof(struct backlight_properties)); |
153 | props.type = BACKLIGHT_RAW; | 202 | props.type = BACKLIGHT_RAW; |
154 | props.max_brightness = 100; | 203 | props.max_brightness = 100; |
155 | bd = backlight_device_register("nv_backlight", &connector->kdev, | 204 | bd = backlight_device_register("nv_backlight", &connector->kdev, |
156 | nv_encoder, &nv50_bl_ops, &props); | 205 | nv_encoder, ops, &props); |
157 | if (IS_ERR(bd)) | 206 | if (IS_ERR(bd)) |
158 | return PTR_ERR(bd); | 207 | return PTR_ERR(bd); |
159 | 208 | ||
160 | dev_priv->backlight = bd; | 209 | dev_priv->backlight = bd; |
161 | bd->props.brightness = nv50_get_intensity(bd); | 210 | bd->props.brightness = bd->ops->get_brightness(bd); |
162 | backlight_update_status(bd); | 211 | backlight_update_status(bd); |
163 | return 0; | 212 | return 0; |
164 | } | 213 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index d9632ae38c6c..43a96b99e180 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h | |||
@@ -826,9 +826,12 @@ | |||
826 | #define NV50_PDISPLAY_SOR_DPMS_STATE_ACTIVE 0x00030000 | 826 | #define NV50_PDISPLAY_SOR_DPMS_STATE_ACTIVE 0x00030000 |
827 | #define NV50_PDISPLAY_SOR_DPMS_STATE_BLANKED 0x00080000 | 827 | #define NV50_PDISPLAY_SOR_DPMS_STATE_BLANKED 0x00080000 |
828 | #define NV50_PDISPLAY_SOR_DPMS_STATE_WAIT 0x10000000 | 828 | #define NV50_PDISPLAY_SOR_DPMS_STATE_WAIT 0x10000000 |
829 | #define NV50_PDISPLAY_SOR_BACKLIGHT 0x0061c084 | 829 | #define NV50_PDISP_SOR_PWM_DIV(i) (0x0061c080 + (i) * 0x800) |
830 | #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE 0x80000000 | 830 | #define NV50_PDISP_SOR_PWM_CTL(i) (0x0061c084 + (i) * 0x800) |
831 | #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL 0x00000fff | 831 | #define NV50_PDISP_SOR_PWM_CTL_NEW 0x80000000 |
832 | #define NVA3_PDISP_SOR_PWM_CTL_UNK 0x40000000 | ||
833 | #define NV50_PDISP_SOR_PWM_CTL_VAL 0x000007ff | ||
834 | #define NVA3_PDISP_SOR_PWM_CTL_VAL 0x00ffffff | ||
832 | #define NV50_SOR_DP_CTRL(i, l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) | 835 | #define NV50_SOR_DP_CTRL(i, l) (0x0061c10c + (i) * 0x800 + (l) * 0x80) |
833 | #define NV50_SOR_DP_CTRL_ENABLED 0x00000001 | 836 | #define NV50_SOR_DP_CTRL_ENABLED 0x00000001 |
834 | #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 | 837 | #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED 0x00004000 |