Commit 0ab15bde authored by Dave Airlie's avatar Dave Airlie

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

radeon and amdgpu fixes for 4.7.  Highlights:
- fixes for GPU VM passthrough
- fixes for powerplay on Polaris GPUs
- pll fixes for rs780/880

* 'drm-fixes-4.7' of git://people.freedesktop.org/~agd5f/linux:
  drm/amd/powerplay: select samu dpm 0 as boot level on polaris.
  drm/amd/powerplay: update powerplay table parsing
  Revert "drm/amdgpu: add pipeline sync while vmid switch in same ctx"
  drm/amdgpu/gfx7: fix broken condition check
  drm/radeon: fix asic initialization for virtualized environments
  amdgpu: fix asic initialization for virtualized environments (v2)
  drm/radeon: don't use fractional dividers on RS[78]80 if SS is enabled
  drm/radeon: do not hard reset GPU while freezing on r600/r700 family
parents d9724d3b 871fd840
...@@ -799,7 +799,6 @@ struct amdgpu_ring { ...@@ -799,7 +799,6 @@ struct amdgpu_ring {
unsigned cond_exe_offs; unsigned cond_exe_offs;
u64 cond_exe_gpu_addr; u64 cond_exe_gpu_addr;
volatile u32 *cond_exe_cpu_addr; volatile u32 *cond_exe_cpu_addr;
int vmid;
}; };
/* /*
...@@ -937,8 +936,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, ...@@ -937,8 +936,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
unsigned vm_id, uint64_t pd_addr, unsigned vm_id, uint64_t pd_addr,
uint32_t gds_base, uint32_t gds_size, uint32_t gds_base, uint32_t gds_size,
uint32_t gws_base, uint32_t gws_size, uint32_t gws_base, uint32_t gws_size,
uint32_t oa_base, uint32_t oa_size, uint32_t oa_base, uint32_t oa_size);
bool vmid_switch);
void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id);
uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr);
int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
...@@ -1822,6 +1820,8 @@ struct amdgpu_asic_funcs { ...@@ -1822,6 +1820,8 @@ struct amdgpu_asic_funcs {
/* MM block clocks */ /* MM block clocks */
int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk); int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk);
int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk); int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk);
/* query virtual capabilities */
u32 (*get_virtual_caps)(struct amdgpu_device *adev);
}; };
/* /*
...@@ -1916,8 +1916,12 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device); ...@@ -1916,8 +1916,12 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device);
/* GPU virtualization */ /* GPU virtualization */
#define AMDGPU_VIRT_CAPS_SRIOV_EN (1 << 0)
#define AMDGPU_VIRT_CAPS_IS_VF (1 << 1)
struct amdgpu_virtualization { struct amdgpu_virtualization {
bool supports_sr_iov; bool supports_sr_iov;
bool is_virtual;
u32 caps;
}; };
/* /*
...@@ -2206,6 +2210,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) ...@@ -2206,6 +2210,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev)) #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev))
#define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d)) #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d))
#define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec)) #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec))
#define amdgpu_asic_get_virtual_caps(adev) ((adev)->asic_funcs->get_virtual_caps((adev)))
#define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev)) #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev))
#define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev)) #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev))
#define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))
......
...@@ -1385,6 +1385,15 @@ static int amdgpu_resume(struct amdgpu_device *adev) ...@@ -1385,6 +1385,15 @@ static int amdgpu_resume(struct amdgpu_device *adev)
return 0; return 0;
} }
static bool amdgpu_device_is_virtual(void)
{
#ifdef CONFIG_X86
return boot_cpu_has(X86_FEATURE_HYPERVISOR);
#else
return false;
#endif
}
/** /**
* amdgpu_device_init - initialize the driver * amdgpu_device_init - initialize the driver
* *
...@@ -1519,8 +1528,14 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -1519,8 +1528,14 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->virtualization.supports_sr_iov = adev->virtualization.supports_sr_iov =
amdgpu_atombios_has_gpu_virtualization_table(adev); amdgpu_atombios_has_gpu_virtualization_table(adev);
/* Check if we are executing in a virtualized environment */
adev->virtualization.is_virtual = amdgpu_device_is_virtual();
adev->virtualization.caps = amdgpu_asic_get_virtual_caps(adev);
/* Post card if necessary */ /* Post card if necessary */
if (!amdgpu_card_posted(adev)) { if (!amdgpu_card_posted(adev) ||
(adev->virtualization.is_virtual &&
!adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN)) {
if (!adev->bios) { if (!adev->bios) {
dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
return -EINVAL; return -EINVAL;
......
...@@ -122,7 +122,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -122,7 +122,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
bool skip_preamble, need_ctx_switch; bool skip_preamble, need_ctx_switch;
unsigned patch_offset = ~0; unsigned patch_offset = ~0;
struct amdgpu_vm *vm; struct amdgpu_vm *vm;
int vmid = 0, old_vmid = ring->vmid;
struct fence *hwf; struct fence *hwf;
uint64_t ctx; uint64_t ctx;
...@@ -136,11 +135,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -136,11 +135,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
if (job) { if (job) {
vm = job->vm; vm = job->vm;
ctx = job->ctx; ctx = job->ctx;
vmid = job->vm_id;
} else { } else {
vm = NULL; vm = NULL;
ctx = 0; ctx = 0;
vmid = 0;
} }
if (!ring->ready) { if (!ring->ready) {
...@@ -166,8 +163,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -166,8 +163,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr, r = amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr,
job->gds_base, job->gds_size, job->gds_base, job->gds_size,
job->gws_base, job->gws_size, job->gws_base, job->gws_size,
job->oa_base, job->oa_size, job->oa_base, job->oa_size);
(ring->current_ctx == ctx) && (old_vmid != vmid));
if (r) { if (r) {
amdgpu_ring_undo(ring); amdgpu_ring_undo(ring);
return r; return r;
...@@ -184,6 +180,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -184,6 +180,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
need_ctx_switch = ring->current_ctx != ctx; need_ctx_switch = ring->current_ctx != ctx;
for (i = 0; i < num_ibs; ++i) { for (i = 0; i < num_ibs; ++i) {
ib = &ibs[i]; ib = &ibs[i];
/* drop preamble IBs if we don't have a context switch */ /* drop preamble IBs if we don't have a context switch */
if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble) if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble)
continue; continue;
...@@ -191,7 +188,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -191,7 +188,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0, amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0,
need_ctx_switch); need_ctx_switch);
need_ctx_switch = false; need_ctx_switch = false;
ring->vmid = vmid;
} }
if (ring->funcs->emit_hdp_invalidate) if (ring->funcs->emit_hdp_invalidate)
...@@ -202,7 +198,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -202,7 +198,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
dev_err(adev->dev, "failed to emit fence (%d)\n", r); dev_err(adev->dev, "failed to emit fence (%d)\n", r);
if (job && job->vm_id) if (job && job->vm_id)
amdgpu_vm_reset_id(adev, job->vm_id); amdgpu_vm_reset_id(adev, job->vm_id);
ring->vmid = old_vmid;
amdgpu_ring_undo(ring); amdgpu_ring_undo(ring);
return r; return r;
} }
......
...@@ -298,8 +298,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, ...@@ -298,8 +298,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
unsigned vm_id, uint64_t pd_addr, unsigned vm_id, uint64_t pd_addr,
uint32_t gds_base, uint32_t gds_size, uint32_t gds_base, uint32_t gds_size,
uint32_t gws_base, uint32_t gws_size, uint32_t gws_base, uint32_t gws_size,
uint32_t oa_base, uint32_t oa_size, uint32_t oa_base, uint32_t oa_size)
bool vmid_switch)
{ {
struct amdgpu_device *adev = ring->adev; struct amdgpu_device *adev = ring->adev;
struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id]; struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id];
...@@ -313,7 +312,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, ...@@ -313,7 +312,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
int r; int r;
if (ring->funcs->emit_pipeline_sync && ( if (ring->funcs->emit_pipeline_sync && (
pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed || vmid_switch)) pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed ||
ring->type == AMDGPU_RING_TYPE_COMPUTE))
amdgpu_ring_emit_pipeline_sync(ring); amdgpu_ring_emit_pipeline_sync(ring);
if (ring->funcs->emit_vm_flush && if (ring->funcs->emit_vm_flush &&
......
...@@ -962,6 +962,12 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev, ...@@ -962,6 +962,12 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev,
return true; return true;
} }
static u32 cik_get_virtual_caps(struct amdgpu_device *adev)
{
/* CIK does not support SR-IOV */
return 0;
}
static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = { static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = {
{mmGRBM_STATUS, false}, {mmGRBM_STATUS, false},
{mmGB_ADDR_CONFIG, false}, {mmGB_ADDR_CONFIG, false},
...@@ -2007,6 +2013,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs = ...@@ -2007,6 +2013,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs =
.get_xclk = &cik_get_xclk, .get_xclk = &cik_get_xclk,
.set_uvd_clocks = &cik_set_uvd_clocks, .set_uvd_clocks = &cik_set_uvd_clocks,
.set_vce_clocks = &cik_set_vce_clocks, .set_vce_clocks = &cik_set_vce_clocks,
.get_virtual_caps = &cik_get_virtual_caps,
/* these should be moved to their own ip modules */ /* these should be moved to their own ip modules */
.get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter, .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter,
.wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle, .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle,
......
...@@ -4833,7 +4833,7 @@ static int gfx_v7_0_eop_irq(struct amdgpu_device *adev, ...@@ -4833,7 +4833,7 @@ static int gfx_v7_0_eop_irq(struct amdgpu_device *adev,
case 2: case 2:
for (i = 0; i < adev->gfx.num_compute_rings; i++) { for (i = 0; i < adev->gfx.num_compute_rings; i++) {
ring = &adev->gfx.compute_ring[i]; ring = &adev->gfx.compute_ring[i];
if ((ring->me == me_id) & (ring->pipe == pipe_id)) if ((ring->me == me_id) && (ring->pipe == pipe_id))
amdgpu_fence_process(ring); amdgpu_fence_process(ring);
} }
break; break;
......
...@@ -421,6 +421,20 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev, ...@@ -421,6 +421,20 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev,
return true; return true;
} }
static u32 vi_get_virtual_caps(struct amdgpu_device *adev)
{
u32 caps = 0;
u32 reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER);
if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, IOV_ENABLE))
caps |= AMDGPU_VIRT_CAPS_SRIOV_EN;
if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, FUNC_IDENTIFIER))
caps |= AMDGPU_VIRT_CAPS_IS_VF;
return caps;
}
static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = { static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = {
{mmGB_MACROTILE_MODE7, true}, {mmGB_MACROTILE_MODE7, true},
}; };
...@@ -1118,6 +1132,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs = ...@@ -1118,6 +1132,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs =
.get_xclk = &vi_get_xclk, .get_xclk = &vi_get_xclk,
.set_uvd_clocks = &vi_set_uvd_clocks, .set_uvd_clocks = &vi_set_uvd_clocks,
.set_vce_clocks = &vi_set_vce_clocks, .set_vce_clocks = &vi_set_vce_clocks,
.get_virtual_caps = &vi_get_virtual_caps,
/* these should be moved to their own ip modules */ /* these should be moved to their own ip modules */
.get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter, .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter,
.wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle, .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle,
......
...@@ -39,6 +39,7 @@ struct phm_ppt_v1_clock_voltage_dependency_record { ...@@ -39,6 +39,7 @@ struct phm_ppt_v1_clock_voltage_dependency_record {
uint8_t phases; uint8_t phases;
uint8_t cks_enable; uint8_t cks_enable;
uint8_t cks_voffset; uint8_t cks_voffset;
uint32_t sclk_offset;
}; };
typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record; typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record;
......
...@@ -999,7 +999,7 @@ static int polaris10_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr, ...@@ -999,7 +999,7 @@ static int polaris10_get_dependency_volt_by_clk(struct pp_hwmgr *hwmgr,
vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), vddci = phm_find_closest_vddci(&(data->vddci_voltage_table),
(dep_table->entries[i].vddc - (dep_table->entries[i].vddc -
(uint16_t)data->vddc_vddci_delta)); (uint16_t)data->vddc_vddci_delta));
*voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT;
} }
if (POLARIS10_VOLTAGE_CONTROL_NONE == data->mvdd_control) if (POLARIS10_VOLTAGE_CONTROL_NONE == data->mvdd_control)
...@@ -3520,10 +3520,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, ...@@ -3520,10 +3520,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state; ATOM_Tonga_State *state_entry = (ATOM_Tonga_State *)state;
ATOM_Tonga_POWERPLAYTABLE *powerplay_table = ATOM_Tonga_POWERPLAYTABLE *powerplay_table =
(ATOM_Tonga_POWERPLAYTABLE *)pp_table; (ATOM_Tonga_POWERPLAYTABLE *)pp_table;
ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table = PPTable_Generic_SubTable_Header *sclk_dep_table =
(ATOM_Tonga_SCLK_Dependency_Table *) (PPTable_Generic_SubTable_Header *)
(((unsigned long)powerplay_table) + (((unsigned long)powerplay_table) +
le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); le16_to_cpu(powerplay_table->usSclkDependencyTableOffset));
ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table =
(ATOM_Tonga_MCLK_Dependency_Table *) (ATOM_Tonga_MCLK_Dependency_Table *)
(((unsigned long)powerplay_table) + (((unsigned long)powerplay_table) +
...@@ -3575,7 +3576,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, ...@@ -3575,7 +3576,11 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
/* Performance levels are arranged from low to high. */ /* Performance levels are arranged from low to high. */
performance_level->memory_clock = mclk_dep_table->entries performance_level->memory_clock = mclk_dep_table->entries
[state_entry->ucMemoryClockIndexLow].ulMclk; [state_entry->ucMemoryClockIndexLow].ulMclk;
performance_level->engine_clock = sclk_dep_table->entries if (sclk_dep_table->ucRevId == 0)
performance_level->engine_clock = ((ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table)->entries
[state_entry->ucEngineClockIndexLow].ulSclk;
else if (sclk_dep_table->ucRevId == 1)
performance_level->engine_clock = ((ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table)->entries
[state_entry->ucEngineClockIndexLow].ulSclk; [state_entry->ucEngineClockIndexLow].ulSclk;
performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap,
state_entry->ucPCIEGenLow); state_entry->ucPCIEGenLow);
...@@ -3586,8 +3591,14 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr, ...@@ -3586,8 +3591,14 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
[polaris10_power_state->performance_level_count++]); [polaris10_power_state->performance_level_count++]);
performance_level->memory_clock = mclk_dep_table->entries performance_level->memory_clock = mclk_dep_table->entries
[state_entry->ucMemoryClockIndexHigh].ulMclk; [state_entry->ucMemoryClockIndexHigh].ulMclk;
performance_level->engine_clock = sclk_dep_table->entries
if (sclk_dep_table->ucRevId == 0)
performance_level->engine_clock = ((ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table)->entries
[state_entry->ucEngineClockIndexHigh].ulSclk; [state_entry->ucEngineClockIndexHigh].ulSclk;
else if (sclk_dep_table->ucRevId == 1)
performance_level->engine_clock = ((ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table)->entries
[state_entry->ucEngineClockIndexHigh].ulSclk;
performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap, performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap,
state_entry->ucPCIEGenHigh); state_entry->ucPCIEGenHigh);
performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap, performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap,
...@@ -3645,7 +3656,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr, ...@@ -3645,7 +3656,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr,
switch (state->classification.ui_label) { switch (state->classification.ui_label) {
case PP_StateUILabel_Performance: case PP_StateUILabel_Performance:
data->use_pcie_performance_levels = true; data->use_pcie_performance_levels = true;
for (i = 0; i < ps->performance_level_count; i++) { for (i = 0; i < ps->performance_level_count; i++) {
if (data->pcie_gen_performance.max < if (data->pcie_gen_performance.max <
ps->performance_levels[i].pcie_gen) ps->performance_levels[i].pcie_gen)
...@@ -3661,7 +3671,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr, ...@@ -3661,7 +3671,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr,
ps->performance_levels[i].pcie_lane) ps->performance_levels[i].pcie_lane)
data->pcie_lane_performance.max = data->pcie_lane_performance.max =
ps->performance_levels[i].pcie_lane; ps->performance_levels[i].pcie_lane;
if (data->pcie_lane_performance.min > if (data->pcie_lane_performance.min >
ps->performance_levels[i].pcie_lane) ps->performance_levels[i].pcie_lane)
data->pcie_lane_performance.min = data->pcie_lane_performance.min =
...@@ -4187,12 +4196,9 @@ int polaris10_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate) ...@@ -4187,12 +4196,9 @@ int polaris10_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate)
{ {
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend); struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
uint32_t mm_boot_level_offset, mm_boot_level_value; uint32_t mm_boot_level_offset, mm_boot_level_value;
struct phm_ppt_v1_information *table_info =
(struct phm_ppt_v1_information *)(hwmgr->pptable);
if (!bgate) { if (!bgate) {
data->smc_state_table.SamuBootLevel = data->smc_state_table.SamuBootLevel = 0;
(uint8_t) (table_info->mm_dep_table->count - 1);
mm_boot_level_offset = data->dpm_table_start + mm_boot_level_offset = data->dpm_table_start +
offsetof(SMU74_Discrete_DpmTable, SamuBootLevel); offsetof(SMU74_Discrete_DpmTable, SamuBootLevel);
mm_boot_level_offset /= 4; mm_boot_level_offset /= 4;
......
...@@ -197,6 +197,22 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Table { ...@@ -197,6 +197,22 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Table {
ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */
} ATOM_Tonga_SCLK_Dependency_Table; } ATOM_Tonga_SCLK_Dependency_Table;
typedef struct _ATOM_Polaris_SCLK_Dependency_Record {
UCHAR ucVddInd; /* Base voltage */
USHORT usVddcOffset; /* Offset relative to base voltage */
ULONG ulSclk;
USHORT usEdcCurrent;
UCHAR ucReliabilityTemperature;
UCHAR ucCKSVOffsetandDisable; /* Bits 0~6: Voltage offset for CKS, Bit 7: Disable/enable for the SCLK level. */
ULONG ulSclkOffset;
} ATOM_Polaris_SCLK_Dependency_Record;
typedef struct _ATOM_Polaris_SCLK_Dependency_Table {
UCHAR ucRevId;
UCHAR ucNumEntries; /* Number of entries. */
ATOM_Polaris_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */
} ATOM_Polaris_SCLK_Dependency_Table;
typedef struct _ATOM_Tonga_PCIE_Record { typedef struct _ATOM_Tonga_PCIE_Record {
UCHAR ucPCIEGenSpeed; UCHAR ucPCIEGenSpeed;
UCHAR usPCIELaneWidth; UCHAR usPCIELaneWidth;
......
...@@ -408,41 +408,78 @@ static int get_mclk_voltage_dependency_table( ...@@ -408,41 +408,78 @@ static int get_mclk_voltage_dependency_table(
static int get_sclk_voltage_dependency_table( static int get_sclk_voltage_dependency_table(
struct pp_hwmgr *hwmgr, struct pp_hwmgr *hwmgr,
phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table, phm_ppt_v1_clock_voltage_dependency_table **pp_tonga_sclk_dep_table,
const ATOM_Tonga_SCLK_Dependency_Table * sclk_dep_table const PPTable_Generic_SubTable_Header *sclk_dep_table
) )
{ {
uint32_t table_size, i; uint32_t table_size, i;
phm_ppt_v1_clock_voltage_dependency_table *sclk_table; phm_ppt_v1_clock_voltage_dependency_table *sclk_table;
PP_ASSERT_WITH_CODE((0 != sclk_dep_table->ucNumEntries), if (sclk_dep_table->ucRevId < 1) {
"Invalid PowerPlay Table!", return -1); const ATOM_Tonga_SCLK_Dependency_Table *tonga_table =
(ATOM_Tonga_SCLK_Dependency_Table *)sclk_dep_table;
table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record) PP_ASSERT_WITH_CODE((0 != tonga_table->ucNumEntries),
* sclk_dep_table->ucNumEntries; "Invalid PowerPlay Table!", return -1);
sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *) table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record)
kzalloc(table_size, GFP_KERNEL); * tonga_table->ucNumEntries;
if (NULL == sclk_table) sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *)
return -ENOMEM; kzalloc(table_size, GFP_KERNEL);
memset(sclk_table, 0x00, table_size); if (NULL == sclk_table)
return -ENOMEM;
sclk_table->count = (uint32_t)sclk_dep_table->ucNumEntries;
memset(sclk_table, 0x00, table_size);
for (i = 0; i < sclk_dep_table->ucNumEntries; i++) {
sclk_table->entries[i].vddInd = sclk_table->count = (uint32_t)tonga_table->ucNumEntries;
sclk_dep_table->entries[i].ucVddInd;
sclk_table->entries[i].vdd_offset = for (i = 0; i < tonga_table->ucNumEntries; i++) {
sclk_dep_table->entries[i].usVddcOffset; sclk_table->entries[i].vddInd =
sclk_table->entries[i].clk = tonga_table->entries[i].ucVddInd;
sclk_dep_table->entries[i].ulSclk; sclk_table->entries[i].vdd_offset =
sclk_table->entries[i].cks_enable = tonga_table->entries[i].usVddcOffset;
(((sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0; sclk_table->entries[i].clk =
sclk_table->entries[i].cks_voffset = tonga_table->entries[i].ulSclk;
(sclk_dep_table->entries[i].ucCKSVOffsetandDisable & 0x7F); sclk_table->entries[i].cks_enable =
} (((tonga_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0;
sclk_table->entries[i].cks_voffset =
(tonga_table->entries[i].ucCKSVOffsetandDisable & 0x7F);
}
} else {
const ATOM_Polaris_SCLK_Dependency_Table *polaris_table =
(ATOM_Polaris_SCLK_Dependency_Table *)sclk_dep_table;
PP_ASSERT_WITH_CODE((0 != polaris_table->ucNumEntries),
"Invalid PowerPlay Table!", return -1);
table_size = sizeof(uint32_t) + sizeof(phm_ppt_v1_clock_voltage_dependency_record)
* polaris_table->ucNumEntries;
sclk_table = (phm_ppt_v1_clock_voltage_dependency_table *)
kzalloc(table_size, GFP_KERNEL);
if (NULL == sclk_table)
return -ENOMEM;
memset(sclk_table, 0x00, table_size);
sclk_table->count = (uint32_t)polaris_table->ucNumEntries;
for (i = 0; i < polaris_table->ucNumEntries; i++) {
sclk_table->entries[i].vddInd =
polaris_table->entries[i].ucVddInd;
sclk_table->entries[i].vdd_offset =
polaris_table->entries[i].usVddcOffset;
sclk_table->entries[i].clk =
polaris_table->entries[i].ulSclk;
sclk_table->entries[i].cks_enable =
(((polaris_table->entries[i].ucCKSVOffsetandDisable & 0x80) >> 7) == 0) ? 1 : 0;
sclk_table->entries[i].cks_voffset =
(polaris_table->entries[i].ucCKSVOffsetandDisable & 0x7F);
sclk_table->entries[i].sclk_offset = polaris_table->entries[i].ulSclkOffset;
}
}
*pp_tonga_sclk_dep_table = sclk_table; *pp_tonga_sclk_dep_table = sclk_table;
return 0; return 0;
...@@ -708,8 +745,8 @@ static int init_clock_voltage_dependency( ...@@ -708,8 +745,8 @@ static int init_clock_voltage_dependency(
const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table = const ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table =
(const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) + (const ATOM_Tonga_MCLK_Dependency_Table *)(((unsigned long) powerplay_table) +
le16_to_cpu(powerplay_table->usMclkDependencyTableOffset)); le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
const ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table = const PPTable_Generic_SubTable_Header *sclk_dep_table =
(const ATOM_Tonga_SCLK_Dependency_Table *)(((unsigned long) powerplay_table) + (const PPTable_Generic_SubTable_Header *)(((unsigned long) powerplay_table) +
le16_to_cpu(powerplay_table->usSclkDependencyTableOffset)); le16_to_cpu(powerplay_table->usSclkDependencyTableOffset));
const ATOM_Tonga_Hard_Limit_Table *pHardLimits = const ATOM_Tonga_Hard_Limit_Table *pHardLimits =
(const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) + (const ATOM_Tonga_Hard_Limit_Table *)(((unsigned long) powerplay_table) +
......
...@@ -589,7 +589,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, ...@@ -589,7 +589,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev)) if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
/* use frac fb div on RS780/RS880 */ /* use frac fb div on RS780/RS880 */
if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880)) if (((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
&& !radeon_crtc->ss_enabled)
radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
if (ASIC_IS_DCE32(rdev) && mode->clock > 165000) if (ASIC_IS_DCE32(rdev) && mode->clock > 165000)
radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
...@@ -626,7 +627,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, ...@@ -626,7 +627,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
if (radeon_crtc->ss.refdiv) { if (radeon_crtc->ss.refdiv) {
radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv;
if (ASIC_IS_AVIVO(rdev)) if (rdev->family >= CHIP_RV770)
radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
} }
} }
......
...@@ -630,6 +630,23 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) ...@@ -630,6 +630,23 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
/* /*
* GPU helpers function. * GPU helpers function.
*/ */
/**
* radeon_device_is_virtual - check if we are running is a virtual environment
*
* Check if the asic has been passed through to a VM (all asics).
* Used at driver startup.
* Returns true if virtual or false if not.
*/
static bool radeon_device_is_virtual(void)
{
#ifdef CONFIG_X86
return boot_cpu_has(X86_FEATURE_HYPERVISOR);
#else
return false;
#endif
}
/** /**
* radeon_card_posted - check if the hw has already been initialized * radeon_card_posted - check if the hw has already been initialized
* *
...@@ -643,6 +660,10 @@ bool radeon_card_posted(struct radeon_device *rdev) ...@@ -643,6 +660,10 @@ bool radeon_card_posted(struct radeon_device *rdev)
{ {
uint32_t reg; uint32_t reg;
/* for pass through, always force asic_init */
if (radeon_device_is_virtual())
return false;
/* required for EFI mode on macbook2,1 which uses an r5xx asic */ /* required for EFI mode on macbook2,1 which uses an r5xx asic */
if (efi_enabled(EFI_BOOT) && if (efi_enabled(EFI_BOOT) &&
(rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) && (rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
...@@ -1631,7 +1652,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, ...@@ -1631,7 +1652,7 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend,
radeon_agp_suspend(rdev); radeon_agp_suspend(rdev);
pci_save_state(dev->pdev); pci_save_state(dev->pdev);
if (freeze && rdev->family >= CHIP_R600) { if (freeze && rdev->family >= CHIP_CEDAR) {
rdev->asic->asic_reset(rdev, true); rdev->asic->asic_reset(rdev, true);
pci_restore_state(dev->pdev); pci_restore_state(dev->pdev);
} else if (suspend) { } else if (suspend) {
......
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