aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-02-26 13:57:45 -0500
committerDave Airlie <airlied@redhat.com>2010-04-08 20:16:14 -0400
commit0ca2ab52d451c25764e53d3d289e1be357c977d7 (patch)
tree55e87915a45821606c9304335ca908fdeedcea2b
parent45f9a39bedc3afab3fc85567792efc0103f34a55 (diff)
drm/radeon/kms/evergreen: add hpd support
Hot plug detect (hpd) for digital monitors Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c166
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
2 files changed, 161 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 5c34349058c1..fcf65d9d6196 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -41,28 +41,180 @@ void evergreen_fini(struct radeon_device *rdev);
41bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) 41bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
42{ 42{
43 bool connected = false; 43 bool connected = false;
44 /* XXX */ 44
45 switch (hpd) {
46 case RADEON_HPD_1:
47 if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE)
48 connected = true;
49 break;
50 case RADEON_HPD_2:
51 if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE)
52 connected = true;
53 break;
54 case RADEON_HPD_3:
55 if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE)
56 connected = true;
57 break;
58 case RADEON_HPD_4:
59 if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE)
60 connected = true;
61 break;
62 case RADEON_HPD_5:
63 if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE)
64 connected = true;
65 break;
66 case RADEON_HPD_6:
67 if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE)
68 connected = true;
69 break;
70 default:
71 break;
72 }
73
45 return connected; 74 return connected;
46} 75}
47 76
48void evergreen_hpd_set_polarity(struct radeon_device *rdev, 77void evergreen_hpd_set_polarity(struct radeon_device *rdev,
49 enum radeon_hpd_id hpd) 78 enum radeon_hpd_id hpd)
50{ 79{
51 /* XXX */ 80 u32 tmp;
81 bool connected = evergreen_hpd_sense(rdev, hpd);
82
83 switch (hpd) {
84 case RADEON_HPD_1:
85 tmp = RREG32(DC_HPD1_INT_CONTROL);
86 if (connected)
87 tmp &= ~DC_HPDx_INT_POLARITY;
88 else
89 tmp |= DC_HPDx_INT_POLARITY;
90 WREG32(DC_HPD1_INT_CONTROL, tmp);
91 break;
92 case RADEON_HPD_2:
93 tmp = RREG32(DC_HPD2_INT_CONTROL);
94 if (connected)
95 tmp &= ~DC_HPDx_INT_POLARITY;
96 else
97 tmp |= DC_HPDx_INT_POLARITY;
98 WREG32(DC_HPD2_INT_CONTROL, tmp);
99 break;
100 case RADEON_HPD_3:
101 tmp = RREG32(DC_HPD3_INT_CONTROL);
102 if (connected)
103 tmp &= ~DC_HPDx_INT_POLARITY;
104 else
105 tmp |= DC_HPDx_INT_POLARITY;
106 WREG32(DC_HPD3_INT_CONTROL, tmp);
107 break;
108 case RADEON_HPD_4:
109 tmp = RREG32(DC_HPD4_INT_CONTROL);
110 if (connected)
111 tmp &= ~DC_HPDx_INT_POLARITY;
112 else
113 tmp |= DC_HPDx_INT_POLARITY;
114 WREG32(DC_HPD4_INT_CONTROL, tmp);
115 break;
116 case RADEON_HPD_5:
117 tmp = RREG32(DC_HPD5_INT_CONTROL);
118 if (connected)
119 tmp &= ~DC_HPDx_INT_POLARITY;
120 else
121 tmp |= DC_HPDx_INT_POLARITY;
122 WREG32(DC_HPD5_INT_CONTROL, tmp);
123 break;
124 case RADEON_HPD_6:
125 tmp = RREG32(DC_HPD6_INT_CONTROL);
126 if (connected)
127 tmp &= ~DC_HPDx_INT_POLARITY;
128 else
129 tmp |= DC_HPDx_INT_POLARITY;
130 WREG32(DC_HPD6_INT_CONTROL, tmp);
131 break;
132 default:
133 break;
134 }
52} 135}
53 136
54void evergreen_hpd_init(struct radeon_device *rdev) 137void evergreen_hpd_init(struct radeon_device *rdev)
55{ 138{
56 /* XXX */ 139 struct drm_device *dev = rdev->ddev;
140 struct drm_connector *connector;
141 u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) |
142 DC_HPDx_RX_INT_TIMER(0xfa) | DC_HPDx_EN;
143
144 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
145 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
146 switch (radeon_connector->hpd.hpd) {
147 case RADEON_HPD_1:
148 WREG32(DC_HPD1_CONTROL, tmp);
149 rdev->irq.hpd[0] = true;
150 break;
151 case RADEON_HPD_2:
152 WREG32(DC_HPD2_CONTROL, tmp);
153 rdev->irq.hpd[1] = true;
154 break;
155 case RADEON_HPD_3:
156 WREG32(DC_HPD3_CONTROL, tmp);
157 rdev->irq.hpd[2] = true;
158 break;
159 case RADEON_HPD_4:
160 WREG32(DC_HPD4_CONTROL, tmp);
161 rdev->irq.hpd[3] = true;
162 break;
163 case RADEON_HPD_5:
164 WREG32(DC_HPD5_CONTROL, tmp);
165 rdev->irq.hpd[4] = true;
166 break;
167 case RADEON_HPD_6:
168 WREG32(DC_HPD6_CONTROL, tmp);
169 rdev->irq.hpd[5] = true;
170 break;
171 default:
172 break;
173 }
174 }
175 if (rdev->irq.installed)
176 evergreen_irq_set(rdev);
57} 177}
58 178
59 179void evergreen_hpd_fini(struct radeon_device *rdev)
60void evergreen_bandwidth_update(struct radeon_device *rdev)
61{ 180{
62 /* XXX */ 181 struct drm_device *dev = rdev->ddev;
182 struct drm_connector *connector;
183
184 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
185 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
186 switch (radeon_connector->hpd.hpd) {
187 case RADEON_HPD_1:
188 WREG32(DC_HPD1_CONTROL, 0);
189 rdev->irq.hpd[0] = false;
190 break;
191 case RADEON_HPD_2:
192 WREG32(DC_HPD2_CONTROL, 0);
193 rdev->irq.hpd[1] = false;
194 break;
195 case RADEON_HPD_3:
196 WREG32(DC_HPD3_CONTROL, 0);
197 rdev->irq.hpd[2] = false;
198 break;
199 case RADEON_HPD_4:
200 WREG32(DC_HPD4_CONTROL, 0);
201 rdev->irq.hpd[3] = false;
202 break;
203 case RADEON_HPD_5:
204 WREG32(DC_HPD5_CONTROL, 0);
205 rdev->irq.hpd[4] = false;
206 break;
207 case RADEON_HPD_6:
208 WREG32(DC_HPD6_CONTROL, 0);
209 rdev->irq.hpd[5] = false;
210 break;
211 default:
212 break;
213 }
214 }
63} 215}
64 216
65void evergreen_hpd_fini(struct radeon_device *rdev) 217void evergreen_bandwidth_update(struct radeon_device *rdev)
66{ 218{
67 /* XXX */ 219 /* XXX */
68} 220}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e0132ef093b4..815df347c08e 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1345,7 +1345,8 @@ extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
1345 1345
1346extern void r700_cp_stop(struct radeon_device *rdev); 1346extern void r700_cp_stop(struct radeon_device *rdev);
1347extern void r700_cp_fini(struct radeon_device *rdev); 1347extern void r700_cp_fini(struct radeon_device *rdev);
1348void evergreen_disable_interrupt_state(struct radeon_device *rdev); 1348extern void evergreen_disable_interrupt_state(struct radeon_device *rdev);
1349extern int evergreen_irq_set(struct radeon_device *rdev);
1349 1350
1350/* evergreen */ 1351/* evergreen */
1351struct evergreen_mc_save { 1352struct evergreen_mc_save {