Skip to content
This repository has been archived by the owner on Aug 27, 2022. It is now read-only.

Commit

Permalink
Merge branch 'drm-fixes-4.7' of git://people.freedesktop.org/~agd5f/l…
Browse files Browse the repository at this point in the history
…inux 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
  • Loading branch information
airlied committed Jun 16, 2016
2 parents d9724d3 + 871fd84 commit 0ab15bd
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 56 deletions.
11 changes: 8 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,6 @@ struct amdgpu_ring {
unsigned cond_exe_offs;
u64 cond_exe_gpu_addr;
volatile u32 *cond_exe_cpu_addr;
int vmid;
};

/*
Expand Down Expand Up @@ -937,8 +936,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
unsigned vm_id, uint64_t pd_addr,
uint32_t gds_base, uint32_t gds_size,
uint32_t gws_base, uint32_t gws_size,
uint32_t oa_base, uint32_t oa_size,
bool vmid_switch);
uint32_t oa_base, uint32_t oa_size);
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);
int amdgpu_vm_update_page_directory(struct amdgpu_device *adev,
Expand Down Expand Up @@ -1822,6 +1820,8 @@ struct amdgpu_asic_funcs {
/* MM block clocks */
int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk);
int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk);
/* query virtual capabilities */
u32 (*get_virtual_caps)(struct amdgpu_device *adev);
};

/*
Expand Down Expand Up @@ -1916,8 +1916,12 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device);


/* GPU virtualization */
#define AMDGPU_VIRT_CAPS_SRIOV_EN (1 << 0)
#define AMDGPU_VIRT_CAPS_IS_VF (1 << 1)
struct amdgpu_virtualization {
bool supports_sr_iov;
bool is_virtual;
u32 caps;
};

/*
Expand Down Expand Up @@ -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_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_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_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))
Expand Down
17 changes: 16 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,15 @@ static int amdgpu_resume(struct amdgpu_device *adev)
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
*
Expand Down Expand Up @@ -1519,8 +1528,14 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->virtualization.supports_sr_iov =
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 */
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) {
dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");
return -EINVAL;
Expand Down
9 changes: 2 additions & 7 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
bool skip_preamble, need_ctx_switch;
unsigned patch_offset = ~0;
struct amdgpu_vm *vm;
int vmid = 0, old_vmid = ring->vmid;
struct fence *hwf;
uint64_t ctx;

Expand All @@ -136,11 +135,9 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
if (job) {
vm = job->vm;
ctx = job->ctx;
vmid = job->vm_id;
} else {
vm = NULL;
ctx = 0;
vmid = 0;
}

if (!ring->ready) {
Expand All @@ -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,
job->gds_base, job->gds_size,
job->gws_base, job->gws_size,
job->oa_base, job->oa_size,
(ring->current_ctx == ctx) && (old_vmid != vmid));
job->oa_base, job->oa_size);
if (r) {
amdgpu_ring_undo(ring);
return r;
Expand All @@ -184,14 +180,14 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
need_ctx_switch = ring->current_ctx != ctx;
for (i = 0; i < num_ibs; ++i) {
ib = &ibs[i];

/* drop preamble IBs if we don't have a context switch */
if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && skip_preamble)
continue;

amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0,
need_ctx_switch);
need_ctx_switch = false;
ring->vmid = vmid;
}

if (ring->funcs->emit_hdp_invalidate)
Expand All @@ -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);
if (job && job->vm_id)
amdgpu_vm_reset_id(adev, job->vm_id);
ring->vmid = old_vmid;
amdgpu_ring_undo(ring);
return r;
}
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
unsigned vm_id, uint64_t pd_addr,
uint32_t gds_base, uint32_t gds_size,
uint32_t gws_base, uint32_t gws_size,
uint32_t oa_base, uint32_t oa_size,
bool vmid_switch)
uint32_t oa_base, uint32_t oa_size)
{
struct amdgpu_device *adev = ring->adev;
struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id];
Expand All @@ -313,7 +312,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring,
int r;

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);

