diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 587b6f5..00eb9b4 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c @@ -220,7 +220,8 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb; uint32_t testval, regoffset = nv04_dac_output_offset(encoder); uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, - saved_rtest_ctrl, temp, saved_gpio_ext = 0, routput; + saved_rtest_ctrl, temp, saved_gpio_ext = 0, saved_pcrtc_850 = 0, + routput; int head, present = 0; #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) @@ -248,11 +249,31 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4 & 0xffffffcf); } - if (dev_priv->chipset >= 0x34) { + if (nv_arch(dev) >= NV_30) { saved_gpio_ext = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT); + printk("PCRTC[0]+GPIO_EXT: %x\n", saved_gpio_ext); + } + + if (nv_arch(dev) >= NV_40) { + saved_pcrtc_850 = NVReadCRTC(dev, 0, NV_PCRTC_850); + printk("PCRTC[0]+850: %x\n", saved_pcrtc_850); + + } - NVWriteCRTC(dev, 0, NV_PCRTC_GPIO_EXT, (saved_gpio_ext & ~(3 << 20)) | + if ((dev_priv->chipset >= 0x34 && dev_priv->chipset < 0x40) || + (nv_arch(dev) == NV_30 && !dev_priv->VBIOS.is_mobile)) { + NVWriteCRTC(dev, 0, NV_PCRTC_GPIO_EXT, + (saved_gpio_ext & ~(3 << 20)) | (dcb->type == OUTPUT_TV ? (1 << 20) : 0)); + + } else if (dev_priv->chipset >= 0x40) { + NVWriteCRTC(dev, 0, NV_PCRTC_850, + (saved_pcrtc_850 & ~0xf0) | + (dcb->type == OUTPUT_TV ? 0x50 : 0x00)); + + NVWriteCRTC(dev, 0, NV_PCRTC_GPIO_EXT, + (saved_gpio_ext & ~0xf0) | + (dcb->type == OUTPUT_TV ? 0x50 : 0x00)); } msleep(4); @@ -268,7 +289,7 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, /* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */ routput = (saved_routput & 0xfffffece) | head << 8; - if (nv_arch(dev) >= NV_40) { + if (dev_priv->chipset >= 0x4b) { if (dcb->type == OUTPUT_TV) routput |= 1 << 20; else @@ -289,6 +310,7 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, msleep(5); temp = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); + printk("NV_PRAMDAC_TEST_CONTROL + %x: %x\n", regoffset, temp); if (dcb->type == OUTPUT_TV) present = (nv17_tv_detect(encoder, connector, (temp >> 28) & 0xe) @@ -308,8 +330,11 @@ enum drm_connector_status nv17_dac_detect(struct drm_encoder *encoder, nvWriteMC(dev, NV_PBUS_POWERCTRL_4, saved_powerctrl_4); nvWriteMC(dev, NV_PBUS_POWERCTRL_2, saved_powerctrl_2); - if (dev_priv->chipset >= 0x34) - NVWriteRAMDAC(dev, 0, NV_PCRTC_GPIO_EXT, saved_gpio_ext); + if (nv_arch(dev) >= NV_30) + NVWriteCRTC(dev, 0, NV_PCRTC_GPIO_EXT, saved_gpio_ext); + + if (nv_arch(dev) >= NV_40) + NVWriteCRTC(dev, 0, NV_PCRTC_850, saved_pcrtc_850); if (present) { NV_INFO(dev, "Load detected on output %c\n", '@' + ffs(dcb->or)); diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 34f95c7..ee9800c 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -237,14 +237,20 @@ static void nv17_tv_dpms(struct drm_encoder *encoder, int mode) nv_load_ptv(dev, regs, 200); - if (dev_priv->chipset >= 0x34) { - uint32_t *gpio_ext = &dev_priv->mode_reg.crtc_reg[0].gpio_ext; - - *gpio_ext &= ~(3 << 20); - if (mode == DRM_MODE_DPMS_ON) - *gpio_ext |= 1 << 20; - - NVWriteCRTC(dev, 0, NV_PCRTC_GPIO_EXT, *gpio_ext); + if ((dev_priv->chipset >= 0x34 && dev_priv->chipset < 0x40) || + (nv_arch(dev) == NV_30 && !dev_priv->VBIOS.is_mobile)) { + NVWriteCRTC(dev, 0, NV_PCRTC_GPIO_EXT, + (dev_priv->mode_reg.crtc_reg[0].gpio_ext & ~(3 << 20)) | + (mode == DRM_MODE_DPMS_ON ? (1 << 20) : 0)); + + } else if (dev_priv->chipset >= 0x40) { + NVWriteCRTC(dev, 0, NV_PCRTC_850, + (NVReadCRTC(dev, 0, NV_PCRTC_850) & ~0xf0) | + (mode == DRM_MODE_DPMS_ON ? 0x50 : 0x00)); + + NVWriteCRTC(dev, 0, NV_PCRTC_GPIO_EXT, + (dev_priv->mode_reg.crtc_reg[0].gpio_ext & ~0xf0) | + (mode == DRM_MODE_DPMS_ON ? 0x50 : 0x00)); } nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); @@ -299,7 +305,7 @@ static void nv17_tv_prepare(struct drm_encoder *encoder) /* Set the DACCLK register */ dacclk = (NVReadRAMDAC(dev, 0, dacclk_off) & ~0x30) | 0x1; - if (nv_arch(dev) == NV_40) + if (dev_priv->chipset >= 0x4b) dacclk |= 1 << 20; if (tv_norm->kind == CTV_ENC_MODE) {