aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/r100.c106
1 files changed, 104 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 109096802e66..2b534c528aaf 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -65,6 +65,95 @@ MODULE_FIRMWARE(FIRMWARE_R520);
65 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 65 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
66 */ 66 */
67 67
68/* hpd for digital panel detect/disconnect */
69bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
70{
71 bool connected = false;
72
73 switch (hpd) {
74 case RADEON_HPD_1:
75 if (RREG32(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE)
76 connected = true;
77 break;
78 case RADEON_HPD_2:
79 if (RREG32(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE)
80 connected = true;
81 break;
82 default:
83 break;
84 }
85 return connected;
86}
87
88void r100_hpd_set_polarity(struct radeon_device *rdev,
89 enum radeon_hpd_id hpd)
90{
91 u32 tmp;
92 bool connected = r100_hpd_sense(rdev, hpd);
93
94 switch (hpd) {
95 case RADEON_HPD_1:
96 tmp = RREG32(RADEON_FP_GEN_CNTL);
97 if (connected)
98 tmp &= ~RADEON_FP_DETECT_INT_POL;
99 else
100 tmp |= RADEON_FP_DETECT_INT_POL;
101 WREG32(RADEON_FP_GEN_CNTL, tmp);
102 break;
103 case RADEON_HPD_2:
104 tmp = RREG32(RADEON_FP2_GEN_CNTL);
105 if (connected)
106 tmp &= ~RADEON_FP2_DETECT_INT_POL;
107 else
108 tmp |= RADEON_FP2_DETECT_INT_POL;
109 WREG32(RADEON_FP2_GEN_CNTL, tmp);
110 break;
111 default:
112 break;
113 }
114}
115
116void r100_hpd_init(struct radeon_device *rdev)
117{
118 struct drm_device *dev = rdev->ddev;
119 struct drm_connector *connector;
120
121 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
122 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
123 switch (radeon_connector->hpd.hpd) {
124 case RADEON_HPD_1:
125 rdev->irq.hpd[0] = true;
126 break;
127 case RADEON_HPD_2:
128 rdev->irq.hpd[1] = true;
129 break;
130 default:
131 break;
132 }
133 }
134 r100_irq_set(rdev);
135}
136
137void r100_hpd_fini(struct radeon_device *rdev)
138{
139 struct drm_device *dev = rdev->ddev;
140 struct drm_connector *connector;
141
142 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
143 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
144 switch (radeon_connector->hpd.hpd) {
145 case RADEON_HPD_1:
146 rdev->irq.hpd[0] = false;
147 break;
148 case RADEON_HPD_2:
149 rdev->irq.hpd[1] = false;
150 break;
151 default:
152 break;
153 }
154 }
155}
156
68/* 157/*
69 * PCI GART 158 * PCI GART
70 */ 159 */
@@ -163,6 +252,12 @@ int r100_irq_set(struct radeon_device *rdev)
163 if (rdev->irq.crtc_vblank_int[1]) { 252 if (rdev->irq.crtc_vblank_int[1]) {
164 tmp |= RADEON_CRTC2_VBLANK_MASK; 253 tmp |= RADEON_CRTC2_VBLANK_MASK;
165 } 254 }
255 if (rdev->irq.hpd[0]) {
256 tmp |= RADEON_FP_DETECT_MASK;
257 }
258 if (rdev->irq.hpd[1]) {
259 tmp |= RADEON_FP2_DETECT_MASK;
260 }
166 WREG32(RADEON_GEN_INT_CNTL, tmp); 261 WREG32(RADEON_GEN_INT_CNTL, tmp);
167 return 0; 262 return 0;
168} 263}
@@ -181,8 +276,9 @@ void r100_irq_disable(struct radeon_device *rdev)
181static inline uint32_t r100_irq_ack(struct radeon_device *rdev) 276static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
182{ 277{
183 uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); 278 uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS);
184 uint32_t irq_mask = RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | 279 uint32_t irq_mask = RADEON_SW_INT_TEST |
185 RADEON_CRTC2_VBLANK_STAT; 280 RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT |
281 RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT;
186 282
187 if (irqs) { 283 if (irqs) {
188 WREG32(RADEON_GEN_INT_STATUS, irqs); 284 WREG32(RADEON_GEN_INT_STATUS, irqs);
@@ -213,6 +309,12 @@ int r100_irq_process(struct radeon_device *rdev)
213 if (status & RADEON_CRTC2_VBLANK_STAT) { 309 if (status & RADEON_CRTC2_VBLANK_STAT) {
214 drm_handle_vblank(rdev->ddev, 1); 310 drm_handle_vblank(rdev->ddev, 1);
215 } 311 }
312 if (status & RADEON_FP_DETECT_STAT) {
313 DRM_INFO("HPD1\n");
314 }
315 if (status & RADEON_FP2_DETECT_STAT) {
316 DRM_INFO("HPD2\n");
317 }
216 status = r100_irq_ack(rdev); 318 status = r100_irq_ack(rdev);
217 } 319 }
218 if (rdev->msi_enabled) { 320 if (rdev->msi_enabled) {