From 44a1246f320312b84134a962caf3bf6af989e193 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 17 Aug 2010 14:34:00 +1000 Subject: drm/nv50: add dcb type 14 to enum to prevent compiler complaint Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 2 +- drivers/gpu/drm/nouveau/nouveau_bios.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index e4f33a4edea1..e10d851a7240 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6153,7 +6153,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; break; - case 0xe: + case OUTPUT_EOL: /* weird g80 mobile type that "nv" treats as a terminator */ dcb->entries--; return false; diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index fd14dfd3d780..c1de2f3fcb0e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -95,6 +95,7 @@ enum dcb_type { OUTPUT_TMDS = 2, OUTPUT_LVDS = 3, OUTPUT_DP = 6, + OUTPUT_EOL = 14, /* DCB 4.0+, appears to be end-of-list */ OUTPUT_ANY = -1 }; -- cgit v1.2.3 From acae116ce16833859eb4eb929de571b9a800d685 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 15 Aug 2010 14:31:31 +0200 Subject: drm/nouveau: Use a helper function to match PCI device/subsystem IDs. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 17 ++++------------- drivers/gpu/drm/nouveau/nouveau_drv.h | 9 +++++++++ drivers/gpu/drm/nouveau/nv17_tv.c | 10 +++------- 3 files changed, 16 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index e10d851a7240..b54597f6eadf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -4381,11 +4381,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b * * For the moment, a quirk will do :) */ - if ((dev->pdev->device == 0x01d7) && - (dev->pdev->subsystem_vendor == 0x1028) && - (dev->pdev->subsystem_device == 0x01c2)) { + if (nv_match_device(dev, 0x01d7, 0x1028, 0x01c2)) bios->fp.duallink_transition_clk = 80000; - } /* set dual_link flag for EDID case */ if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) @@ -5814,9 +5811,7 @@ parse_dcb_gpio_table(struct nvbios *bios) */ /* Apple iMac G4 NV18 */ - if (dev->pdev->device == 0x0189 && - dev->pdev->subsystem_vendor == 0x10de && - dev->pdev->subsystem_device == 0x0010) { + if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) { struct dcb_gpio_entry *gpio = new_gpio_entry(bios); gpio->tag = DCB_GPIO_TVDAC0; @@ -5898,9 +5893,7 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx) struct drm_device *dev = bios->dev; /* Gigabyte NX85T */ - if ((dev->pdev->device == 0x0421) && - (dev->pdev->subsystem_vendor == 0x1458) && - (dev->pdev->subsystem_device == 0x344c)) { + if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) { if (cte->type == DCB_CONNECTOR_HDMI_1) cte->type = DCB_CONNECTOR_DVI_I; } @@ -6321,9 +6314,7 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) * nasty problems until this is sorted (assuming it's not a * VBIOS bug). */ - if ((dev->pdev->device == 0x040d) && - (dev->pdev->subsystem_vendor == 0x1028) && - (dev->pdev->subsystem_device == 0x019b)) { + if (nv_match_device(dev, 0x040d, 0x1028, 0x019b)) { if (*conn == 0x02026312 && *conf == 0x00000020) return false; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 1e093a069b7b..b1be617373b6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1389,6 +1389,15 @@ nv_two_reg_pll(struct drm_device *dev) return false; } +static inline bool +nv_match_device(struct drm_device *dev, unsigned device, + unsigned sub_vendor, unsigned sub_device) +{ + return dev->pdev->device == device && + dev->pdev->subsystem_vendor == sub_vendor && + dev->pdev->subsystem_device == sub_device; +} + #define NV_SW 0x0000506e #define NV_SW_DMA_SEMAPHORE 0x00000060 #define NV_SW_SEMAPHORE_OFFSET 0x00000064 diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index eefa5c856932..13cdc05b7c2d 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c @@ -121,18 +121,14 @@ static bool get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) { /* Zotac FX5200 */ - if (dev->pdev->device == 0x0322 && - dev->pdev->subsystem_vendor == 0x19da && - (dev->pdev->subsystem_device == 0x1035 || - dev->pdev->subsystem_device == 0x2035)) { + if (nv_match_device(dev, 0x0322, 0x19da, 0x1035) || + nv_match_device(dev, 0x0322, 0x19da, 0x2035)) { *pin_mask = 0xc; return false; } /* MSI nForce2 IGP */ - if (dev->pdev->device == 0x01f0 && - dev->pdev->subsystem_vendor == 0x1462 && - dev->pdev->subsystem_device == 0x5710) { + if (nv_match_device(dev, 0x01f0, 0x1462, 0x5710)) { *pin_mask = 0xc; return false; } -- cgit v1.2.3 From f5cb8ab1541390d5ac3bb906f81c4300d0fdb574 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 18 Aug 2010 16:07:34 +0200 Subject: drm/nv30: Apply modesetting to the correct slave encoder Signed-off-by: Patrice Mandin Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv04_dfp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index a5dcf7685800..ea89f6e69d4c 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -444,6 +444,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct dcb_entry *dcbe = nv_encoder->dcb; int head = nouveau_crtc(encoder->crtc)->index; + struct drm_encoder *slave_encoder; if (dcbe->type == OUTPUT_TMDS) run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); @@ -462,9 +463,10 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); /* Init external transmitters */ - if (get_tmds_slave(encoder)) - get_slave_funcs(get_tmds_slave(encoder))->mode_set( - encoder, &nv_encoder->mode, &nv_encoder->mode); + slave_encoder = get_tmds_slave(encoder); + if (slave_encoder) + get_slave_funcs(slave_encoder)->mode_set( + slave_encoder, &nv_encoder->mode, &nv_encoder->mode); helper->dpms(encoder, DRM_MODE_DPMS_ON); -- cgit v1.2.3 From d31e078d847fb2816d26c9476f4a68e89dc65a0b Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 20 Aug 2010 14:19:45 +0200 Subject: drm/nouveau: Fix backlight control on PPC machines with an internal TMDS panel. This commit fixes fdo bug 29685. Reported-by: Vlado Plaga Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 25 ++++--------------------- drivers/gpu/drm/nouveau/nv04_dfp.c | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index b54597f6eadf..f6c615b228d4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -3869,27 +3869,10 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entr } #ifdef __powerpc__ /* Powerbook specific quirks */ - if ((dev->pci_device & 0xffff) == 0x0179 || - (dev->pci_device & 0xffff) == 0x0189 || - (dev->pci_device & 0xffff) == 0x0329) { - if (script == LVDS_RESET) { - nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); - - } else if (script == LVDS_PANEL_ON) { - bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, - bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) - | (1 << 31)); - bios_wr32(bios, NV_PCRTC_GPIO_EXT, - bios_rd32(bios, NV_PCRTC_GPIO_EXT) | 1); - - } else if (script == LVDS_PANEL_OFF) { - bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, - bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) - & ~(1 << 31)); - bios_wr32(bios, NV_PCRTC_GPIO_EXT, - bios_rd32(bios, NV_PCRTC_GPIO_EXT) & ~3); - } - } + if (script == LVDS_RESET && + (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || + dev->pci_device == 0x0329)) + nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); #endif return 0; diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index ea89f6e69d4c..0d3206a7046c 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -475,6 +475,27 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } +static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) +{ +#ifdef __powerpc__ + struct drm_device *dev = encoder->dev; + + /* BIOS scripts usually take care of the backlight, thanks + * Apple for your consistency. + */ + if (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || + dev->pci_device == 0x0329) { + if (mode == DRM_MODE_DPMS_ON) { + nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31); + nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 1); + } else { + nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0); + nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 0); + } + } +#endif +} + static inline bool is_powersaving_dpms(int mode) { return (mode != DRM_MODE_DPMS_ON); @@ -522,6 +543,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) LVDS_PANEL_OFF, 0); } + nv04_dfp_update_backlight(encoder, mode); nv04_dfp_update_fp_control(encoder, mode); if (mode == DRM_MODE_DPMS_ON) @@ -545,6 +567,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", mode, nv_encoder->dcb->index); + nv04_dfp_update_backlight(encoder, mode); nv04_dfp_update_fp_control(encoder, mode); } -- cgit v1.2.3 From fba675283429e41270feb661a1f6f3bc05d71981 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 24 Aug 2010 23:02:02 +0200 Subject: drm/nouveau: Fix TMDS on some DCB1.5 boards. The TMDS output of an nv11 was being detected as LVDS, because it uses DCB type 2 for TMDS instead of type 4. Reported-by: Bertrand VIEILLE Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index f6c615b228d4..974b0f8ae048 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6166,22 +6166,14 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, entry->type = OUTPUT_TV; break; case 2: - case 3: - entry->type = OUTPUT_LVDS; - break; case 4: - switch ((conn & 0x000000f0) >> 4) { - case 0: - entry->type = OUTPUT_TMDS; - break; - case 1: + if (conn & 0x10) entry->type = OUTPUT_LVDS; - break; - default: - NV_ERROR(dev, "Unknown DCB subtype 4/%d\n", - (conn & 0x000000f0) >> 4); - return false; - } + else + entry->type = OUTPUT_TMDS; + break; + case 3: + entry->type = OUTPUT_LVDS; break; default: NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); -- cgit v1.2.3 From ee508b821c2042fb852a078e594bd36606973780 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 25 Aug 2010 12:54:53 +0200 Subject: drm/nv20: Don't use pushbuf calls on the original nv20. The "return" command is buggy on the original nv20, it jumps back to the caller address as expected, but it doesn't clear the subroutine active bit making the subsequent pushbuf calls fail with a "stack" overflow. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index a915dcdd9a49..613f878e6d0f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -663,7 +663,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, push[i].length); } } else - if (dev_priv->card_type >= NV_20) { + if (dev_priv->chipset >= 0x25) { ret = RING_SPACE(chan, req->nr_push * 2); if (ret) { NV_ERROR(dev, "cal_space: %d\n", ret); @@ -738,7 +738,7 @@ out_next: req->suffix0 = 0x00000000; req->suffix1 = 0x00000000; } else - if (dev_priv->card_type >= NV_20) { + if (dev_priv->chipset >= 0x25) { req->suffix0 = 0x00020000; req->suffix1 = 0x00000000; } else { -- cgit v1.2.3 From e3461a2bc0d67ce60a915e0f26e2a6eb4a4d4b99 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 26 Aug 2010 14:58:57 +1000 Subject: drm: export drm_global_mutex for drivers to use Nouveau needs to be able to drop the mutex before sleeping to prevent a deadlock from occuring. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/drm_fops.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 2ca8df8b6102..41dfaae41159 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -41,6 +41,7 @@ /* from BKL pushdown: note that nothing else serializes idr_find() */ DEFINE_MUTEX(drm_global_mutex); +EXPORT_SYMBOL(drm_global_mutex); static int drm_open_helper(struct inode *inode, struct file *filp, struct drm_device * dev); -- cgit v1.2.3 From ab699ec64a4294f2f6ccd34b9bf8a2dcb4c4cb3c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 26 Aug 2010 15:02:32 +1000 Subject: drm/nouveau: drop drm_global_mutex before sleeping in submission path If we keep hold of the mutex here, the process which currently holds the buffer object will never be able to release it, causing a deadlock. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_gem.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 613f878e6d0f..93711dfcafc1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -337,7 +337,9 @@ retry: return -EINVAL; } + mutex_unlock(&drm_global_mutex); ret = ttm_bo_wait_cpu(&nvbo->bo, false); + mutex_lock(&drm_global_mutex); if (ret) { NV_ERROR(dev, "fail wait_cpu\n"); return ret; -- cgit v1.2.3