if (ring->funcs->emit_vm_flush &&
Expand Down
7 changes: 7 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/cik.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,12 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev,
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[] = {
{mmGRBM_STATUS, false},
{mmGB_ADDR_CONFIG, false},
Expand Down Expand Up @@ -2007,6 +2013,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs =
.get_xclk = &cik_get_xclk,
.set_uvd_clocks = &cik_set_uvd_clocks,
.set_vce_clocks = &cik_set_vce_clocks,
.get_virtual_caps = &cik_get_virtual_caps,
/* these should be moved to their own ip modules */
.get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter,
.wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle,
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -4833,7 +4833,7 @@ static int gfx_v7_0_eop_irq(struct amdgpu_device *adev,
case 2:
for (i = 0; i < adev->gfx.num_compute_rings; 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);
}
break;
Expand Down
15 changes: 15 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/vi.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,20 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev,
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[] = {
{mmGB_MACROTILE_MODE7, true},
};
Expand Down Expand Up @@ -1118,6 +1132,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs =
.get_xclk = &vi_get_xclk,
.set_uvd_clocks = &vi_set_uvd_clocks,
.set_vce_clocks = &vi_set_vce_clocks,
.get_virtual_caps = &vi_get_virtual_caps,
/* these should be moved to their own ip modules */
.get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter,
.wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr_ppt.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct phm_ppt_v1_clock_voltage_dependency_record {
uint8_t phases;
uint8_t cks_enable;
uint8_t cks_voffset;
uint32_t sclk_offset;
};

typedef struct phm_ppt_v1_clock_voltage_dependency_record phm_ppt_v1_clock_voltage_dependency_record;
Expand Down
28 changes: 17 additions & 11 deletions drivers/gpu/drm/amd/powerplay/hwmgr/polaris10_hwmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
(dep_table->entries[i].vddc -
(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)
Expand Down Expand Up @@ -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_POWERPLAYTABLE *powerplay_table =
(ATOM_Tonga_POWERPLAYTABLE *)pp_table;
ATOM_Tonga_SCLK_Dependency_Table *sclk_dep_table =
(ATOM_Tonga_SCLK_Dependency_Table *)
PPTable_Generic_SubTable_Header *sclk_dep_table =
(PPTable_Generic_SubTable_Header *)
(((unsigned long)powerplay_table) +
le16_to_cpu(powerplay_table->usSclkDependencyTableOffset));

ATOM_Tonga_MCLK_Dependency_Table *mclk_dep_table =
(ATOM_Tonga_MCLK_Dependency_Table *)
(((unsigned long)powerplay_table) +
Expand Down Expand Up @@ -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_level->memory_clock = mclk_dep_table->entries
[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;
performance_level->pcie_gen = get_pcie_gen_support(data->pcie_gen_cap,
state_entry->ucPCIEGenLow);
Expand All @@ -3586,8 +3591,14 @@ static int polaris10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
[polaris10_power_state->performance_level_count++]);
performance_level->memory_clock = mclk_dep_table->entries
[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;
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,
state_entry->ucPCIEGenHigh);
performance_level->pcie_lane = get_pcie_lane_support(data->pcie_lane_cap,
Expand Down Expand Up @@ -3645,7 +3656,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr,
switch (state->classification.ui_label) {
case PP_StateUILabel_Performance:
data->use_pcie_performance_levels = true;

for (i = 0; i < ps->performance_level_count; i++) {
if (data->pcie_gen_performance.max <
ps->performance_levels[i].pcie_gen)
Expand All @@ -3661,7 +3671,6 @@ static int polaris10_get_pp_table_entry(struct pp_hwmgr *hwmgr,
ps->performance_levels[i].pcie_lane)
data->pcie_lane_performance.max =
ps->performance_levels[i].pcie_lane;

if (data->pcie_lane_performance.min >
ps->performance_levels[i].pcie_lane)
data->pcie_lane_performance.min =
Expand Down Expand Up @@ -4187,12 +4196,9 @@ int polaris10_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate)
{
struct polaris10_hwmgr *data = (struct polaris10_hwmgr *)(hwmgr->backend);
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) {
data->smc_state_table.SamuBootLevel =
(uint8_t) (table_info->mm_dep_table->count - 1);
data->smc_state_table.SamuBootLevel = 0;
mm_boot_level_offset = data->dpm_table_start +
offsetof(SMU74_Discrete_DpmTable, SamuBootLevel);
mm_boot_level_offset /= 4;
Expand Down
16 changes: 16 additions & 0 deletions drivers/gpu/drm/amd/powerplay/hwmgr/tonga_pptable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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 {
UCHAR ucPCIEGenSpeed;
UCHAR usPCIELaneWidth;
Expand Down
Loading

0 comments on commit 0ab15bd

Please sign in to comment.