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.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c
index 1cb19e3acb55..ea3627041ecf 100644
--- a/drivers/gpu/drm/nouveau/nv04_dac.c
+++ b/drivers/gpu/drm/nouveau/nv04_dac.c
@@ -220,6 +220,7 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
220{ 220{
221 struct drm_device *dev = encoder->dev; 221 struct drm_device *dev = encoder->dev;
222 struct drm_nouveau_private *dev_priv = dev->dev_private; 222 struct drm_nouveau_private *dev_priv = dev->dev_private;
223 struct nouveau_gpio_engine *gpio = &dev_priv->engine.gpio;
223 struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; 224 struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
224 uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); 225 uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder);
225 uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, 226 uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput,
@@ -251,22 +252,21 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
251 nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf); 252 nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf);
252 } 253 }
253 254
254 saved_gpio1 = nv17_gpio_get(dev, DCB_GPIO_TVDAC1); 255 saved_gpio1 = gpio->get(dev, DCB_GPIO_TVDAC1);
255 saved_gpio0 = nv17_gpio_get(dev, DCB_GPIO_TVDAC0); 256 saved_gpio0 = gpio->get(dev, DCB_GPIO_TVDAC0);
256 257
257 nv17_gpio_set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV); 258 gpio->set(dev, DCB_GPIO_TVDAC1, dcb->type == OUTPUT_TV);
258 nv17_gpio_set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV); 259 gpio->set(dev, DCB_GPIO_TVDAC0, dcb->type == OUTPUT_TV);
259 260
260 msleep(4); 261 msleep(4);
261 262
262 saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); 263 saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
263 head = (saved_routput & 0x100) >> 8; 264 head = (saved_routput & 0x100) >> 8;
264#if 0 265
265 /* if there's a spare crtc, using it will minimise flicker for the case 266 /* if there's a spare crtc, using it will minimise flicker */
266 * where the in-use crtc is in use by an off-chip tmds encoder */ 267 if (!(NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX) & 0xC0))
267 if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled)
268 head ^= 1; 268 head ^= 1;
269#endif 269
270 /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */ 270 /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
271 routput = (saved_routput & 0xfffffece) | head << 8; 271 routput = (saved_routput & 0xfffffece) | head << 8;
272 272
@@ -304,8 +304,8 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
304 nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4); 304 nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4);
305 nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2); 305 nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2);
306 306
307 nv17_gpio_set(dev, DCB_GPIO_TVDAC1, saved_gpio1); 307 gpio->set(dev, DCB_GPIO_TVDAC1, saved_gpio1);
308 nv17_gpio_set(dev, DCB_GPIO_TVDAC0, saved_gpio0); 308 gpio->set(dev, DCB_GPIO_TVDAC0, saved_gpio0);
309 309
310 return sample; 310 return sample;
311} 311}
@@ -315,9 +315,12 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
315{ 315{
316 struct drm_device *dev = encoder->dev; 316 struct drm_device *dev = encoder->dev;
317 struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; 317 struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
318 uint32_t sample = nv17_dac_sample_load(encoder);
319 318
320 if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { 319 if (nv04_dac_in_use(encoder))
320 return connector_status_disconnected;
321
322 if (nv17_dac_sample_load(encoder) &
323 NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
321 NV_INFO(dev, "Load detected on output %c\n", 324 NV_INFO(dev, "Load detected on output %c\n",
322 '@' + ffs(dcb->or)); 325 '@' + ffs(dcb->or));
323 return connector_status_connected; 326 return connector_status_connected;
@@ -330,6 +333,9 @@ static bool nv04_dac_mode_fixup(struct drm_encoder *encoder,
330 struct drm_display_mode *mode, 333 struct drm_display_mode *mode,
331 struct drm_display_mode *adjusted_mode) 334 struct drm_display_mode *adjusted_mode)
332{ 335{
336 if (nv04_dac_in_use(encoder))
337 return false;
338
333 return true; 339 return true;
334} 340}
335 341
@@ -428,6 +434,17 @@ void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
428 } 434 }
429} 435}
430 436
437/* Check if the DAC corresponding to 'encoder' is being used by
438 * someone else. */
439bool nv04_dac_in_use(struct drm_encoder *encoder)
440{
441 struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
442 struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
443
444 return nv_gf4_disp_arch(encoder->dev) &&
445 (dev_priv->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index));
446}
447
431static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) 448static void nv04_dac_dpms(struct drm_encoder *encoder, int mode)
432{ 449{
433 struct drm_device *dev = encoder->dev; 450 struct drm_device *dev = encoder->dev;
@@ -501,11 +518,13 @@ static const struct drm_encoder_funcs nv04_dac_funcs = {
501 .destroy = nv04_dac_destroy, 518 .destroy = nv04_dac_destroy,
502}; 519};
503 520
504int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) 521int
522nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
505{ 523{
506 const struct drm_encoder_helper_funcs *helper; 524 const struct drm_encoder_helper_funcs *helper;
507 struct drm_encoder *encoder;
508 struct nouveau_encoder *nv_encoder = NULL; 525 struct nouveau_encoder *nv_encoder = NULL;
526 struct drm_device *dev = connector->dev;
527 struct drm_encoder *encoder;
509 528
510 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); 529 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
511 if (!nv_encoder) 530 if (!nv_encoder)
@@ -527,5 +546,6 @@ int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry)
527 encoder->possible_crtcs = entry->heads; 546 encoder->possible_crtcs = entry->heads;
528 encoder->possible_clones = 0; 547 encoder->possible_clones = 0;
529 548
549 drm_mode_connector_attach_encoder(connector, encoder);
530 return 0; 550 return 0;
531} 551}