diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-08-02 05:29:37 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 02:09:56 -0400 |
commit | 10b461e40a5a5522fe996805a0625c9cd4e5c1a7 (patch) | |
tree | 4000f3922cb3218950fa8cc89cb85bfe1869f3c3 /drivers/gpu | |
parent | 730764812ded8b53643670131219b3abbdab52c8 (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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_backlight.c | 58 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_connector.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_encoder.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 4 |
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 d412adc67403..4f3d1ff3e472 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "nouveau_drv.h" | 37 | #include "nouveau_drv.h" |
38 | #include "nouveau_drm.h" | 38 | #include "nouveau_drm.h" |
39 | #include "nouveau_reg.h" | 39 | #include "nouveau_reg.h" |
40 | #include "nouveau_encoder.h" | ||
40 | 41 | ||
41 | static int | 42 | static int |
42 | nv40_get_intensity(struct backlight_device *bd) | 43 | nv40_get_intensity(struct backlight_device *bd) |
@@ -96,18 +97,22 @@ nv40_backlight_init(struct drm_connector *connector) | |||
96 | static int | 97 | static int |
97 | nv50_get_intensity(struct backlight_device *bd) | 98 | nv50_get_intensity(struct backlight_device *bd) |
98 | { | 99 | { |
99 | struct drm_device *dev = bl_get_data(bd); | 100 | struct nouveau_encoder *nv_encoder = bl_get_data(bd); |
101 | struct drm_device *dev = nv_encoder->base.base.dev; | ||
102 | int or = nv_encoder->or; | ||
100 | 103 | ||
101 | return nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT); | 104 | return nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800)); |
102 | } | 105 | } |
103 | 106 | ||
104 | static int | 107 | static int |
105 | nv50_set_intensity(struct backlight_device *bd) | 108 | nv50_set_intensity(struct backlight_device *bd) |
106 | { | 109 | { |
107 | struct drm_device *dev = bl_get_data(bd); | 110 | struct nouveau_encoder *nv_encoder = bl_get_data(bd); |
111 | struct drm_device *dev = nv_encoder->base.base.dev; | ||
108 | int val = bd->props.brightness; | 112 | int val = bd->props.brightness; |
113 | int or = nv_encoder->or; | ||
109 | 114 | ||
110 | nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT, | 115 | nv_wr32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800), |
111 | val | NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE); | 116 | val | NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE); |
112 | return 0; | 117 | return 0; |
113 | } | 118 | } |
@@ -123,17 +128,28 @@ nv50_backlight_init(struct drm_connector *connector) | |||
123 | { | 128 | { |
124 | struct drm_device *dev = connector->dev; | 129 | struct drm_device *dev = connector->dev; |
125 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 130 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
131 | struct nouveau_encoder *nv_encoder; | ||
126 | struct backlight_properties props; | 132 | struct backlight_properties props; |
127 | struct backlight_device *bd; | 133 | struct backlight_device *bd; |
134 | int or; | ||
135 | |||
136 | nv_encoder = find_encoder(connector, OUTPUT_LVDS); | ||
137 | if (!nv_encoder) { | ||
138 | nv_encoder = find_encoder(connector, OUTPUT_DP); | ||
139 | if (!nv_encoder) | ||
140 | return -ENODEV; | ||
141 | } | ||
142 | |||
143 | or = nv_encoder->or; | ||
128 | 144 | ||
129 | if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT)) | 145 | if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT + (or * 0x800))) |
130 | return 0; | 146 | return 0; |
131 | 147 | ||
132 | memset(&props, 0, sizeof(struct backlight_properties)); | 148 | memset(&props, 0, sizeof(struct backlight_properties)); |
133 | props.type = BACKLIGHT_RAW; | 149 | props.type = BACKLIGHT_RAW; |
134 | props.max_brightness = 1025; | 150 | props.max_brightness = 1025; |
135 | bd = backlight_device_register("nv_backlight", &connector->kdev, dev, | 151 | bd = backlight_device_register("nv_backlight", &connector->kdev, |
136 | &nv50_bl_ops, &props); | 152 | nv_encoder, &nv50_bl_ops, &props); |
137 | if (IS_ERR(bd)) | 153 | if (IS_ERR(bd)) |
138 | return PTR_ERR(bd); | 154 | return PTR_ERR(bd); |
139 | 155 | ||
@@ -144,10 +160,10 @@ nv50_backlight_init(struct drm_connector *connector) | |||
144 | } | 160 | } |
145 | 161 | ||
146 | int | 162 | int |
147 | nouveau_backlight_init(struct drm_connector *connector) | 163 | nouveau_backlight_init(struct drm_device *dev) |
148 | { | 164 | { |
149 | struct drm_device *dev = connector->dev; | ||
150 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 165 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
166 | struct drm_connector *connector; | ||
151 | 167 | ||
152 | #ifdef CONFIG_ACPI | 168 | #ifdef CONFIG_ACPI |
153 | if (acpi_video_backlight_support()) { | 169 | if (acpi_video_backlight_support()) { |
@@ -157,22 +173,28 @@ nouveau_backlight_init(struct drm_connector *connector) | |||
157 | } | 173 | } |
158 | #endif | 174 | #endif |
159 | 175 | ||
160 | switch (dev_priv->card_type) { | 176 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
161 | case NV_40: | 177 | if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && |
162 | return nv40_backlight_init(connector); | 178 | connector->connector_type != DRM_MODE_CONNECTOR_eDP) |
163 | case NV_50: | 179 | continue; |
164 | return nv50_backlight_init(connector); | 180 | |
165 | default: | 181 | switch (dev_priv->card_type) { |
166 | break; | 182 | case NV_40: |
183 | return nv40_backlight_init(connector); | ||
184 | case NV_50: | ||
185 | return nv50_backlight_init(connector); | ||
186 | default: | ||
187 | break; | ||
188 | } | ||
167 | } | 189 | } |
168 | 190 | ||
191 | |||
169 | return 0; | 192 | return 0; |
170 | } | 193 | } |
171 | 194 | ||
172 | void | 195 | void |
173 | nouveau_backlight_exit(struct drm_connector *connector) | 196 | nouveau_backlight_exit(struct drm_device *dev) |
174 | { | 197 | { |
175 | struct drm_device *dev = connector->dev; | ||
176 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 198 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
177 | 199 | ||
178 | if (dev_priv->backlight) { | 200 | if (dev_priv->backlight) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 561d4c6677ea..5308024ce56a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | static void nouveau_connector_hotplug(void *, int); | 40 | static void nouveau_connector_hotplug(void *, int); |
41 | 41 | ||
42 | static struct nouveau_encoder * | 42 | struct nouveau_encoder * |
43 | find_encoder(struct drm_connector *connector, int type) | 43 | find_encoder(struct drm_connector *connector, int type) |
44 | { | 44 | { |
45 | struct drm_device *dev = connector->dev; | 45 | struct drm_device *dev = connector->dev; |
@@ -116,10 +116,6 @@ nouveau_connector_destroy(struct drm_connector *connector) | |||
116 | nouveau_connector_hotplug, connector); | 116 | nouveau_connector_hotplug, connector); |
117 | } | 117 | } |
118 | 118 | ||
119 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS || | ||
120 | connector->connector_type == DRM_MODE_CONNECTOR_eDP) | ||
121 | nouveau_backlight_exit(connector); | ||
122 | |||
123 | kfree(nv_connector->edid); | 119 | kfree(nv_connector->edid); |
124 | drm_sysfs_connector_remove(connector); | 120 | drm_sysfs_connector_remove(connector); |
125 | drm_connector_cleanup(connector); | 121 | drm_connector_cleanup(connector); |
@@ -901,10 +897,6 @@ nouveau_connector_create(struct drm_device *dev, int index) | |||
901 | 897 | ||
902 | drm_sysfs_connector_add(connector); | 898 | drm_sysfs_connector_add(connector); |
903 | 899 | ||
904 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS || | ||
905 | connector->connector_type == DRM_MODE_CONNECTOR_eDP) | ||
906 | nouveau_backlight_init(connector); | ||
907 | |||
908 | dcb->drm = connector; | 900 | dcb->drm = connector; |
909 | return dcb->drm; | 901 | return dcb->drm; |
910 | 902 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index ee0f0d129d3e..3e9e7cc09a7d 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 | |||
1054 | 1054 | ||
1055 | /* nouveau_backlight.c */ | 1055 | /* nouveau_backlight.c */ |
1056 | #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT | 1056 | #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT |
1057 | extern int nouveau_backlight_init(struct drm_connector *); | 1057 | extern int nouveau_backlight_init(struct drm_device *); |
1058 | extern void nouveau_backlight_exit(struct drm_connector *); | 1058 | extern void nouveau_backlight_exit(struct drm_device *); |
1059 | #else | 1059 | #else |
1060 | static inline int nouveau_backlight_init(struct drm_connector *dev) | 1060 | static inline int nouveau_backlight_init(struct drm_device *dev) |
1061 | { | 1061 | { |
1062 | return 0; | 1062 | return 0; |
1063 | } | 1063 | } |
1064 | 1064 | ||
1065 | static inline void nouveau_backlight_exit(struct drm_connector *dev) { } | 1065 | static inline void nouveau_backlight_exit(struct drm_device *dev) { } |
1066 | #endif | 1066 | #endif |
1067 | 1067 | ||
1068 | /* nouveau_bios.c */ | 1068 | /* nouveau_bios.c */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index 2bb316d2421c..70f0232558ff 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h | |||
@@ -57,6 +57,9 @@ struct nouveau_encoder { | |||
57 | }; | 57 | }; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | struct nouveau_encoder * | ||
61 | find_encoder(struct drm_connector *connector, int type); | ||
62 | |||
60 | static inline struct nouveau_encoder *nouveau_encoder(struct drm_encoder *enc) | 63 | static inline struct nouveau_encoder *nouveau_encoder(struct drm_encoder *enc) |
61 | { | 64 | { |
62 | struct drm_encoder_slave *slave = to_encoder_slave(enc); | 65 | 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 baaecf10a585..50df52da3aad 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) | |||
728 | if (ret) | 728 | if (ret) |
729 | goto out_irq; | 729 | goto out_irq; |
730 | 730 | ||
731 | nouveau_backlight_init(dev); | ||
732 | |||
731 | if (dev_priv->eng[NVOBJ_ENGINE_GR]) { | 733 | if (dev_priv->eng[NVOBJ_ENGINE_GR]) { |
732 | ret = nouveau_fence_init(dev); | 734 | ret = nouveau_fence_init(dev); |
733 | if (ret) | 735 | if (ret) |
@@ -757,6 +759,7 @@ out_chan: | |||
757 | out_fence: | 759 | out_fence: |
758 | nouveau_fence_fini(dev); | 760 | nouveau_fence_fini(dev); |
759 | out_disp: | 761 | out_disp: |
762 | nouveau_backlight_exit(dev); | ||
760 | engine->display.destroy(dev); | 763 | engine->display.destroy(dev); |
761 | out_irq: | 764 | out_irq: |
762 | nouveau_irq_fini(dev); | 765 | nouveau_irq_fini(dev); |
@@ -817,6 +820,7 @@ static void nouveau_card_takedown(struct drm_device *dev) | |||
817 | nouveau_fence_fini(dev); | 820 | nouveau_fence_fini(dev); |
818 | } | 821 | } |
819 | 822 | ||
823 | nouveau_backlight_exit(dev); | ||
820 | engine->display.destroy(dev); | 824 | engine->display.destroy(dev); |
821 | drm_mode_config_cleanup(dev); | 825 | drm_mode_config_cleanup(dev); |
822 | 826 | ||