aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-09-21 15:41:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-09-21 15:41:28 -0400
commit36a21fe6399cafc440163890035ccd9b891de00f (patch)
tree19099be4abce1eaea206c29bd3fe9254817e1934 /drivers
parent6551d6fe2128eaeb487c42ec4b1864b5f3245e60 (diff)
parent017a27e7f52346ca8de6fc776579fbcc8ea55b48 (diff)
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "Fixes for big 3 drivers: nouveau: revert earlier MBP fix, put a dmi based MBP fix in its place (fixes a regression we found on some Dell eDP panels doing some internal testing) radeon: revert pll fixes, real fix is too invasive, fix scratch leak intel: 3 minor fixes, one for HDMI audio." * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/nouveau: add dmi quirk for gpio reset drm/radeon: Prevent leak of scratch register on resume from suspend Revert "drm/nv50-/gpio: initialise to vbios defaults during init" Revert "drm/radeon: rework pll selection (v3)" drm/i915: HDMI - Clear Audio Enable bit for Hot Plug drm/i915: Reduce a pin-leak BUG into a WARN drm/i915: enable lvds pin pairs before dpll on gen2
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c3
-rw-r--r--drivers/gpu/drm/i915/intel_display.c12
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv50_gpio.c15
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c163
-rw-r--r--drivers/gpu/drm/radeon/r100.c3
6 files changed, 59 insertions, 139 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 489e2b162b27..274d25de521e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3242,7 +3242,8 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
3242{ 3242{
3243 int ret; 3243 int ret;
3244 3244
3245 BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); 3245 if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
3246 return -EBUSY;
3246 3247
3247 if (obj->gtt_space != NULL) { 3248 if (obj->gtt_space != NULL) {
3248 if ((alignment && obj->gtt_offset & (alignment - 1)) || 3249 if ((alignment && obj->gtt_offset & (alignment - 1)) ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bc2ad348e5d8..c040aee1341c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4191,12 +4191,6 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
4191 POSTING_READ(DPLL(pipe)); 4191 POSTING_READ(DPLL(pipe));
4192 udelay(150); 4192 udelay(150);
4193 4193
4194 I915_WRITE(DPLL(pipe), dpll);
4195
4196 /* Wait for the clocks to stabilize. */
4197 POSTING_READ(DPLL(pipe));
4198 udelay(150);
4199
4200 /* The LVDS pin pair needs to be on before the DPLLs are enabled. 4194 /* The LVDS pin pair needs to be on before the DPLLs are enabled.
4201 * This is an exception to the general rule that mode_set doesn't turn 4195 * This is an exception to the general rule that mode_set doesn't turn
4202 * things on. 4196 * things on.
@@ -4204,6 +4198,12 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
4204 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) 4198 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
4205 intel_update_lvds(crtc, clock, adjusted_mode); 4199 intel_update_lvds(crtc, clock, adjusted_mode);
4206 4200
4201 I915_WRITE(DPLL(pipe), dpll);
4202
4203 /* Wait for the clocks to stabilize. */
4204 POSTING_READ(DPLL(pipe));
4205 udelay(150);
4206
4207 /* The pixel multiplier can only be updated once the 4207 /* The pixel multiplier can only be updated once the
4208 * DPLL is enabled and the clocks are stable. 4208 * DPLL is enabled and the clocks are stable.
4209 * 4209 *
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 98f602427eb8..12dc3308ab8c 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -609,7 +609,7 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
609 u32 temp; 609 u32 temp;
610 u32 enable_bits = SDVO_ENABLE; 610 u32 enable_bits = SDVO_ENABLE;
611 611
612 if (intel_hdmi->has_audio) 612 if (intel_hdmi->has_audio || mode != DRM_MODE_DPMS_ON)
613 enable_bits |= SDVO_AUDIO_ENABLE; 613 enable_bits |= SDVO_AUDIO_ENABLE;
614 614
615 temp = I915_READ(intel_hdmi->sdvox_reg); 615 temp = I915_READ(intel_hdmi->sdvox_reg);
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c
index f03490534893..c399d510b27a 100644
--- a/drivers/gpu/drm/nouveau/nv50_gpio.c
+++ b/drivers/gpu/drm/nouveau/nv50_gpio.c
@@ -22,6 +22,7 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <linux/dmi.h>
25#include "drmP.h" 26#include "drmP.h"
26#include "nouveau_drv.h" 27#include "nouveau_drv.h"
27#include "nouveau_hw.h" 28#include "nouveau_hw.h"
@@ -110,13 +111,25 @@ nv50_gpio_isr(struct drm_device *dev)
110 nv_wr32(dev, 0xe074, intr1); 111 nv_wr32(dev, 0xe074, intr1);
111} 112}
112 113
114static struct dmi_system_id gpio_reset_ids[] = {
115 {
116 .ident = "Apple Macbook 10,1",
117 .matches = {
118 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
119 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
120 }
121 },
122 { }
123};
124
113int 125int
114nv50_gpio_init(struct drm_device *dev) 126nv50_gpio_init(struct drm_device *dev)
115{ 127{
116 struct drm_nouveau_private *dev_priv = dev->dev_private; 128 struct drm_nouveau_private *dev_priv = dev->dev_private;
117 129
118 /* initialise gpios and routing to vbios defaults */ 130 /* initialise gpios and routing to vbios defaults */
119 nouveau_gpio_reset(dev); 131 if (dmi_check_system(gpio_reset_ids))
132 nouveau_gpio_reset(dev);
120 133
121 /* disable, and ack any pending gpio interrupts */ 134 /* disable, and ack any pending gpio interrupts */
122 nv_wr32(dev, 0xe050, 0x00000000); 135 nv_wr32(dev, 0xe050, 0x00000000);
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index e721e3087b99..2817101fb167 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1479,98 +1479,14 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
1479 } 1479 }
1480} 1480}
1481 1481
1482/**
1483 * radeon_get_pll_use_mask - look up a mask of which pplls are in use
1484 *
1485 * @crtc: drm crtc
1486 *
1487 * Returns the mask of which PPLLs (Pixel PLLs) are in use.
1488 */
1489static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
1490{
1491 struct drm_device *dev = crtc->dev;
1492 struct drm_crtc *test_crtc;
1493 struct radeon_crtc *radeon_test_crtc;
1494 u32 pll_in_use = 0;
1495
1496 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1497 if (crtc == test_crtc)
1498 continue;
1499
1500 radeon_test_crtc = to_radeon_crtc(test_crtc);
1501 if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
1502 pll_in_use |= (1 << radeon_test_crtc->pll_id);
1503 }
1504 return pll_in_use;
1505}
1506
1507/**
1508 * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP
1509 *
1510 * @crtc: drm crtc
1511 *
1512 * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
1513 * also in DP mode. For DP, a single PPLL can be used for all DP
1514 * crtcs/encoders.
1515 */
1516static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
1517{
1518 struct drm_device *dev = crtc->dev;
1519 struct drm_encoder *test_encoder;
1520 struct radeon_crtc *radeon_test_crtc;
1521
1522 list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
1523 if (test_encoder->crtc && (test_encoder->crtc != crtc)) {
1524 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
1525 /* for DP use the same PLL for all */
1526 radeon_test_crtc = to_radeon_crtc(test_encoder->crtc);
1527 if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
1528 return radeon_test_crtc->pll_id;
1529 }
1530 }
1531 }
1532 return ATOM_PPLL_INVALID;
1533}
1534
1535/**
1536 * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc.
1537 *
1538 * @crtc: drm crtc
1539 *
1540 * Returns the PPLL (Pixel PLL) to be used by the crtc. For DP monitors
1541 * a single PPLL can be used for all DP crtcs/encoders. For non-DP
1542 * monitors a dedicated PPLL must be used. If a particular board has
1543 * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
1544 * as there is no need to program the PLL itself. If we are not able to
1545 * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
1546 * avoid messing up an existing monitor.
1547 *
1548 * Asic specific PLL information
1549 *
1550 * DCE 6.1
1551 * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
1552 * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
1553 *
1554 * DCE 6.0
1555 * - PPLL0 is available to all UNIPHY (DP only)
1556 * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
1557 *
1558 * DCE 5.0
1559 * - DCPLL is available to all UNIPHY (DP only)
1560 * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
1561 *
1562 * DCE 3.0/4.0/4.1
1563 * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
1564 *
1565 */
1566static int radeon_atom_pick_pll(struct drm_crtc *crtc) 1482static int radeon_atom_pick_pll(struct drm_crtc *crtc)
1567{ 1483{
1568 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 1484 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
1569 struct drm_device *dev = crtc->dev; 1485 struct drm_device *dev = crtc->dev;
1570 struct radeon_device *rdev = dev->dev_private; 1486 struct radeon_device *rdev = dev->dev_private;
1571 struct drm_encoder *test_encoder; 1487 struct drm_encoder *test_encoder;
1572 u32 pll_in_use; 1488 struct drm_crtc *test_crtc;
1573 int pll; 1489 uint32_t pll_in_use = 0;
1574 1490
1575 if (ASIC_IS_DCE61(rdev)) { 1491 if (ASIC_IS_DCE61(rdev)) {
1576 list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { 1492 list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
@@ -1582,40 +1498,32 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
1582 1498
1583 if ((test_radeon_encoder->encoder_id == 1499 if ((test_radeon_encoder->encoder_id ==
1584 ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && 1500 ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
1585 (dig->linkb == false)) 1501 (dig->linkb == false)) /* UNIPHY A uses PPLL2 */
1586 /* UNIPHY A uses PPLL2 */
1587 return ATOM_PPLL2; 1502 return ATOM_PPLL2;
1588 else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
1589 /* UNIPHY B/C/D/E/F */
1590 if (rdev->clock.dp_extclk)
1591 /* skip PPLL programming if using ext clock */
1592 return ATOM_PPLL_INVALID;
1593 else {
1594 /* use the same PPLL for all DP monitors */
1595 pll = radeon_get_shared_dp_ppll(crtc);
1596 if (pll != ATOM_PPLL_INVALID)
1597 return pll;
1598 }
1599 }
1600 break;
1601 } 1503 }
1602 } 1504 }
1603 /* UNIPHY B/C/D/E/F */ 1505 /* UNIPHY B/C/D/E/F */
1604 pll_in_use = radeon_get_pll_use_mask(crtc); 1506 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1605 if (!(pll_in_use & (1 << ATOM_PPLL0))) 1507 struct radeon_crtc *radeon_test_crtc;
1508
1509 if (crtc == test_crtc)
1510 continue;
1511
1512 radeon_test_crtc = to_radeon_crtc(test_crtc);
1513 if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
1514 (radeon_test_crtc->pll_id == ATOM_PPLL1))
1515 pll_in_use |= (1 << radeon_test_crtc->pll_id);
1516 }
1517 if (!(pll_in_use & 4))
1606 return ATOM_PPLL0; 1518 return ATOM_PPLL0;
1607 if (!(pll_in_use & (1 << ATOM_PPLL1))) 1519 return ATOM_PPLL1;
1608 return ATOM_PPLL1;
1609 DRM_ERROR("unable to allocate a PPLL\n");
1610 return ATOM_PPLL_INVALID;
1611 } else if (ASIC_IS_DCE4(rdev)) { 1520 } else if (ASIC_IS_DCE4(rdev)) {
1612 list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { 1521 list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
1613 if (test_encoder->crtc && (test_encoder->crtc == crtc)) { 1522 if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
1614 /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, 1523 /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
1615 * depending on the asic: 1524 * depending on the asic:
1616 * DCE4: PPLL or ext clock 1525 * DCE4: PPLL or ext clock
1617 * DCE5: PPLL, DCPLL, or ext clock 1526 * DCE5: DCPLL or ext clock
1618 * DCE6: PPLL, PPLL0, or ext clock
1619 * 1527 *
1620 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip 1528 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
1621 * PPLL/DCPLL programming and only program the DP DTO for the 1529 * PPLL/DCPLL programming and only program the DP DTO for the
@@ -1623,34 +1531,31 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
1623 */ 1531 */
1624 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { 1532 if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
1625 if (rdev->clock.dp_extclk) 1533 if (rdev->clock.dp_extclk)
1626 /* skip PPLL programming if using ext clock */
1627 return ATOM_PPLL_INVALID; 1534 return ATOM_PPLL_INVALID;
1628 else if (ASIC_IS_DCE6(rdev)) 1535 else if (ASIC_IS_DCE6(rdev))
1629 /* use PPLL0 for all DP */
1630 return ATOM_PPLL0; 1536 return ATOM_PPLL0;
1631 else if (ASIC_IS_DCE5(rdev)) 1537 else if (ASIC_IS_DCE5(rdev))
1632 /* use DCPLL for all DP */
1633 return ATOM_DCPLL; 1538 return ATOM_DCPLL;
1634 else {
1635 /* use the same PPLL for all DP monitors */
1636 pll = radeon_get_shared_dp_ppll(crtc);
1637 if (pll != ATOM_PPLL_INVALID)
1638 return pll;
1639 }
1640 } 1539 }
1641 break;
1642 } 1540 }
1643 } 1541 }
1644 /* all other cases */ 1542
1645 pll_in_use = radeon_get_pll_use_mask(crtc); 1543 /* otherwise, pick one of the plls */
1646 if (!(pll_in_use & (1 << ATOM_PPLL2))) 1544 list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
1647 return ATOM_PPLL2; 1545 struct radeon_crtc *radeon_test_crtc;
1648 if (!(pll_in_use & (1 << ATOM_PPLL1))) 1546
1547 if (crtc == test_crtc)
1548 continue;
1549
1550 radeon_test_crtc = to_radeon_crtc(test_crtc);
1551 if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
1552 (radeon_test_crtc->pll_id <= ATOM_PPLL2))
1553 pll_in_use |= (1 << radeon_test_crtc->pll_id);
1554 }
1555 if (!(pll_in_use & 1))
1649 return ATOM_PPLL1; 1556 return ATOM_PPLL1;
1650 DRM_ERROR("unable to allocate a PPLL\n"); 1557 return ATOM_PPLL2;
1651 return ATOM_PPLL_INVALID;
1652 } else 1558 } else
1653 /* use PPLL1 or PPLL2 */
1654 return radeon_crtc->crtc_id; 1559 return radeon_crtc->crtc_id;
1655 1560
1656} 1561}
@@ -1792,7 +1697,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
1792 break; 1697 break;
1793 } 1698 }
1794done: 1699done:
1795 radeon_crtc->pll_id = ATOM_PPLL_INVALID; 1700 radeon_crtc->pll_id = -1;
1796} 1701}
1797 1702
1798static const struct drm_crtc_helper_funcs atombios_helper_funcs = { 1703static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
@@ -1841,6 +1746,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
1841 else 1746 else
1842 radeon_crtc->crtc_offset = 0; 1747 radeon_crtc->crtc_offset = 0;
1843 } 1748 }
1844 radeon_crtc->pll_id = ATOM_PPLL_INVALID; 1749 radeon_crtc->pll_id = -1;
1845 drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); 1750 drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
1846} 1751}
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 8acb34fd3fd5..8d7e33a0b243 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -1182,7 +1182,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
1182 ring->ready = true; 1182 ring->ready = true;
1183 radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); 1183 radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
1184 1184
1185 if (radeon_ring_supports_scratch_reg(rdev, ring)) { 1185 if (!ring->rptr_save_reg /* not resuming from suspend */
1186 && radeon_ring_supports_scratch_reg(rdev, ring)) {
1186 r = radeon_scratch_get(rdev, &ring->rptr_save_reg); 1187 r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
1187 if (r) { 1188 if (r) {
1188 DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r); 1189 DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r);