[pull] radeon drm-fixes-3.7
From: Alex Deucher Hi Dave, One last fix for 3.7 from Jerome. This fixes a display regression which results in blank displays in some cases. The following changes since commit 452f19201f35d20a1a6c9009acbcfa6799163c6a: Merge branch 'drm-fixes-3.7' of git://people.freedesktop.org/~agd5f/linux into drm-fixes (2012-11-22 13:21:57 +1000) are available in the git repository at: git://people.freedesktop.org/~agd5f/linux drm-fixes-3.7 Jerome Glisse (1): radeon: fix pll/ctrc mapping on dce2 and dce3 hardware drivers/gpu/drm/radeon/atombios_crtc.c | 48 +-- 1 files changed, 14 insertions(+), 34 deletions(-)
[pull] radeon drm-next-3.7
From: Alex Deucher Hi Dave, This is the drm-next pull request for 3.7. Most of these patches have been in my drm-next-3.7-wip branch for a while now, and I've been using it regularly now for a while. The big changes for 3.7 include: - Asynchronous VM page table updates for Cayman/SI - 2 level VM page table support. Saves memory compared to 1 level page tables. - Reworked PLL handing in the display code allows lots more combinations of monitors to work, including more than two DP displays assuming compatible clocks across shared PLLs. This also allows us to power down extra PLLs when we can share a single one across multiple displays which saves power. - Native backlight control on ATOMBIOS systems. - Improved ACPI support for interacting with the GPU. Fixes backlight control on some laptops. - Document AMD ACPI interfaces - Lots of code cleanup - Bug fixes The branch is against your drm-fixes branch due to conflicts, let me know if you have trouble pulling it in. The following changes since commit 16c58081eb95e35f284421176f355eccfc773bbe: drm/radeon: Prevent leak of scratch register on resume from suspend (2012-09-20 12:59:16 -0400) are available in the git repository at: git://people.freedesktop.org/~agd5f/linux drm-next-3.7 Alex Deucher (45): drm/radeon/dce4+: don't use radeon_crtc for vblank callback drm/radeon: clean up evergreen_get_vblank_counter drm/radeon/r1xx-r4xx: don't use radeon_crtc for vblank callback drm/radeon/r5xx-r7xx: don't use radeon_crtc for vblank callback (v2) drm/radeon: properly handle mc_stop/mc_resume on evergreen+ (v2) drm/radeon/dynpm: wait for fences on all rings when reclocking drm/radeon: remove gui_idle interrupt infrastructure drm/radeon: add new AMD ACPI header and update relevant code (v2) drm/radeon: add a license header to radeon_apci.c drm/radeon: track whether the GPU controls the backlight (v2) drm/radeon: rework legacy backlight control drm/radeon: add backlight control for atom devices (v2) drm/radeon: re-organize the acpi notifier callback drm/radeon: document radeon_acpi.c drm/radeon: update ATPX verify interface handling (v2) drm/radeon: reorganize ATPX support (v2) drm/radeon: document radeon_atpx_handler.c (v2) drm/radeon: add initial support for ATCS ACPI methods drm/radeon: rework the backlight control to be an asic callback drm/radeon/atom: add consolidate bpc code drm/radeon: document async VM changes in ni.c drm/radeon: implement bounds checking on thermal controller lookup drm/radeon: remove dead function def drm/radeon: clean up encoder dp checks drm/radeon: white space cleanup in transmitter setup drm/radeon/atom: fix typo in SetPixelClock handling drm/radeon: fix typo in atombios_get_encoder_mode drm/radeon: rework pll selection (v4) drm/radeon/dce3: use a single PPLL for all DP displays drm/radeon: allow PPLL sharing on non-DP displays drm/radeon: rework crtc pll setup to better support PPLL sharing drm/radeon: store the encoder in the radeon_crtc drm/radeon: make non-DP PPLL sharing more robust drm/radeon: work around KMS modeset limitations in PLL allocation (v2) drm/radeon: validate PPLL in crtc fixup drm/radeon: only adjust default clocks on NI GPUs drm/radeon: add get_backlight_level callback drm/radeon: restore backlight level on resume drm/radeon: Add MSI quirk for gateway RS690 drm/radeon: force MSIs on RS690 asics drm/radeon: fix radeon power state debug output drm/radeon/pm: fix multi-head profile handling on BTC+ (v2) drm/radeon: use WRITE_DATA packets for vm flush on SI drm/radeon: rework the vm_flush interface drm/radeon: add vm set_page() callback for SI Christian K?nig (18): drm/radeon: cleanup VM id handling a bit drm/radeon: move VM funcs into asic structure drm/radeon: remove vm_unbind drm/radeon: add sync helper function drm/radeon: make VM flushs a ring operation drm/radeon: rework VMID handling drm/radeon: rework VM page table handling drm/radeon: Move looping over the PTEs into chip code drm/radeon: make page table updates async v2 drm/radeon: fix VM syncing with multiple rings drm/radeon: fix VA range check drm/radeon: fix VA overlap check drm/radeon: move IB pool to 1MB offset drm/radeon: move and rename radeon_bo_va function drm/radeon: let bo_reserve take no_intr instead of no_wait param drm/radeon: fix gem_close_object handling drm/radeon: rework the VM code a bit more (v2) drm/radeon: refactor set_page chipset interface v5 Dmitry Cherkasov (1): drm/radeon: add 2-level VM pagetables support v9 Jerome Glisse (1): drm/radeon: make sure ib bo is properly bound and up to date in vm space Lauri Kasanen (2):
[PATCH 1/2] drm/radeon: use %zu for formatting size_t
From: Luca Tettamanti
Fixes compiler warnings on 32bit.
Signed-off-by: Luca Tettamanti
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_acpi.c |4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c
b/drivers/gpu/drm/radeon/radeon_acpi.c
index c3976eb..faf1ed5 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -203,7 +203,7 @@ static int radeon_atif_verify_interface(acpi_handle handle,
size = *(u16 *) info->buffer.pointer;
if (size < 12) {
- DRM_INFO("ATIF buffer is too small: %lu\n", size);
+ DRM_INFO("ATIF buffer is too small: %zu\n", size);
err = -EINVAL;
goto out;
}
@@ -487,7 +487,7 @@ static int radeon_atcs_verify_interface(acpi_handle handle,
size = *(u16 *) info->buffer.pointer;
if (size < 8) {
- DRM_INFO("ATCS buffer is too small: %lu\n", size);
+ DRM_INFO("ATCS buffer is too small: %zu\n", size);
err = -EINVAL;
goto out;
}
--
1.7.7.5
[PATCH 2/2] drm/radeon: fix compilation with backlight disabled
From: Alex Deucher
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_acpi.c|2 +
drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 42 +++---
2 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c
b/drivers/gpu/drm/radeon/radeon_acpi.c
index faf1ed5..6a4d75a 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -372,6 +372,7 @@ int radeon_atif_handler(struct radeon_device *rdev,
radeon_set_backlight_level(rdev, enc,
req.backlight_level);
+#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||
defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
if (rdev->is_atom_bios) {
struct radeon_encoder_atom_dig *dig =
enc->enc_priv;
backlight_force_update(dig->bl_dev,
@@ -381,6 +382,7 @@ int radeon_atif_handler(struct radeon_device *rdev,
backlight_force_update(dig->bl_dev,
BACKLIGHT_UPDATE_HOTKEY);
}
+#endif
}
}
/* TODO: check other events */
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 8ad9c5f..c5690de 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -269,27 +269,6 @@ static const struct drm_encoder_helper_funcs
radeon_legacy_lvds_helper_funcs = {
.disable = radeon_legacy_encoder_disable,
};
-#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||
defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
-
-static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd)
-{
- struct radeon_backlight_privdata *pdata = bl_get_data(bd);
- uint8_t level;
-
- /* Convert brightness to hardware level */
- if (bd->props.brightness < 0)
- level = 0;
- else if (bd->props.brightness > RADEON_MAX_BL_LEVEL)
- level = RADEON_MAX_BL_LEVEL;
- else
- level = bd->props.brightness;
-
- if (pdata->negative)
- level = RADEON_MAX_BL_LEVEL - level;
-
- return level;
-}
-
u8
radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder)
{
@@ -331,6 +310,27 @@ radeon_legacy_set_backlight_level(struct radeon_encoder
*radeon_encoder, u8 leve
radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode);
}
+#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||
defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
+
+static uint8_t radeon_legacy_lvds_level(struct backlight_device *bd)
+{
+ struct radeon_backlight_privdata *pdata = bl_get_data(bd);
+ uint8_t level;
+
+ /* Convert brightness to hardware level */
+ if (bd->props.brightness < 0)
+ level = 0;
+ else if (bd->props.brightness > RADEON_MAX_BL_LEVEL)
+ level = RADEON_MAX_BL_LEVEL;
+ else
+ level = bd->props.brightness;
+
+ if (pdata->negative)
+ level = RADEON_MAX_BL_LEVEL - level;
+
+ return level;
+}
+
static int radeon_legacy_backlight_update_status(struct backlight_device *bd)
{
struct radeon_backlight_privdata *pdata = bl_get_data(bd);
--
1.7.7.5
[PATCH] drm/radeon: allocate PPLLs from low to high
From: Alex Deucher
The order shouldn't matter, but there have been problems
reported on certain older asics. This behaves more
like the original code before the PPLL allocation
rework.
Signed-off-by: Alex Deucher
Cc: Markus Trippelsdorf
---
drivers/gpu/drm/radeon/atombios_crtc.c |8
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 96184d0..2e566e1 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1690,10 +1690,10 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
}
/* all other cases */
pll_in_use = radeon_get_pll_use_mask(crtc);
- if (!(pll_in_use & (1 << ATOM_PPLL2)))
- return ATOM_PPLL2;
if (!(pll_in_use & (1 << ATOM_PPLL1)))
return ATOM_PPLL1;
+ if (!(pll_in_use & (1 << ATOM_PPLL2)))
+ return ATOM_PPLL2;
DRM_ERROR("unable to allocate a PPLL\n");
return ATOM_PPLL_INVALID;
} else {
@@ -1715,10 +1715,10 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
}
/* all other cases */
pll_in_use = radeon_get_pll_use_mask(crtc);
- if (!(pll_in_use & (1 << ATOM_PPLL2)))
- return ATOM_PPLL2;
if (!(pll_in_use & (1 << ATOM_PPLL1)))
return ATOM_PPLL1;
+ if (!(pll_in_use & (1 << ATOM_PPLL2)))
+ return ATOM_PPLL2;
DRM_ERROR("unable to allocate a PPLL\n");
return ATOM_PPLL_INVALID;
} else {
--
1.7.7.5
[PATCH] drm/radeon: update comments to clarify VM setup
From: Alex Deucher
The actual set up and assignment of VM page tables
is done on the fly in radeon_gart.c.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/ni.c|4
drivers/gpu/drm/radeon/radeon_device.c |3 +++
drivers/gpu/drm/radeon/si.c|7 ---
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 48e2337..cfb9276 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -770,6 +770,10 @@ static int cayman_pcie_gart_enable(struct radeon_device
*rdev)
WREG32(0x15DC, 0);
/* empty context1-7 */
+ /* Assign the pt base to something valid for now; the pts used for
+* the VMs are determined by the application and setup and assigned
+* on the fly in the vm part of radeon_gart.c
+*/
for (i = 1; i < 8; i++) {
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), 0);
diff --git a/drivers/gpu/drm/radeon/radeon_device.c
b/drivers/gpu/drm/radeon/radeon_device.c
index 64a4264..1fad47e 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1018,6 +1018,9 @@ int radeon_device_init(struct radeon_device *rdev,
return r;
/* initialize vm here */
mutex_init(&rdev->vm_manager.lock);
+ /* FIXME start with 4G, once using 2 level pt switch to full
+* vm size space
+*/
rdev->vm_manager.max_pfn = 1 << 20;
INIT_LIST_HEAD(&rdev->vm_manager.lru_vm);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index c76825f..f272ead 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2407,12 +2407,13 @@ static int si_pcie_gart_enable(struct radeon_device
*rdev)
WREG32(0x15DC, 0);
/* empty context1-15 */
- /* FIXME start with 4G, once using 2 level pt switch to full
-* vm size space
-*/
/* set vm size, must be a multiple of 4 */
WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
+ /* Assign the pt base to something valid for now; the pts used for
+* the VMs are determined by the application and setup and assigned
+* on the fly in the vm part of radeon_gart.c
+*/
for (i = 1; i < 16; i++) {
if (i < 8)
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
--
1.7.7.5
[PATCH 1/2] drm/radeon: update comments to clarify VM setup (v2)
From: Alex Deucher
The actual set up and assignment of VM page tables
is done on the fly in radeon_gart.c.
v2: update vm size comments
Signed-off-by: Alex Deucher
Reviewed-by: Christian K?nig
---
drivers/gpu/drm/radeon/ni.c|4
drivers/gpu/drm/radeon/radeon_device.c |4
drivers/gpu/drm/radeon/si.c|7 ---
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 9a46f7d..6883e14 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -770,6 +770,10 @@ static int cayman_pcie_gart_enable(struct radeon_device
*rdev)
WREG32(0x15DC, 0);
/* empty context1-7 */
+ /* Assign the pt base to something valid for now; the pts used for
+* the VMs are determined by the application and setup and assigned
+* on the fly in the vm part of radeon_gart.c
+*/
for (i = 1; i < 8; i++) {
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), 0);
diff --git a/drivers/gpu/drm/radeon/radeon_device.c
b/drivers/gpu/drm/radeon/radeon_device.c
index 64a4264..bd13ca0 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1018,6 +1018,10 @@ int radeon_device_init(struct radeon_device *rdev,
return r;
/* initialize vm here */
mutex_init(&rdev->vm_manager.lock);
+ /* Adjust VM size here.
+* Currently set to 4GB ((1 << 20) 4k pages).
+* Max GPUVM size for cayman and SI is 40 bits.
+*/
rdev->vm_manager.max_pfn = 1 << 20;
INIT_LIST_HEAD(&rdev->vm_manager.lru_vm);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index c76825f..f272ead 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2407,12 +2407,13 @@ static int si_pcie_gart_enable(struct radeon_device
*rdev)
WREG32(0x15DC, 0);
/* empty context1-15 */
- /* FIXME start with 4G, once using 2 level pt switch to full
-* vm size space
-*/
/* set vm size, must be a multiple of 4 */
WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
+ /* Assign the pt base to something valid for now; the pts used for
+* the VMs are determined by the application and setup and assigned
+* on the fly in the vm part of radeon_gart.c
+*/
for (i = 1; i < 16; i++) {
if (i < 8)
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
--
1.7.7.5
[PATCH] drm/radeon/cayman: set VM max pfn at MC init
From: Alex Deucher
No need to emit them at VM flush as we no longer use
variable sized page tables now that we support 2 level
page tables. This matches the behavior of SI (which
does not support variable sized page tables).
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/ni.c |8 +---
1 files changed, 1 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index cfb9276..cc0701a 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -776,7 +776,7 @@ static int cayman_pcie_gart_enable(struct radeon_device
*rdev)
*/
for (i = 1; i < 8; i++) {
WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
- WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), 0);
+ WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2),
rdev->vm_manager.max_pfn);
WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
rdev->gart.table_addr >> 12);
}
@@ -1576,12 +1576,6 @@ void cayman_vm_flush(struct radeon_device *rdev, int
ridx, struct radeon_vm *vm)
if (vm == NULL)
return;
- radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_START_ADDR +
(vm->id << 2), 0));
- radeon_ring_write(ring, 0);
-
- radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_END_ADDR +
(vm->id << 2), 0));
- radeon_ring_write(ring, rdev->vm_manager.max_pfn);
-
radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR +
(vm->id << 2), 0));
radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
--
1.7.7.5
[PATCH] drm/radeon: check if pcie gen 2 is already enabled
From: Alex Deucher
If so, skip enabling it.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/evergreen.c |8 ++--
drivers/gpu/drm/radeon/r600.c |7 ++-
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index a1f49c5..888c798 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3431,9 +3431,13 @@ void evergreen_pcie_gen2_enable(struct radeon_device
*rdev)
if (!(mask & DRM_PCIE_SPEED_50))
return;
- DRM_INFO("enabling PCIE gen 2 link speeds, disable with
radeon.pcie_gen2=0\n");
-
speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+ if (speed_cntl & LC_CURRENT_DATA_RATE) {
+ DRM_INFO("PCIE gen 2 link speeds already enabled\n");
+ return;
+ } else
+ DRM_INFO("enabling PCIE gen 2 link speeds, disable with
radeon.pcie_gen2=0\n");
+
if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
(speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 70c800f..20e4fad 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -3703,7 +3703,12 @@ static void r600_pcie_gen2_enable(struct radeon_device
*rdev)
if (!(mask & DRM_PCIE_SPEED_50))
return;
- DRM_INFO("enabling PCIE gen 2 link speeds, disable with
radeon.pcie_gen2=0\n");
+ speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+ if (speed_cntl & LC_CURRENT_DATA_RATE) {
+ DRM_INFO("PCIE gen 2 link speeds already enabled\n");
+ return;
+ } else
+ DRM_INFO("enabling PCIE gen 2 link speeds, disable with
radeon.pcie_gen2=0\n");
/* 55 nm r6xx asics */
if ((rdev->family == CHIP_RV670) ||
--
1.7.7.5
[PATCH] drm/radeon: check if pcie gen 2 is already enabled (v2)
From: Alex Deucher
If so, skip enabling it to save time.
v2: coding style fixes
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/evergreen.c |7 ++-
drivers/gpu/drm/radeon/r600.c |6 ++
2 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index a1f49c5..14313ad 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3431,9 +3431,14 @@ void evergreen_pcie_gen2_enable(struct radeon_device
*rdev)
if (!(mask & DRM_PCIE_SPEED_50))
return;
+ speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+ if (speed_cntl & LC_CURRENT_DATA_RATE) {
+ DRM_INFO("PCIE gen 2 link speeds already enabled\n");
+ return;
+ }
+
DRM_INFO("enabling PCIE gen 2 link speeds, disable with
radeon.pcie_gen2=0\n");
- speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
(speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 70c800f..cda280d 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -3703,6 +3703,12 @@ static void r600_pcie_gen2_enable(struct radeon_device
*rdev)
if (!(mask & DRM_PCIE_SPEED_50))
return;
+ speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
+ if (speed_cntl & LC_CURRENT_DATA_RATE) {
+ DRM_INFO("PCIE gen 2 link speeds already enabled\n");
+ return;
+ }
+
DRM_INFO("enabling PCIE gen 2 link speeds, disable with
radeon.pcie_gen2=0\n");
/* 55 nm r6xx asics */
--
1.7.7.5
[pull] radeon drm-fixes-3.7
From: Alex Deucher Hi Dave, This is the first -fixes pull for 3.7. I would have preferred to have gotten it out a bit sooner, but I was on holiday last week. - Cleanup of the new 2 level page table code it get it in better shape and using less memory. - Fix some display issues related to the PLL rework. - Fix some cmpiler warnings and errors with certain config options. - Other misc bug fixes. The following changes since commit ceb736c395058699dc82e5efdb2a9279a5b29451: Merge branch 'drm-nouveau-fixes' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next (2012-10-09 14:48:46 +1000) are available in the git repository at: git://people.freedesktop.org/~agd5f/linux drm-fixes-3.7 Alex Deucher (5): drm/radeon: fix compilation with backlight disabled drm/radeon: allocate PPLLs from low to high drm/radeon: update comments to clarify VM setup (v2) drm/radeon/cayman: set VM max pfn at MC init drm/radeon: check if pcie gen 2 is already enabled (v2) Christian K?nig (3): drm/radeon: allocate page tables on demand v4 drm/radeon: don't add the IB pool to all VMs v2 drm/radeon: separate pt alloc from lru add Egbert Eich (1): drm/radeon: Don't destroy I2C Bus Rec in radeon_ext_tmds_enc_destroy(). Luca Tettamanti (1): drm/radeon: use %zu for formatting size_t Thomas Friebel (1): drm/radeon: fix spelling typos in debugging output drivers/gpu/drm/radeon/atombios_crtc.c |8 +- drivers/gpu/drm/radeon/evergreen.c |7 +- drivers/gpu/drm/radeon/ni.c | 12 +- drivers/gpu/drm/radeon/r600.c |6 + drivers/gpu/drm/radeon/radeon.h | 14 +- drivers/gpu/drm/radeon/radeon_acpi.c|6 +- drivers/gpu/drm/radeon/radeon_cs.c |1 + drivers/gpu/drm/radeon/radeon_device.c |4 + drivers/gpu/drm/radeon/radeon_gart.c| 374 --- drivers/gpu/drm/radeon/radeon_kms.c | 22 ++- drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 48 ++-- drivers/gpu/drm/radeon/radeon_ring.c|2 +- drivers/gpu/drm/radeon/si.c |7 +- 13 files changed, 359 insertions(+), 152 deletions(-)
[PATCH] drm/radeon: add some new SI PCI ids
From: Alex Deucher
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
include/drm/drm_pciids.h |3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index c78bb99..af1cbaf 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -205,6 +205,8 @@
{0x1002, 0x6788, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
{0x1002, 0x678A, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6790, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6791, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6792, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6799, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
{0x1002, 0x679A, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_TAHITI|RADEON_NEW_MEMMAP}, \
@@ -217,6 +219,7 @@
{0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6811, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6816, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6817, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
--
1.7.7.5
[PATCH] drm/radeon: give each backlight a unique id
From: Alex Deucher
In cases where we have multiple radeons with backlight controls.
Should fix:
https://bugzilla.kernel.org/show_bug.cgi?id=48941
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_encoders.c |5 -
drivers/gpu/drm/radeon/radeon_legacy_encoders.c |5 -
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c
b/drivers/gpu/drm/radeon/atombios_encoders.c
index 806cbcc..a9a059c 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -184,6 +184,7 @@ void radeon_atom_backlight_init(struct radeon_encoder
*radeon_encoder,
struct radeon_backlight_privdata *pdata;
struct radeon_encoder_atom_dig *dig;
u8 backlight_level;
+ char bl_name[16];
if (!radeon_encoder->enc_priv)
return;
@@ -203,7 +204,9 @@ void radeon_atom_backlight_init(struct radeon_encoder
*radeon_encoder,
memset(&props, 0, sizeof(props));
props.max_brightness = RADEON_MAX_BL_LEVEL;
props.type = BACKLIGHT_RAW;
- bd = backlight_device_register("radeon_bl", &drm_connector->kdev,
+ snprintf(bl_name, sizeof(bl_name),
+"radeon_bl%d", dev->primary->index);
+ bd = backlight_device_register(bl_name, &drm_connector->kdev,
pdata, &radeon_atom_backlight_ops,
&props);
if (IS_ERR(bd)) {
DRM_ERROR("Backlight registration failed\n");
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 8ad9c5f..687b07c 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -370,6 +370,7 @@ void radeon_legacy_backlight_init(struct radeon_encoder
*radeon_encoder,
struct backlight_properties props;
struct radeon_backlight_privdata *pdata;
uint8_t backlight_level;
+ char bl_name[16];
if (!radeon_encoder->enc_priv)
return;
@@ -389,7 +390,9 @@ void radeon_legacy_backlight_init(struct radeon_encoder
*radeon_encoder,
memset(&props, 0, sizeof(props));
props.max_brightness = RADEON_MAX_BL_LEVEL;
props.type = BACKLIGHT_RAW;
- bd = backlight_device_register("radeon_bl", &drm_connector->kdev,
+ snprintf(bl_name, sizeof(bl_name),
+"radeon_bl%d", dev->primary->index);
+ bd = backlight_device_register(bl_name, &drm_connector->kdev,
pdata, &radeon_backlight_ops, &props);
if (IS_ERR(bd)) {
DRM_ERROR("Backlight registration failed\n");
--
1.7.7.5
[PATCH] drm/radeon: add error output if VM CS fails on cayman
From: Alex Deucher
So we know why the CS was rejected.
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/evergreen_cs.c |1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c
b/drivers/gpu/drm/radeon/evergreen_cs.c
index 573ed1b..30271b64 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -2829,6 +2829,7 @@ static bool evergreen_vm_reg_valid(u32 reg)
case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS:
return true;
default:
+ DRM_ERROR("Invalid register 0x%x in CS\n", reg);
return false;
}
}
--
1.7.7.5
[PATCH] drm/radeon: fix ATPX regression in acpi rework
From: Alex Deucher
Copy and paste typo in the apci rework.
Fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=49351
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_atpx_handler.c |2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 5c5e5bb..37f6a90 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -87,7 +87,7 @@ static union acpi_object *radeon_atpx_call(acpi_handle
handle, int function,
atpx_arg_elements[1].integer.value = 0;
}
- status = acpi_evaluate_object(handle, "ATPX", &atpx_arg, &buffer);
+ status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
/* Fail only if calling the method fails and ATPX is supported */
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
--
1.7.7.5
[pull] radeon drm-fixes-3.7
From: Alex Deucher Hi Dave, Fixes pull request for radeon. The main things here are fixing a ATPX regression from the acpi rework, fixing some fallout from the async VM work, and fixing some module options that were broken in certain cases. Other than that, mainly just bug fixes. The following changes since commit b8e902f24fdd16c4373ddc37a4e150c4afe9c6db: drm/ttm: Fix a theoretical race in ttm_bo_cleanup_refs() (2012-10-23 10:15:21 +1000) are available in the git repository at: git://people.freedesktop.org/~agd5f/linux drm-fixes-3.7 Alex Deucher (6): drm/radeon: add some new SI PCI ids drm/radeon: fix sparse warning drm/radeon: give each backlight a unique id drm/radeon: add error output if VM CS fails on cayman drm/radeon: fix ATPX function documentation drm/radeon: fix ATPX regression in acpi rework Christian K?nig (9): drm/radeon: fix PFP sync in vm_flush drm/radeon: fix cayman_vm_set_page v2 drm/radeon: fix si_set_page v2 drm/radeon: remove set_page check from VM code drm/radeon: fix header size estimation in VM code drm/radeon: fix and simplify pot argument checks v3 drm/radeon: use vzalloc for gart pages drm/radeon: move size limits to gem_object_create. drm/radeon: move the retry to gem_object_create drivers/gpu/drm/radeon/atombios_encoders.c |5 ++- drivers/gpu/drm/radeon/evergreen_cs.c |1 + drivers/gpu/drm/radeon/ni.c | 45 ++--- drivers/gpu/drm/radeon/nid.h|1 + drivers/gpu/drm/radeon/radeon_atpx_handler.c|6 +- drivers/gpu/drm/radeon/radeon_device.c | 60 +-- drivers/gpu/drm/radeon/radeon_gart.c| 22 - drivers/gpu/drm/radeon/radeon_gem.c | 18 ++- drivers/gpu/drm/radeon/radeon_legacy_encoders.c |5 ++- drivers/gpu/drm/radeon/radeon_object.c | 19 --- drivers/gpu/drm/radeon/si.c | 47 +++--- include/drm/drm_pciids.h|3 + 12 files changed, 122 insertions(+), 110 deletions(-)
[PATCH] drm/radeon: add load detection support for ext DAC on R200
From: Alex Deucher
The R200 asics use an external DAC for the secondary DAC.
The current KMS code tries to use code for the integrated
TV DAC for R200 which leads to unpredictable results since
R200 does not have an integrated TV DAC. This patch ports
the external DAC load detection support from the UMS
driver to KMS.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 97 +++
1 files changed, 97 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 817392f..8c1b812 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -1422,6 +1422,96 @@ static bool radeon_legacy_tv_detect(struct drm_encoder
*encoder,
return found;
}
+static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder,
+struct drm_connector *connector)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
+ uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b,
disp_lin_trans_grph_c;
+ uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e,
disp_lin_trans_grph_f;
+ uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp;
+ uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
+ bool found = false;
+ int i;
+
+ /* save the regs we need */
+ gpio_monid = RREG32(RADEON_GPIO_MONID);
+ fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
+ disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
+ crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
+ disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A);
+ disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B);
+ disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C);
+ disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D);
+ disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E);
+ disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F);
+ crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP);
+ crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP);
+ crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID);
+ crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+ tmp = RREG32(RADEON_GPIO_MONID);
+ tmp &= ~RADEON_GPIO_A_0;
+ WREG32(RADEON_GPIO_MONID, tmp);
+
+ WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON |
+RADEON_FP2_PANEL_FORMAT |
+R200_FP2_SOURCE_SEL_TRANS_UNIT |
+RADEON_FP2_DVO_EN |
+R200_FP2_DVO_RATE_SEL_SDR));
+
+ WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX |
+RADEON_DISP_TRANS_MATRIX_GRAPHICS));
+
+ WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN |
+ RADEON_CRTC2_DISP_REQ_EN_B));
+
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x03f0);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x03f0);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x03f0);
+
+ WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x0108);
+ WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x0800);
+ WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+ WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x0080);
+
+ for (i = 0; i < 200; i++) {
+ tmp = RREG32(RADEON_GPIO_MONID);
+ if (tmp & RADEON_GPIO_Y_0)
+ found = true;
+
+ if (!found)
+ break;
+
+ if (!drm_can_sleep())
+ mdelay(1);
+ else
+ msleep(1);
+ }
+
+ /* restore the regs we used */
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
+ WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
+ WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
+ WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
+ WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
+ WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+ WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+ WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl)
[PATCH] drm/radeon: add load detection support for ext DAC on R200 (v2)
From: Alex Deucher
The R200 asics use an external DAC for the secondary DAC.
The current KMS code tries to use code for the integrated
TV DAC for R200 which leads to unpredictable results since
R200 does not have an integrated TV DAC. This patch ports
the external DAC load detection support from the UMS
driver to KMS.
v2: fix typo in loop break logic
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 97 +++
1 files changed, 97 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 817392f..f5ba224 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -1422,6 +1422,96 @@ static bool radeon_legacy_tv_detect(struct drm_encoder
*encoder,
return found;
}
+static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder,
+struct drm_connector *connector)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
+ uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b,
disp_lin_trans_grph_c;
+ uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e,
disp_lin_trans_grph_f;
+ uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp;
+ uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
+ bool found = false;
+ int i;
+
+ /* save the regs we need */
+ gpio_monid = RREG32(RADEON_GPIO_MONID);
+ fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
+ disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
+ crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
+ disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A);
+ disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B);
+ disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C);
+ disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D);
+ disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E);
+ disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F);
+ crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP);
+ crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP);
+ crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID);
+ crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+ tmp = RREG32(RADEON_GPIO_MONID);
+ tmp &= ~RADEON_GPIO_A_0;
+ WREG32(RADEON_GPIO_MONID, tmp);
+
+ WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON |
+RADEON_FP2_PANEL_FORMAT |
+R200_FP2_SOURCE_SEL_TRANS_UNIT |
+RADEON_FP2_DVO_EN |
+R200_FP2_DVO_RATE_SEL_SDR));
+
+ WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX |
+RADEON_DISP_TRANS_MATRIX_GRAPHICS));
+
+ WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN |
+ RADEON_CRTC2_DISP_REQ_EN_B));
+
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x03f0);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x03f0);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x03f0);
+
+ WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x0108);
+ WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x0800);
+ WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+ WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x0080);
+
+ for (i = 0; i < 200; i++) {
+ tmp = RREG32(RADEON_GPIO_MONID);
+ if (tmp & RADEON_GPIO_Y_0)
+ found = true;
+
+ if (found)
+ break;
+
+ if (!drm_can_sleep())
+ mdelay(1);
+ else
+ msleep(1);
+ }
+
+ /* restore the regs we used */
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
+ WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
+ WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
+ WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
+ WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
+ WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
+ WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+ WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+ WREG32(R
[PATCH] drm/radeon: rework pll selection (v3)
From: Alex Deucher
For DP we can use the same PPLL for all active DP
encoders. Take advantage of that to prevent cases
where we may end up sharing a PPLL between DP and
non-DP which won't work. Also clean up the code
a bit.
v2: - fix missing pll_id assignment in crtc init
v3: - fix DP PPLL check
- document functions
- break in main encoder search loop after matching.
no need to keep checking additional encoders.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_crtc.c | 163 +---
1 files changed, 129 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 2817101..e721e30 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1479,14 +1479,98 @@ static void radeon_legacy_atom_fixup(struct drm_crtc
*crtc)
}
}
+/**
+ * radeon_get_pll_use_mask - look up a mask of which pplls are in use
+ *
+ * @crtc: drm crtc
+ *
+ * Returns the mask of which PPLLs (Pixel PLLs) are in use.
+ */
+static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *test_crtc;
+ struct radeon_crtc *radeon_test_crtc;
+ u32 pll_in_use = 0;
+
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+
+ radeon_test_crtc = to_radeon_crtc(test_crtc);
+ if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
+ pll_in_use |= (1 << radeon_test_crtc->pll_id);
+ }
+ return pll_in_use;
+}
+
+/**
+ * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP
+ *
+ * @crtc: drm crtc
+ *
+ * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
+ * also in DP mode. For DP, a single PPLL can be used for all DP
+ * crtcs/encoders.
+ */
+static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_encoder *test_encoder;
+ struct radeon_crtc *radeon_test_crtc;
+
+ list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head)
{
+ if (test_encoder->crtc && (test_encoder->crtc != crtc)) {
+ if
(ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
+ /* for DP use the same PLL for all */
+ radeon_test_crtc =
to_radeon_crtc(test_encoder->crtc);
+ if (radeon_test_crtc->pll_id !=
ATOM_PPLL_INVALID)
+ return radeon_test_crtc->pll_id;
+ }
+ }
+ }
+ return ATOM_PPLL_INVALID;
+}
+
+/**
+ * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc.
+ *
+ * @crtc: drm crtc
+ *
+ * Returns the PPLL (Pixel PLL) to be used by the crtc. For DP monitors
+ * a single PPLL can be used for all DP crtcs/encoders. For non-DP
+ * monitors a dedicated PPLL must be used. If a particular board has
+ * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
+ * as there is no need to program the PLL itself. If we are not able to
+ * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
+ * avoid messing up an existing monitor.
+ *
+ * Asic specific PLL information
+ *
+ * DCE 6.1
+ * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
+ * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
+ *
+ * DCE 6.0
+ * - PPLL0 is available to all UNIPHY (DP only)
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
+ * DCE 5.0
+ * - DCPLL is available to all UNIPHY (DP only)
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
+ * DCE 3.0/4.0/4.1
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
+ */
static int radeon_atom_pick_pll(struct drm_crtc *crtc)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
struct drm_encoder *test_encoder;
- struct drm_crtc *test_crtc;
- uint32_t pll_in_use = 0;
+ u32 pll_in_use;
+ int pll;
if (ASIC_IS_DCE61(rdev)) {
list_for_each_entry(test_encoder,
&dev->mode_config.encoder_list, head) {
@@ -1498,32 +1582,40 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
if ((test_radeon_encoder->encoder_id ==
ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
- (dig->linkb == false)) /* UNIPHY A uses
PPLL2 */
+ (dig->linkb == false))
+ /* UNIPHY A uses PPLL2 */
return ATOM_PPLL2;
+
[PATCH 1/3] drm/radeon/kms: add some loop timeouts in pageflip code
From: Alex Deucher
Avoid infinite loops waiting for surface updates if a GPU
reset happens while waiting for a page flip.
See:
https://bugs.freedesktop.org/show_bug.cgi?id=43191
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
Cc: Mario Kleiner
---
drivers/gpu/drm/radeon/evergreen.c |7 ++-
drivers/gpu/drm/radeon/r100.c |7 ++-
drivers/gpu/drm/radeon/rs600.c |7 ++-
drivers/gpu/drm/radeon/rv770.c |7 ++-
4 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index 99cdc5d..e78feab 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -84,6 +84,7 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int
crtc_id, u64 crtc_base)
{
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
+ int i;
/* Lock the graphics update lock */
tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
@@ -101,7 +102,11 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int
crtc_id, u64 crtc_base)
(u32)crtc_base);
/* Wait for update_pending to go high. */
- while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) &
EVERGREEN_GRPH_SURFACE_UPDATE_PENDING));
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) &
EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)
+ break;
+ udelay(1);
+ }
DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside vblank */
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 4e71da0..d7fd5aa 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -187,13 +187,18 @@ u32 r100_page_flip(struct radeon_device *rdev, int
crtc_id, u64 crtc_base)
{
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
+ int i;
/* Lock the graphics update lock */
/* update the scanout addresses */
WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
/* Wait for update_pending to go high. */
- while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) &
RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET));
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) &
RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
+ break;
+ udelay(1);
+ }
DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside vblank */
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 8ce17ed..8a52cf0 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -62,6 +62,7 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id,
u64 crtc_base)
{
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
+ int i;
/* Lock the graphics update lock */
tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
@@ -74,7 +75,11 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id,
u64 crtc_base)
(u32)crtc_base);
/* Wait for update_pending to go high. */
- while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
+ for (i = 0; i < rdev->usec_timeout; i++) {
+ if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
+ break;
+ udelay(1);
+ }
DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
/* Unlock the lock, so double-buffering can take place inside vblank */
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index a9242e6..7bec3f4 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -47,6 +47,7 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id,
u64 crtc_base)
{
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
+ int i;
/* Lock the graphics update lock */
tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
@@ -66,7 +67,11 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id,
u64 crtc_base)
(u32)crtc_base);
/* Wait for update_pending to go high. */
- while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) &
AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
+ for (i = 0; i < rdev->usec_timeout; i++) {
+
[PATCH 2/3] drm/radeon/kms: fix scanout of 2D tiled buffers on EG/CM
From: Alex Deucher
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=43191
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_crtc.c | 35 ++-
drivers/gpu/drm/radeon/evergreen_reg.h | 29 ++
2 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 87631fe..2b97262 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1107,9 +1107,40 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
return -EINVAL;
}
- if (tiling_flags & RADEON_TILING_MACRO)
+ if (tiling_flags & RADEON_TILING_MACRO) {
+ if (rdev->family >= CHIP_CAYMAN)
+ tmp = rdev->config.cayman.tile_config;
+ else
+ tmp = rdev->config.evergreen.tile_config;
+
+ switch ((tmp & 0xf0) >> 4) {
+ case 0: /* 4 banks */
+ fb_format |=
EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK);
+ break;
+ case 1: /* 8 banks */
+ default:
+ fb_format |=
EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK);
+ break;
+ case 2: /* 16 banks */
+ fb_format |=
EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK);
+ break;
+ }
+
+ switch ((tmp & 0xf000) >> 12) {
+ case 0: /* 1KB rows */
+ default:
+ fb_format |=
EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB);
+ break;
+ case 1: /* 2KB rows */
+ fb_format |=
EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB);
+ break;
+ case 2: /* 4KB rows */
+ fb_format |=
EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB);
+ break;
+ }
+
fb_format |=
EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
- else if (tiling_flags & RADEON_TILING_MICRO)
+ } else if (tiling_flags & RADEON_TILING_MICRO)
fb_format |=
EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
switch (radeon_crtc->crtc_id) {
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h
b/drivers/gpu/drm/radeon/evergreen_reg.h
index c781c92..7d7f215 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -42,6 +42,17 @@
# define EVERGREEN_GRPH_DEPTH_8BPP0
# define EVERGREEN_GRPH_DEPTH_16BPP 1
# define EVERGREEN_GRPH_DEPTH_32BPP 2
+# define EVERGREEN_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2)
+# define EVERGREEN_ADDR_SURF_2_BANK 0
+# define EVERGREEN_ADDR_SURF_4_BANK 1
+# define EVERGREEN_ADDR_SURF_8_BANK 2
+# define EVERGREEN_ADDR_SURF_16_BANK 3
+# define EVERGREEN_GRPH_Z(x) (((x) & 0x3) << 4)
+# define EVERGREEN_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6)
+# define EVERGREEN_ADDR_SURF_BANK_WIDTH_1 0
+# define EVERGREEN_ADDR_SURF_BANK_WIDTH_2 1
+# define EVERGREEN_ADDR_SURF_BANK_WIDTH_4 2
+# define EVERGREEN_ADDR_SURF_BANK_WIDTH_8 3
# define EVERGREEN_GRPH_FORMAT(x) (((x) & 0x7) << 8)
/* 8 BPP */
# define EVERGREEN_GRPH_FORMAT_INDEXED0
@@ -61,6 +72,24 @@
# define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5
# define EVERGREEN_GRPH_FORMAT_RGB10 6
# define EVERGREEN_GRPH_FORMAT_BGR10 7
+# define EVERGREEN_GRPH_BANK_HEIGHT(x)(((x) & 0x3) << 11)
+# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_10
+# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_21
+# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_42
+# define EVERGREEN_ADDR_SURF_BANK_HEIGHT_83
+# define EVERGREEN_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13)
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_64B 0
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_128B 1
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_256B 2
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_512B 3
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB 4
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB 5
+# define EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB 6
+# define EVERGREEN_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18)
+# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1 0
+# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2 1
+# define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4 2
+# define E
[PATCH 3/3] drm/radeon/kms: fix 2D tiling CS support on EG/CM
From: Alex Deucher
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=43191
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/evergreen_cs.c | 149 +++--
drivers/gpu/drm/radeon/evergreend.h | 31 +++
2 files changed, 154 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c
b/drivers/gpu/drm/radeon/evergreen_cs.c
index 38e1bda..cd4590a 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -38,6 +38,7 @@ struct evergreen_cs_track {
u32 group_size;
u32 nbanks;
u32 npipes;
+ u32 row_size;
/* value we track */
u32 nsamples;
u32 cb_color_base_last[12];
@@ -77,6 +78,44 @@ struct evergreen_cs_track {
struct radeon_bo*db_s_write_bo;
};
+static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
+{
+ if (tiling_flags & RADEON_TILING_MACRO)
+ return ARRAY_2D_TILED_THIN1;
+ else if (tiling_flags & RADEON_TILING_MICRO)
+ return ARRAY_1D_TILED_THIN1;
+ else
+ return ARRAY_LINEAR_GENERAL;
+}
+
+static u32 evergreen_cs_get_num_banks(u32 nbanks)
+{
+ switch (nbanks) {
+ case 2:
+ return ADDR_SURF_2_BANK;
+ case 4:
+ return ADDR_SURF_4_BANK;
+ case 8:
+ default:
+ return ADDR_SURF_8_BANK;
+ case 16:
+ return ADDR_SURF_16_BANK;
+ }
+}
+
+static u32 evergreen_cs_get_tile_split(u32 row_size)
+{
+ switch (row_size) {
+ case 1:
+ default:
+ return ADDR_SURF_TILE_SPLIT_1KB;
+ case 2:
+ return ADDR_SURF_TILE_SPLIT_2KB;
+ case 4:
+ return ADDR_SURF_TILE_SPLIT_4KB;
+ }
+}
+
static void evergreen_cs_track_init(struct evergreen_cs_track *track)
{
int i;
@@ -490,12 +529,11 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser
*p, u32 reg, u32 idx)
}
ib[idx] &= ~Z_ARRAY_MODE(0xf);
track->db_z_info &= ~Z_ARRAY_MODE(0xf);
+ ib[idx] |=
Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+ track->db_z_info |=
Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
- ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- track->db_z_info |=
Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- } else {
- ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
- track->db_z_info |=
Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+ ib[idx] |=
DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+ ib[idx] |=
DB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
}
}
break;
@@ -618,13 +656,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser
*p, u32 reg, u32 idx)
"0x%04X\n", reg);
return -EINVAL;
}
- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
- ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- track->cb_color_info[tmp] |=
CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- } else if (reloc->lobj.tiling_flags &
RADEON_TILING_MICRO) {
- ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
- track->cb_color_info[tmp] |=
CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
- }
+ ib[idx] |=
CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+ track->cb_color_info[tmp] |=
CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
}
break;
case CB_COLOR8_INFO:
@@ -640,13 +673,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser
*p, u32 reg, u32 idx)
"0x%04X\n", reg);
return -EINVAL;
}
- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
- ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- track->cb_color_info[tmp] |=
CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
- } else if (reloc->lobj.tiling_flags &
RADEON_TILING_MICRO) {
- ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
- track->cb_color_info[t
[PATCH] drm/radeon/kms: Fix logic error in DP HPD handler
From: Alex Deucher
Only disable the pipe if the monitor is physically
disconnected. The previous logic also disabled the
pipe if the link was trained.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41248
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/radeon_connectors.c |8
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c
b/drivers/gpu/drm/radeon/radeon_connectors.c
index c4b8741..bce63fd 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -68,11 +68,11 @@ void radeon_connector_hotplug(struct drm_connector
*connector)
if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
int saved_dpms = connector->dpms;
- if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) &&
- radeon_dp_needs_link_train(radeon_connector))
- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
- else
+ /* Only turn off the display it it's physically disconnected */
+ if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+ else if (radeon_dp_needs_link_train(radeon_connector))
+ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
connector->dpms = saved_dpms;
}
}
--
1.7.1.1
[PATCH 1/2] drm/radeon/kms: fix regression in DP aux defer handling
From: Alex Deucher
An incorrect ordering in the error checking code lead
to DP aux defer being skipped in the aux native write
path. Move the bytes transferred check (ret == 0)
below the defer check.
Tracked down by: Brad Campbell
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41121
Signed-off-by: Alex Deucher
Cc: Brad Campbell
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/atombios_dp.c |4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c
b/drivers/gpu/drm/radeon/atombios_dp.c
index 7ad43c6..f526fa7 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -158,14 +158,14 @@ static int radeon_dp_aux_native_read(struct
radeon_connector *radeon_connector,
while (1) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, recv, recv_bytes,
delay, &ack);
- if (ret == 0)
- return -EPROTO;
if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
return ret;
else if ((ack & AUX_NATIVE_REPLY_MASK) ==
AUX_NATIVE_REPLY_DEFER)
udelay(400);
+ else if (ret == 0)
+ return -EPROTO;
else
return -EIO;
}
--
1.7.1.1
[PATCH 2/2] drm/radeon/kms: add retry limits for native DP aux defer
From: Alex Deucher
The previous code could potentially loop forever. Limit
the number of DP aux defer retries to 4 for native aux
transactions, same as i2c over aux transactions.
Noticed by: Brad Campbell
Signed-off-by: Alex Deucher
Cc: Brad Campbell
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/atombios_dp.c | 12
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c
b/drivers/gpu/drm/radeon/atombios_dp.c
index f526fa7..4da2388 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -115,6 +115,7 @@ static int radeon_dp_aux_native_write(struct
radeon_connector *radeon_connector,
u8 msg[20];
int msg_bytes = send_bytes + 4;
u8 ack;
+ unsigned retry;
if (send_bytes > 16)
return -1;
@@ -125,20 +126,20 @@ static int radeon_dp_aux_native_write(struct
radeon_connector *radeon_connector,
msg[3] = (msg_bytes << 4) | (send_bytes - 1);
memcpy(&msg[4], send, send_bytes);
- while (1) {
+ for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, NULL, 0, delay,
&ack);
if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
- break;
+ return send_bytes;
else if ((ack & AUX_NATIVE_REPLY_MASK) ==
AUX_NATIVE_REPLY_DEFER)
udelay(400);
else
return -EIO;
}
- return send_bytes;
+ return -EIO;
}
static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,
@@ -149,13 +150,14 @@ static int radeon_dp_aux_native_read(struct
radeon_connector *radeon_connector,
int msg_bytes = 4;
u8 ack;
int ret;
+ unsigned retry;
msg[0] = address;
msg[1] = address >> 8;
msg[2] = AUX_NATIVE_READ << 4;
msg[3] = (msg_bytes << 4) | (recv_bytes - 1);
- while (1) {
+ for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, recv, recv_bytes,
delay, &ack);
if (ret < 0)
@@ -169,6 +171,8 @@ static int radeon_dp_aux_native_read(struct
radeon_connector *radeon_connector,
else
return -EIO;
}
+
+ return -EIO;
}
static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector,
--
1.7.1.1
[PATCH] drm/radeon/kms: fix channel_remap setup
From: Alex Deucher Most asics just use the hw default value which requires no explicit programming. For those that need a different value, the vbios will program it properly. As such, there's no need to program these registers explicitly in the driver. Changing these registers requires a reload of all data in vram otherwise its contents will be scambled. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=40103 Signed-off-by: Alex Deucher Cc: stable at kernel.org --- drivers/gpu/drm/radeon/evergreen.c |3 ++- drivers/gpu/drm/radeon/ni.c|3 ++- drivers/gpu/drm/radeon/rv770.c |3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e8a7467..276509d 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2078,7 +2078,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(DMIF_ADDR_CONFIG, gb_addr_config); WREG32(HDP_ADDR_CONFIG, gb_addr_config); - evergreen_program_channel_remap(rdev); + /* Use the hw default or as set up by the vbios */ + /* evergreen_program_channel_remap(rdev);*/ num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1; grbm_gfx_index = INSTANCE_BROADCAST_WRITES; diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 99fbd79..f15bf6b 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -842,7 +842,8 @@ static void cayman_gpu_init(struct radeon_device *rdev) WREG32(DMIF_ADDR_CONFIG, gb_addr_config); WREG32(HDP_ADDR_CONFIG, gb_addr_config); - cayman_program_channel_remap(rdev); + /* Use the hw default or as set up by the vbios */ + /* cayman_program_channel_remap(rdev); */ /* primary versions */ WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4720d00..98e3b7e 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -785,7 +785,8 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0x)); WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0x)); - rv770_program_channel_remap(rdev); + /* Use the hw default or as set up by the vbios */ + /* rv770_program_channel_remap(rdev); */ WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); -- 1.7.1.1
[PATCH] drm/radeon/kms: fix channel_remap setup (v2)
From: Alex Deucher
Most asics just use the hw default value which requires
no explicit programming. For those that need a different
value, the vbios will program it properly. As such,
there's no need to program these registers explicitly
in the driver. Changing MC_SHARED_CHREMAP requires a reload
of all data in vram otherwise its contents will be scambled.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=40103
v2: drop now unused channel_remap functions.
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/evergreen.c | 44 ---
drivers/gpu/drm/radeon/ni.c| 32 --
drivers/gpu/drm/radeon/rv770.c | 51
3 files changed, 0 insertions(+), 127 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index e8a7467..c4ffa14 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1590,48 +1590,6 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct
radeon_device *rdev,
return backend_map;
}
-static void evergreen_program_channel_remap(struct radeon_device *rdev)
-{
- u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp;
-
- tmp = RREG32(MC_SHARED_CHMAP);
- switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
- case 0:
- case 1:
- case 2:
- case 3:
- default:
- /* default mapping */
- mc_shared_chremap = 0x00fac688;
- break;
- }
-
- switch (rdev->family) {
- case CHIP_HEMLOCK:
- case CHIP_CYPRESS:
- case CHIP_BARTS:
- tcp_chan_steer_lo = 0x54763210;
- tcp_chan_steer_hi = 0xba98;
- break;
- case CHIP_JUNIPER:
- case CHIP_REDWOOD:
- case CHIP_CEDAR:
- case CHIP_PALM:
- case CHIP_SUMO:
- case CHIP_SUMO2:
- case CHIP_TURKS:
- case CHIP_CAICOS:
- default:
- tcp_chan_steer_lo = 0x76543210;
- tcp_chan_steer_hi = 0xba98;
- break;
- }
-
- WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo);
- WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi);
- WREG32(MC_SHARED_CHREMAP, mc_shared_chremap);
-}
-
static void evergreen_gpu_init(struct radeon_device *rdev)
{
u32 cc_rb_backend_disable = 0;
@@ -2078,8 +2036,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
WREG32(HDP_ADDR_CONFIG, gb_addr_config);
- evergreen_program_channel_remap(rdev);
-
num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3))
>> 12) + 1;
grbm_gfx_index = INSTANCE_BROADCAST_WRITES;
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 99fbd79..8c79ca9 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -569,36 +569,6 @@ static u32 cayman_get_tile_pipe_to_backend_map(struct
radeon_device *rdev,
return backend_map;
}
-static void cayman_program_channel_remap(struct radeon_device *rdev)
-{
- u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp;
-
- tmp = RREG32(MC_SHARED_CHMAP);
- switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
- case 0:
- case 1:
- case 2:
- case 3:
- default:
- /* default mapping */
- mc_shared_chremap = 0x00fac688;
- break;
- }
-
- switch (rdev->family) {
- case CHIP_CAYMAN:
- default:
- //tcp_chan_steer_lo = 0x54763210
- tcp_chan_steer_lo = 0x76543210;
- tcp_chan_steer_hi = 0xba98;
- break;
- }
-
- WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo);
- WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi);
- WREG32(MC_SHARED_CHREMAP, mc_shared_chremap);
-}
-
static u32 cayman_get_disable_mask_per_asic(struct radeon_device *rdev,
u32 disable_mask_per_se,
u32 max_disable_mask_per_se,
@@ -842,8 +812,6 @@ static void cayman_gpu_init(struct radeon_device *rdev)
WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
WREG32(HDP_ADDR_CONFIG, gb_addr_config);
- cayman_program_channel_remap(rdev);
-
/* primary versions */
WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 4720d00..b13c2ee 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -536,55 +536,6 @@ static u32 r700_get_tile_pipe_to_backend_map(struct
radeon_device *rdev,
return backend_map;
}
-static void rv770_program_channel_remap(struct radeon_device *rdev)
-{
- u32 tcp_chan_steer, mc_shared_chrem
[PATCH] drm/radeon/kms: fix dp_detect handling for DP bridge chips
From: Alex Deucher
The HPD pin is not reliable for detecting whether a monitor
is connected or not. Skip HPD and just use DDC or load
detection.
Fixes phantom VGA connected bugs.
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/radeon_connectors.c | 21 ++---
1 files changed, 6 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c
b/drivers/gpu/drm/radeon/radeon_connectors.c
index bce63fd..449c3d8 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1303,23 +1303,14 @@ radeon_dp_detect(struct drm_connector *connector, bool
force)
/* get the DPCD from the bridge */
radeon_dp_getdpcd(radeon_connector);
- if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
- ret = connector_status_connected;
- else {
- /* need to setup ddc on the bridge */
- if (encoder)
- radeon_atom_ext_encoder_setup_ddc(encoder);
+ if (encoder) {
+ /* setup ddc on the bridge */
+ radeon_atom_ext_encoder_setup_ddc(encoder);
if (radeon_ddc_probe(radeon_connector,
-
radeon_connector->requires_extended_probe))
+
radeon_connector->requires_extended_probe)) /* try DDC */
ret = connector_status_connected;
- }
-
- if ((ret == connector_status_disconnected) &&
- radeon_connector->dac_load_detect) {
- struct drm_encoder *encoder =
radeon_best_single_encoder(connector);
- struct drm_encoder_helper_funcs *encoder_funcs;
- if (encoder) {
- encoder_funcs = encoder->helper_private;
+ else if (radeon_connector->dac_load_detect) { /* try
load detection */
+ struct drm_encoder_helper_funcs *encoder_funcs
= encoder->helper_private;
ret = encoder_funcs->detect(encoder, connector);
}
}
--
1.7.1.1
[PATCH] drm/radeon/kms: retry aux transactions if there are status flags
From: Alex Deucher
If there are error flags in the aux status, retry the transaction.
This makes aux much more reliable, especially on llano systems.
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/atombios_dp.c | 12 +---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c
b/drivers/gpu/drm/radeon/atombios_dp.c
index 4da2388..79e8ebc 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -129,7 +129,9 @@ static int radeon_dp_aux_native_write(struct
radeon_connector *radeon_connector,
for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, NULL, 0, delay,
&ack);
- if (ret < 0)
+ if (ret == -EBUSY)
+ continue;
+ else if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
return send_bytes;
@@ -160,7 +162,9 @@ static int radeon_dp_aux_native_read(struct
radeon_connector *radeon_connector,
for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, recv, recv_bytes,
delay, &ack);
- if (ret < 0)
+ if (ret == -EBUSY)
+ continue;
+ else if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
return ret;
@@ -236,7 +240,9 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int
mode,
for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(auxch,
msg, msg_bytes, reply, reply_bytes,
0, &ack);
- if (ret < 0) {
+ if (ret == -EBUSY)
+ continue;
+ else if (ret < 0) {
DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
return ret;
}
--
1.7.1.1
[PATCH] drm/radeon/kms: set DMA mask properly on newer PCI asics
From: Alex Deucher If a card wasn't PCIE, we always set the DMA mask to 32 bits. This is only applies to the old rage128/r1xx gart block on early radeon asics (~r1xx-r4xx). Newer PCI and IGP cards can handle 40 bits just fine. Signed-off-by: Alex Deucher Cc: Chen Jie --- drivers/gpu/drm/radeon/radeon_device.c |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index b51e157..2c3429d 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -750,14 +750,15 @@ int radeon_device_init(struct radeon_device *rdev, /* set DMA mask + need_dma32 flags. * PCIE - can handle 40-bits. -* IGP - can handle 40-bits (in theory) +* IGP - can handle 40-bits * AGP - generally dma32 is safest -* PCI - only dma32 +* PCI - dma32 for legacy pci gart, 40 bits on newer asics */ rdev->need_dma32 = false; if (rdev->flags & RADEON_IS_AGP) rdev->need_dma32 = true; - if (rdev->flags & RADEON_IS_PCI) + if ((rdev->flags & RADEON_IS_PCI) && + (rdev->family < CHIP_RS400)) rdev->need_dma32 = true; dma_bits = rdev->need_dma32 ? 32 : 40; -- 1.7.1.1
[PATCH] drm/radeon/kms: use hardcoded dig encoder to transmitter mapping for DCE4.1
From: Alex Deucher
The encoders are supposedly fully routeable, but changing the mapping
doesn't always seem to take. Using a hardcoded mapping is much more
reliable.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41366
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/radeon_encoders.c |9 ++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c
b/drivers/gpu/drm/radeon/radeon_encoders.c
index 13690f3..8a171b2 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1755,9 +1755,12 @@ static int radeon_atom_pick_dig_encoder(struct
drm_encoder *encoder)
/* DCE4/5 */
if (ASIC_IS_DCE4(rdev)) {
dig = radeon_encoder->enc_priv;
- if (ASIC_IS_DCE41(rdev))
- return radeon_crtc->crtc_id;
- else {
+ if (ASIC_IS_DCE41(rdev)) {
+ if (dig->linkb)
+ return 1;
+ else
+ return 0;
+ } else {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
if (dig->linkb)
--
1.7.1.1
[PATCH 1/2] drm/radeon/kms: bail early in dvi_detect for digital only connectors
From: Alex Deucher
DVI-D and HDMI-A are digital only, so there's no need to
attempt analog load detect. Also, skip bail before the
!force check, or we fail to get a disconnect events.
The next patches in the series attempt to fix disconnect
events for connectors with analog support (DVI-I, HDMI-B,
DVI-A).
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41561
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/radeon_connectors.c |5 +
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c
b/drivers/gpu/drm/radeon/radeon_connectors.c
index 449c3d8..103eb1b 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -959,6 +959,11 @@ radeon_dvi_detect(struct drm_connector *connector, bool
force)
if ((ret == connector_status_connected) &&
(radeon_connector->use_digital == true))
goto out;
+ /* DVI-D and HDMI-A are digital only */
+ if ((connector->connector_type == DRM_MODE_CONNECTOR_DVID) ||
+ (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
+ goto out;
+
if (!force) {
ret = connector->status;
goto out;
--
1.7.1.1
[PATCH 2/2] drm/radeon/kms: handle !force case in connector detect more gracefully
From: Alex Deucher
When force == false, we don't do load detection in the connector
detect functions. Unforunately, we also return the previous
connector state so we never get disconnect events for DVI-I, DVI-A,
or VGA. Save whether we detected the monitor via load detection
previously and use that to determine whether we return the previous
state or not.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41561
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/radeon_connectors.c | 23 ---
drivers/gpu/drm/radeon/radeon_mode.h |1 +
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c
b/drivers/gpu/drm/radeon/radeon_connectors.c
index 103eb1b..dec6cbe 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -724,6 +724,7 @@ radeon_vga_detect(struct drm_connector *connector, bool
force)
dret = radeon_ddc_probe(radeon_connector,
radeon_connector->requires_extended_probe);
if (dret) {
+ radeon_connector->detected_by_load = false;
if (radeon_connector->edid) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
@@ -750,12 +751,21 @@ radeon_vga_detect(struct drm_connector *connector, bool
force)
} else {
/* if we aren't forcing don't do destructive polling */
- if (!force)
- return connector->status;
+ if (!force) {
+ /* only return the previous status if we last
+* detected a monitor via load.
+*/
+ if (radeon_connector->detected_by_load)
+ return connector->status;
+ else
+ return ret;
+ }
if (radeon_connector->dac_load_detect && encoder) {
encoder_funcs = encoder->helper_private;
ret = encoder_funcs->detect(encoder, connector);
+ if (ret == connector_status_connected)
+ radeon_connector->detected_by_load = true;
}
}
@@ -897,6 +907,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool
force)
dret = radeon_ddc_probe(radeon_connector,
radeon_connector->requires_extended_probe);
if (dret) {
+ radeon_connector->detected_by_load = false;
if (radeon_connector->edid) {
kfree(radeon_connector->edid);
radeon_connector->edid = NULL;
@@ -964,8 +975,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool
force)
(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
goto out;
+ /* if we aren't forcing don't do destructive polling */
if (!force) {
- ret = connector->status;
+ /* only return the previous status if we last
+* detected a monitor via load.
+*/
+ if (radeon_connector->detected_by_load)
+ ret = connector->status;
goto out;
}
@@ -989,6 +1005,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool
force)
ret = encoder_funcs->detect(encoder,
connector);
if (ret == connector_status_connected) {
radeon_connector->use_digital =
false;
+
radeon_connector->detected_by_load = true;
}
}
break;
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h
b/drivers/gpu/drm/radeon/radeon_mode.h
index 68820f5..ed0178f 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -447,6 +447,7 @@ struct radeon_connector {
struct edid *edid;
void *con_priv;
bool dac_load_detect;
+ bool detected_by_load; /* if the connection status was determined by
load */
uint16_t connector_object_id;
struct radeon_hpd hpd;
struct radeon_router router;
--
1.7.1.1
[PATCH 1/3] drm/radeon/kms/DCE4.1: fix dig encoder to transmitter mapping
From: Alex Deucher
llano has fully routeable dig encoders similar to DCE3.2 while
ontario has a hardcoded mapping similar to DCE4.0.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_encoders.c | 13 +
1 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c
b/drivers/gpu/drm/radeon/radeon_encoders.c
index 8a171b2..a90d9ee 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1756,10 +1756,15 @@ static int radeon_atom_pick_dig_encoder(struct
drm_encoder *encoder)
if (ASIC_IS_DCE4(rdev)) {
dig = radeon_encoder->enc_priv;
if (ASIC_IS_DCE41(rdev)) {
- if (dig->linkb)
- return 1;
- else
- return 0;
+ /* ontario follows DCE4 */
+ if (rdev->family == CHIP_PALM) {
+ if (dig->linkb)
+ return 1;
+ else
+ return 0;
+ } else
+ /* llano follows DCE3.2 */
+ return radeon_crtc->crtc_id;
} else {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
--
1.7.1.1
[PATCH 2/3] drm/radeon/kms/DCE4.1: ss is not supported on the internal pplls
From: Alex Deucher
It's handled via external clock. It should already be protected
by the external ss flag, but add an explicit check just in case.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_crtc.c |2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index c742944..a515b2a 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -466,7 +466,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
return;
}
args.v2.ucEnable = enable;
- if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK))
+ if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK)
|| ASIC_IS_DCE41(rdev))
args.v2.ucEnable = ATOM_DISABLE;
} else if (ASIC_IS_DCE3(rdev)) {
args.v1.usSpreadSpectrumPercentage =
cpu_to_le16(ss->percentage);
--
1.7.1.1
[PATCH 3/3] drm/radeon/kms/DCE4.1: fix Select_CrtcSource EncodeMode setting for DP bridges
From: Alex Deucher
Settings in this table reflect the physical panel/connector rather
than the internal dig encoding.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_encoders.c | 12 +++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c
b/drivers/gpu/drm/radeon/radeon_encoders.c
index a90d9ee..bfe1662 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1638,7 +1638,17 @@ atombios_set_encoder_crtc_source(struct drm_encoder
*encoder)
break;
case 2:
args.v2.ucCRTC = radeon_crtc->crtc_id;
- args.v2.ucEncodeMode =
atombios_get_encoder_mode(encoder);
+ if (radeon_encoder_is_dp_bridge(encoder)) {
+ struct drm_connector *connector =
radeon_get_connector_for_encoder(encoder);
+
+ if (connector->connector_type ==
DRM_MODE_CONNECTOR_LVDS)
+ args.v2.ucEncodeMode =
ATOM_ENCODER_MODE_LVDS;
+ else if (connector->connector_type ==
DRM_MODE_CONNECTOR_VGA)
+ args.v2.ucEncodeMode =
ATOM_ENCODER_MODE_LVDS;
+ else
+ args.v2.ucEncodeMode =
atombios_get_encoder_mode(encoder);
+ } else
+ args.v2.ucEncodeMode =
atombios_get_encoder_mode(encoder);
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
--
1.7.1.1
[PATCH 3/3] drm/radeon/kms/DCE4.1: fix Select_CrtcSource EncodeMode setting for DP bridges (v2)
From: Alex Deucher
Settings in this table reflect the physical panel/connector rather
than the internal dig encoding.
v2: fix typo for DRM_MODE_CONNECTOR_VGA case.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_encoders.c | 12 +++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c
b/drivers/gpu/drm/radeon/radeon_encoders.c
index a90d9ee..eb3f6dc 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1638,7 +1638,17 @@ atombios_set_encoder_crtc_source(struct drm_encoder
*encoder)
break;
case 2:
args.v2.ucCRTC = radeon_crtc->crtc_id;
- args.v2.ucEncodeMode =
atombios_get_encoder_mode(encoder);
+ if (radeon_encoder_is_dp_bridge(encoder)) {
+ struct drm_connector *connector =
radeon_get_connector_for_encoder(encoder);
+
+ if (connector->connector_type ==
DRM_MODE_CONNECTOR_LVDS)
+ args.v2.ucEncodeMode =
ATOM_ENCODER_MODE_LVDS;
+ else if (connector->connector_type ==
DRM_MODE_CONNECTOR_VGA)
+ args.v2.ucEncodeMode =
ATOM_ENCODER_MODE_CRT;
+ else
+ args.v2.ucEncodeMode =
atombios_get_encoder_mode(encoder);
+ } else
+ args.v2.ucEncodeMode =
atombios_get_encoder_mode(encoder);
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
--
1.7.1.1
[PATCH] drm/radeon/kms: make r600-NI blit suspend code common
From: Alex Deucher
r600-NI shared the same blit suspend code. Clean it up
and make it a shared function.
Signed-off-by: Alex Deucher
Cc: Ilija Hadzic
---
drivers/gpu/drm/radeon/evergreen.c | 10 +-
drivers/gpu/drm/radeon/ni.c| 10 +-
drivers/gpu/drm/radeon/r600.c | 26 --
drivers/gpu/drm/radeon/radeon.h|2 ++
drivers/gpu/drm/radeon/rv770.c | 12 ++--
5 files changed, 22 insertions(+), 38 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index 80c4ee3..5c515f2 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3107,21 +3107,13 @@ int evergreen_resume(struct radeon_device *rdev)
int evergreen_suspend(struct radeon_device *rdev)
{
- int r;
-
/* FIXME: we should wait for ring to be empty */
r700_cp_stop(rdev);
rdev->cp.ready = false;
evergreen_irq_suspend(rdev);
radeon_wb_disable(rdev);
evergreen_pcie_gart_disable(rdev);
-
- /* unpin shaders bo */
- r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
- if (likely(r == 0)) {
- radeon_bo_unpin(rdev->r600_blit.shader_obj);
- radeon_bo_unreserve(rdev->r600_blit.shader_obj);
- }
+ r600_blit_suspend(rdev);
return 0;
}
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index cc0e911..e560da5 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1423,21 +1423,13 @@ int cayman_resume(struct radeon_device *rdev)
int cayman_suspend(struct radeon_device *rdev)
{
- int r;
-
/* FIXME: we should wait for ring to be empty */
cayman_cp_enable(rdev, false);
rdev->cp.ready = false;
evergreen_irq_suspend(rdev);
radeon_wb_disable(rdev);
cayman_pcie_gart_disable(rdev);
-
- /* unpin shaders bo */
- r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
- if (likely(r == 0)) {
- radeon_bo_unpin(rdev->r600_blit.shader_obj);
- radeon_bo_unreserve(rdev->r600_blit.shader_obj);
- }
+ r600_blit_suspend(rdev);
return 0;
}
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index c2f0dbe..f7f693a 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2375,6 +2375,20 @@ int r600_copy_blit(struct radeon_device *rdev,
return 0;
}
+void r600_blit_suspend(struct radeon_device *rdev)
+{
+ int r;
+
+ /* unpin shaders bo */
+ if (rdev->r600_blit.shader_obj) {
+ r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
+ if (!r) {
+ radeon_bo_unpin(rdev->r600_blit.shader_obj);
+ radeon_bo_unreserve(rdev->r600_blit.shader_obj);
+ }
+ }
+}
+
int r600_set_surface_reg(struct radeon_device *rdev, int reg,
uint32_t tiling_flags, uint32_t pitch,
uint32_t offset, uint32_t obj_size)
@@ -2494,8 +2508,6 @@ int r600_resume(struct radeon_device *rdev)
int r600_suspend(struct radeon_device *rdev)
{
- int r;
-
r600_audio_fini(rdev);
/* FIXME: we should wait for ring to be empty */
r600_cp_stop(rdev);
@@ -2503,14 +2515,8 @@ int r600_suspend(struct radeon_device *rdev)
r600_irq_suspend(rdev);
radeon_wb_disable(rdev);
r600_pcie_gart_disable(rdev);
- /* unpin shaders bo */
- if (rdev->r600_blit.shader_obj) {
- r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
- if (!r) {
- radeon_bo_unpin(rdev->r600_blit.shader_obj);
- radeon_bo_unreserve(rdev->r600_blit.shader_obj);
- }
- }
+ r600_blit_suspend(rdev);
+
return 0;
}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 7b0cb74..93768f5 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -555,6 +555,8 @@ struct r600_blit {
struct radeon_ib *vb_ib;
};
+void r600_blit_suspend(struct radeon_device *rdev);
+
int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib);
void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib);
int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index b13c2ee..4901837 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1184,8 +1184,6 @@ int rv770_resume(struct radeon_device *rdev)
int rv770_suspend(struct radeon_device *rdev)
{
- int r;
-
r600_audio_fini(rdev);
/* FIXME: we should wait for ring to be empty */
r700_cp_stop(rdev);
@@ -1193,14 +1191,8 @@ int rv770_suspend(struct radeon_device *rdev)
r600_
[PATCH] drm/radeon/kms/atom: check fb scratch array access
From: Alex Deucher
Check access to the fb scratch array to avoid accessing
memory past the end of the array.
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/atom.c | 15 +--
drivers/gpu/drm/radeon/atom.h |1 +
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index e88c644..f69b852 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx,
uint8_t attr,
case ATOM_ARG_FB:
idx = U8(*ptr);
(*ptr)++;
- val = gctx->scratch[((gctx->fb_base + idx) / 4)];
+ if ((gctx->fb_base + idx) > gctx->scratch_size_bytes) {
+ DRM_DEBUG_KMS("ATOM: fb read beyond scratch region: %d
vs. %d\n",
+ gctx->fb_base + idx,
gctx->scratch_size_bytes);
+ val = 0;
+ } else
+ val = gctx->scratch[((gctx->fb_base + idx) / 4)];
if (print)
DEBUG("FB[0x%02X]", idx);
break;
@@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_context *ctx, int arg,
uint8_t attr,
case ATOM_ARG_FB:
idx = U8(*ptr);
(*ptr)++;
- gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
+ if ((gctx->fb_base + idx) > gctx->scratch_size_bytes) {
+ DRM_DEBUG_KMS("ATOM: fb write beyond scratch region: %d
vs. %d\n",
+ gctx->fb_base + idx,
gctx->scratch_size_bytes);
+ } else
+ gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
DEBUG("FB[0x%02X]", idx);
break;
case ATOM_ARG_PLL:
@@ -1370,11 +1379,13 @@ int atom_allocate_fb_scratch(struct atom_context *ctx)
usage_bytes =
firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
}
+ ctx->scratch_size_bytes = 0;
if (usage_bytes == 0)
usage_bytes = 20 * 1024;
/* allocate some scratch memory */
ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
if (!ctx->scratch)
return -ENOMEM;
+ ctx->scratch_size_bytes = usage_bytes;
return 0;
}
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
index a589a55..93cfe20 100644
--- a/drivers/gpu/drm/radeon/atom.h
+++ b/drivers/gpu/drm/radeon/atom.h
@@ -137,6 +137,7 @@ struct atom_context {
int cs_equal, cs_above;
int io_mode;
uint32_t *scratch;
+ int scratch_size_bytes;
};
extern int atom_debug;
--
1.7.1.1
[PATCH] drm/radeon/kms/atom: fix handling of FB scratch indices
From: Alex Deucher
FB scratch indices are dword indices, but we were treating
them as byte indices. As such, we were getting the wrong
FB scratch data for non-0 indices. Fix the indices and
guard the indexing against indices larger than the scratch
allocation.
Fixes potential memory corruption on some boards if data
was written past the end of the FB scratch array.
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/atom.c | 15 +--
drivers/gpu/drm/radeon/atom.h |1 +
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index e88c644..14cc88a 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx,
uint8_t attr,
case ATOM_ARG_FB:
idx = U8(*ptr);
(*ptr)++;
- val = gctx->scratch[((gctx->fb_base + idx) / 4)];
+ if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
+ DRM_ERROR("ATOM: fb read beyond scratch region: %d vs.
%d\n",
+ gctx->fb_base + (idx * 4),
gctx->scratch_size_bytes);
+ val = 0;
+ } else
+ val = gctx->scratch[(gctx->fb_base / 4) + idx];
if (print)
DEBUG("FB[0x%02X]", idx);
break;
@@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_context *ctx, int arg,
uint8_t attr,
case ATOM_ARG_FB:
idx = U8(*ptr);
(*ptr)++;
- gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
+ if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
+ DRM_ERROR("ATOM: fb write beyond scratch region: %d vs.
%d\n",
+ gctx->fb_base + (idx * 4),
gctx->scratch_size_bytes);
+ } else
+ gctx->scratch[(gctx->fb_base / 4) + idx] = val;
DEBUG("FB[0x%02X]", idx);
break;
case ATOM_ARG_PLL:
@@ -1370,11 +1379,13 @@ int atom_allocate_fb_scratch(struct atom_context *ctx)
usage_bytes =
firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
}
+ ctx->scratch_size_bytes = 0;
if (usage_bytes == 0)
usage_bytes = 20 * 1024;
/* allocate some scratch memory */
ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
if (!ctx->scratch)
return -ENOMEM;
+ ctx->scratch_size_bytes = usage_bytes;
return 0;
}
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
index a589a55..93cfe20 100644
--- a/drivers/gpu/drm/radeon/atom.h
+++ b/drivers/gpu/drm/radeon/atom.h
@@ -137,6 +137,7 @@ struct atom_context {
int cs_equal, cs_above;
int io_mode;
uint32_t *scratch;
+ int scratch_size_bytes;
};
extern int atom_debug;
--
1.7.1.1
[PATCH] drm/radeon/kms: remove useless radeon_ddc_dump()
From: Alex Deucher
The function didn't work with DP, eDP, or DP bridge
connectors and thus confused users as it lead them to
believe nothing was connected or the EDID was invalid
when in fact is was, just on the aux bus rather an i2c.
It should also speed up module loading as it avoids a
bunch of extra DDC probing.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_display.c | 33 ---
1 files changed, 0 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_display.c
b/drivers/gpu/drm/radeon/radeon_display.c
index 6adb3e5..4998736 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -33,8 +33,6 @@
#include "drm_crtc_helper.h"
#include "drm_edid.h"
-static int radeon_ddc_dump(struct drm_connector *connector);
-
static void avivo_crtc_load_lut(struct drm_crtc *crtc)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
@@ -669,7 +667,6 @@ static void radeon_print_display_setup(struct drm_device
*dev)
static bool radeon_setup_enc_conn(struct drm_device *dev)
{
struct radeon_device *rdev = dev->dev_private;
- struct drm_connector *drm_connector;
bool ret = false;
if (rdev->bios) {
@@ -689,8 +686,6 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
if (ret) {
radeon_setup_encoder_clones(dev);
radeon_print_display_setup(dev);
- list_for_each_entry(drm_connector,
&dev->mode_config.connector_list, head)
- radeon_ddc_dump(drm_connector);
}
return ret;
@@ -743,34 +738,6 @@ int radeon_ddc_get_modes(struct radeon_connector
*radeon_connector)
return 0;
}
-static int radeon_ddc_dump(struct drm_connector *connector)
-{
- struct edid *edid;
- struct radeon_connector *radeon_connector =
to_radeon_connector(connector);
- int ret = 0;
-
- /* on hw with routers, select right port */
- if (radeon_connector->router.ddc_valid)
- radeon_router_select_ddc_port(radeon_connector);
-
- if (!radeon_connector->ddc_bus)
- return -1;
- edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
- /* Log EDID retrieval status here. In particular with regard to
-* connectors with requires_extended_probe flag set, that will prevent
-* function radeon_dvi_detect() to fetch EDID on this connector,
-* as long as there is no valid EDID header found */
- if (edid) {
- DRM_INFO("Radeon display connector %s: Found valid EDID",
- drm_get_connector_name(connector));
- kfree(edid);
- } else {
- DRM_INFO("Radeon display connector %s: No monitor connected or
invalid EDID",
- drm_get_connector_name(connector));
- }
- return ret;
-}
-
/* avivo */
static void avivo_get_fb_div(struct radeon_pll *pll,
u32 target_clock,
--
1.7.1.1
[PATCH 1/2] drm/radeon/kms: rework texture cache flush in r6xx+ blit code
From: Alex Deucher
Move the TC flush before the texture setup to match mesa and
the ddx. Also, move the TC flush into the texture setup
function.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/evergreen_blit_kms.c |5 -
drivers/gpu/drm/radeon/r600_blit_kms.c | 10 +-
drivers/gpu/drm/radeon/radeon.h |2 +-
3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
index dcf11bb..879f733 100644
--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
+++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
@@ -174,7 +174,7 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
static void
set_tex_resource(struct radeon_device *rdev,
int format, int w, int h, int pitch,
-u64 gpu_addr)
+u64 gpu_addr, u32 size)
{
u32 sq_tex_resource_word0, sq_tex_resource_word1;
u32 sq_tex_resource_word4, sq_tex_resource_word7;
@@ -196,6 +196,9 @@ set_tex_resource(struct radeon_device *rdev,
sq_tex_resource_word7 = format |
S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_TEXTURE);
+ cp_set_surface_sync(rdev,
+ PACKET3_TC_ACTION_ENA, size, gpu_addr);
+
radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 8));
radeon_ring_write(rdev, 0);
radeon_ring_write(rdev, sq_tex_resource_word0);
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c
b/drivers/gpu/drm/radeon/r600_blit_kms.c
index c4cf130..ff36532 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -201,7 +201,7 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
static void
set_tex_resource(struct radeon_device *rdev,
int format, int w, int h, int pitch,
-u64 gpu_addr)
+u64 gpu_addr, u32 size)
{
uint32_t sq_tex_resource_word0, sq_tex_resource_word1,
sq_tex_resource_word4;
@@ -222,6 +222,9 @@ set_tex_resource(struct radeon_device *rdev,
S_038010_DST_SEL_Z(SQ_SEL_Z) |
S_038010_DST_SEL_W(SQ_SEL_W);
+ cp_set_surface_sync(rdev,
+ PACKET3_TC_ACTION_ENA, size, gpu_addr);
+
radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7));
radeon_ring_write(rdev, 0);
radeon_ring_write(rdev, sq_tex_resource_word0);
@@ -760,10 +763,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
vb[11] = i2f(h);
rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8,
- w, h, w,
src_gpu_addr);
- rdev->r600_blit.primitives.cp_set_surface_sync(rdev,
-
PACKET3_TC_ACTION_ENA,
- size_in_bytes,
src_gpu_addr);
+ w, h, w,
src_gpu_addr, size_in_bytes);
rdev->r600_blit.primitives.set_render_target(rdev,
COLOR_8_8_8_8,
w, h,
dst_gpu_addr);
rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index aa11ae8..c16724f 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -585,7 +585,7 @@ struct r600_blit_cp_primitives {
void (*set_vtx_resource)(struct radeon_device *rdev, u64 gpu_addr);
void (*set_tex_resource)(struct radeon_device *rdev,
int format, int w, int h, int pitch,
-u64 gpu_addr);
+u64 gpu_addr, u32 size);
void (*set_scissors)(struct radeon_device *rdev, int x1, int y1,
int x2, int y2);
void (*draw_auto)(struct radeon_device *rdev);
--
1.7.1.1
[PATCH 2/2] drm/radeon/kms/cayman/blit: specify CP_COHER_CNTL2 with surface_sync
From: Alex Deucher
CP_COHER_CNTL2 has to be programmed manually when submitting packets
to the ring directly rather than programmed via an IB.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/evergreen_blit_kms.c | 11 +++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
index 879f733..551e76f 100644
--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
+++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
@@ -94,6 +94,15 @@ cp_set_surface_sync(struct radeon_device *rdev,
else
cp_coher_size = ((size + 255) >> 8);
+ if (rdev->family >= CHIP_CAYMAN) {
+ /* CP_COHER_CNTL2 has to be set manually when submitting a
surface_sync
+* to the RB directly. For IBs, the CP programs this as part of
the
+* surface_sync packet.
+*/
+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+ radeon_ring_write(rdev, (0x85e8 - PACKET3_SET_CONFIG_REG_START)
>> 2);
+ radeon_ring_write(rdev, 0); /* CP_COHER_CNTL2 */
+ }
radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
radeon_ring_write(rdev, sync_type);
radeon_ring_write(rdev, cp_coher_size);
@@ -621,6 +630,8 @@ int evergreen_blit_init(struct radeon_device *rdev)
rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */
rdev->r600_blit.ring_size_per_loop = 74;
+ if (rdev->family >= CHIP_CAYMAN)
+ rdev->r600_blit.ring_size_per_loop += 9; /* additional DWs for
surface sync */
rdev->r600_blit.max_dim = 16384;
--
1.7.1.1
[PATCH 1/4] drm/radeon/kms: cleanup atombios_adjust_pll()
From: Alex Deucher
The logic was messy and hard to follow.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_crtc.c | 41 ++-
1 files changed, 13 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index a515b2a..4901179 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -638,38 +638,23 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (ss_enabled && ss->percentage)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_SS_ENABLE;
- if (radeon_encoder->devices &
(ATOM_DEVICE_DFP_SUPPORT) ||
- radeon_encoder_is_dp_bridge(encoder)) {
+ if (encoder_mode == ATOM_ENCODER_MODE_DP) {
+ args.v3.sInput.ucDispPllConfig |=
+ DISPPLL_CONFIG_COHERENT_MODE;
+ /* 16200 or 27000 */
+ args.v3.sInput.usPixelClock =
cpu_to_le16(dp_clock / 10);
+ } else if (radeon_encoder->devices &
(ATOM_DEVICE_DFP_SUPPORT)) {
struct radeon_encoder_atom_dig *dig =
radeon_encoder->enc_priv;
- if (encoder_mode ==
ATOM_ENCODER_MODE_DP) {
+ if (encoder_mode ==
ATOM_ENCODER_MODE_HDMI)
+ /* deep color support */
+ args.v3.sInput.usPixelClock =
+
cpu_to_le16((mode->clock * bpc / 8) / 10);
+ if (dig->coherent_mode)
args.v3.sInput.ucDispPllConfig
|=
DISPPLL_CONFIG_COHERENT_MODE;
- /* 16200 or 27000 */
- args.v3.sInput.usPixelClock =
cpu_to_le16(dp_clock / 10);
- } else {
- if (encoder_mode ==
ATOM_ENCODER_MODE_HDMI) {
- /* deep color support */
-
args.v3.sInput.usPixelClock =
-
cpu_to_le16((mode->clock * bpc / 8) / 10);
- }
- if (dig->coherent_mode)
-
args.v3.sInput.ucDispPllConfig |=
-
DISPPLL_CONFIG_COHERENT_MODE;
- if (mode->clock > 165000)
-
args.v3.sInput.ucDispPllConfig |=
-
DISPPLL_CONFIG_DUAL_LINK;
- }
- } else if (radeon_encoder->devices &
(ATOM_DEVICE_LCD_SUPPORT)) {
- if (encoder_mode ==
ATOM_ENCODER_MODE_DP) {
+ if (mode->clock > 165000)
args.v3.sInput.ucDispPllConfig
|=
-
DISPPLL_CONFIG_COHERENT_MODE;
- /* 16200 or 27000 */
- args.v3.sInput.usPixelClock =
cpu_to_le16(dp_clock / 10);
- } else if (encoder_mode !=
ATOM_ENCODER_MODE_LVDS) {
- if (mode->clock > 165000)
-
args.v3.sInput.ucDispPllConfig |=
-
DISPPLL_CONFIG_DUAL_LINK;
- }
+
DISPPLL_CONFIG_DUAL_LINK;
}
if (radeon_encoder_is_dp_bridge(encoder)) {
struct drm_encoder *ext_encoder =
radeon_atom_get_external_encoder(encoder);
--
1.7.1.1
[PATCH 2/4] drm/radeon/kms: rework DP bridge checks
From: Alex Deucher
Return the encoder id rather than a boolean. This is needed
for differentiate between multiple DP bridge chips.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_crtc.c | 12 ++--
drivers/gpu/drm/radeon/atombios_dp.c |6 --
drivers/gpu/drm/radeon/radeon_connectors.c | 16 +++-
drivers/gpu/drm/radeon/radeon_display.c|3 ++-
drivers/gpu/drm/radeon/radeon_encoders.c | 11 ++-
drivers/gpu/drm/radeon/radeon_mode.h |4 ++--
6 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 4901179..9bb3d6f 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -558,7 +558,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
bpc = connector->display_info.bpc;
encoder_mode = atombios_get_encoder_mode(encoder);
if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT
| ATOM_DEVICE_DFP_SUPPORT)) ||
- radeon_encoder_is_dp_bridge(encoder)) {
+ (radeon_encoder_get_dp_bridge_encoder_id(encoder)
!= ENCODER_OBJECT_ID_NONE)) {
if (connector) {
struct radeon_connector
*radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig
*dig_connector =
@@ -656,11 +656,11 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
args.v3.sInput.ucDispPllConfig
|=
DISPPLL_CONFIG_DUAL_LINK;
}
- if (radeon_encoder_is_dp_bridge(encoder)) {
- struct drm_encoder *ext_encoder =
radeon_atom_get_external_encoder(encoder);
- struct radeon_encoder
*ext_radeon_encoder = to_radeon_encoder(ext_encoder);
- args.v3.sInput.ucExtTransmitterID =
ext_radeon_encoder->encoder_id;
- } else
+ if
(radeon_encoder_get_dp_bridge_encoder_id(encoder) !=
+ ENCODER_OBJECT_ID_NONE)
+ args.v3.sInput.ucExtTransmitterID =
+
radeon_encoder_get_dp_bridge_encoder_id(encoder);
+ else
args.v3.sInput.ucExtTransmitterID = 0;
atom_execute_table(rdev->mode_info.atom_context,
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c
b/drivers/gpu/drm/radeon/atombios_dp.c
index 79e8ebc..018a630 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -482,7 +482,8 @@ static int radeon_dp_get_dp_link_clock(struct drm_connector
*connector,
int bpp = convert_bpc_to_bpp(connector->display_info.bpc);
int lane_num, max_pix_clock;
- if (radeon_connector_encoder_is_dp_bridge(connector))
+ if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
+ ENCODER_OBJECT_ID_NONE)
return 27;
lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock);
@@ -558,7 +559,8 @@ static void radeon_dp_set_panel_mode(struct drm_encoder
*encoder,
if (!ASIC_IS_DCE4(rdev))
return;
- if (radeon_connector_encoder_is_dp_bridge(connector))
+ if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
+ ENCODER_OBJECT_ID_NONE)
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
atombios_dig_encoder_setup(encoder,
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c
b/drivers/gpu/drm/radeon/radeon_connectors.c
index dec6cbe..8cec3db 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -44,8 +44,6 @@ extern void
radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
struct drm_connector *drm_connector);
-bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector);
-
void radeon_connector_hotplug(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
@@ -1203,7 +1201,8 @@ static int radeon_dp_get_modes(struct drm_connector
*connector)
}
} else {
/* need to setup ddc on the bridge */
- if (radeon_connector_encoder_is_dp_bridge(connector)) {
+ if
(radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
+ ENCODER_OBJECT_ID_NONE) {
if (encoder)
radeon_atom_ext_encoder
[PATCH 3/4] drm/radeon/kms: only require 2.7 Ghz DP clock for NUTMEG
From: Alex Deucher Use the regular logic for other bridge chips. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/atombios_dp.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 018a630..16de05f 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -482,8 +482,8 @@ static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, int bpp = convert_bpc_to_bpp(connector->display_info.bpc); int lane_num, max_pix_clock; - if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != - ENCODER_OBJECT_ID_NONE) + if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == + ENCODER_OBJECT_ID_NUTMEG) return 27; lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); -- 1.7.1.1
[PATCH 4/4] drm/radeon/kms/atom: rework encoder dpms
From: Alex Deucher
The existing function was getting too big and complex.
Break it down into a more manageable set of functions.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_encoders.c | 340 --
1 files changed, 187 insertions(+), 153 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c
b/drivers/gpu/drm/radeon/radeon_encoders.c
index 9838865..f01b6b1 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1356,45 +1356,25 @@ atombios_yuv_setup(struct drm_encoder *encoder, bool
enable)
}
static void
-radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
+radeon_atom_encoder_dpms_avivo(struct drm_encoder *encoder, int mode)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- struct drm_encoder *ext_encoder =
radeon_atom_get_external_encoder(encoder);
DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
int index = 0;
- bool is_dig = false;
- bool is_dce5_dac = false;
- bool is_dce5_dvo = false;
memset(&args, 0, sizeof(args));
- DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices
%08x\n",
- radeon_encoder->encoder_id, mode, radeon_encoder->devices,
- radeon_encoder->active_device);
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
break;
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
- is_dig = true;
- break;
case ENCODER_OBJECT_ID_INTERNAL_DVO1:
case ENCODER_OBJECT_ID_INTERNAL_DDI:
- index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
- break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
- if (ASIC_IS_DCE5(rdev))
- is_dce5_dvo = true;
- else if (ASIC_IS_DCE3(rdev))
- is_dig = true;
- else
- index = GetIndexIntoMasterTable(COMMAND,
DVOOutputControl);
+ index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
break;
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
@@ -1407,16 +1387,12 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder,
int mode)
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
- if (ASIC_IS_DCE5(rdev))
- is_dce5_dac = true;
- else {
- if (radeon_encoder->active_device &
(ATOM_DEVICE_TV_SUPPORT))
- index = GetIndexIntoMasterTable(COMMAND,
TV1OutputControl);
- else if (radeon_encoder->active_device &
(ATOM_DEVICE_CV_SUPPORT))
- index = GetIndexIntoMasterTable(COMMAND,
CV1OutputControl);
- else
- index = GetIndexIntoMasterTable(COMMAND,
DAC1OutputControl);
- }
+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
+ index = GetIndexIntoMasterTable(COMMAND,
TV1OutputControl);
+ else if (radeon_encoder->active_device &
(ATOM_DEVICE_CV_SUPPORT))
+ index = GetIndexIntoMasterTable(COMMAND,
CV1OutputControl);
+ else
+ index = GetIndexIntoMasterTable(COMMAND,
DAC1OutputControl);
break;
case ENCODER_OBJECT_ID_INTERNAL_DAC2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
@@ -1427,138 +1403,196 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder,
int mode)
else
index = GetIndexIntoMasterTable(COMMAND,
DAC2OutputControl);
break;
+ default:
+ return;
}
- if (is_dig) {
- switch (mode) {
- case DRM_MODE_DPMS_ON:
- /* some early dce3.2 boards have a bug in their
transmitter control table */
- if ((rdev->family == CHIP_RV710) || (rdev->family ==
CHIP_RV730))
- atombios_dig_transmitter_setup(encoder,
ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
- else
- atombios_dig_transmitter_setup(encoder,
ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
- if (atombios_get_encoder_mode(encoder) ==
ATOM_ENCODER_MODE_DP)
[PATCH] drm/radeon/kms: check for DP MST mode in a few more places (v2)
From: Alex Deucher
DP MST is DP multi-stream support, part of DP 1.2.
v2: switch to a helper macro as suggested by Michel.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_crtc.c |5 +++--
drivers/gpu/drm/radeon/radeon_encoders.c | 20 +---
drivers/gpu/drm/radeon/radeon_mode.h |2 ++
3 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 9bb3d6f..87921c8 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -638,7 +638,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (ss_enabled && ss->percentage)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_SS_ENABLE;
- if (encoder_mode == ATOM_ENCODER_MODE_DP) {
+ if (ENCODER_MODE_IS_DP(encoder_mode)) {
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_COHERENT_MODE;
/* 16200 or 27000 */
@@ -930,6 +930,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc,
struct drm_display_mode
bpc = connector->display_info.bpc;
switch (encoder_mode) {
+ case ATOM_ENCODER_MODE_DP_MST:
case ATOM_ENCODER_MODE_DP:
/* DP/eDP */
dp_clock = dig_connector->dp_clock / 10;
@@ -1435,7 +1436,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
* PPLL/DCPLL programming and only program the
DP DTO for the
* crtc virtual pixel clock.
*/
- if (atombios_get_encoder_mode(test_encoder) ==
ATOM_ENCODER_MODE_DP) {
+ if
(ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
if (ASIC_IS_DCE5(rdev) ||
rdev->clock.dp_extclk)
return ATOM_PPLL_INVALID;
}
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c
b/drivers/gpu/drm/radeon/radeon_encoders.c
index f01b6b1..e57fd6d 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -834,8 +834,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int
action, int panel_mo
else
args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);
- if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) ||
- (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST))
+ if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
args.v1.ucLaneNum = dp_lane_count;
else if (radeon_encoder->pixel_clock > 165000)
args.v1.ucLaneNum = 8;
@@ -843,8 +842,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int
action, int panel_mo
args.v1.ucLaneNum = 4;
if (ASIC_IS_DCE5(rdev)) {
- if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) ||
- (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) {
+ if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) {
if (dp_clock == 27)
args.v1.ucConfig |=
ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
else if (dp_clock == 54)
@@ -877,7 +875,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int
action, int panel_mo
else
args.v4.ucHPD_ID = hpd_id + 1;
} else if (ASIC_IS_DCE4(rdev)) {
- if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) &&
(dp_clock == 27))
+ if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock ==
27))
args.v1.ucConfig |=
ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
args.v3.acConfig.ucDigSel = dig->dig_encoder;
switch (bpc) {
@@ -902,7 +900,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int
action, int panel_mo
break;
}
} else {
- if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) &&
(dp_clock == 27))
+ if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock ==
27))
args.v1.ucConfig |=
ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
@@ -977,7 +975,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder,
int action, uint8_t
if (dig_encoder == -1)
return;
- if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
+
[PATCH] drm/radeon/kms: allocate vram scratch page on 6xx+
From: Alex Deucher
The vram scratch was originally only used on some 7xx asics
to work around a hw bug. Allocate the scratch page on all 6xx+
radeons and set the MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR to point
to it. We shouldn't ever hit it since we limit the system
aperture to vram or vram and AGP, but better safe than sorry.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/evergreen.c |5 +++
drivers/gpu/drm/radeon/ni.c|5 +++
drivers/gpu/drm/radeon/r600.c | 54 +++-
drivers/gpu/drm/radeon/radeon.h| 13 ++--
drivers/gpu/drm/radeon/rv770.c | 60 ---
5 files changed, 80 insertions(+), 57 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index ed406e8..db9027d 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3031,6 +3031,10 @@ static int evergreen_startup(struct radeon_device *rdev)
}
}
+ r = r600_vram_scratch_init(rdev);
+ if (r)
+ return r;
+
evergreen_mc_program(rdev);
if (rdev->flags & RADEON_IS_AGP) {
evergreen_agp_enable(rdev);
@@ -3235,6 +3239,7 @@ void evergreen_fini(struct radeon_device *rdev)
radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
evergreen_pcie_gart_fini(rdev);
+ r600_vram_scratch_fini(rdev);
radeon_gem_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_agp_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 556b7bc..56afaff 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1361,6 +1361,10 @@ static int cayman_startup(struct radeon_device *rdev)
return r;
}
+ r = r600_vram_scratch_init(rdev);
+ if (r)
+ return r;
+
evergreen_mc_program(rdev);
r = cayman_pcie_gart_enable(rdev);
if (r)
@@ -1556,6 +1560,7 @@ void cayman_fini(struct radeon_device *rdev)
radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
cayman_pcie_gart_fini(rdev);
+ r600_vram_scratch_fini(rdev);
radeon_gem_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_bo_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 12470b0..3aa46d7 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1137,7 +1137,7 @@ static void r600_mc_program(struct radeon_device *rdev)
WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >>
12);
WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >>
12);
}
- WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+ WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr
>> 12);
tmp = ((rdev->mc.vram_end >> 24) & 0x) << 16;
tmp |= ((rdev->mc.vram_start >> 24) & 0x);
WREG32(MC_VM_FB_LOCATION, tmp);
@@ -1276,6 +1276,53 @@ int r600_mc_init(struct radeon_device *rdev)
return 0;
}
+int r600_vram_scratch_init(struct radeon_device *rdev)
+{
+ int r;
+
+ if (rdev->vram_scratch.robj == NULL) {
+ r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE,
+PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
+&rdev->vram_scratch.robj);
+ if (r) {
+ return r;
+ }
+ }
+
+ r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
+ if (unlikely(r != 0))
+ return r;
+ r = radeon_bo_pin(rdev->vram_scratch.robj,
+ RADEON_GEM_DOMAIN_VRAM, &rdev->vram_scratch.gpu_addr);
+ if (r) {
+ radeon_bo_unreserve(rdev->vram_scratch.robj);
+ return r;
+ }
+ r = radeon_bo_kmap(rdev->vram_scratch.robj,
+ (void **)&rdev->vram_scratch.ptr);
+ if (r)
+ radeon_bo_unpin(rdev->vram_scratch.robj);
+ radeon_bo_unreserve(rdev->vram_scratch.robj);
+
+ return r;
+}
+
+void r600_vram_scratch_fini(struct radeon_device *rdev)
+{
+ int r;
+
+ if (rdev->vram_scratch.robj == NULL) {
+ return;
+ }
+ r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
+ if (likely(r == 0)) {
+ radeon_bo_kunmap(rdev->vram_scratch.robj);
+ radeon_bo_unpin(rdev->vram_scratch.robj);
+ radeon_bo_unreserve(rdev->vram_scratch.robj);
+ }
+ radeon_bo_unref(&rdev->vram_scratch.robj);
+}
+
/* We doesn't check that the GPU really needs a reset we simply do the
* reset, it's up to the caller to determine if the GPU needs one. We
* might add an helper function to check that.
@@ -2420,6 +2467,10 @@ int r600_startup(struct radeon_device *rdev)
}
}
+ r = r
[PATCH] drm/radeon/kms: always do extended edid probe
From: Alex Deucher
Rather than having a quirk list just always check the EDID header
when probing. This is the recommended behavior according to the
display team. This avoids problems with improperly terminated
i2c lines on some boards. This is also what the proprietary
driver does.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_connectors.c | 69 ++-
drivers/gpu/drm/radeon/radeon_i2c.c| 28 ---
drivers/gpu/drm/radeon/radeon_mode.h |6 +--
3 files changed, 18 insertions(+), 85 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c
b/drivers/gpu/drm/radeon/radeon_connectors.c
index 8cec3db..7b70c8a 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -430,55 +430,6 @@ int radeon_connector_set_property(struct drm_connector
*connector, struct drm_pr
return 0;
}
-/*
- * Some integrated ATI Radeon chipset implementations (e. g.
- * Asus M2A-VM HDMI) may indicate the availability of a DDC,
- * even when there's no monitor connected. For these connectors
- * following DDC probe extension will be applied: check also for the
- * availability of EDID with at least a correct EDID header. Only then,
- * DDC is assumed to be available. This prevents drm_get_edid() and
- * drm_edid_block_valid() from periodically dumping data and kernel
- * errors into the logs and onto the terminal.
- */
-static bool radeon_connector_needs_extended_probe(struct radeon_device *dev,
-uint32_t supported_device,
-int connector_type)
-{
- /* Asus M2A-VM HDMI board sends data to i2c bus even,
-* if HDMI add-on card is not plugged in or HDMI is disabled in
-* BIOS. Valid DDC can only be assumed, if also a valid EDID header
-* can be retrieved via i2c bus during DDC probe */
- if ((dev->pdev->device == 0x791e) &&
- (dev->pdev->subsystem_vendor == 0x1043) &&
- (dev->pdev->subsystem_device == 0x826d)) {
- if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
- (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
- return true;
- }
- /* ECS A740GM-M with ATI RADEON 2100 sends data to i2c bus
-* for a DVI connector that is not implemented */
- if ((dev->pdev->device == 0x796e) &&
- (dev->pdev->subsystem_vendor == 0x1019) &&
- (dev->pdev->subsystem_device == 0x2615)) {
- if ((connector_type == DRM_MODE_CONNECTOR_DVID) &&
- (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
- return true;
- }
- /* TOSHIBA Satellite L300D with ATI Mobility Radeon x1100
-* (RS690M) sends data to i2c bus for a HDMI connector that
-* is not implemented */
- if ((dev->pdev->device == 0x791f) &&
- (dev->pdev->subsystem_vendor == 0x1179) &&
- (dev->pdev->subsystem_device == 0xff68)) {
- if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
- (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
- return true;
- }
-
- /* Default: no EDID header probe required for DDC probing */
- return false;
-}
-
static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
struct drm_connector *connector)
{
@@ -719,8 +670,7 @@ radeon_vga_detect(struct drm_connector *connector, bool
force)
ret = connector_status_disconnected;
if (radeon_connector->ddc_bus)
- dret = radeon_ddc_probe(radeon_connector,
-
radeon_connector->requires_extended_probe);
+ dret = radeon_ddc_probe(radeon_connector);
if (dret) {
radeon_connector->detected_by_load = false;
if (radeon_connector->edid) {
@@ -902,8 +852,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool
force)
bool dret = false;
if (radeon_connector->ddc_bus)
- dret = radeon_ddc_probe(radeon_connector,
-
radeon_connector->requires_extended_probe);
+ dret = radeon_ddc_probe(radeon_connector);
if (dret) {
radeon_connector->detected_by_load = false;
if (radeon_connector->edid) {
@@ -1326,8 +1275,7 @@ radeon_dp_detect(struct drm_connector *connector, bool
force)
if (encoder) {
/* setup ddc on the bridge */
radeon_atom_ext_encoder_setup_ddc(encoder);
- if (radeon_ddc_probe(radeon_connector,
-
radeon_connector->requires_extended_probe)) /* try DDC */
+ if (radeon_ddc_probe(radeon_connector)) /* try DDC */
ret = connector_stat
[PATCH 2/4] drm/radeon/kms: make atombios_dvo_setup() version based
From: Alex Deucher
Use table version numbers for param setup.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_encoders.c | 63 +--
1 files changed, 40 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c
b/drivers/gpu/drm/radeon/atombios_encoders.c
index 36274fa..7d91d3c 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -239,32 +239,49 @@ atombios_dvo_setup(struct drm_encoder *encoder, int
action)
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
union dvo_encoder_control args;
int index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
+ uint8_t frev, crev;
memset(&args, 0, sizeof(args));
- if (ASIC_IS_DCE3(rdev)) {
- /* DCE3+ */
- args.dvo_v3.ucAction = action;
- args.dvo_v3.usPixelClock =
cpu_to_le16(radeon_encoder->pixel_clock / 10);
- args.dvo_v3.ucDVOConfig = 0; /* XXX */
- } else if (ASIC_IS_DCE2(rdev)) {
- /* DCE2 (pre-DCE3 R6xx, RS600/690/740 */
- args.dvo.sDVOEncoder.ucAction = action;
- args.dvo.sDVOEncoder.usPixelClock =
cpu_to_le16(radeon_encoder->pixel_clock / 10);
- /* DFP1, CRT1, TV1 depending on the type of port */
- args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
-
- if (radeon_encoder->pixel_clock > 165000)
- args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute
|= PANEL_ENCODER_MISC_DUAL;
- } else {
- /* R4xx, R5xx */
- args.ext_tmds.sXTmdsEncoder.ucEnable = action;
+ if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
&crev))
+ return;
- if (radeon_encoder->pixel_clock > 165000)
- args.ext_tmds.sXTmdsEncoder.ucMisc |=
PANEL_ENCODER_MISC_DUAL;
+ switch (frev) {
+ case 1:
+ switch (crev) {
+ case 1:
+ /* R4xx, R5xx */
+ args.ext_tmds.sXTmdsEncoder.ucEnable = action;
+
+ if (radeon_encoder->pixel_clock > 165000)
+ args.ext_tmds.sXTmdsEncoder.ucMisc |=
PANEL_ENCODER_MISC_DUAL;
+
+ args.ext_tmds.sXTmdsEncoder.ucMisc |=
ATOM_PANEL_MISC_888RGB;
+ break;
+ case 2:
+ /* RS600/690/740 */
+ args.dvo.sDVOEncoder.ucAction = action;
+ args.dvo.sDVOEncoder.usPixelClock =
cpu_to_le16(radeon_encoder->pixel_clock / 10);
+ /* DFP1, CRT1, TV1 depending on the type of port */
+ args.dvo.sDVOEncoder.ucDeviceType =
ATOM_DEVICE_DFP1_INDEX;
- /*if (pScrn->rgbBits == 8)*/
- args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;
+ if (radeon_encoder->pixel_clock > 165000)
+
args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |=
PANEL_ENCODER_MISC_DUAL;
+ break;
+ case 3:
+ /* R6xx */
+ args.dvo_v3.ucAction = action;
+ args.dvo_v3.usPixelClock =
cpu_to_le16(radeon_encoder->pixel_clock / 10);
+ args.dvo_v3.ucDVOConfig = 0; /* XXX */
+ break;
+ default:
+ DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+ break;
+ }
+ break;
+ default:
+ DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+ break;
}
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t
*)&args);
--
1.7.1.1
[PATCH 1/4] drm/radeon/kms: move atom encoder setup to a new file
From: Alex Deucher
Leave the common code in radeon_encoders.c and move the atom
specific code to atombios_encoders.c. This matches legacy
encoder setup and crtc setup.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/Makefile|2 +-
drivers/gpu/drm/radeon/atombios_encoders.c | 2210
drivers/gpu/drm/radeon/radeon_encoders.c | 2182 +---
drivers/gpu/drm/radeon/radeon_mode.h |2 +-
4 files changed, 2214 insertions(+), 2182 deletions(-)
create mode 100644 drivers/gpu/drm/radeon/atombios_encoders.c
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 9f363e0..cf8b4bc 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -70,7 +70,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
evergreen.o evergreen_cs.o evergreen_blit_shaders.o
evergreen_blit_kms.o \
- radeon_trace_points.o ni.o cayman_blit_shaders.o
+ radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o
radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c
b/drivers/gpu/drm/radeon/atombios_encoders.c
new file mode 100644
index 000..36274fa
--- /dev/null
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -0,0 +1,2210 @@
+/*
+ * Copyright 2007-11 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ * Alex Deucher
+ */
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "radeon_drm.h"
+#include "radeon.h"
+#include "atom.h"
+
+extern int atom_debug;
+
+/* evil but including atombios.h is much worse */
+bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
+ struct drm_display_mode *mode);
+
+
+static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
+{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ switch (radeon_encoder->encoder_id) {
+ case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+ case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+ case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+ case ENCODER_OBJECT_ID_INTERNAL_DDI:
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static struct drm_connector *
+radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_connector *connector;
+ struct radeon_connector *radeon_connector;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ radeon_connector = to_radeon_connector(connector);
+ if (radeon_encoder->devices & radeon_connector->devices)
+ return connector;
+ }
+ return NULL;
+}
+
+static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+
+ /* set the active enc
[PATCH 3/4] drm/radeon/kms: make atombios_dig_encoder_setup() version based
From: Alex Deucher
set up the params based on the table version number.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_encoders.c | 213 +---
1 files changed, 128 insertions(+), 85 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c
b/drivers/gpu/drm/radeon/atombios_encoders.c
index 7d91d3c..e0285c4 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -585,97 +585,140 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder,
int action, int panel_mo
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
&crev))
return;
- args.v1.ucAction = action;
- args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
- if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)
- args.v3.ucPanelMode = panel_mode;
- else
- args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);
+ switch (frev) {
+ case 1:
+ switch (crev) {
+ case 1:
+ args.v1.ucAction = action;
+ args.v1.usPixelClock =
cpu_to_le16(radeon_encoder->pixel_clock / 10);
+ if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)
+ args.v3.ucPanelMode = panel_mode;
+ else
+ args.v1.ucEncoderMode =
atombios_get_encoder_mode(encoder);
- if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
- args.v1.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
- args.v1.ucLaneNum = 8;
- else
- args.v1.ucLaneNum = 4;
-
- if (ASIC_IS_DCE5(rdev)) {
- if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) {
- if (dp_clock == 27)
- args.v1.ucConfig |=
ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
- else if (dp_clock == 54)
- args.v1.ucConfig |=
ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
- }
- args.v4.acConfig.ucDigSel = dig->dig_encoder;
- switch (bpc) {
- case 0:
- args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE;
- break;
- case 6:
- args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR;
- break;
- case 8:
- default:
- args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
- break;
- case 10:
- args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR;
- break;
- case 12:
- args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR;
- break;
- case 16:
- args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR;
+ if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
+ args.v1.ucLaneNum = dp_lane_count;
+ else if (radeon_encoder->pixel_clock > 165000)
+ args.v1.ucLaneNum = 8;
+ else
+ args.v1.ucLaneNum = 4;
+
+ if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) &&
(dp_clock == 27))
+ args.v1.ucConfig |=
ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+ switch (radeon_encoder->encoder_id) {
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+ args.v1.ucConfig =
ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+ args.v1.ucConfig =
ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+ args.v1.ucConfig =
ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
+ break;
+ }
+ if (dig->linkb)
+ args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
+ else
+ args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
break;
- }
- if (hpd_id == RADEON_HPD_NONE)
- args.v4.ucHPD_ID = 0;
- else
- args.v4.ucHPD_ID = hpd_id + 1;
- } else if (ASIC_IS_DCE4(rdev)) {
- if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock ==
27))
- args.v1.ucConfig |=
ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
- args.v3.acConfig.ucDigSel = dig->dig_e
[PATCH 4/4] drm/radeon/kms: make atombios_dig_transmitter_setup() version based
From: Alex Deucher
Use the table version to determine which params to use.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_encoders.c | 343 ++--
1 files changed, 221 insertions(+), 122 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c
b/drivers/gpu/drm/radeon/atombios_encoders.c
index e0285c4..39c04c1 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -772,6 +772,11 @@ atombios_dig_transmitter_setup(struct drm_encoder
*encoder, int action, uint8_t
igp_lane_info = dig_connector->igp_lane_info;
}
+ if (encoder->crtc) {
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
+ pll_id = radeon_crtc->pll_id;
+ }
+
/* no dig encoder assigned */
if (dig_encoder == -1)
return;
@@ -798,146 +803,240 @@ atombios_dig_transmitter_setup(struct drm_encoder
*encoder, int action, uint8_t
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
&crev))
return;
- args.v1.ucAction = action;
- if (action == ATOM_TRANSMITTER_ACTION_INIT) {
- args.v1.usInitInfo = cpu_to_le16(connector_object_id);
- } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
- args.v1.asMode.ucLaneSel = lane_num;
- args.v1.asMode.ucLaneSet = lane_set;
- } else {
- if (is_dp)
- args.v1.usPixelClock =
- cpu_to_le16(dp_clock / 10);
- else if (radeon_encoder->pixel_clock > 165000)
- args.v1.usPixelClock =
cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
- else
- args.v1.usPixelClock =
cpu_to_le16(radeon_encoder->pixel_clock / 10);
- }
- if (ASIC_IS_DCE4(rdev)) {
- if (is_dp)
- args.v3.ucLaneNum = dp_lane_count;
- else if (radeon_encoder->pixel_clock > 165000)
- args.v3.ucLaneNum = 8;
- else
- args.v3.ucLaneNum = 4;
+ switch (frev) {
+ case 1:
+ switch (crev) {
+ case 1:
+ args.v1.ucAction = action;
+ if (action == ATOM_TRANSMITTER_ACTION_INIT) {
+ args.v1.usInitInfo =
cpu_to_le16(connector_object_id);
+ } else if (action ==
ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) {
+ args.v1.asMode.ucLaneSel = lane_num;
+ args.v1.asMode.ucLaneSet = lane_set;
+ } else {
+ if (is_dp)
+ args.v1.usPixelClock =
+ cpu_to_le16(dp_clock / 10);
+ else if (radeon_encoder->pixel_clock > 165000)
+ args.v1.usPixelClock =
cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
+ else
+ args.v1.usPixelClock =
cpu_to_le16(radeon_encoder->pixel_clock / 10);
+ }
- if (dig->linkb)
- args.v3.acConfig.ucLinkSel = 1;
- if (dig_encoder & 1)
- args.v3.acConfig.ucEncoderSel = 1;
+ args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
- /* Select the PLL for the PHY
-* DP PHY should be clocked from external src if there is
-* one.
-*/
- if (encoder->crtc) {
- struct radeon_crtc *radeon_crtc =
to_radeon_crtc(encoder->crtc);
- pll_id = radeon_crtc->pll_id;
- }
+ if (dig_encoder)
+ args.v1.ucConfig |=
ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
+ else
+ args.v1.ucConfig |=
ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
+
+ if ((rdev->flags & RADEON_IS_IGP) &&
+ (radeon_encoder->encoder_id ==
ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {
+ if (is_dp || (radeon_encoder->pixel_clock <=
165000)) {
+ if (igp_lane_info & 0x1)
+ args.v1.ucConfig |=
ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+ else if (igp_lane_info & 0x2)
+ args.v1.ucConfig |=
ATOM_TRANSMITTER_CONFIG_LANE_4_7;
+ else if (igp_lane_info & 0x4)
+ args.v1.ucConfig |=
ATOM_TRANSMITTER_CONFIG_LANE_8_11;
+
[PATCH] drm/radeon/kms: make sure pci max read request size is valid on evergreen+
From: Alex Deucher
If the bios or OS sets the pci max read request size to 0 or an
invalid value (6,7), it can result in a hang or slowdown. Check
and set it to something sane if it's invalid.
Fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=42162
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/evergreen.c | 24
drivers/gpu/drm/radeon/ni.c|3 +++
2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index d8b725d..1e040f5 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -41,6 +41,28 @@ static void evergreen_gpu_init(struct radeon_device *rdev);
void evergreen_fini(struct radeon_device *rdev);
static void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
+#define PCI_DEVICE_CNTL 0x60
+#define PCI_MAX_READ_REQUEST_SIZE_SHIFT 12
+#define PCI_MAX_READ_REQUEST_SIZE_MASK (7 << 12)
+
+void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
+{
+ u16 tmp;
+
+ pci_read_config_word(rdev->pdev, PCI_DEVICE_CNTL, &tmp);
+
+ /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it
+* to avoid hangs or perfomance issues
+*/
+ if tmp & PCI_MAX_READ_REQUEST_SIZE_MASK) >>
PCI_MAX_READ_REQUEST_SIZE_SHIFT) == 0) ||
+ (((tmp & PCI_MAX_READ_REQUEST_SIZE_MASK) >>
PCI_MAX_READ_REQUEST_SIZE_SHIFT) == 6) ||
+ (((tmp & PCI_MAX_READ_REQUEST_SIZE_MASK) >>
PCI_MAX_READ_REQUEST_SIZE_SHIFT) == 7)) {
+ tmp &= ~PCI_MAX_READ_REQUEST_SIZE_MASK;
+ tmp |= (2 << PCI_MAX_READ_REQUEST_SIZE_SHIFT);
+ pci_write_config_word(rdev->pdev, PCI_DEVICE_CNTL, tmp);
+ }
+}
+
void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc)
{
/* enable the pflip int */
@@ -1865,6 +1887,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
+ evergreen_fix_pci_max_read_req_size(rdev);
+
cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2;
cc_gc_shader_pipe_config |=
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index d916c82..d6cb534 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -39,6 +39,7 @@ extern int evergreen_mc_wait_for_idle(struct radeon_device
*rdev);
extern void evergreen_mc_program(struct radeon_device *rdev);
extern void evergreen_irq_suspend(struct radeon_device *rdev);
extern int evergreen_mc_init(struct radeon_device *rdev);
+extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
#define EVERGREEN_PFP_UCODE_SIZE 1120
#define EVERGREEN_PM4_UCODE_SIZE 1376
@@ -724,6 +725,8 @@ static void cayman_gpu_init(struct radeon_device *rdev)
WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
+ evergreen_fix_pci_max_read_req_size(rdev);
+
mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
--
1.7.1.1
[PATCH] drm/radeon/kms: make sure pci max read request size is valid on evergreen+ (v2)
From: Alex Deucher
If the bios or OS sets the pci max read request size to 0 or an
invalid value (6,7), it can result in a hang or slowdown. Check
and set it to something sane if it's invalid.
Fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=42162
v2: use pci reg defines from include/linux/pci_regs.h
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/evergreen.c | 27 +++
drivers/gpu/drm/radeon/ni.c|3 +++
2 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index d8b725d..cf5704f 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -41,6 +41,31 @@ static void evergreen_gpu_init(struct radeon_device *rdev);
void evergreen_fini(struct radeon_device *rdev);
static void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
+void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
+{
+ u16 ctl, v;
+ int cap, err;
+
+ cap = pci_pcie_cap(rdev->pdev);
+ if (!cap)
+ return;
+
+ err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl);
+ if (err)
+ return;
+
+ v = (ctl & PCI_EXP_DEVCTL_READRQ) >> 12;
+
+ /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it
+* to avoid hangs or perfomance issues
+*/
+ if ((v == 0) || (v == 6) || (v == 7)) {
+ ctl &= ~PCI_EXP_DEVCTL_READRQ;
+ ctl |= (2 << 12);
+ pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl);
+ }
+}
+
void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc)
{
/* enable the pflip int */
@@ -1865,6 +1890,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
+ evergreen_fix_pci_max_read_req_size(rdev);
+
cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2;
cc_gc_shader_pipe_config |=
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index d916c82..d6cb534 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -39,6 +39,7 @@ extern int evergreen_mc_wait_for_idle(struct radeon_device
*rdev);
extern void evergreen_mc_program(struct radeon_device *rdev);
extern void evergreen_irq_suspend(struct radeon_device *rdev);
extern int evergreen_mc_init(struct radeon_device *rdev);
+extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
#define EVERGREEN_PFP_UCODE_SIZE 1120
#define EVERGREEN_PM4_UCODE_SIZE 1376
@@ -724,6 +725,8 @@ static void cayman_gpu_init(struct radeon_device *rdev)
WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
+ evergreen_fix_pci_max_read_req_size(rdev);
+
mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
--
1.7.1.1
[PATCH] drm/radeon/kms: fix DP detect and EDID fetch for DP bridges
From: Alex Deucher
Sink type is always DP for DP bridges and EDID fetch on
DP bridges is always i2c over aux rather than plain i2c.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_connectors.c | 37 ++--
drivers/gpu/drm/radeon/radeon_display.c| 19 +-
2 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c
b/drivers/gpu/drm/radeon/radeon_connectors.c
index 7f65940..9efb356 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1287,12 +1287,33 @@ radeon_dp_detect(struct drm_connector *connector, bool
force)
if (!radeon_dig_connector->edp_on)
atombios_set_edp_panel_power(connector,
ATOM_TRANSMITTER_ACTION_POWER_OFF);
- } else {
- /* need to setup ddc on the bridge */
- if (radeon_connector_encoder_is_dp_bridge(connector)) {
+ } else if (radeon_connector_encoder_is_dp_bridge(connector)) {
+ /* DP bridges are always DP */
+ radeon_dig_connector->dp_sink_type =
CONNECTOR_OBJECT_ID_DISPLAYPORT;
+ /* get the DPCD from the bridge */
+ radeon_dp_getdpcd(radeon_connector);
+
+ if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
+ ret = connector_status_connected;
+ else {
+ /* need to setup ddc on the bridge */
if (encoder)
radeon_atom_ext_encoder_setup_ddc(encoder);
+ if (radeon_ddc_probe(radeon_connector,
+
radeon_connector->requires_extended_probe))
+ ret = connector_status_connected;
+ }
+
+ if ((ret == connector_status_disconnected) &&
+ radeon_connector->dac_load_detect) {
+ struct drm_encoder *encoder =
radeon_best_single_encoder(connector);
+ struct drm_encoder_helper_funcs *encoder_funcs;
+ if (encoder) {
+ encoder_funcs = encoder->helper_private;
+ ret = encoder_funcs->detect(encoder, connector);
+ }
}
+ } else {
radeon_dig_connector->dp_sink_type =
radeon_dp_getsinktype(radeon_connector);
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
ret = connector_status_connected;
@@ -1308,16 +1329,6 @@ radeon_dp_detect(struct drm_connector *connector, bool
force)
ret = connector_status_connected;
}
}
-
- if ((ret == connector_status_disconnected) &&
- radeon_connector->dac_load_detect) {
- struct drm_encoder *encoder =
radeon_best_single_encoder(connector);
- struct drm_encoder_helper_funcs *encoder_funcs;
- if (encoder) {
- encoder_funcs = encoder->helper_private;
- ret = encoder_funcs->detect(encoder, connector);
- }
- }
}
radeon_connector_update_scratch_regs(connector, ret);
diff --git a/drivers/gpu/drm/radeon/radeon_display.c
b/drivers/gpu/drm/radeon/radeon_display.c
index 1a85894..6cc17fb 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -707,16 +707,21 @@ int radeon_ddc_get_modes(struct radeon_connector
*radeon_connector)
radeon_router_select_ddc_port(radeon_connector);
if ((radeon_connector->base.connector_type ==
DRM_MODE_CONNECTOR_DisplayPort) ||
- (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
+ (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) ||
+ radeon_connector_encoder_is_dp_bridge(&radeon_connector->base)) {
struct radeon_connector_atom_dig *dig =
radeon_connector->con_priv;
+
if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
dig->dp_i2c_bus)
- radeon_connector->edid =
drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter);
- }
- if (!radeon_connector->ddc_bus)
- return -1;
- if (!radeon_connector->edid) {
- radeon_connector->edid = drm_get_edid(&radeon_connector->base,
&radeon_connector->ddc_bus->adapter);
+ radeon_connector->edid =
drm_get_edid(&radeon_connector->base,
+
&dig->dp_i2c_bus->adapter);
+ else if (radeon_connec
[PATCH 1/2] drm/radeon/kms: fix typo in r100_blit_copy
From: Alex Deucher cur_pages is the number of pages per loop iteration. Signed-off-by: Alex Deucher Cc: stable at kernel.org --- drivers/gpu/drm/radeon/r100.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index d0fd430..2d27156 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -775,8 +775,8 @@ int r100_copy_blit(struct radeon_device *rdev, radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); radeon_ring_write(rdev, 0); radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); - radeon_ring_write(rdev, num_pages); - radeon_ring_write(rdev, num_pages); + radeon_ring_write(rdev, cur_pages); + radeon_ring_write(rdev, cur_pages); radeon_ring_write(rdev, cur_pages | (stride_pixels << 16)); } radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); -- 1.7.1.1
[PATCH 2/2] drm/radeon/kms: Make GPU/CPU page size handling consistent in blit code (v2)
From: Alex Deucher
The BO blit code inconsistenly handled the page size. This wasn't
an issue on system with 4k pages since the GPU's page size is 4k as
well. Switch the driver blit callbacks to take num pages in GPU
page units.
Fixes lemote mipsel systems using AMD rs780/rs880 chipsets.
v2: incorporate suggestions from Michel.
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/evergreen.c | 10 ++
drivers/gpu/drm/radeon/r100.c| 12 ++--
drivers/gpu/drm/radeon/r200.c|4 ++--
drivers/gpu/drm/radeon/r600.c| 10 ++
drivers/gpu/drm/radeon/radeon.h |7 ---
drivers/gpu/drm/radeon/radeon_asic.h |8
drivers/gpu/drm/radeon/radeon_ttm.c |7 ++-
7 files changed, 34 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index cf5704f..57152a2 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3207,21 +3207,23 @@ int evergreen_suspend(struct radeon_device *rdev)
}
int evergreen_copy_blit(struct radeon_device *rdev,
- uint64_t src_offset, uint64_t dst_offset,
- unsigned num_pages, struct radeon_fence *fence)
+ uint64_t src_offset,
+ uint64_t dst_offset,
+ unsigned num_gpu_pages,
+ struct radeon_fence *fence)
{
int r;
mutex_lock(&rdev->r600_blit.mutex);
rdev->r600_blit.vb_ib = NULL;
- r = evergreen_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
+ r = evergreen_blit_prepare_copy(rdev, num_gpu_pages *
RADEON_GPU_PAGE_SIZE);
if (r) {
if (rdev->r600_blit.vb_ib)
radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
mutex_unlock(&rdev->r600_blit.mutex);
return r;
}
- evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_pages *
RADEON_GPU_PAGE_SIZE);
+ evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages *
RADEON_GPU_PAGE_SIZE);
evergreen_blit_done_copy(rdev, fence);
mutex_unlock(&rdev->r600_blit.mutex);
return 0;
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 2d27156..1a4387c 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -723,11 +723,11 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
int r100_copy_blit(struct radeon_device *rdev,
uint64_t src_offset,
uint64_t dst_offset,
- unsigned num_pages,
+ unsigned num_gpu_pages,
struct radeon_fence *fence)
{
uint32_t cur_pages;
- uint32_t stride_bytes = PAGE_SIZE;
+ uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE;
uint32_t pitch;
uint32_t stride_pixels;
unsigned ndw;
@@ -739,7 +739,7 @@ int r100_copy_blit(struct radeon_device *rdev,
/* radeon pitch is /64 */
pitch = stride_bytes / 64;
stride_pixels = stride_bytes / 4;
- num_loops = DIV_ROUND_UP(num_pages, 8191);
+ num_loops = DIV_ROUND_UP(num_gpu_pages, 8191);
/* Ask for enough room for blit + flush + fence */
ndw = 64 + (10 * num_loops);
@@ -748,12 +748,12 @@ int r100_copy_blit(struct radeon_device *rdev,
DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw);
return -EINVAL;
}
- while (num_pages > 0) {
- cur_pages = num_pages;
+ while (num_gpu_pages > 0) {
+ cur_pages = num_gpu_pages;
if (cur_pages > 8191) {
cur_pages = 8191;
}
- num_pages -= cur_pages;
+ num_gpu_pages -= cur_pages;
/* pages are in Y direction - height
page width in X direction - width */
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index f240583..a1f3ba0 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -84,7 +84,7 @@ static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
int r200_copy_dma(struct radeon_device *rdev,
uint64_t src_offset,
uint64_t dst_offset,
- unsigned num_pages,
+ unsigned num_gpu_pages,
struct radeon_fence *fence)
{
uint32_t size;
@@ -93,7 +93,7 @@ int r200_copy_dma(struct radeon_device *rdev,
int r = 0;
/* radeon pitch is /64 */
- size = num_pages << PAGE_SHIFT;
+ size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT;
num_loops = DIV_ROUND_UP(size, 0x1F);
r = radeon_ring_lock(rdev, num_loops * 4 + 64);
if (r) {
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 81b1bdf..a842e79 100644
--- a/drivers/gpu/
[PATCH] drm/radeon/kms: fix DDIA enable on some rs690 systems
From: Alex Deucher
DVOOutputControl checks the value of of bios scratch reg 3
on some tables and assumes the encoder is already enabled
if the DFP2_ACTIVE bit is set. Clear that bit so the table
sets the DDIA enable bit properly.
Signed-off-by: Alex Deucher
Cc: stable at kernel.org
---
drivers/gpu/drm/radeon/radeon_encoders.c |9 -
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c
b/drivers/gpu/drm/radeon/radeon_encoders.c
index 9c1fdb2..2554fe3 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1505,7 +1505,14 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder,
int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
args.ucAction = ATOM_ENABLE;
- atom_execute_table(rdev->mode_info.atom_context, index,
(uint32_t *)&args);
+ /* workaround for DVOOutputControl on some RS690
systems */
+ if (radeon_encoder->encoder_id ==
ENCODER_OBJECT_ID_INTERNAL_DDI) {
+ u32 reg = RREG32(RADEON_BIOS_3_SCRATCH);
+ WREG32(RADEON_BIOS_3_SCRATCH, reg &
~ATOM_S3_DFP2I_ACTIVE);
+
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+ WREG32(RADEON_BIOS_3_SCRATCH, reg);
+ } else
+
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
if (radeon_encoder->devices &
(ATOM_DEVICE_LCD_SUPPORT)) {
args.ucAction = ATOM_LCD_BLON;
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
--
1.7.1.1
[PATCH] drm/radeon: fix error return code in TN thermal setup
From: Alex Deucher
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_pm.c |2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c
b/drivers/gpu/drm/radeon/radeon_pm.c
index caa55d6..17571da 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -520,7 +520,7 @@ static int radeon_hwmon_init(struct radeon_device *rdev)
case THERMAL_TYPE_SI:
/* No support for TN yet */
if (rdev->family == CHIP_ARUBA)
- return err;
+ return -ENOSYS;
rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev);
if (IS_ERR(rdev->pm.int_hwmon_dev)) {
err = PTR_ERR(rdev->pm.int_hwmon_dev);
--
1.7.7.5
[PATCH] drm/radeon/kms: fix DVO setup on some r4xx chips
From: Alex Deucher
Some r4xx chips have the wrong frev in the
DVOEncoderControl table. It should always be 1
on r4xx. Fixes modesetting on DVO on r4xx chips
with the bad frev.
Reported by twied on #radeon.
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/atombios_encoders.c |4
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c
b/drivers/gpu/drm/radeon/atombios_encoders.c
index b88c460..5e1d0b5 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -230,6 +230,10 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
&crev))
return;
+ /* some R4xx chips have the wrong frev */
+ if (rdev->family <= CHIP_RV410)
+ frev = 1;
+
switch (frev) {
case 1:
switch (crev) {
--
1.7.7.5
[PATCH] drm/radeon: only add the mm i2c bus if the hw_i2c module param is set
From: Alex Deucher It seems it can corrupt the monitor EDID in certain cases on certain boards when running sensors detect. It's rarely used anyway outside of AIW boards. http://lists.lm-sensors.org/pipermail/lm-sensors/2012-April/035847.html http://lists.freedesktop.org/archives/xorg/2011-January/052239.html Signed-off-by: Alex Deucher Cc: stable at vger.kernel.org Cc: Jean Delvare --- drivers/gpu/drm/radeon/radeon_i2c.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 85bcfc8..3edec1c 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -900,6 +900,10 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_chan *i2c; int ret; + /* don't add the mm_i2c bus unless hw_i2c is enabled */ + if (rec->mm_i2c && (radeon_hw_i2c == 0)) + return NULL; + i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); if (i2c == NULL) return NULL; -- 1.7.7.5
[PATCH] drm/radeon/si: add missing radeon_bo_unreserve in si_rlc_init()
From: Alex Deucher
Forget to unreserve after pinning. This can lead to problems in
soft reset and resume.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/si.c |3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index ac7a199..23a114c 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -3005,6 +3005,7 @@ int si_rlc_init(struct radeon_device *rdev)
si_rlc_fini(rdev);
return r;
}
+ radeon_bo_unreserve(rdev->rlc.save_restore_obj);
/* clear state block */
if (rdev->rlc.clear_state_obj == NULL) {
@@ -3024,12 +3025,12 @@ int si_rlc_init(struct radeon_device *rdev)
r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
&rdev->rlc.clear_state_gpu_addr);
if (r) {
-
radeon_bo_unreserve(rdev->rlc.clear_state_obj);
dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
si_rlc_fini(rdev);
return r;
}
+ radeon_bo_unreserve(rdev->rlc.clear_state_obj);
return 0;
}
--
1.7.7.5
[PATCH] drm/radeon/si: add missing radeon_bo_unreserve in si_rlc_init() v2
From: Alex Deucher
Forget to unreserve after pinning. This can lead to problems in
soft reset and resume.
v2: rework patch as per Michel's suggestion.
Signed-off-by: Alex Deucher
Reviewed-by: Michel D?nzer
---
drivers/gpu/drm/radeon/si.c |5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index ac7a199..27bda98 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2999,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev)
}
r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
&rdev->rlc.save_restore_gpu_addr);
+ radeon_bo_unreserve(rdev->rlc.save_restore_obj);
if (r) {
- radeon_bo_unreserve(rdev->rlc.save_restore_obj);
dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
si_rlc_fini(rdev);
return r;
@@ -3023,9 +3023,8 @@ int si_rlc_init(struct radeon_device *rdev)
}
r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
&rdev->rlc.clear_state_gpu_addr);
+ radeon_bo_unreserve(rdev->rlc.clear_state_obj);
if (r) {
-
- radeon_bo_unreserve(rdev->rlc.clear_state_obj);
dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
si_rlc_fini(rdev);
return r;
--
1.7.7.5
[PATCH] drm/radeon: fix logic inversion in load detect fix
From: Alex Deucher Reported-by: Takashi Iwai Signed-off-by: Alex Deucher Cc: stable at vger.kernel.org --- drivers/gpu/drm/radeon/radeon_connectors.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 910ea6d..4bbb6d4 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -977,7 +977,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) encoder = obj_to_encoder(obj); - if (encoder->encoder_type != DRM_MODE_ENCODER_DAC || + if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) continue; -- 1.7.7.5
[PATCH] drm/radeon/kms: use frac fb div on APUs
From: Alex Deucher
Seems to be more stable on certain monitors.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=48880
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/atombios_crtc.c |3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index b5ff1f7..c5c31e0 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -575,6 +575,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (rdev->family < CHIP_RV770)
pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
+ /* use frac fb div on APUs */
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
+ pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV;
} else {
pll->flags |= RADEON_PLL_LEGACY;
--
1.7.7.5
[PATCH] drm/radeon/kms: need to set up ss on DP bridges as well
From: Alex Deucher
Makes Nutmeg DP to VGA bridges work for me.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=42490
Noticed by Jerome Glisse
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/atombios_crtc.c |4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index c5c31e0..af1054f 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -958,8 +958,8 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc,
struct drm_display_mode
break;
}
- if (radeon_encoder->active_device &
- (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) {
+ if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT |
ATOM_DEVICE_DFP_SUPPORT)) ||
+ (radeon_encoder_get_dp_bridge_encoder_id(encoder) !=
ENCODER_OBJECT_ID_NONE)) {
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
struct drm_connector *connector =
radeon_get_connector_for_encoder(encoder);
--
1.7.7.5
[PATCH] drm/radeon: fix some missing parens in asic macros
From: Alex Deucher Better safe than sorry. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 118e4b9..9f58885 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1789,11 +1789,11 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) -#define radeon_pre_page_flip(rdev, crtc) rdev->asic->pflip.pre_page_flip((rdev), (crtc)) -#define radeon_page_flip(rdev, crtc, base) rdev->asic->pflip.page_flip((rdev), (crtc), (base)) -#define radeon_post_page_flip(rdev, crtc) rdev->asic->pflip.post_page_flip((rdev), (crtc)) -#define radeon_wait_for_vblank(rdev, crtc) rdev->asic->display.wait_for_vblank((rdev), (crtc)) -#define radeon_mc_wait_for_idle(rdev) rdev->asic->mc_wait_for_idle((rdev)) +#define radeon_pre_page_flip(rdev, crtc) (rdev)->asic->pflip.pre_page_flip((rdev), (crtc)) +#define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base)) +#define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) +#define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) +#define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) /* Common functions */ /* AGP */ -- 1.7.7.5
[PATCH] drm/radeon: add some new SI pci ids
From: Alex Deucher
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
include/drm/drm_pciids.h |3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index 7ff5c99..c78bb99 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -213,9 +213,12 @@
{0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6801, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6802, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6806, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6816, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6817, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6819, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6820, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
--
1.7.7.5
[PATCH] drm/radeon: fix ordering in pll picking on dce4+
From: Alex Deucher
No functional change, but re-order the cases so they
evaluate properly due to the way the DCE macros work.
Noticed by kallisti5 on IRC.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_crtc.c |8
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index dc279eb..c6fcb5b 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1531,12 +1531,12 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
* crtc virtual pixel clock.
*/
if
(ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
- if (ASIC_IS_DCE5(rdev))
- return ATOM_DCPLL;
+ if (rdev->clock.dp_extclk)
+ return ATOM_PPLL_INVALID;
else if (ASIC_IS_DCE6(rdev))
return ATOM_PPLL0;
- else if (rdev->clock.dp_extclk)
- return ATOM_PPLL_INVALID;
+ else if (ASIC_IS_DCE5(rdev))
+ return ATOM_DCPLL;
}
}
}
--
1.7.7.5
[PATCH 1/2] drm/radeon/dynpm: wait for fences on all rings when reclocking
From: Alex Deucher
1. Drop gui idle stuff, it's not as reliable as fences and only
covers the 3D engine.
2. Wait for fences on all rings. This makes sure all rings are
idle when reclocking.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_pm.c | 17 ++---
1 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c
b/drivers/gpu/drm/radeon/radeon_pm.c
index 7ae6066..2c2c901 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -253,18 +253,13 @@ static void radeon_pm_set_clocks(struct radeon_device
*rdev)
down_write(&rdev->pm.mclk_lock);
mutex_lock(&rdev->ring_lock);
- /* gui idle int has issues on older chips it seems */
- if (rdev->family >= CHIP_R600) {
- if (rdev->irq.installed) {
- /* wait for GPU to become idle */
- radeon_irq_kms_wait_gui_idle(rdev);
- }
- } else {
- struct radeon_ring *ring =
&rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
- if (ring->ready) {
- radeon_fence_wait_empty_locked(rdev,
RADEON_RING_TYPE_GFX_INDEX);
- }
+ /* wait for the rings to drain */
+ for (i = 0; i < RADEON_NUM_RINGS; i++) {
+ struct radeon_ring *ring = &rdev->ring[i];
+ if (ring->ready)
+ radeon_fence_wait_empty_locked(rdev, i);
}
+
radeon_unmap_vram_bos(rdev);
if (rdev->irq.installed) {
--
1.7.7.5
[PATCH 2/2] drm/radeon: remove gui_idle interrupt infrastructure
From: Alex Deucher
It was only used for dynpm, but has been replaced with
a better implementation using fences. Remove it.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/evergreen.c |5
drivers/gpu/drm/radeon/r100.c | 19 -
drivers/gpu/drm/radeon/r600.c |5
drivers/gpu/drm/radeon/radeon.h |4 ---
drivers/gpu/drm/radeon/radeon_device.c |1 -
drivers/gpu/drm/radeon/radeon_irq_kms.c | 33 ---
drivers/gpu/drm/radeon/rs600.c | 19 -
drivers/gpu/drm/radeon/si.c |5
8 files changed, 0 insertions(+), 91 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index e93b80a..90293c1 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2541,10 +2541,6 @@ int evergreen_irq_set(struct radeon_device *rdev)
DRM_DEBUG("evergreen_irq_set: hdmi 5\n");
afmt6 |= AFMT_AZ_FORMAT_WTRIG_MASK;
}
- if (rdev->irq.gui_idle) {
- DRM_DEBUG("gui idle\n");
- grbm_int_cntl |= GUI_IDLE_INT_ENABLE;
- }
if (rdev->family >= CHIP_CAYMAN) {
cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl);
@@ -3079,7 +3075,6 @@ restart_ih:
break;
case 233: /* GUI IDLE */
DRM_DEBUG("IH: GUI idle\n");
- wake_up(&rdev->irq.idle_queue);
break;
default:
DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id,
src_data);
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 8acb34f..4774e50 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -698,9 +698,6 @@ int r100_irq_set(struct radeon_device *rdev)
if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
tmp |= RADEON_SW_INT_ENABLE;
}
- if (rdev->irq.gui_idle) {
- tmp |= RADEON_GUI_IDLE_MASK;
- }
if (rdev->irq.crtc_vblank_int[0] ||
atomic_read(&rdev->irq.pflip[0])) {
tmp |= RADEON_CRTC_VBLANK_MASK;
@@ -737,12 +734,6 @@ static uint32_t r100_irq_ack(struct radeon_device *rdev)
RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT |
RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT;
- /* the interrupt works, but the status bit is permanently asserted */
- if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) {
- if (!rdev->irq.gui_idle_acked)
- irq_mask |= RADEON_GUI_IDLE_STAT;
- }
-
if (irqs) {
WREG32(RADEON_GEN_INT_STATUS, irqs);
}
@@ -754,9 +745,6 @@ int r100_irq_process(struct radeon_device *rdev)
uint32_t status, msi_rearm;
bool queue_hotplug = false;
- /* reset gui idle ack. the status bit is broken */
- rdev->irq.gui_idle_acked = false;
-
status = r100_irq_ack(rdev);
if (!status) {
return IRQ_NONE;
@@ -769,11 +757,6 @@ int r100_irq_process(struct radeon_device *rdev)
if (status & RADEON_SW_INT_TEST) {
radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
}
- /* gui idle interrupt */
- if (status & RADEON_GUI_IDLE_STAT) {
- rdev->irq.gui_idle_acked = true;
- wake_up(&rdev->irq.idle_queue);
- }
/* Vertical blank interrupts */
if (status & RADEON_CRTC_VBLANK_STAT) {
if (rdev->irq.crtc_vblank_int[0]) {
@@ -803,8 +786,6 @@ int r100_irq_process(struct radeon_device *rdev)
}
status = r100_irq_ack(rdev);
}
- /* reset gui idle ack. the status bit is broken */
- rdev->irq.gui_idle_acked = false;
if (queue_hotplug)
schedule_work(&rdev->hotplug_work);
if (rdev->msi_enabled) {
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index d79c639..459c251 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -3088,10 +3088,6 @@ int r600_irq_set(struct radeon_device *rdev)
DRM_DEBUG("r600_irq_set: hdmi 0\n");
hdmi1 |= HDMI0_AZ_FORMAT_WTRIG_MASK;
}
- if (rdev->irq.gui_idle) {
- DRM_DEBUG("gui idle\n");
- grbm_int_cntl |= GUI_IDLE_INT_ENABLE;
- }
WREG32(CP_INT_CNTL, cp_int_cntl);
WREG32(DxMODE_INT_MASK, mode_int);
@@ -3475,7 +3471,6 @@ restart_ih:
break;
case 233: /* GUI IDLE */
DRM_DEBUG("IH: GUI idle\n");
- wake_up(&rdev->irq.idle_queue);
break;
default:
[pull] radeon drm-fixes-3.6
From: Alex Deucher Hi Dave, This is the current set of radeon fixes for 3.6. Nothing too major. Highlights: - various display fixes - some SI fixes - new SI pci ids - major VM fix - CS checker support for MSAA I've tested on a number of cards across generations and noticed no problems. There is also a patch to implement vbios fetching on legacy free UEFI systems: https://bugs.freedesktop.org/show_bug.cgi?id=26891 The patch is posted there, but I'm waiting to hear back from the author. Look for that in a future pull. The following changes since commit d323748a8e6df3fb91872b73766e29da2f68b025: drm/edid: Fix potential memory leak in edid_load() (2012-08-09 10:10:37 +1000) are available in the git repository at: git://people.freedesktop.org/~agd5f/linux drm-fixes-3.6 Alex Deucher (9): drm/radeon: fix handling for ddc type 5 on combios drm/radeon/dce4+: set a more reasonable cursor watermark drm/radeon: properly handle SS overrides on TN (v2) drm/radeon: properly handle crtc powergating drm/radeon: fix bank tiling parameters on evergreen drm/radeon: fix bank tiling parameters on cayman drm/radeon: fix ordering in pll picking on dce4+ drm/radeon: add some new SI pci ids drm/radeon: fix some missing parens in asic macros Christian K?nig (1): drm/radeon: fix bank tiling parameters on SI Jerome Glisse (2): drm/radeon: do not reenable crtc after moving vram start address drm/radeon: fence virtual address and free it once idle v4 Marek Ol??k (3): drm/radeon/kms: reorder code in r600_check_texture_resource drm/radeon/kms: add MSAA texture support for r600-evergreen drm/radeon/kms: implement timestamp userspace query (v2) drivers/gpu/drm/radeon/atombios_crtc.c | 22 ++-- drivers/gpu/drm/radeon/evergreen.c | 71 -- drivers/gpu/drm/radeon/evergreen_cs.c |7 +++ drivers/gpu/drm/radeon/ni.c | 14 - drivers/gpu/drm/radeon/r600.c | 20 drivers/gpu/drm/radeon/r600_cs.c| 59 -- drivers/gpu/drm/radeon/r600d.h |3 + drivers/gpu/drm/radeon/radeon.h | 12 +++-- drivers/gpu/drm/radeon/radeon_asic.h| 10 ++-- drivers/gpu/drm/radeon/radeon_atombios.c| 49 ++- drivers/gpu/drm/radeon/radeon_combios.c | 57 ++ drivers/gpu/drm/radeon/radeon_cs.c | 32 +++- drivers/gpu/drm/radeon/radeon_cursor.c |6 ++- drivers/gpu/drm/radeon/radeon_device.c |1 + drivers/gpu/drm/radeon/radeon_drv.c |4 +- drivers/gpu/drm/radeon/radeon_gart.c| 24 - drivers/gpu/drm/radeon/radeon_gem.c | 13 + drivers/gpu/drm/radeon/radeon_kms.c | 35 +++-- drivers/gpu/drm/radeon/radeon_legacy_crtc.c |4 ++ drivers/gpu/drm/radeon/radeon_mode.h|1 + drivers/gpu/drm/radeon/radeon_object.c |6 +-- drivers/gpu/drm/radeon/rv515.c | 13 - drivers/gpu/drm/radeon/si.c | 35 -- drivers/gpu/drm/radeon/sid.h|3 + include/drm/drm_pciids.h|3 + include/drm/radeon_drm.h|2 + 26 files changed, 319 insertions(+), 187 deletions(-)
[PATCH 1/5] drm/radeon/dce4+: don't use radeon_crtc for vblank callback
From: Alex Deucher
This might be called before we've allocated the radeon_crtcs
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/evergreen.c | 20
1 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index e93b80a..0c79d9e 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -37,6 +37,16 @@
#define EVERGREEN_PFP_UCODE_SIZE 1120
#define EVERGREEN_PM4_UCODE_SIZE 1376
+static const u32 crtc_offsets[6] =
+{
+ EVERGREEN_CRTC0_REGISTER_OFFSET,
+ EVERGREEN_CRTC1_REGISTER_OFFSET,
+ EVERGREEN_CRTC2_REGISTER_OFFSET,
+ EVERGREEN_CRTC3_REGISTER_OFFSET,
+ EVERGREEN_CRTC4_REGISTER_OFFSET,
+ EVERGREEN_CRTC5_REGISTER_OFFSET
+};
+
static void evergreen_gpu_init(struct radeon_device *rdev);
void evergreen_fini(struct radeon_device *rdev);
void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
@@ -109,17 +119,19 @@ void evergreen_fix_pci_max_read_req_size(struct
radeon_device *rdev)
*/
void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
- struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
int i;
- if (RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset) &
EVERGREEN_CRTC_MASTER_EN) {
+ if (crtc >= rdev->num_crtc)
+ return;
+
+ if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) &
EVERGREEN_CRTC_MASTER_EN) {
for (i = 0; i < rdev->usec_timeout; i++) {
- if (!(RREG32(EVERGREEN_CRTC_STATUS +
radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK))
+ if (!(RREG32(EVERGREEN_CRTC_STATUS +
crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK))
break;
udelay(1);
}
for (i = 0; i < rdev->usec_timeout; i++) {
- if (RREG32(EVERGREEN_CRTC_STATUS +
radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK)
+ if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc])
& EVERGREEN_CRTC_V_BLANK)
break;
udelay(1);
}
--
1.7.7.5
[PATCH 2/5] drm/radeon: clean up evergreen_get_vblank_counter
From: Alex Deucher
Use the new offset array rather than open coding it.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/evergreen.c | 18 +++---
1 files changed, 3 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index 0c79d9e..585c117 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2345,22 +2345,10 @@ int evergreen_asic_reset(struct radeon_device *rdev)
u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc)
{
- switch (crtc) {
- case 0:
- return RREG32(CRTC_STATUS_FRAME_COUNT +
EVERGREEN_CRTC0_REGISTER_OFFSET);
- case 1:
- return RREG32(CRTC_STATUS_FRAME_COUNT +
EVERGREEN_CRTC1_REGISTER_OFFSET);
- case 2:
- return RREG32(CRTC_STATUS_FRAME_COUNT +
EVERGREEN_CRTC2_REGISTER_OFFSET);
- case 3:
- return RREG32(CRTC_STATUS_FRAME_COUNT +
EVERGREEN_CRTC3_REGISTER_OFFSET);
- case 4:
- return RREG32(CRTC_STATUS_FRAME_COUNT +
EVERGREEN_CRTC4_REGISTER_OFFSET);
- case 5:
- return RREG32(CRTC_STATUS_FRAME_COUNT +
EVERGREEN_CRTC5_REGISTER_OFFSET);
- default:
+ if (crtc >= rdev->num_crtc)
return 0;
- }
+ else
+ return RREG32(CRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
}
void evergreen_disable_interrupt_state(struct radeon_device *rdev)
--
1.7.7.5
[PATCH 3/5] drm/radeon/r1xx-r4xx: don't use radeon_crtc for vblank callback
From: Alex Deucher
This might be called before we've allocated the radeon_crtcs
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/r100.c |6 --
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 8acb34f..2ac693c 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -80,10 +80,12 @@ MODULE_FIRMWARE(FIRMWARE_R520);
*/
void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
- struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
int i;
- if (radeon_crtc->crtc_id == 0) {
+ if (crtc >= rdev->num_crtc)
+ return;
+
+ if (crtc == 0) {
if (RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN) {
for (i = 0; i < rdev->usec_timeout; i++) {
if (!(RREG32(RADEON_CRTC_STATUS) &
RADEON_CRTC_VBLANK_CUR))
--
1.7.7.5
[PATCH 4/5] drm/radeon/r5xx-r7xx: don't use radeon_crtc for vblank callback
From: Alex Deucher
This might be called before we've allocated the radeon_crtcs
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/rs600.c | 16
1 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 5301b3d..2abde19 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -46,19 +46,27 @@
void rs600_gpu_init(struct radeon_device *rdev);
int rs600_mc_wait_for_idle(struct radeon_device *rdev);
+static const u32 crtc_offsets[6] =
+{
+ 0,
+ AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
+};
+
void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
- struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
int i;
- if (RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset) &
AVIVO_CRTC_EN) {
+ if (crtc >= rdev->num_crtc)
+ return;
+
+ if (RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN) {
for (i = 0; i < rdev->usec_timeout; i++) {
- if (!(RREG32(AVIVO_D1CRTC_STATUS +
radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK))
+ if (!(RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc])
& AVIVO_D1CRTC_V_BLANK))
break;
udelay(1);
}
for (i = 0; i < rdev->usec_timeout; i++) {
- if (RREG32(AVIVO_D1CRTC_STATUS +
radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK)
+ if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) &
AVIVO_D1CRTC_V_BLANK)
break;
udelay(1);
}
--
1.7.7.5
[PATCH 5/5] drm/radeon: properly handle mc_stop/mc_resume on evergreen+
From: Alex Deucher
- Stop the displays from accessing the FB
- Block CPU access
- Turn off MC client access
This should fix issues some users have seen, especially
with UEFI, when changing the MC FB location that result
in hangs or display corruption.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/evergreen.c | 169 +++-
drivers/gpu/drm/radeon/evergreen_reg.h |2 +
drivers/gpu/drm/radeon/evergreend.h|7 ++
drivers/gpu/drm/radeon/radeon_asic.h |1 +
4 files changed, 88 insertions(+), 91 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen.c
b/drivers/gpu/drm/radeon/evergreen.c
index 585c117..1959e97 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1241,116 +1241,103 @@ void evergreen_agp_enable(struct radeon_device *rdev)
void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save
*save)
{
+ u32 crtc_enabled, tmp, frame_count, blackout;
+ int i, j;
+
save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
- /* Stop all video */
+ /* disable VGA render */
WREG32(VGA_RENDER_CONTROL, 0);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
- if (rdev->num_crtc >= 4) {
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK +
EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK +
EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
- }
- if (rdev->num_crtc >= 6) {
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK +
EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK +
EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
- }
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
- if (rdev->num_crtc >= 4) {
- WREG32(EVERGREEN_CRTC_CONTROL +
EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_CONTROL +
EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
- }
- if (rdev->num_crtc >= 6) {
- WREG32(EVERGREEN_CRTC_CONTROL +
EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_CONTROL +
EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
- }
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
- if (rdev->num_crtc >= 4) {
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK +
EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK +
EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
- }
- if (rdev->num_crtc >= 6) {
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK +
EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK +
EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
+ /* blank the display controllers */
+ for (i = 0; i < rdev->num_crtc; i++) {
+ crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
+ if (crtc_enabled) {
+ save->crtc_enabled[i] = true;
+ if (ASIC_IS_DCE6(rdev)) {
+ tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL +
crtc_offsets[i]);
+ if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
+ radeon_wait_for_vblank(rdev, i);
+ tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
+ WREG32(EVERGREEN_CRTC_BLANK_CONTROL +
crtc_offsets[i], tmp);
+ }
+ } else {
+ tmp = RREG32(EVERGREEN_CRTC_CONTROL +
crtc_offsets[i]);
+ if (!(tmp &
EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
+ radeon_wait_for_vblank(rdev, i);
+ tmp |=
EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
+ WREG32(EVERGREEN_CRTC_CONTROL +
crtc_offsets[i], tmp);
+ }
+ }
+ /* wait for the next frame */
+ frame_count = radeon_get_vblank_counter(rdev, i);
+ for (j = 0; j < rdev->usec_timeout; j++) {
+ if (radeon_get_vblank_counter(rdev, i) !=
frame_count)
+ break;
+ udelay(1);
+ }
+ }
}
- WREG32(D1VGA_CONTROL, 0);
- WREG32(D2VGA_CONTROL, 0);
- if (rdev->num_crtc >= 4) {
- WREG32(EVERGREEN_D3VGA_CONTROL, 0);
- WREG32(EVERGREEN_D4VGA_CONTROL, 0);
- }
- if (rdev->
[PATCH 4/5] drm/radeon/r5xx-r7xx: don't use radeon_crtc for vblank callback (v2)
From: Alex Deucher
This might be called before we've allocated the radeon_crtcs
v2: fix typo in array size
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/rs600.c | 16
1 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 5301b3d..31b84b6 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -46,19 +46,27 @@
void rs600_gpu_init(struct radeon_device *rdev);
int rs600_mc_wait_for_idle(struct radeon_device *rdev);
+static const u32 crtc_offsets[2] =
+{
+ 0,
+ AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
+};
+
void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
{
- struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
int i;
- if (RREG32(AVIVO_D1CRTC_CONTROL + radeon_crtc->crtc_offset) &
AVIVO_CRTC_EN) {
+ if (crtc >= rdev->num_crtc)
+ return;
+
+ if (RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[crtc]) & AVIVO_CRTC_EN) {
for (i = 0; i < rdev->usec_timeout; i++) {
- if (!(RREG32(AVIVO_D1CRTC_STATUS +
radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK))
+ if (!(RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc])
& AVIVO_D1CRTC_V_BLANK))
break;
udelay(1);
}
for (i = 0; i < rdev->usec_timeout; i++) {
- if (RREG32(AVIVO_D1CRTC_STATUS +
radeon_crtc->crtc_offset) & AVIVO_D1CRTC_V_BLANK)
+ if (RREG32(AVIVO_D1CRTC_STATUS + crtc_offsets[crtc]) &
AVIVO_D1CRTC_V_BLANK)
break;
udelay(1);
}
--
1.7.7.5
[PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch
From: David L
This is required for pure UEFI systems. The vbios is stored
in ACPI rather than at the legacy vga location.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=26891
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/radeon_bios.c | 59 ++
1 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c
b/drivers/gpu/drm/radeon/radeon_bios.c
index 501f488..f06494a7 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -32,6 +32,9 @@
#include
#include
+#ifdef CONFIG_ACPI
+#include
+#endif
/*
* BIOS.
*/
@@ -476,6 +479,58 @@ static bool radeon_read_disabled_bios(struct radeon_device
*rdev)
return legacy_read_disabled_bios(rdev);
}
+#ifdef CONFIG_ACPI
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ bool ret = false;
+ struct acpi_table_header *hdr;
+ /* acpi_get_table_with_size is not exported :( */
+ acpi_size tbl_size = 0x7fff;
+ UEFI_ACPI_VFCT *vfct;
+ GOP_VBIOS_CONTENT *vbios;
+ VFCT_IMAGE_HEADER *vhdr;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ return false;
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short
#1)\n");
+ goto out_unmap;
+ }
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short
#2)\n");
+ goto out_unmap;
+ }
+
+ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
+ vhdr = &vbios->VbiosHeader;
+ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size
%d\n",
+ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
+ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
+
+ if (vhdr->PCIBus != rdev->pdev->bus->number ||
+ vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
+ vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
+ vhdr->VendorID != rdev->pdev->vendor ||
+ vhdr->DeviceID != rdev->pdev->device) {
+ DRM_INFO("ACPI VFCT table is not for this card\n");
+ goto out_unmap;
+ };
+
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) +
vhdr->ImageLength > tbl_size) {
+ DRM_ERROR("ACPI VFCT image truncated\n");
+ goto out_unmap;
+ }
+
+ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength,
GFP_KERNEL);
+ ret = !!rdev->bios;
+
+out_unmap:
+ /* uh, no idea what to do here... */
+ return ret;
+}
+#endif
bool radeon_get_bios(struct radeon_device *rdev)
{
@@ -487,6 +542,10 @@ bool radeon_get_bios(struct radeon_device *rdev)
r = igp_read_bios_from_vram(rdev);
if (r == false)
r = radeon_read_bios(rdev);
+#ifdef CONFIG_ACPI
+ if (r == false)
+ r = radeon_acpi_vfct_bios(rdev);
+#endif
if (r == false) {
r = radeon_read_disabled_bios(rdev);
}
--
1.7.7.5
[PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler
From: Alex Deucher
There are systems that use ATRM, but not ATPX.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41265
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/radeon.h | 15 -
drivers/gpu/drm/radeon/radeon_atpx_handler.c | 56 +--
drivers/gpu/drm/radeon/radeon_bios.c | 79 --
3 files changed, 75 insertions(+), 75 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b70ec30..5dbd591 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -142,21 +142,6 @@ struct radeon_device;
/*
* BIOS.
*/
-#define ATRM_BIOS_PAGE 4096
-
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_atrm_supported(struct pci_dev *pdev);
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
-#else
-static inline bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- return false;
-}
-
-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int
len){
- return -EINVAL;
-}
-#endif
bool radeon_get_bios(struct radeon_device *rdev);
/*
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 98724fc..2a2cf0b 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv {
/* handle for device - and atpx */
acpi_handle dhandle;
acpi_handle atpx_handle;
- acpi_handle atrm_handle;
} radeon_atpx_priv;
-/* retrieve the ROM in 4k blocks */
-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
- int offset, int len)
-{
- acpi_status status;
- union acpi_object atrm_arg_elements[2], *obj;
- struct acpi_object_list atrm_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
-
- atrm_arg.count = 2;
- atrm_arg.pointer = &atrm_arg_elements[0];
-
- atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[0].integer.value = offset;
-
- atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[1].integer.value = len;
-
- status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
- if (ACPI_FAILURE(status)) {
- printk("failed to evaluate ATRM got %s\n",
acpi_format_exception(status));
- return -ENODEV;
- }
-
- obj = (union acpi_object *)buffer.pointer;
- memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
- len = obj->buffer.length;
- kfree(buffer.pointer);
- return len;
-}
-
-bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- /* get the discrete ROM only via ATRM */
- if (!radeon_atpx_priv.atpx_detected)
- return false;
-
- if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
- return false;
- return true;
-}
-
-
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
-{
- return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset,
len);
-}
-
static int radeon_atpx_get_version(acpi_handle handle)
{
acpi_status status;
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum
vga_switcheroo_client_id id,
static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
{
- acpi_handle dhandle, atpx_handle, atrm_handle;
+ acpi_handle dhandle, atpx_handle;
acpi_status status;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev
*pdev)
if (ACPI_FAILURE(status))
return false;
- status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
- if (ACPI_FAILURE(status))
- return false;
-
radeon_atpx_priv.dhandle = dhandle;
radeon_atpx_priv.atpx_handle = atpx_handle;
- radeon_atpx_priv.atrm_handle = atrm_handle;
return true;
}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c
b/drivers/gpu/drm/radeon/radeon_bios.c
index f06494a7..c36659a 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -101,16 +101,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)
return true;
}
+#ifdef CONFIG_ACPI
/* ATRM is used to get the BIOS on the discrete cards in
* dual-gpu systems.
*/
+/* retrieve the ROM in 4k blocks */
+#define ATRM_BIOS_PAGE 4096
+/**
+ * radeon_atrm_call - fetch a chunk of the vbios
+ *
+ * @atrm_handle: acpi ATRM handle
+ * @bios: vbios image pointer
+ * @offset: offset of vbios image data to fetch
+ * @len: length of vbios image data to fetch
+ *
+ * Executes ATRM to fetch a chunk of the discrete
+ * vbios image on PX systems (all asics).
+ * Returns the length of the buffer fetched.
+ */
+static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
+
[PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2)
From: David L
This is required for pure UEFI systems. The vbios is stored
in ACPI rather than at the legacy vga location.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=26891
V2: fix #ifdefs as per Greg's comments
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/radeon_bios.c | 62 ++
1 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c
b/drivers/gpu/drm/radeon/radeon_bios.c
index 501f488..bf21f65 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -32,6 +32,9 @@
#include
#include
+#ifdef CONFIG_ACPI
+#include
+#endif
/*
* BIOS.
*/
@@ -476,6 +479,63 @@ static bool radeon_read_disabled_bios(struct radeon_device
*rdev)
return legacy_read_disabled_bios(rdev);
}
+#ifdef CONFIG_ACPI
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ bool ret = false;
+ struct acpi_table_header *hdr;
+ /* acpi_get_table_with_size is not exported :( */
+ acpi_size tbl_size = 0x7fff;
+ UEFI_ACPI_VFCT *vfct;
+ GOP_VBIOS_CONTENT *vbios;
+ VFCT_IMAGE_HEADER *vhdr;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ return false;
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short
#1)\n");
+ goto out_unmap;
+ }
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short
#2)\n");
+ goto out_unmap;
+ }
+
+ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
+ vhdr = &vbios->VbiosHeader;
+ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size
%d\n",
+ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
+ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
+
+ if (vhdr->PCIBus != rdev->pdev->bus->number ||
+ vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
+ vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
+ vhdr->VendorID != rdev->pdev->vendor ||
+ vhdr->DeviceID != rdev->pdev->device) {
+ DRM_INFO("ACPI VFCT table is not for this card\n");
+ goto out_unmap;
+ };
+
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) +
vhdr->ImageLength > tbl_size) {
+ DRM_ERROR("ACPI VFCT image truncated\n");
+ goto out_unmap;
+ }
+
+ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength,
GFP_KERNEL);
+ ret = !!rdev->bios;
+
+out_unmap:
+ /* uh, no idea what to do here... */
+ return ret;
+}
+#else
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ return false;
+}
+#endif
bool radeon_get_bios(struct radeon_device *rdev)
{
@@ -484,6 +544,8 @@ bool radeon_get_bios(struct radeon_device *rdev)
r = radeon_atrm_get_bios(rdev);
if (r == false)
+ r = radeon_acpi_vfct_bios(rdev);
+ if (r == false)
r = igp_read_bios_from_vram(rdev);
if (r == false)
r = radeon_read_bios(rdev);
--
1.7.7.5
[PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler (v2)
From: Alex Deucher
There are systems that use ATRM, but not ATPX.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41265
V2: fix #ifdefs as per Greg's comments
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/radeon.h | 15 -
drivers/gpu/drm/radeon/radeon_atpx_handler.c | 56 +-
drivers/gpu/drm/radeon/radeon_bios.c | 82 --
3 files changed, 77 insertions(+), 76 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9930419..59a1531 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -142,21 +142,6 @@ struct radeon_device;
/*
* BIOS.
*/
-#define ATRM_BIOS_PAGE 4096
-
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_atrm_supported(struct pci_dev *pdev);
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
-#else
-static inline bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- return false;
-}
-
-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int
len){
- return -EINVAL;
-}
-#endif
bool radeon_get_bios(struct radeon_device *rdev);
/*
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 98724fc..2a2cf0b 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv {
/* handle for device - and atpx */
acpi_handle dhandle;
acpi_handle atpx_handle;
- acpi_handle atrm_handle;
} radeon_atpx_priv;
-/* retrieve the ROM in 4k blocks */
-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
- int offset, int len)
-{
- acpi_status status;
- union acpi_object atrm_arg_elements[2], *obj;
- struct acpi_object_list atrm_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
-
- atrm_arg.count = 2;
- atrm_arg.pointer = &atrm_arg_elements[0];
-
- atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[0].integer.value = offset;
-
- atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[1].integer.value = len;
-
- status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
- if (ACPI_FAILURE(status)) {
- printk("failed to evaluate ATRM got %s\n",
acpi_format_exception(status));
- return -ENODEV;
- }
-
- obj = (union acpi_object *)buffer.pointer;
- memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
- len = obj->buffer.length;
- kfree(buffer.pointer);
- return len;
-}
-
-bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- /* get the discrete ROM only via ATRM */
- if (!radeon_atpx_priv.atpx_detected)
- return false;
-
- if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
- return false;
- return true;
-}
-
-
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
-{
- return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset,
len);
-}
-
static int radeon_atpx_get_version(acpi_handle handle)
{
acpi_status status;
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum
vga_switcheroo_client_id id,
static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
{
- acpi_handle dhandle, atpx_handle, atrm_handle;
+ acpi_handle dhandle, atpx_handle;
acpi_status status;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev
*pdev)
if (ACPI_FAILURE(status))
return false;
- status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
- if (ACPI_FAILURE(status))
- return false;
-
radeon_atpx_priv.dhandle = dhandle;
radeon_atpx_priv.atpx_handle = atpx_handle;
- radeon_atpx_priv.atrm_handle = atrm_handle;
return true;
}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c
b/drivers/gpu/drm/radeon/radeon_bios.c
index bf21f65..e97779d 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -32,9 +32,7 @@
#include
#include
-#ifdef CONFIG_ACPI
#include
-#endif
/*
* BIOS.
*/
@@ -101,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)
return true;
}
+#ifdef CONFIG_ACPI
/* ATRM is used to get the BIOS on the discrete cards in
* dual-gpu systems.
*/
+/* retrieve the ROM in 4k blocks */
+#define ATRM_BIOS_PAGE 4096
+/**
+ * radeon_atrm_call - fetch a chunk of the vbios
+ *
+ * @atrm_handle: acpi ATRM handle
+ * @bios: vbios image pointer
+ * @offset: offset of vbios image data to fetch
+ * @len: length of vbios image data to fetch
+ *
+ * Executes ATRM to fetch a chunk of the discrete
+ * vbios image on PX systems (all asi
[PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v3)
From: David Lamparter
This is required for pure UEFI systems. The vbios is stored
in ACPI rather than at the legacy vga location.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=26891
V2: fix #ifdefs as per Greg's comments
V3: fix it harder
Signed-off-by: Alex Deucher
Reviewed-by: Jerome Glisse
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/radeon_bios.c | 60 ++
1 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c
b/drivers/gpu/drm/radeon/radeon_bios.c
index 501f488..a32232f 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -32,6 +32,7 @@
#include
#include
+#include
/*
* BIOS.
*/
@@ -476,6 +477,63 @@ static bool radeon_read_disabled_bios(struct radeon_device
*rdev)
return legacy_read_disabled_bios(rdev);
}
+#ifdef CONFIG_ACPI
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ bool ret = false;
+ struct acpi_table_header *hdr;
+ /* acpi_get_table_with_size is not exported :( */
+ acpi_size tbl_size = 0x7fff;
+ UEFI_ACPI_VFCT *vfct;
+ GOP_VBIOS_CONTENT *vbios;
+ VFCT_IMAGE_HEADER *vhdr;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ return false;
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short
#1)\n");
+ goto out_unmap;
+ }
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short
#2)\n");
+ goto out_unmap;
+ }
+
+ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
+ vhdr = &vbios->VbiosHeader;
+ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size
%d\n",
+ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
+ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
+
+ if (vhdr->PCIBus != rdev->pdev->bus->number ||
+ vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
+ vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
+ vhdr->VendorID != rdev->pdev->vendor ||
+ vhdr->DeviceID != rdev->pdev->device) {
+ DRM_INFO("ACPI VFCT table is not for this card\n");
+ goto out_unmap;
+ };
+
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) +
vhdr->ImageLength > tbl_size) {
+ DRM_ERROR("ACPI VFCT image truncated\n");
+ goto out_unmap;
+ }
+
+ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength,
GFP_KERNEL);
+ ret = !!rdev->bios;
+
+out_unmap:
+ /* uh, no idea what to do here... */
+ return ret;
+}
+#else
+static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ return false;
+}
+#endif
bool radeon_get_bios(struct radeon_device *rdev)
{
@@ -484,6 +542,8 @@ bool radeon_get_bios(struct radeon_device *rdev)
r = radeon_atrm_get_bios(rdev);
if (r == false)
+ r = radeon_acpi_vfct_bios(rdev);
+ if (r == false)
r = igp_read_bios_from_vram(rdev);
if (r == false)
r = radeon_read_bios(rdev);
--
1.7.7.5
[PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler (v3)
From: Alex Deucher
There are systems that use ATRM, but not ATPX.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41265
V2: fix #ifdefs as per Greg's comments
V3: fix it harder
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/radeon.h | 15 -
drivers/gpu/drm/radeon/radeon_atpx_handler.c | 56 +--
drivers/gpu/drm/radeon/radeon_bios.c | 80 -
3 files changed, 77 insertions(+), 74 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9930419..59a1531 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -142,21 +142,6 @@ struct radeon_device;
/*
* BIOS.
*/
-#define ATRM_BIOS_PAGE 4096
-
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_atrm_supported(struct pci_dev *pdev);
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
-#else
-static inline bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- return false;
-}
-
-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int
len){
- return -EINVAL;
-}
-#endif
bool radeon_get_bios(struct radeon_device *rdev);
/*
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 98724fc..2a2cf0b 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv {
/* handle for device - and atpx */
acpi_handle dhandle;
acpi_handle atpx_handle;
- acpi_handle atrm_handle;
} radeon_atpx_priv;
-/* retrieve the ROM in 4k blocks */
-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
- int offset, int len)
-{
- acpi_status status;
- union acpi_object atrm_arg_elements[2], *obj;
- struct acpi_object_list atrm_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
-
- atrm_arg.count = 2;
- atrm_arg.pointer = &atrm_arg_elements[0];
-
- atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[0].integer.value = offset;
-
- atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[1].integer.value = len;
-
- status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
- if (ACPI_FAILURE(status)) {
- printk("failed to evaluate ATRM got %s\n",
acpi_format_exception(status));
- return -ENODEV;
- }
-
- obj = (union acpi_object *)buffer.pointer;
- memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
- len = obj->buffer.length;
- kfree(buffer.pointer);
- return len;
-}
-
-bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- /* get the discrete ROM only via ATRM */
- if (!radeon_atpx_priv.atpx_detected)
- return false;
-
- if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
- return false;
- return true;
-}
-
-
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
-{
- return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset,
len);
-}
-
static int radeon_atpx_get_version(acpi_handle handle)
{
acpi_status status;
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum
vga_switcheroo_client_id id,
static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
{
- acpi_handle dhandle, atpx_handle, atrm_handle;
+ acpi_handle dhandle, atpx_handle;
acpi_status status;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev
*pdev)
if (ACPI_FAILURE(status))
return false;
- status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
- if (ACPI_FAILURE(status))
- return false;
-
radeon_atpx_priv.dhandle = dhandle;
radeon_atpx_priv.atpx_handle = atpx_handle;
- radeon_atpx_priv.atrm_handle = atrm_handle;
return true;
}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c
b/drivers/gpu/drm/radeon/radeon_bios.c
index a32232f..602898d 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -99,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)
return true;
}
+#ifdef CONFIG_ACPI
/* ATRM is used to get the BIOS on the discrete cards in
* dual-gpu systems.
*/
+/* retrieve the ROM in 4k blocks */
+#define ATRM_BIOS_PAGE 4096
+/**
+ * radeon_atrm_call - fetch a chunk of the vbios
+ *
+ * @atrm_handle: acpi ATRM handle
+ * @bios: vbios image pointer
+ * @offset: offset of vbios image data to fetch
+ * @len: length of vbios image data to fetch
+ *
+ * Executes ATRM to fetch a chunk of the discrete
+ * vbios image on PX systems (all asics).
+ * Returns the length of the buffer fetched.
+ */
+static int radeon_atrm_ca
[PATCH 1/4] drm/radeon: implement ACPI VFCT vbios fetch (v3)
From: David Lamparter
This is required for pure UEFI systems. The vbios is stored
in ACPI rather than at the legacy vga location.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=26891
V2: fix #ifdefs as per Greg's comments
V3: fix it harder
Signed-off-by: Alex Deucher
Reviewed-by: Jerome Glisse
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/radeon_bios.c | 60 ++
1 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c
b/drivers/gpu/drm/radeon/radeon_bios.c
index 501f488..a32232f 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -32,6 +32,7 @@
#include
#include
+#include
/*
* BIOS.
*/
@@ -476,6 +477,63 @@ static bool radeon_read_disabled_bios(struct radeon_device
*rdev)
return legacy_read_disabled_bios(rdev);
}
+#ifdef CONFIG_ACPI
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ bool ret = false;
+ struct acpi_table_header *hdr;
+ /* acpi_get_table_with_size is not exported :( */
+ acpi_size tbl_size = 0x7fff;
+ UEFI_ACPI_VFCT *vfct;
+ GOP_VBIOS_CONTENT *vbios;
+ VFCT_IMAGE_HEADER *vhdr;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ return false;
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short
#1)\n");
+ goto out_unmap;
+ }
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short
#2)\n");
+ goto out_unmap;
+ }
+
+ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
+ vhdr = &vbios->VbiosHeader;
+ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size
%d\n",
+ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
+ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
+
+ if (vhdr->PCIBus != rdev->pdev->bus->number ||
+ vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
+ vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
+ vhdr->VendorID != rdev->pdev->vendor ||
+ vhdr->DeviceID != rdev->pdev->device) {
+ DRM_INFO("ACPI VFCT table is not for this card\n");
+ goto out_unmap;
+ };
+
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) +
vhdr->ImageLength > tbl_size) {
+ DRM_ERROR("ACPI VFCT image truncated\n");
+ goto out_unmap;
+ }
+
+ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength,
GFP_KERNEL);
+ ret = !!rdev->bios;
+
+out_unmap:
+ /* uh, no idea what to do here... */
+ return ret;
+}
+#else
+static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ return false;
+}
+#endif
bool radeon_get_bios(struct radeon_device *rdev)
{
@@ -484,6 +542,8 @@ bool radeon_get_bios(struct radeon_device *rdev)
r = radeon_atrm_get_bios(rdev);
if (r == false)
+ r = radeon_acpi_vfct_bios(rdev);
+ if (r == false)
r = igp_read_bios_from_vram(rdev);
if (r == false)
r = radeon_read_bios(rdev);
--
1.7.7.5
[PATCH 2/4] ACPI: export symbol acpi_get_table_with_size
From: Alex Deucher We need it in the radeon drm module to fetch and verify the vbios image on UEFI systems. Signed-off-by: Alex Deucher Cc: stable at vger.kernel.org --- drivers/acpi/acpica/tbxface.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index ea4c6d5..29e51bc 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -387,6 +387,7 @@ acpi_get_table_with_size(char *signature, return (AE_NOT_FOUND); } +ACPI_EXPORT_SYMBOL(acpi_get_table_with_size) acpi_status acpi_get_table(char *signature, -- 1.7.7.5
[PATCH 3/4] drm/radeon: convert radeon vfct code to use acpi_get_table_with_size
From: Alex Deucher
Allows us to verify the table size.
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/radeon_bios.c |6 ++
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c
b/drivers/gpu/drm/radeon/radeon_bios.c
index a32232f..ab0b2f7 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -482,13 +482,12 @@ static bool radeon_acpi_vfct_bios(struct radeon_device
*rdev)
{
bool ret = false;
struct acpi_table_header *hdr;
- /* acpi_get_table_with_size is not exported :( */
- acpi_size tbl_size = 0x7fff;
+ acpi_size tbl_size;
UEFI_ACPI_VFCT *vfct;
GOP_VBIOS_CONTENT *vbios;
VFCT_IMAGE_HEADER *vhdr;
- if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size)))
return false;
if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
DRM_ERROR("ACPI VFCT table present but broken (too short
#1)\n");
@@ -525,7 +524,6 @@ static bool radeon_acpi_vfct_bios(struct radeon_device
*rdev)
ret = !!rdev->bios;
out_unmap:
- /* uh, no idea what to do here... */
return ret;
}
#else
--
1.7.7.5
[PATCH 4/4] drm/radeon: split ATRM support out from the ATPX handler (v3)
From: Alex Deucher
There are systems that use ATRM, but not ATPX.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41265
V2: fix #ifdefs as per Greg's comments
V3: fix it harder
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/radeon.h | 15 -
drivers/gpu/drm/radeon/radeon_atpx_handler.c | 56 +--
drivers/gpu/drm/radeon/radeon_bios.c | 80 -
3 files changed, 77 insertions(+), 74 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9930419..59a1531 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -142,21 +142,6 @@ struct radeon_device;
/*
* BIOS.
*/
-#define ATRM_BIOS_PAGE 4096
-
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_atrm_supported(struct pci_dev *pdev);
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
-#else
-static inline bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- return false;
-}
-
-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int
len){
- return -EINVAL;
-}
-#endif
bool radeon_get_bios(struct radeon_device *rdev);
/*
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 98724fc..2a2cf0b 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv {
/* handle for device - and atpx */
acpi_handle dhandle;
acpi_handle atpx_handle;
- acpi_handle atrm_handle;
} radeon_atpx_priv;
-/* retrieve the ROM in 4k blocks */
-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
- int offset, int len)
-{
- acpi_status status;
- union acpi_object atrm_arg_elements[2], *obj;
- struct acpi_object_list atrm_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
-
- atrm_arg.count = 2;
- atrm_arg.pointer = &atrm_arg_elements[0];
-
- atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[0].integer.value = offset;
-
- atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[1].integer.value = len;
-
- status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
- if (ACPI_FAILURE(status)) {
- printk("failed to evaluate ATRM got %s\n",
acpi_format_exception(status));
- return -ENODEV;
- }
-
- obj = (union acpi_object *)buffer.pointer;
- memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
- len = obj->buffer.length;
- kfree(buffer.pointer);
- return len;
-}
-
-bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- /* get the discrete ROM only via ATRM */
- if (!radeon_atpx_priv.atpx_detected)
- return false;
-
- if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
- return false;
- return true;
-}
-
-
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
-{
- return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset,
len);
-}
-
static int radeon_atpx_get_version(acpi_handle handle)
{
acpi_status status;
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum
vga_switcheroo_client_id id,
static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
{
- acpi_handle dhandle, atpx_handle, atrm_handle;
+ acpi_handle dhandle, atpx_handle;
acpi_status status;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev
*pdev)
if (ACPI_FAILURE(status))
return false;
- status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
- if (ACPI_FAILURE(status))
- return false;
-
radeon_atpx_priv.dhandle = dhandle;
radeon_atpx_priv.atpx_handle = atpx_handle;
- radeon_atpx_priv.atrm_handle = atrm_handle;
return true;
}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c
b/drivers/gpu/drm/radeon/radeon_bios.c
index ab0b2f7..d306cc8 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -99,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)
return true;
}
+#ifdef CONFIG_ACPI
/* ATRM is used to get the BIOS on the discrete cards in
* dual-gpu systems.
*/
+/* retrieve the ROM in 4k blocks */
+#define ATRM_BIOS_PAGE 4096
+/**
+ * radeon_atrm_call - fetch a chunk of the vbios
+ *
+ * @atrm_handle: acpi ATRM handle
+ * @bios: vbios image pointer
+ * @offset: offset of vbios image data to fetch
+ * @len: length of vbios image data to fetch
+ *
+ * Executes ATRM to fetch a chunk of the discrete
+ * vbios image on PX systems (all asics).
+ * Returns the length of the buffer fetched.
+ */
+static int radeon_atrm_ca
[pull] radeon drm-fixes-3.6
From: Alex Deucher Hi Dave, This is the current set of radeon fixes for 3.6. Nothing too major. Highlights: - fix vbios fetch on pure uefi systems - fix vbios fetch on thunderbolt systems - MSAA fixes - lockup timeout fix - modesetting fix The following changes since commit 2e26c73a1e410448fbd2c0fbd34f06d98eaf8e48: Merge branch 'drm-nouveau-fixes' of git://git.freedesktop.org/git/nouveau/linux-2.6 into drm-fixes (2012-08-15 20:31:22 +1000) are available in the git repository at: git://people.freedesktop.org/~agd5f/linux drm-fixes-3.6 Alex Deucher (4): ACPI: export symbol acpi_get_table_with_size drm/radeon: convert radeon vfct code to use acpi_get_table_with_size drm/radeon: split ATRM support out from the ATPX handler (v3) Revert "drm/radeon: fix bo creation retry path" Christian K?nig (1): drm/radeon: init lockup timeout on ring init David Lamparter (1): drm/radeon: implement ACPI VFCT vbios fetch (v3) Jerome Glisse (1): drm/radeon: avoid turning off spread spectrum for used pll Marek Ol??k (2): drm/radeon: allow CMASK and FMASK in the CS checker on r600-r700 drm/radeon: fix checking of MSAA renderbuffers on r600-r700 Tvrtko Ursulin (1): drm/radeon/kms: extend the Fujitsu D3003-S2 board connector quirk to cover later silicon stepping drivers/acpi/acpica/tbxface.c|1 + drivers/gpu/drm/radeon/atombios_crtc.c | 25 - drivers/gpu/drm/radeon/r600_cs.c | 105 --- drivers/gpu/drm/radeon/r600d.h | 17 +++ drivers/gpu/drm/radeon/radeon.h | 15 --- drivers/gpu/drm/radeon/radeon_atombios.c |2 +- drivers/gpu/drm/radeon/radeon_atpx_handler.c | 56 +-- drivers/gpu/drm/radeon/radeon_bios.c | 138 +- drivers/gpu/drm/radeon/radeon_drv.c |3 +- drivers/gpu/drm/radeon/radeon_object.c |3 +- drivers/gpu/drm/radeon/radeon_ring.c |1 + drivers/gpu/drm/radeon/reg_srcs/r600 |8 -- 12 files changed, 267 insertions(+), 107 deletions(-)
[PATCH 1/2] drm/radeon: don't disable plls that are in use by other crtcs
From: Alex Deucher
Some plls are shared for DP.
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/atombios_crtc.c | 14 ++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index bcc5cd3..6b274ff 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1722,9 +1722,22 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_atom_ss ss;
+ int i;
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+ for (i = 0; i < rdev->num_crtc; i++) {
+ if (rdev->mode_info.crtcs[i] &&
+ rdev->mode_info.crtcs[i]->enabled &&
+ i != radeon_crtc->crtc_id &&
+ radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) {
+ /* one other crtc is using this pll don't turn
+* off the pll
+*/
+ goto done;
+ }
+ }
+
switch (radeon_crtc->pll_id) {
case ATOM_PPLL1:
case ATOM_PPLL2:
@@ -1741,6 +1754,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
default:
break;
}
+done:
radeon_crtc->pll_id = -1;
}
--
1.7.7.5
[PATCH 2/2] drm/radeon/atom: rework DIG modesetting on DCE3+
From: Alex Deucher
The ordering is important and the current drm code
wasn't cutting it for modern DIG encoders. We need
to have information about crtc before setting up
the encoders so I've shifted the ordering a bit.
Probably we'll need a full rework akin to danvet's
recent intel patchs. This patch fixes numerous
issues with DP bridge chips and makes link training
much more reliable.
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/atombios_encoders.c | 109
1 files changed, 47 insertions(+), 62 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c
b/drivers/gpu/drm/radeon/atombios_encoders.c
index f9bc27f..4a7f95e 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -1379,6 +1379,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder,
int mode)
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
struct drm_connector *connector =
radeon_get_connector_for_encoder(encoder);
struct radeon_connector *radeon_connector = NULL;
struct radeon_connector_atom_dig *radeon_dig_connector = NULL;
@@ -1390,19 +1392,37 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder
*encoder, int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
- /* some early dce3.2 boards have a bug in their transmitter
control table */
- if ((rdev->family == CHIP_RV710) || (rdev->family ==
CHIP_RV730) ||
- ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
- if (ASIC_IS_DCE6(rdev)) {
- /* It seems we need to call
ATOM_ENCODER_CMD_SETUP again
-* before reenabling encoder on DPMS ON,
otherwise we never
-* get picture
-*/
- atombios_dig_encoder_setup(encoder,
ATOM_ENCODER_CMD_SETUP, 0);
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
+ if (!connector)
+ dig->panel_mode =
DP_PANEL_MODE_EXTERNAL_DP_MODE;
+ else
+ dig->panel_mode =
radeon_dp_get_panel_mode(encoder, connector);
+
+ /* setup and enable the encoder */
+ atombios_dig_encoder_setup(encoder,
ATOM_ENCODER_CMD_SETUP, 0);
+ atombios_dig_encoder_setup(encoder,
+
ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
+ dig->panel_mode);
+ if (ext_encoder) {
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
+
atombios_external_encoder_setup(encoder, ext_encoder,
+
EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
}
atombios_dig_transmitter_setup(encoder,
ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
- } else {
+ } else if (ASIC_IS_DCE4(rdev)) {
+ /* setup and enable the encoder */
+ atombios_dig_encoder_setup(encoder,
ATOM_ENCODER_CMD_SETUP, 0);
+ /* enable the transmitter */
+ atombios_dig_transmitter_setup(encoder,
ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
atombios_dig_transmitter_setup(encoder,
ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+ } else {
+ /* setup and enable the encoder and transmitter */
+ atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0);
+ atombios_dig_transmitter_setup(encoder,
ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
+ atombios_dig_transmitter_setup(encoder,
ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+ /* some early dce3.2 boards have a bug in their
transmitter control table */
+ if ((rdev->family != CHIP_RV710) || (rdev->family !=
CHIP_RV730))
+ atombios_dig_transmitter_setup(encoder,
ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
}
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) &&
connector) {
if (connector->connector_type ==
DRM_MODE_CONNECTOR_eDP) {
@@ -1420,10 +1440,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder
*encoder, int mode)
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
-
[PATCH] drm/radeon/atom: powergating fixes for DCE6
From: Alex Deucher
Power gating is per crtc pair, but the powergating registers
should be called individually. The hw handles power up/down
properly. The pair is powered up if either crtc in the pair
is powered up and the pair is not powered down until both
crtcs in the pair are powered down. This simplifies
programming and should save power additional power.
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/atombios_crtc.c | 22 ++
1 files changed, 2 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 961d366..2817101 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -258,7 +258,6 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
radeon_crtc->enabled = true;
/* adjust pm to dpms changes BEFORE enabling crtcs */
radeon_pm_compute_clocks(rdev);
- /* disable crtc pair power gating before programming */
if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
atombios_powergate_crtc(crtc, ATOM_DISABLE);
atombios_enable_crtc(crtc, ATOM_ENABLE);
@@ -278,25 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
atombios_enable_crtc(crtc, ATOM_DISABLE);
radeon_crtc->enabled = false;
- /* power gating is per-pair */
- if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) {
- struct drm_crtc *other_crtc;
- struct radeon_crtc *other_radeon_crtc;
- list_for_each_entry(other_crtc,
&rdev->ddev->mode_config.crtc_list, head) {
- other_radeon_crtc = to_radeon_crtc(other_crtc);
- if (((radeon_crtc->crtc_id == 0) &&
(other_radeon_crtc->crtc_id == 1)) ||
- ((radeon_crtc->crtc_id == 1) &&
(other_radeon_crtc->crtc_id == 0)) ||
- ((radeon_crtc->crtc_id == 2) &&
(other_radeon_crtc->crtc_id == 3)) ||
- ((radeon_crtc->crtc_id == 3) &&
(other_radeon_crtc->crtc_id == 2)) ||
- ((radeon_crtc->crtc_id == 4) &&
(other_radeon_crtc->crtc_id == 5)) ||
- ((radeon_crtc->crtc_id == 5) &&
(other_radeon_crtc->crtc_id == 4))) {
- /* if both crtcs in the pair are off,
enable power gating */
- if (other_radeon_crtc->enabled == false)
- atombios_powergate_crtc(crtc,
ATOM_ENABLE);
- break;
- }
- }
- }
+ if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set)
+ atombios_powergate_crtc(crtc, ATOM_ENABLE);
/* adjust pm to dpms changes AFTER disabling crtcs */
radeon_pm_compute_clocks(rdev);
break;
--
1.7.7.5
[PATCH] drm/radeon: rework panel mode setup
From: Alex Deucher
Adjust the panel mode setup to match the behavior
of the vbios. Rather than checking for specific
bridge chip ids, just check the eDP configuration register.
This saves extra aux transactions and works across
DP bridge chips without requiring additional per chip
id checking.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_dp.c | 29 -
1 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c
b/drivers/gpu/drm/radeon/atombios_dp.c
index 7712cf5..3623b98 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -577,30 +577,25 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
struct radeon_device *rdev = dev->dev_private;
struct radeon_connector *radeon_connector =
to_radeon_connector(connector);
int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
+ u16 dp_bridge =
radeon_connector_encoder_get_dp_bridge_encoder_id(connector);
+ u8 tmp;
if (!ASIC_IS_DCE4(rdev))
return panel_mode;
- if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
- ENCODER_OBJECT_ID_NUTMEG)
- panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
- else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
-ENCODER_OBJECT_ID_TRAVIS) {
- u8 id[6];
- int i;
- for (i = 0; i < 6; i++)
- id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 +
i);
- if (id[0] == 0x73 &&
- id[1] == 0x69 &&
- id[2] == 0x76 &&
- id[3] == 0x61 &&
- id[4] == 0x72 &&
- id[5] == 0x54)
+ if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
+ /* DP bridge chips */
+ tmp = radeon_read_dpcd_reg(radeon_connector,
DP_EDP_CONFIGURATION_CAP);
+ if (tmp & 1)
+ panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+ else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
+(dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
else
- panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+ panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
- u8 tmp = radeon_read_dpcd_reg(radeon_connector,
DP_EDP_CONFIGURATION_CAP);
+ /* eDP */
+ tmp = radeon_read_dpcd_reg(radeon_connector,
DP_EDP_CONFIGURATION_CAP);
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
}
--
1.7.7.5
[pull] radeon drm-fixes-3.6
From: Alex Deucher Hi Dave, This is the current set of radeon fixes for 3.6. Nothing too major. Highlights: - fix a gart regression on older IGP chips - more MSAA fixes - fix a double free in gpu reset code - modesetting fixes The following changes since commit 84f720ecba6716d198b21936d1bf6253e8ab42a1: Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-fixes (2012-08-29 20:09:23 +1000) are available in the git repository at: git://people.freedesktop.org/~agd5f/linux drm-fixes-3.6 Alex Deucher (4): drm/radeon: don't disable plls that are in use by other crtcs drm/radeon/atom: rework DIG modesetting on DCE3+ drm/radeon/atom: powergating fixes for DCE6 drm/radeon: rework panel mode setup Christian K?nig (1): drm/radeon: fix double free in radeon_gpu_reset Jerome Glisse (1): drm/radeon: force dma32 to fix regression rs4xx,rs6xx,rs740 Marek Ol??k (3): drm/radeon: fix reading CB_COLORn_MASK from the CS drm/radeon: initialize tracked CS state drm/radeon: add proper checking of RESOLVE_BOX command for r600-r700 drivers/gpu/drm/radeon/atombios_crtc.c | 36 - drivers/gpu/drm/radeon/atombios_dp.c | 29 +++- drivers/gpu/drm/radeon/atombios_encoders.c | 109 drivers/gpu/drm/radeon/r600_cs.c | 30 +++- drivers/gpu/drm/radeon/r600d.h |8 ++ drivers/gpu/drm/radeon/radeon_device.c |5 +- drivers/gpu/drm/radeon/radeon_drv.c|3 +- drivers/gpu/drm/radeon/reg_srcs/r600 |1 - 8 files changed, 115 insertions(+), 106 deletions(-)
[PATCH] drm/radeon: fix dig encoder selection on DCE61
From: Alex Deucher
Was using the DCE41 code which was wrong. Fixes
blank displays on a number of Trinity systems.
Signed-off-by: Alex Deucher
Cc: stable at vger.kernel.org
---
drivers/gpu/drm/radeon/atombios_encoders.c | 31 +++
1 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c
b/drivers/gpu/drm/radeon/atombios_encoders.c
index 4a7f95e..6e8803a 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -1769,13 +1769,34 @@ static int radeon_atom_pick_dig_encoder(struct
drm_encoder *encoder)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_encoder *test_encoder;
- struct radeon_encoder_atom_dig *dig;
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
uint32_t dig_enc_in_use = 0;
- /* DCE4/5 */
- if (ASIC_IS_DCE4(rdev)) {
- dig = radeon_encoder->enc_priv;
- if (ASIC_IS_DCE41(rdev)) {
+ if (ASIC_IS_DCE6(rdev)) {
+ /* DCE6 */
+ switch (radeon_encoder->encoder_id) {
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+ if (dig->linkb)
+ return 1;
+ else
+ return 0;
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+ if (dig->linkb)
+ return 3;
+ else
+ return 2;
+ break;
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+ if (dig->linkb)
+ return 5;
+ else
+ return 4;
+ break;
+ }
+ } else if (ASIC_IS_DCE4(rdev)) {
+ /* DCE4/5 */
+ if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) {
/* ontario follows DCE4 */
if (rdev->family == CHIP_PALM) {
if (dig->linkb)
--
1.7.7.5
[PATCH] drm/radeon: implement bounds checking on thermal controller lookup
From: Alex Deucher
Don't read past the end of the array if we encounter an unknown
thermal controller.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/radeon_atombios.c | 11 +--
1 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c
b/drivers/gpu/drm/radeon/radeon_atombios.c
index e368b30..01b90b4 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -2009,7 +2009,8 @@ static int radeon_atombios_parse_power_table_1_3(struct
radeon_device *rdev)
power_info = (union power_info *)(mode_info->atom_context->bios +
data_offset);
/* add the i2c bus for thermal/fan chip */
- if (power_info->info.ucOverdriveThermalController > 0) {
+ if ((power_info->info.ucOverdriveThermalController > 0) &&
+ (power_info->info.ucOverdriveThermalController <
ARRAY_SIZE(thermal_controller_names))) {
DRM_INFO("Possible %s thermal controller at 0x%02x\n",
thermal_controller_names[power_info->info.ucOverdriveThermalController],
power_info->info.ucOverdriveControllerAddress >> 1);
@@ -2213,7 +2214,7 @@ static void
radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
(controller->ucType ==
ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) {
DRM_INFO("Special thermal controller config\n");
- } else {
+ } else if (controller->ucType <
ARRAY_SIZE(pp_lib_thermal_controller_names)) {
DRM_INFO("Possible %s thermal controller at 0x%02x %s
fan control\n",
pp_lib_thermal_controller_names[controller->ucType],
controller->ucI2cAddress >> 1,
@@ -2228,6 +2229,12 @@ static void
radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
strlcpy(info.type, name, sizeof(info.type));
i2c_new_device(&rdev->pm.i2c_bus->adapter,
&info);
}
+ } else {
+ DRM_INFO("Unknown thermal controller type %d at 0x%02x
%s fan control\n",
+controller->ucType,
+controller->ucI2cAddress >> 1,
+(controller->ucFanParameters &
+ ATOM_PP_FANPARAMETERS_NOFAN) ? "without" :
"with");
}
}
}
--
1.7.7.5
[PATCH] drm/radeon: rework pll selection
From: Alex Deucher
For DP we can use the same PPLL for all active DP
encoders. Take advantage of that to prevent cases
where we may end up sharing a PPLL between DP and
non-DP which won't work. Also clean up the code
a bit.
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_crtc.c | 100 +--
1 files changed, 68 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 9dc0220..6c300f1 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1503,6 +1503,24 @@ static void radeon_legacy_atom_fixup(struct drm_crtc
*crtc)
}
}
+static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *test_crtc;
+ struct radeon_crtc *radeon_test_crtc;
+ u32 pll_in_use = 0;
+
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+
+ radeon_test_crtc = to_radeon_crtc(test_crtc);
+ if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
+ pll_in_use |= (1 << radeon_test_crtc->pll_id);
+ }
+ return pll_in_use;
+}
+
static int radeon_atom_pick_pll(struct drm_crtc *crtc)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
@@ -1510,7 +1528,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
struct radeon_device *rdev = dev->dev_private;
struct drm_encoder *test_encoder;
struct drm_crtc *test_crtc;
- uint32_t pll_in_use = 0;
+ u32 pll_in_use;
if (ASIC_IS_DCE61(rdev)) {
list_for_each_entry(test_encoder,
&dev->mode_config.encoder_list, head) {
@@ -1522,32 +1540,45 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
if ((test_radeon_encoder->encoder_id ==
ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
- (dig->linkb == false)) /* UNIPHY A uses
PPLL2 */
+ (dig->linkb == false))
+ /* UNIPHY A uses PPLL2 */
return ATOM_PPLL2;
+ else if
(ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
+ /* UNIPHY B/C/D/E/F */
+ if (rdev->clock.dp_extclk)
+ return ATOM_PPLL_INVALID;
+ else {
+ list_for_each_entry(test_crtc,
&dev->mode_config.crtc_list, head) {
+ struct radeon_crtc
*radeon_test_crtc;
+
+ if (crtc == test_crtc)
+ continue;
+
+ /* for DP use the same
PLL for all */
+ radeon_test_crtc =
to_radeon_crtc(test_crtc);
+ if
(radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
+ return
radeon_test_crtc->pll_id;
+ }
+ }
+ }
}
}
/* UNIPHY B/C/D/E/F */
- list_for_each_entry(test_crtc, &dev->mode_config.crtc_list,
head) {
- struct radeon_crtc *radeon_test_crtc;
-
- if (crtc == test_crtc)
- continue;
-
- radeon_test_crtc = to_radeon_crtc(test_crtc);
- if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
- (radeon_test_crtc->pll_id == ATOM_PPLL1))
- pll_in_use |= (1 << radeon_test_crtc->pll_id);
- }
- if (!(pll_in_use & 4))
+ pll_in_use = radeon_get_pll_use_mask(crtc);
+ if (!(pll_in_use & (1 << ATOM_PPLL0)))
return ATOM_PPLL0;
- return ATOM_PPLL1;
+ if (!(pll_in_use & (1 << ATOM_PPLL1)))
+ return ATOM_PPLL1;
+ DRM_ERROR("unable to allocate a PPLL\n");
+ return ATOM_PPLL_INVALID;
} else if (ASIC_IS_DCE4(rdev)) {
list_for_each_entry(test_encoder,
&dev->mode_config.encoder_list, head) {
if (test_encoder->crtc && (test_encoder->crtc == crtc))
{
/* in DP mode, the DP ref clock can come from
PPLL, DCPLL, or ext clock,
[PATCH] drm/radeon: rework pll selection (v2)
From: Alex Deucher
For DP we can use the same PPLL for all active DP
encoders. Take advantage of that to prevent cases
where we may end up sharing a PPLL between DP and
non-DP which won't work. Also clean up the code
a bit.
v2: fix missing pll_id assignment in crtc init
Signed-off-by: Alex Deucher
---
drivers/gpu/drm/radeon/atombios_crtc.c | 102 +--
1 files changed, 69 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
b/drivers/gpu/drm/radeon/atombios_crtc.c
index 2817101..3b42ea2 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1479,6 +1479,24 @@ static void radeon_legacy_atom_fixup(struct drm_crtc
*crtc)
}
}
+static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc *test_crtc;
+ struct radeon_crtc *radeon_test_crtc;
+ u32 pll_in_use = 0;
+
+ list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+ if (crtc == test_crtc)
+ continue;
+
+ radeon_test_crtc = to_radeon_crtc(test_crtc);
+ if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
+ pll_in_use |= (1 << radeon_test_crtc->pll_id);
+ }
+ return pll_in_use;
+}
+
static int radeon_atom_pick_pll(struct drm_crtc *crtc)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
@@ -1486,7 +1504,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
struct radeon_device *rdev = dev->dev_private;
struct drm_encoder *test_encoder;
struct drm_crtc *test_crtc;
- uint32_t pll_in_use = 0;
+ u32 pll_in_use;
if (ASIC_IS_DCE61(rdev)) {
list_for_each_entry(test_encoder,
&dev->mode_config.encoder_list, head) {
@@ -1498,32 +1516,45 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
if ((test_radeon_encoder->encoder_id ==
ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
- (dig->linkb == false)) /* UNIPHY A uses
PPLL2 */
+ (dig->linkb == false))
+ /* UNIPHY A uses PPLL2 */
return ATOM_PPLL2;
+ else if
(ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
+ /* UNIPHY B/C/D/E/F */
+ if (rdev->clock.dp_extclk)
+ return ATOM_PPLL_INVALID;
+ else {
+ list_for_each_entry(test_crtc,
&dev->mode_config.crtc_list, head) {
+ struct radeon_crtc
*radeon_test_crtc;
+
+ if (crtc == test_crtc)
+ continue;
+
+ /* for DP use the same
PLL for all */
+ radeon_test_crtc =
to_radeon_crtc(test_crtc);
+ if
(radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
+ return
radeon_test_crtc->pll_id;
+ }
+ }
+ }
}
}
/* UNIPHY B/C/D/E/F */
- list_for_each_entry(test_crtc, &dev->mode_config.crtc_list,
head) {
- struct radeon_crtc *radeon_test_crtc;
-
- if (crtc == test_crtc)
- continue;
-
- radeon_test_crtc = to_radeon_crtc(test_crtc);
- if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
- (radeon_test_crtc->pll_id == ATOM_PPLL1))
- pll_in_use |= (1 << radeon_test_crtc->pll_id);
- }
- if (!(pll_in_use & 4))
+ pll_in_use = radeon_get_pll_use_mask(crtc);
+ if (!(pll_in_use & (1 << ATOM_PPLL0)))
return ATOM_PPLL0;
- return ATOM_PPLL1;
+ if (!(pll_in_use & (1 << ATOM_PPLL1)))
+ return ATOM_PPLL1;
+ DRM_ERROR("unable to allocate a PPLL\n");
+ return ATOM_PPLL_INVALID;
} else if (ASIC_IS_DCE4(rdev)) {
list_for_each_entry(test_encoder,
&dev->mode_config.encoder_list, head) {
if (test_encoder->crtc && (test_encoder->crtc == crtc))
{
/* in DP mode, the DP ref clock can come from
PPLL, DCP
