aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv04_dac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv04_dac.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv04_dac.c41
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
215enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, 219uint32_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
313static enum drm_connector_status
314nv17_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
322static bool nv04_dac_mode_fixup(struct drm_encoder *encoder, 329static 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)