Commit fb328d73 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-fixes-3.11' of git://people.freedesktop.org/~agd5f/linux

more DPM fixes for radeon.

* 'drm-fixes-3.11' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon/dpm: add debugfs support for RS780/RS880 (v3)
  drm/radeon/dpm/atom: fix broken gcc harder
  drm/radeon/dpm/atom: restructure logic to work around a compiler bug
  drm/radeon/dpm: fix atom vram table parsing
  drm/radeon: fix an endian bug in atom table parsing
  drm/radeon: add a module parameter to disable aspm
parents 6bd2cab2 444bddc4
...@@ -5515,6 +5515,9 @@ void evergreen_program_aspm(struct radeon_device *rdev) ...@@ -5515,6 +5515,9 @@ void evergreen_program_aspm(struct radeon_device *rdev)
*/ */
bool fusion_platform = false; bool fusion_platform = false;
if (radeon_aspm == 0)
return;
if (!(rdev->flags & RADEON_IS_PCIE)) if (!(rdev->flags & RADEON_IS_PCIE))
return; return;
......
...@@ -97,6 +97,7 @@ extern int radeon_msi; ...@@ -97,6 +97,7 @@ extern int radeon_msi;
extern int radeon_lockup_timeout; extern int radeon_lockup_timeout;
extern int radeon_fastfb; extern int radeon_fastfb;
extern int radeon_dpm; extern int radeon_dpm;
extern int radeon_aspm;
/* /*
* Copy from radeon_drv.h so we don't have to include both and have conflicting * Copy from radeon_drv.h so we don't have to include both and have conflicting
......
...@@ -1270,6 +1270,7 @@ static struct radeon_asic rs780_asic = { ...@@ -1270,6 +1270,7 @@ static struct radeon_asic rs780_asic = {
.get_sclk = &rs780_dpm_get_sclk, .get_sclk = &rs780_dpm_get_sclk,
.get_mclk = &rs780_dpm_get_mclk, .get_mclk = &rs780_dpm_get_mclk,
.print_power_state = &rs780_dpm_print_power_state, .print_power_state = &rs780_dpm_print_power_state,
.debugfs_print_current_performance_level = &rs780_dpm_debugfs_print_current_performance_level,
}, },
.pflip = { .pflip = {
.pre_page_flip = &rs600_pre_page_flip, .pre_page_flip = &rs600_pre_page_flip,
......
...@@ -433,6 +433,8 @@ u32 rs780_dpm_get_sclk(struct radeon_device *rdev, bool low); ...@@ -433,6 +433,8 @@ u32 rs780_dpm_get_sclk(struct radeon_device *rdev, bool low);
u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low); u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low);
void rs780_dpm_print_power_state(struct radeon_device *rdev, void rs780_dpm_print_power_state(struct radeon_device *rdev,
struct radeon_ps *ps); struct radeon_ps *ps);
void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
struct seq_file *m);
/* uvd */ /* uvd */
int r600_uvd_init(struct radeon_device *rdev); int r600_uvd_init(struct radeon_device *rdev);
......
...@@ -3513,7 +3513,6 @@ int radeon_atom_get_memory_info(struct radeon_device *rdev, ...@@ -3513,7 +3513,6 @@ int radeon_atom_get_memory_info(struct radeon_device *rdev,
u8 frev, crev, i; u8 frev, crev, i;
u16 data_offset, size; u16 data_offset, size;
union vram_info *vram_info; union vram_info *vram_info;
u8 *p;
memset(mem_info, 0, sizeof(struct atom_memory_info)); memset(mem_info, 0, sizeof(struct atom_memory_info));
...@@ -3529,13 +3528,12 @@ int radeon_atom_get_memory_info(struct radeon_device *rdev, ...@@ -3529,13 +3528,12 @@ int radeon_atom_get_memory_info(struct radeon_device *rdev,
if (module_index < vram_info->v1_3.ucNumOfVRAMModule) { if (module_index < vram_info->v1_3.ucNumOfVRAMModule) {
ATOM_VRAM_MODULE_V3 *vram_module = ATOM_VRAM_MODULE_V3 *vram_module =
(ATOM_VRAM_MODULE_V3 *)vram_info->v1_3.aVramInfo; (ATOM_VRAM_MODULE_V3 *)vram_info->v1_3.aVramInfo;
p = (u8 *)vram_info->v1_3.aVramInfo;
for (i = 0; i < module_index; i++) { for (i = 0; i < module_index; i++) {
vram_module = (ATOM_VRAM_MODULE_V3 *)p;
if (le16_to_cpu(vram_module->usSize) == 0) if (le16_to_cpu(vram_module->usSize) == 0)
return -EINVAL; return -EINVAL;
p += le16_to_cpu(vram_module->usSize); vram_module = (ATOM_VRAM_MODULE_V3 *)
((u8 *)vram_module + le16_to_cpu(vram_module->usSize));
} }
mem_info->mem_vendor = vram_module->asMemory.ucMemoryVenderID & 0xf; mem_info->mem_vendor = vram_module->asMemory.ucMemoryVenderID & 0xf;
mem_info->mem_type = vram_module->asMemory.ucMemoryType & 0xf0; mem_info->mem_type = vram_module->asMemory.ucMemoryType & 0xf0;
...@@ -3547,13 +3545,12 @@ int radeon_atom_get_memory_info(struct radeon_device *rdev, ...@@ -3547,13 +3545,12 @@ int radeon_atom_get_memory_info(struct radeon_device *rdev,
if (module_index < vram_info->v1_4.ucNumOfVRAMModule) { if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {
ATOM_VRAM_MODULE_V4 *vram_module = ATOM_VRAM_MODULE_V4 *vram_module =
(ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo; (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;
p = (u8 *)vram_info->v1_4.aVramInfo;
for (i = 0; i < module_index; i++) { for (i = 0; i < module_index; i++) {
vram_module = (ATOM_VRAM_MODULE_V4 *)p;
if (le16_to_cpu(vram_module->usModuleSize) == 0) if (le16_to_cpu(vram_module->usModuleSize) == 0)
return -EINVAL; return -EINVAL;
p += le16_to_cpu(vram_module->usModuleSize); vram_module = (ATOM_VRAM_MODULE_V4 *)
((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
} }
mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf; mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;
mem_info->mem_type = vram_module->ucMemoryType & 0xf0; mem_info->mem_type = vram_module->ucMemoryType & 0xf0;
...@@ -3572,13 +3569,12 @@ int radeon_atom_get_memory_info(struct radeon_device *rdev, ...@@ -3572,13 +3569,12 @@ int radeon_atom_get_memory_info(struct radeon_device *rdev,
if (module_index < vram_info->v2_1.ucNumOfVRAMModule) { if (module_index < vram_info->v2_1.ucNumOfVRAMModule) {
ATOM_VRAM_MODULE_V7 *vram_module = ATOM_VRAM_MODULE_V7 *vram_module =
(ATOM_VRAM_MODULE_V7 *)vram_info->v2_1.aVramInfo; (ATOM_VRAM_MODULE_V7 *)vram_info->v2_1.aVramInfo;
p = (u8 *)vram_info->v2_1.aVramInfo;
for (i = 0; i < module_index; i++) { for (i = 0; i < module_index; i++) {
vram_module = (ATOM_VRAM_MODULE_V7 *)p;
if (le16_to_cpu(vram_module->usModuleSize) == 0) if (le16_to_cpu(vram_module->usModuleSize) == 0)
return -EINVAL; return -EINVAL;
p += le16_to_cpu(vram_module->usModuleSize); vram_module = (ATOM_VRAM_MODULE_V7 *)
((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
} }
mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf; mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf;
mem_info->mem_type = vram_module->ucMemoryType & 0xf0; mem_info->mem_type = vram_module->ucMemoryType & 0xf0;
...@@ -3628,21 +3624,19 @@ int radeon_atom_get_mclk_range_table(struct radeon_device *rdev, ...@@ -3628,21 +3624,19 @@ int radeon_atom_get_mclk_range_table(struct radeon_device *rdev,
if (module_index < vram_info->v1_4.ucNumOfVRAMModule) { if (module_index < vram_info->v1_4.ucNumOfVRAMModule) {
ATOM_VRAM_MODULE_V4 *vram_module = ATOM_VRAM_MODULE_V4 *vram_module =
(ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo; (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo;
ATOM_MEMORY_TIMING_FORMAT *format;
p = (u8 *)vram_info->v1_4.aVramInfo;
for (i = 0; i < module_index; i++) { for (i = 0; i < module_index; i++) {
vram_module = (ATOM_VRAM_MODULE_V4 *)p;
if (le16_to_cpu(vram_module->usModuleSize) == 0) if (le16_to_cpu(vram_module->usModuleSize) == 0)
return -EINVAL; return -EINVAL;
p += le16_to_cpu(vram_module->usModuleSize); vram_module = (ATOM_VRAM_MODULE_V4 *)
((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize));
} }
mclk_range_table->num_entries = (u8) mclk_range_table->num_entries = (u8)
((vram_module->usModuleSize - offsetof(ATOM_VRAM_MODULE_V4, asMemTiming)) / ((le16_to_cpu(vram_module->usModuleSize) - offsetof(ATOM_VRAM_MODULE_V4, asMemTiming)) /
mem_timing_size); mem_timing_size);
p = (u8 *)vram_module->asMemTiming; p = (u8 *)&vram_module->asMemTiming[0];
for (i = 0; i < mclk_range_table->num_entries; i++) { for (i = 0; i < mclk_range_table->num_entries; i++) {
format = (ATOM_MEMORY_TIMING_FORMAT *)p; ATOM_MEMORY_TIMING_FORMAT *format = (ATOM_MEMORY_TIMING_FORMAT *)p;
mclk_range_table->mclk[i] = le32_to_cpu(format->ulClkRange); mclk_range_table->mclk[i] = le32_to_cpu(format->ulClkRange);
p += mem_timing_size; p += mem_timing_size;
} }
...@@ -3705,17 +3699,21 @@ int radeon_atom_init_mc_reg_table(struct radeon_device *rdev, ...@@ -3705,17 +3699,21 @@ int radeon_atom_init_mc_reg_table(struct radeon_device *rdev,
(ATOM_MEMORY_SETTING_DATA_BLOCK *) (ATOM_MEMORY_SETTING_DATA_BLOCK *)
((u8 *)reg_block + (2 * sizeof(u16)) + ((u8 *)reg_block + (2 * sizeof(u16)) +
le16_to_cpu(reg_block->usRegIndexTblSize)); le16_to_cpu(reg_block->usRegIndexTblSize));
ATOM_INIT_REG_INDEX_FORMAT *format = &reg_block->asRegIndexBuf[0];
num_entries = (u8)((le16_to_cpu(reg_block->usRegIndexTblSize)) / num_entries = (u8)((le16_to_cpu(reg_block->usRegIndexTblSize)) /
sizeof(ATOM_INIT_REG_INDEX_FORMAT)) - 1; sizeof(ATOM_INIT_REG_INDEX_FORMAT)) - 1;
if (num_entries > VBIOS_MC_REGISTER_ARRAY_SIZE) if (num_entries > VBIOS_MC_REGISTER_ARRAY_SIZE)
return -EINVAL; return -EINVAL;
while (!(reg_block->asRegIndexBuf[i].ucPreRegDataLength & ACCESS_PLACEHOLDER) && while (i < num_entries) {
(i < num_entries)) { if (format->ucPreRegDataLength & ACCESS_PLACEHOLDER)
break;
reg_table->mc_reg_address[i].s1 = reg_table->mc_reg_address[i].s1 =
(u16)(le16_to_cpu(reg_block->asRegIndexBuf[i].usRegIndex)); (u16)(le16_to_cpu(format->usRegIndex));
reg_table->mc_reg_address[i].pre_reg_data = reg_table->mc_reg_address[i].pre_reg_data =
(u8)(reg_block->asRegIndexBuf[i].ucPreRegDataLength); (u8)(format->ucPreRegDataLength);
i++; i++;
format = (ATOM_INIT_REG_INDEX_FORMAT *)
((u8 *)format + sizeof(ATOM_INIT_REG_INDEX_FORMAT));
} }
reg_table->last = i; reg_table->last = i;
while ((*(u32 *)reg_data != END_OF_REG_DATA_BLOCK) && while ((*(u32 *)reg_data != END_OF_REG_DATA_BLOCK) &&
......
...@@ -167,6 +167,7 @@ int radeon_msi = -1; ...@@ -167,6 +167,7 @@ int radeon_msi = -1;
int radeon_lockup_timeout = 10000; int radeon_lockup_timeout = 10000;
int radeon_fastfb = 0; int radeon_fastfb = 0;
int radeon_dpm = -1; int radeon_dpm = -1;
int radeon_aspm = -1;
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
module_param_named(no_wb, radeon_no_wb, int, 0444); module_param_named(no_wb, radeon_no_wb, int, 0444);
...@@ -225,6 +226,9 @@ module_param_named(fastfb, radeon_fastfb, int, 0444); ...@@ -225,6 +226,9 @@ module_param_named(fastfb, radeon_fastfb, int, 0444);
MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)"); MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)");
module_param_named(dpm, radeon_dpm, int, 0444); module_param_named(dpm, radeon_dpm, int, 0444);
MODULE_PARM_DESC(aspm, "ASPM support (1 = enable, 0 = disable, -1 = auto)");
module_param_named(aspm, radeon_aspm, int, 0444);
static struct pci_device_id pciidlist[] = { static struct pci_device_id pciidlist[] = {
radeon_PCI_IDS radeon_PCI_IDS
}; };
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "r600_dpm.h" #include "r600_dpm.h"
#include "rs780_dpm.h" #include "rs780_dpm.h"
#include "atom.h" #include "atom.h"
#include <linux/seq_file.h>
static struct igp_ps *rs780_get_ps(struct radeon_ps *rps) static struct igp_ps *rs780_get_ps(struct radeon_ps *rps)
{ {
...@@ -961,3 +962,27 @@ u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low) ...@@ -961,3 +962,27 @@ u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low)
return pi->bootup_uma_clk; return pi->bootup_uma_clk;
} }
void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
struct seq_file *m)
{
struct radeon_ps *rps = rdev->pm.dpm.current_ps;
struct igp_ps *ps = rs780_get_ps(rps);
u32 current_fb_div = RREG32(FVTHROT_STATUS_REG0) & CURRENT_FEEDBACK_DIV_MASK;
u32 func_cntl = RREG32(CG_SPLL_FUNC_CNTL);
u32 ref_div = ((func_cntl & SPLL_REF_DIV_MASK) >> SPLL_REF_DIV_SHIFT) + 1;
u32 post_div = ((func_cntl & SPLL_SW_HILEN_MASK) >> SPLL_SW_HILEN_SHIFT) + 1 +
((func_cntl & SPLL_SW_LOLEN_MASK) >> SPLL_SW_LOLEN_SHIFT) + 1;
u32 sclk = (rdev->clock.spll.reference_freq * current_fb_div) /
(post_div * ref_div);
seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
/* guess based on the current sclk */
if (sclk < (ps->sclk_low + 500))
seq_printf(m, "power level 0 sclk: %u vddc_index: %d\n",
ps->sclk_low, ps->min_voltage);
else
seq_printf(m, "power level 1 sclk: %u vddc_index: %d\n",
ps->sclk_high, ps->max_voltage);
}
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
# define SPLL_SLEEP (1 << 1) # define SPLL_SLEEP (1 << 1)
# define SPLL_REF_DIV(x) ((x) << 2) # define SPLL_REF_DIV(x) ((x) << 2)
# define SPLL_REF_DIV_MASK (7 << 2) # define SPLL_REF_DIV_MASK (7 << 2)
# define SPLL_REF_DIV_SHIFT 2
# define SPLL_FB_DIV(x) ((x) << 5) # define SPLL_FB_DIV(x) ((x) << 5)
# define SPLL_FB_DIV_MASK (0xff << 2) # define SPLL_FB_DIV_MASK (0xff << 2)
# define SPLL_FB_DIV_SHIFT 2 # define SPLL_FB_DIV_SHIFT 2
...@@ -36,8 +37,10 @@ ...@@ -36,8 +37,10 @@
# define SPLL_PULSENUM_MASK (3 << 14) # define SPLL_PULSENUM_MASK (3 << 14)
# define SPLL_SW_HILEN(x) ((x) << 16) # define SPLL_SW_HILEN(x) ((x) << 16)
# define SPLL_SW_HILEN_MASK (0xf << 16) # define SPLL_SW_HILEN_MASK (0xf << 16)
# define SPLL_SW_HILEN_SHIFT 16
# define SPLL_SW_LOLEN(x) ((x) << 20) # define SPLL_SW_LOLEN(x) ((x) << 20)
# define SPLL_SW_LOLEN_MASK (0xf << 20) # define SPLL_SW_LOLEN_MASK (0xf << 20)
# define SPLL_SW_LOLEN_SHIFT 20
# define SPLL_DIVEN (1 << 24) # define SPLL_DIVEN (1 << 24)
# define SPLL_BYPASS_EN (1 << 25) # define SPLL_BYPASS_EN (1 << 25)
# define SPLL_CHG_STATUS (1 << 29) # define SPLL_CHG_STATUS (1 << 29)
......
...@@ -1763,12 +1763,14 @@ void rv6xx_setup_asic(struct radeon_device *rdev) ...@@ -1763,12 +1763,14 @@ void rv6xx_setup_asic(struct radeon_device *rdev)
{ {
r600_enable_acpi_pm(rdev); r600_enable_acpi_pm(rdev);
if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L0s) if (radeon_aspm != 0) {
rv6xx_enable_l0s(rdev); if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L0s)
if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L1) rv6xx_enable_l0s(rdev);
rv6xx_enable_l1(rdev); if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L1)
if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1) rv6xx_enable_l1(rdev);
rv6xx_enable_pll_sleep_in_l1(rdev); if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1)
rv6xx_enable_pll_sleep_in_l1(rdev);
}
} }
void rv6xx_dpm_display_configuration_changed(struct radeon_device *rdev) void rv6xx_dpm_display_configuration_changed(struct radeon_device *rdev)
......
...@@ -2099,12 +2099,14 @@ void rv770_dpm_setup_asic(struct radeon_device *rdev) ...@@ -2099,12 +2099,14 @@ void rv770_dpm_setup_asic(struct radeon_device *rdev)
rv770_enable_acpi_pm(rdev); rv770_enable_acpi_pm(rdev);
if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L0s) if (radeon_aspm != 0) {
rv770_enable_l0s(rdev); if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L0s)
if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L1) rv770_enable_l0s(rdev);
rv770_enable_l1(rdev); if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L1)
if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1) rv770_enable_l1(rdev);
rv770_enable_pll_sleep_in_l1(rdev); if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1)
rv770_enable_pll_sleep_in_l1(rdev);
}
} }
void rv770_dpm_display_configuration_changed(struct radeon_device *rdev) void rv770_dpm_display_configuration_changed(struct radeon_device *rdev)
......
...@@ -7053,6 +7053,9 @@ static void si_program_aspm(struct radeon_device *rdev) ...@@ -7053,6 +7053,9 @@ static void si_program_aspm(struct radeon_device *rdev)
bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false; bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
bool disable_clkreq = false; bool disable_clkreq = false;
if (radeon_aspm == 0)
return;
if (!(rdev->flags & RADEON_IS_PCIE)) if (!(rdev->flags & RADEON_IS_PCIE))
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment