diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv04_dac.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_dac.c | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index d9f32879ba38..1d73b15d70da 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c | |||
@@ -119,7 +119,7 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, | |||
119 | struct drm_connector *connector) | 119 | struct drm_connector *connector) |
120 | { | 120 | { |
121 | struct drm_device *dev = encoder->dev; | 121 | struct drm_device *dev = encoder->dev; |
122 | uint8_t saved_seq1, saved_pi, saved_rpc1; | 122 | uint8_t saved_seq1, saved_pi, saved_rpc1, saved_cr_mode; |
123 | uint8_t saved_palette0[3], saved_palette_mask; | 123 | uint8_t saved_palette0[3], saved_palette_mask; |
124 | uint32_t saved_rtest_ctrl, saved_rgen_ctrl; | 124 | uint32_t saved_rtest_ctrl, saved_rgen_ctrl; |
125 | int i; | 125 | int i; |
@@ -135,6 +135,9 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, | |||
135 | /* only implemented for head A for now */ | 135 | /* only implemented for head A for now */ |
136 | NVSetOwner(dev, 0); | 136 | NVSetOwner(dev, 0); |
137 | 137 | ||
138 | saved_cr_mode = NVReadVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX); | ||
139 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode | 0x80); | ||
140 | |||
138 | saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX); | 141 | saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX); |
139 | NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20); | 142 | NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20); |
140 | 143 | ||
@@ -203,6 +206,7 @@ out: | |||
203 | NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi); | 206 | NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi); |
204 | NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1); | 207 | NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1); |
205 | NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); | 208 | NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); |
209 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); | ||
206 | 210 | ||
207 | if (blue == 0x18) { | 211 | if (blue == 0x18) { |
208 | NV_INFO(dev, "Load detected on head A\n"); | 212 | NV_INFO(dev, "Load detected on head A\n"); |
@@ -212,16 +216,15 @@ out: | |||
212 | return connector_status_disconnected; | 216 | return connector_status_disconnected; |
213 | } | 217 | } |
214 | 218 | ||
215 | enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, | 219 | uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) |
216 | struct drm_connector *connector) | ||
217 | { | 220 | { |
218 | struct drm_device *dev = encoder->dev; | 221 | struct drm_device *dev = encoder->dev; |
219 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 222 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
220 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; | 223 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; |
221 | uint32_t testval, regoffset = nv04_dac_output_offset(encoder); | 224 | uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); |
222 | uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, | 225 | uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, |
223 | saved_rtest_ctrl, saved_gpio0, saved_gpio1, temp, routput; | 226 | saved_rtest_ctrl, saved_gpio0, saved_gpio1, temp, routput; |
224 | int head, present = 0; | 227 | int head; |
225 | 228 | ||
226 | #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) | 229 | #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) |
227 | if (dcb->type == OUTPUT_TV) { | 230 | if (dcb->type == OUTPUT_TV) { |
@@ -287,13 +290,7 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, | |||
287 | temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); | 290 | temp | NV_PRAMDAC_TEST_CONTROL_TP_INS_EN_ASSERTED); |
288 | msleep(5); | 291 | msleep(5); |
289 | 292 | ||
290 | temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); | 293 | sample = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); |
291 | |||
292 | if (dcb->type == OUTPUT_TV) | ||
293 | present = (nv17_tv_detect(encoder, connector, temp) | ||
294 | == connector_status_connected); | ||
295 | else | ||
296 | present = temp & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI; | ||
297 | 294 | ||
298 | temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL); | 295 | temp = NVReadRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL); |
299 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL, | 296 | NVWriteRAMDAC(dev, head, NV_PRAMDAC_TEST_CONTROL, |
@@ -310,15 +307,25 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, | |||
310 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); | 307 | nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); |
311 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); | 308 | nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); |
312 | 309 | ||
313 | if (present) { | 310 | return sample; |
314 | NV_INFO(dev, "Load detected on output %c\n", '@' + ffs(dcb->or)); | 311 | } |
312 | |||
313 | static enum drm_connector_status | ||
314 | nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | ||
315 | { | ||
316 | struct drm_device *dev = encoder->dev; | ||
317 | struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; | ||
318 | uint32_t sample = nv17_dac_sample_load(encoder); | ||
319 | |||
320 | if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { | ||
321 | NV_INFO(dev, "Load detected on output %c\n", | ||
322 | '@' + ffs(dcb->or)); | ||
315 | return connector_status_connected; | 323 | return connector_status_connected; |
324 | } else { | ||
325 | return connector_status_disconnected; | ||
316 | } | 326 | } |
317 | |||
318 | return connector_status_disconnected; | ||
319 | } | 327 | } |
320 | 328 | ||
321 | |||
322 | static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, | 329 | static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, |
323 | struct drm_display_mode *mode, | 330 | struct drm_display_mode *mode, |
324 | struct drm_display_mode *adjusted_mode) | 331 | struct drm_display_mode *adjusted_mode) |