mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
Merge branch 'drm-next-4.16' of git://people.freedesktop.org/~agd5f/linux into drm-next
First feature request for 4.16. Highlights: - RV and Vega header cleanups - TTM operation context support - 48 bit GPUVM fixes for Vega/RV - More smatch fixes - ECC support for vega10 - Resizeable BAR support - Multi-display sync support in DC - SR-IOV fixes - Various scheduler improvements - GPU reset fixes and vram lost tracking - Clean up DC/powerplay interfaces - DCN display fixes - Various DC fixes * 'drm-next-4.16' of git://people.freedesktop.org/~agd5f/linux: (291 commits) drm/radeon: Use drm_fb_helper_lastclose() and _poll_changed() drm/amdgpu: Use drm_fb_helper_lastclose() and _poll_changed() drm/amd/display: Use drm_fb_helper_poll_changed() drm/ttm: swap consecutive allocated pooled pages v4 drm/amdgpu: fix amdgpu_sync_resv v2 drm/ttm: swap consecutive allocated cached pages v3 drm/amd/amdgpu: set gtt size according to system memory size only drm/amdgpu: Get rid of dep_sync as a seperate object. drm/amdgpu: allow specifying vm_block_size for multi level PDs v2 drm/amdgpu: move validation of the VM size into the VM code drm/amdgpu: allow non pot VM size values drm/amdgpu: choose number of VM levels based on VM size drm/amdgpu: unify VM size handling of Vega10 with older generation drm/amdgpu: fix amdgpu_vm_num_entries drm/amdgpu: fix VM PD addr shift drm/amdgpu: correct vce4.0 fw config for SRIOV (V2) drm/amd/display: Don't call dm_log_to_buffer directly in dc_conn_log drm/amd/display: Add dm_logger_append_va API drm/ttm: Use a static string instead of an array of char * drm/amd/display: remove usage of legacy_cursor_update ...
This commit is contained in:
commit
9c606cd411
313 changed files with 17919 additions and 74641 deletions
|
@ -47,6 +47,8 @@
|
|||
#include <drm/amdgpu_drm.h>
|
||||
|
||||
#include <kgd_kfd_interface.h>
|
||||
#include "dm_pp_interface.h"
|
||||
#include "kgd_pp_interface.h"
|
||||
|
||||
#include "amd_shared.h"
|
||||
#include "amdgpu_mode.h"
|
||||
|
@ -59,7 +61,6 @@
|
|||
#include "amdgpu_sync.h"
|
||||
#include "amdgpu_ring.h"
|
||||
#include "amdgpu_vm.h"
|
||||
#include "amd_powerplay.h"
|
||||
#include "amdgpu_dpm.h"
|
||||
#include "amdgpu_acp.h"
|
||||
#include "amdgpu_uvd.h"
|
||||
|
@ -67,11 +68,11 @@
|
|||
#include "amdgpu_vcn.h"
|
||||
#include "amdgpu_mn.h"
|
||||
#include "amdgpu_dm.h"
|
||||
|
||||
#include "gpu_scheduler.h"
|
||||
#include "amdgpu_virt.h"
|
||||
#include "amdgpu_gart.h"
|
||||
|
||||
|
||||
/*
|
||||
* Modules parameters.
|
||||
*/
|
||||
|
@ -177,6 +178,10 @@ extern int amdgpu_cik_support;
|
|||
#define CIK_CURSOR_WIDTH 128
|
||||
#define CIK_CURSOR_HEIGHT 128
|
||||
|
||||
/* GPU RESET flags */
|
||||
#define AMDGPU_RESET_INFO_VRAM_LOST (1 << 0)
|
||||
#define AMDGPU_RESET_INFO_FULLRESET (1 << 1)
|
||||
|
||||
struct amdgpu_device;
|
||||
struct amdgpu_ib;
|
||||
struct amdgpu_cs_parser;
|
||||
|
@ -735,6 +740,7 @@ struct amdgpu_ctx {
|
|||
struct amdgpu_device *adev;
|
||||
struct amdgpu_queue_mgr queue_mgr;
|
||||
unsigned reset_counter;
|
||||
unsigned reset_counter_query;
|
||||
uint32_t vram_lost_counter;
|
||||
spinlock_t ring_lock;
|
||||
struct dma_fence **fences;
|
||||
|
@ -743,6 +749,7 @@ struct amdgpu_ctx {
|
|||
enum amd_sched_priority init_priority;
|
||||
enum amd_sched_priority override_priority;
|
||||
struct mutex lock;
|
||||
atomic_t guilty;
|
||||
};
|
||||
|
||||
struct amdgpu_ctx_mgr {
|
||||
|
@ -1114,7 +1121,6 @@ struct amdgpu_job {
|
|||
struct amdgpu_vm *vm;
|
||||
struct amdgpu_ring *ring;
|
||||
struct amdgpu_sync sync;
|
||||
struct amdgpu_sync dep_sync;
|
||||
struct amdgpu_sync sched_sync;
|
||||
struct amdgpu_ib *ibs;
|
||||
struct dma_fence *fence; /* the hw fence */
|
||||
|
@ -1405,6 +1411,7 @@ struct amdgpu_fw_vram_usage {
|
|||
};
|
||||
|
||||
int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev);
|
||||
void amdgpu_fw_reserve_vram_fini(struct amdgpu_device *adev);
|
||||
|
||||
/*
|
||||
* CGS
|
||||
|
@ -1421,6 +1428,13 @@ typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
|
|||
typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
|
||||
typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
struct amd_powerplay {
|
||||
struct cgs_device *cgs_device;
|
||||
void *pp_handle;
|
||||
const struct amd_ip_funcs *ip_funcs;
|
||||
const struct amd_pm_funcs *pp_funcs;
|
||||
};
|
||||
|
||||
#define AMDGPU_RESET_MAGIC_NUM 64
|
||||
struct amdgpu_device {
|
||||
struct device *dev;
|
||||
|
@ -1616,9 +1630,6 @@ struct amdgpu_device {
|
|||
/* link all shadow bo */
|
||||
struct list_head shadow_list;
|
||||
struct mutex shadow_list_lock;
|
||||
/* link all gtt */
|
||||
spinlock_t gtt_list_lock;
|
||||
struct list_head gtt_list;
|
||||
/* keep an lru list of rings by HW IP */
|
||||
struct list_head ring_lru_list;
|
||||
spinlock_t ring_lru_list_lock;
|
||||
|
@ -1629,7 +1640,8 @@ struct amdgpu_device {
|
|||
|
||||
/* record last mm index being written through WREG32*/
|
||||
unsigned long last_mm_index;
|
||||
bool in_sriov_reset;
|
||||
bool in_gpu_reset;
|
||||
struct mutex lock_reset;
|
||||
};
|
||||
|
||||
static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev)
|
||||
|
@ -1823,7 +1835,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
|
|||
#define amdgpu_psp_check_fw_loading_status(adev, i) (adev)->firmware.funcs->check_fw_loading_status((adev), (i))
|
||||
|
||||
/* Common functions */
|
||||
int amdgpu_gpu_reset(struct amdgpu_device *adev);
|
||||
int amdgpu_gpu_recover(struct amdgpu_device *adev, struct amdgpu_job* job);
|
||||
bool amdgpu_need_backup(struct amdgpu_device *adev);
|
||||
void amdgpu_pci_config_reset(struct amdgpu_device *adev);
|
||||
bool amdgpu_need_post(struct amdgpu_device *adev);
|
||||
|
@ -1835,6 +1847,7 @@ void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain);
|
|||
bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
|
||||
void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base);
|
||||
void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc);
|
||||
int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev);
|
||||
void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size);
|
||||
int amdgpu_ttm_init(struct amdgpu_device *adev);
|
||||
void amdgpu_ttm_fini(struct amdgpu_device *adev);
|
||||
|
|
|
@ -85,7 +85,7 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
|
|||
kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions();
|
||||
break;
|
||||
default:
|
||||
dev_info(adev->dev, "kfd not supported on this ASIC\n");
|
||||
dev_dbg(adev->dev, "kfd not supported on this ASIC\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -690,12 +690,12 @@ int amdgpu_atombios_get_clock_info(struct amdgpu_device *adev)
|
|||
le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
|
||||
/* set a reasonable default for DP */
|
||||
if (adev->clock.default_dispclk < 53900) {
|
||||
DRM_INFO("Changing default dispclk from %dMhz to 600Mhz\n",
|
||||
adev->clock.default_dispclk / 100);
|
||||
DRM_DEBUG("Changing default dispclk from %dMhz to 600Mhz\n",
|
||||
adev->clock.default_dispclk / 100);
|
||||
adev->clock.default_dispclk = 60000;
|
||||
} else if (adev->clock.default_dispclk <= 60000) {
|
||||
DRM_INFO("Changing default dispclk from %dMhz to 625Mhz\n",
|
||||
adev->clock.default_dispclk / 100);
|
||||
DRM_DEBUG("Changing default dispclk from %dMhz to 625Mhz\n",
|
||||
adev->clock.default_dispclk / 100);
|
||||
adev->clock.default_dispclk = 62500;
|
||||
}
|
||||
adev->clock.dp_extclk =
|
||||
|
|
|
@ -948,7 +948,6 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device,
|
|||
(amdgpu_crtc->v_border * 2);
|
||||
mode_info->vblank_time_us = vblank_lines * line_time_us;
|
||||
mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
|
||||
mode_info->ref_clock = adev->clock.spll.reference_freq;
|
||||
mode_info = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -958,7 +957,6 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device,
|
|||
if (mode_info != NULL) {
|
||||
mode_info->vblank_time_us = adev->pm.pm_display_cfg.min_vblank_time;
|
||||
mode_info->refresh_rate = adev->pm.pm_display_cfg.vrefresh;
|
||||
mode_info->ref_clock = adev->clock.spll.reference_freq;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -90,6 +90,12 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
|
|||
goto free_chunk;
|
||||
}
|
||||
|
||||
/* skip guilty context job */
|
||||
if (atomic_read(&p->ctx->guilty) == 1) {
|
||||
ret = -ECANCELED;
|
||||
goto free_chunk;
|
||||
}
|
||||
|
||||
mutex_lock(&p->ctx->lock);
|
||||
|
||||
/* get chunks */
|
||||
|
@ -337,7 +343,7 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
|
|||
struct amdgpu_bo *bo)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
u64 initial_bytes_moved, bytes_moved;
|
||||
struct ttm_operation_ctx ctx = { true, false };
|
||||
uint32_t domain;
|
||||
int r;
|
||||
|
||||
|
@ -367,15 +373,13 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
|
|||
|
||||
retry:
|
||||
amdgpu_ttm_placement_from_domain(bo, domain);
|
||||
initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
|
||||
bytes_moved = atomic64_read(&adev->num_bytes_moved) -
|
||||
initial_bytes_moved;
|
||||
p->bytes_moved += bytes_moved;
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
|
||||
p->bytes_moved += ctx.bytes_moved;
|
||||
if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
|
||||
bo->tbo.mem.mem_type == TTM_PL_VRAM &&
|
||||
bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT)
|
||||
p->bytes_moved_vis += bytes_moved;
|
||||
p->bytes_moved_vis += ctx.bytes_moved;
|
||||
|
||||
if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
|
||||
domain = bo->allowed_domains;
|
||||
|
@ -390,6 +394,7 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
|
|||
struct amdgpu_bo *validated)
|
||||
{
|
||||
uint32_t domain = validated->allowed_domains;
|
||||
struct ttm_operation_ctx ctx = { true, false };
|
||||
int r;
|
||||
|
||||
if (!p->evictable)
|
||||
|
@ -431,7 +436,7 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
|
|||
bo->tbo.mem.mem_type == TTM_PL_VRAM &&
|
||||
bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT;
|
||||
initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
bytes_moved = atomic64_read(&adev->num_bytes_moved) -
|
||||
initial_bytes_moved;
|
||||
p->bytes_moved += bytes_moved;
|
||||
|
@ -470,6 +475,7 @@ static int amdgpu_cs_validate(void *param, struct amdgpu_bo *bo)
|
|||
static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
|
||||
struct list_head *validated)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = { true, false };
|
||||
struct amdgpu_bo_list_entry *lobj;
|
||||
int r;
|
||||
|
||||
|
@ -487,8 +493,7 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
|
|||
lobj->user_pages) {
|
||||
amdgpu_ttm_placement_from_domain(bo,
|
||||
AMDGPU_GEM_DOMAIN_CPU);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, true,
|
||||
false);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
if (r)
|
||||
return r;
|
||||
amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm,
|
||||
|
@ -678,7 +683,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
|
|||
if (!r && p->uf_entry.robj) {
|
||||
struct amdgpu_bo *uf = p->uf_entry.robj;
|
||||
|
||||
r = amdgpu_ttm_bind(&uf->tbo, &uf->tbo.mem);
|
||||
r = amdgpu_ttm_alloc_gart(&uf->tbo);
|
||||
p->job->uf_addr += amdgpu_bo_gpu_offset(uf);
|
||||
}
|
||||
|
||||
|
@ -781,7 +786,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
|
|||
return r;
|
||||
|
||||
r = amdgpu_sync_fence(adev, &p->job->sync,
|
||||
fpriv->prt_va->last_pt_update);
|
||||
fpriv->prt_va->last_pt_update, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -795,7 +800,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
|
|||
return r;
|
||||
|
||||
f = bo_va->last_pt_update;
|
||||
r = amdgpu_sync_fence(adev, &p->job->sync, f);
|
||||
r = amdgpu_sync_fence(adev, &p->job->sync, f, false);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -818,7 +823,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
|
|||
return r;
|
||||
|
||||
f = bo_va->last_pt_update;
|
||||
r = amdgpu_sync_fence(adev, &p->job->sync, f);
|
||||
r = amdgpu_sync_fence(adev, &p->job->sync, f, false);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
@ -829,7 +834,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_sync_fence(adev, &p->job->sync, vm->last_update);
|
||||
r = amdgpu_sync_fence(adev, &p->job->sync, vm->last_update, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -865,8 +870,8 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
|
|||
struct amdgpu_bo_va_mapping *m;
|
||||
struct amdgpu_bo *aobj = NULL;
|
||||
struct amdgpu_cs_chunk *chunk;
|
||||
uint64_t offset, va_start;
|
||||
struct amdgpu_ib *ib;
|
||||
uint64_t offset;
|
||||
uint8_t *kptr;
|
||||
|
||||
chunk = &p->chunks[i];
|
||||
|
@ -876,14 +881,14 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
|
|||
if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB)
|
||||
continue;
|
||||
|
||||
r = amdgpu_cs_find_mapping(p, chunk_ib->va_start,
|
||||
&aobj, &m);
|
||||
va_start = chunk_ib->va_start & AMDGPU_VA_HOLE_MASK;
|
||||
r = amdgpu_cs_find_mapping(p, va_start, &aobj, &m);
|
||||
if (r) {
|
||||
DRM_ERROR("IB va_start is invalid\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
if ((chunk_ib->va_start + chunk_ib->ib_bytes) >
|
||||
if ((va_start + chunk_ib->ib_bytes) >
|
||||
(m->last + 1) * AMDGPU_GPU_PAGE_SIZE) {
|
||||
DRM_ERROR("IB va_start+ib_bytes is invalid\n");
|
||||
return -EINVAL;
|
||||
|
@ -896,7 +901,7 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
|
|||
}
|
||||
|
||||
offset = m->start * AMDGPU_GPU_PAGE_SIZE;
|
||||
kptr += chunk_ib->va_start - offset;
|
||||
kptr += va_start - offset;
|
||||
|
||||
memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
|
||||
amdgpu_bo_kunmap(aobj);
|
||||
|
@ -1033,8 +1038,8 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p,
|
|||
amdgpu_ctx_put(ctx);
|
||||
return r;
|
||||
} else if (fence) {
|
||||
r = amdgpu_sync_fence(p->adev, &p->job->sync,
|
||||
fence);
|
||||
r = amdgpu_sync_fence(p->adev, &p->job->sync, fence,
|
||||
true);
|
||||
dma_fence_put(fence);
|
||||
amdgpu_ctx_put(ctx);
|
||||
if (r)
|
||||
|
@ -1053,7 +1058,7 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_sync_fence(p->adev, &p->job->sync, fence);
|
||||
r = amdgpu_sync_fence(p->adev, &p->job->sync, fence, true);
|
||||
dma_fence_put(fence);
|
||||
|
||||
return r;
|
||||
|
@ -1194,11 +1199,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
|
|||
job->uf_sequence = seq;
|
||||
|
||||
amdgpu_job_free_resources(job);
|
||||
amdgpu_ring_priority_get(job->ring,
|
||||
amd_sched_get_job_priority(&job->base));
|
||||
amdgpu_ring_priority_get(job->ring, job->base.s_priority);
|
||||
|
||||
trace_amdgpu_cs_ioctl(job);
|
||||
amd_sched_entity_push_job(&job->base);
|
||||
amd_sched_entity_push_job(&job->base, entity);
|
||||
|
||||
ttm_eu_fence_buffer_objects(&p->ticket, &p->validated, p->fence);
|
||||
amdgpu_mn_unlock(p->mn);
|
||||
|
@ -1570,6 +1574,7 @@ int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
|
|||
struct amdgpu_bo_va_mapping **map)
|
||||
{
|
||||
struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
struct amdgpu_vm *vm = &fpriv->vm;
|
||||
struct amdgpu_bo_va_mapping *mapping;
|
||||
int r;
|
||||
|
@ -1590,11 +1595,10 @@ int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
|
|||
if (!((*bo)->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)) {
|
||||
(*bo)->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
|
||||
amdgpu_ttm_placement_from_domain(*bo, (*bo)->allowed_domains);
|
||||
r = ttm_bo_validate(&(*bo)->tbo, &(*bo)->placement, false,
|
||||
false);
|
||||
r = ttm_bo_validate(&(*bo)->tbo, &(*bo)->placement, &ctx);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
return amdgpu_ttm_bind(&(*bo)->tbo, &(*bo)->tbo.mem);
|
||||
return amdgpu_ttm_alloc_gart(&(*bo)->tbo);
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
|
|||
}
|
||||
|
||||
ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
|
||||
ctx->reset_counter_query = ctx->reset_counter;
|
||||
ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
|
||||
ctx->init_priority = priority;
|
||||
ctx->override_priority = AMD_SCHED_PRIORITY_UNSET;
|
||||
|
@ -90,7 +91,7 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
|
|||
continue;
|
||||
|
||||
r = amd_sched_entity_init(&ring->sched, &ctx->rings[i].entity,
|
||||
rq, amdgpu_sched_jobs);
|
||||
rq, amdgpu_sched_jobs, &ctx->guilty);
|
||||
if (r)
|
||||
goto failed;
|
||||
}
|
||||
|
@ -216,11 +217,45 @@ static int amdgpu_ctx_query(struct amdgpu_device *adev,
|
|||
/* determine if a GPU reset has occured since the last call */
|
||||
reset_counter = atomic_read(&adev->gpu_reset_counter);
|
||||
/* TODO: this should ideally return NO, GUILTY, or INNOCENT. */
|
||||
if (ctx->reset_counter == reset_counter)
|
||||
if (ctx->reset_counter_query == reset_counter)
|
||||
out->state.reset_status = AMDGPU_CTX_NO_RESET;
|
||||
else
|
||||
out->state.reset_status = AMDGPU_CTX_UNKNOWN_RESET;
|
||||
ctx->reset_counter = reset_counter;
|
||||
ctx->reset_counter_query = reset_counter;
|
||||
|
||||
mutex_unlock(&mgr->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_ctx_query2(struct amdgpu_device *adev,
|
||||
struct amdgpu_fpriv *fpriv, uint32_t id,
|
||||
union drm_amdgpu_ctx_out *out)
|
||||
{
|
||||
struct amdgpu_ctx *ctx;
|
||||
struct amdgpu_ctx_mgr *mgr;
|
||||
|
||||
if (!fpriv)
|
||||
return -EINVAL;
|
||||
|
||||
mgr = &fpriv->ctx_mgr;
|
||||
mutex_lock(&mgr->lock);
|
||||
ctx = idr_find(&mgr->ctx_handles, id);
|
||||
if (!ctx) {
|
||||
mutex_unlock(&mgr->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
out->state.flags = 0x0;
|
||||
out->state.hangs = 0x0;
|
||||
|
||||
if (ctx->reset_counter != atomic_read(&adev->gpu_reset_counter))
|
||||
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RESET;
|
||||
|
||||
if (ctx->vram_lost_counter != atomic_read(&adev->vram_lost_counter))
|
||||
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_VRAMLOST;
|
||||
|
||||
if (atomic_read(&ctx->guilty))
|
||||
out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY;
|
||||
|
||||
mutex_unlock(&mgr->lock);
|
||||
return 0;
|
||||
|
@ -257,6 +292,9 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
|
|||
case AMDGPU_CTX_OP_QUERY_STATE:
|
||||
r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
|
||||
break;
|
||||
case AMDGPU_CTX_OP_QUERY_STATE2:
|
||||
r = amdgpu_ctx_query2(adev, fpriv, id, &args->out);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -410,6 +410,9 @@ static int amdgpu_doorbell_init(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (pci_resource_flags(adev->pdev, 2) & IORESOURCE_UNSET)
|
||||
return -EINVAL;
|
||||
|
||||
/* doorbell bar mapping */
|
||||
adev->doorbell.base = pci_resource_start(adev->pdev, 2);
|
||||
adev->doorbell.size = pci_resource_len(adev->pdev, 2);
|
||||
|
@ -575,41 +578,13 @@ void amdgpu_wb_free(struct amdgpu_device *adev, u32 wb)
|
|||
* @base: base address at which to put VRAM
|
||||
*
|
||||
* Function will try to place VRAM at base address provided
|
||||
* as parameter (which is so far either PCI aperture address or
|
||||
* for IGP TOM base address).
|
||||
*
|
||||
* If there is not enough space to fit the unvisible VRAM in the 32bits
|
||||
* address space then we limit the VRAM size to the aperture.
|
||||
*
|
||||
* Note: We don't explicitly enforce VRAM start to be aligned on VRAM size,
|
||||
* this shouldn't be a problem as we are using the PCI aperture as a reference.
|
||||
* Otherwise this would be needed for rv280, all r3xx, and all r4xx, but
|
||||
* not IGP.
|
||||
*
|
||||
* Note: we use mc_vram_size as on some board we need to program the mc to
|
||||
* cover the whole aperture even if VRAM size is inferior to aperture size
|
||||
* Novell bug 204882 + along with lots of ubuntu ones
|
||||
*
|
||||
* Note: when limiting vram it's safe to overwritte real_vram_size because
|
||||
* we are not in case where real_vram_size is inferior to mc_vram_size (ie
|
||||
* note afected by bogus hw of Novell bug 204882 + along with lots of ubuntu
|
||||
* ones)
|
||||
*
|
||||
* Note: IGP TOM addr should be the same as the aperture addr, we don't
|
||||
* explicitly check for that though.
|
||||
*
|
||||
* FIXME: when reducing VRAM size align new size on power of 2.
|
||||
* as parameter.
|
||||
*/
|
||||
void amdgpu_vram_location(struct amdgpu_device *adev, struct amdgpu_mc *mc, u64 base)
|
||||
{
|
||||
uint64_t limit = (uint64_t)amdgpu_vram_limit << 20;
|
||||
|
||||
mc->vram_start = base;
|
||||
if (mc->mc_vram_size > (adev->mc.mc_mask - base + 1)) {
|
||||
dev_warn(adev->dev, "limiting VRAM to PCI aperture size\n");
|
||||
mc->real_vram_size = mc->aper_size;
|
||||
mc->mc_vram_size = mc->aper_size;
|
||||
}
|
||||
mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
|
||||
if (limit && limit < mc->real_vram_size)
|
||||
mc->real_vram_size = limit;
|
||||
|
@ -647,7 +622,10 @@ void amdgpu_gart_location(struct amdgpu_device *adev, struct amdgpu_mc *mc)
|
|||
dev_warn(adev->dev, "limiting GTT\n");
|
||||
mc->gart_size = size_af;
|
||||
}
|
||||
mc->gart_start = mc->vram_end + 1;
|
||||
/* VCE doesn't like it when BOs cross a 4GB segment, so align
|
||||
* the GART base on a 4GB boundary as well.
|
||||
*/
|
||||
mc->gart_start = ALIGN(mc->vram_end + 1, 0x100000000ULL);
|
||||
}
|
||||
mc->gart_end = mc->gart_start + mc->gart_size - 1;
|
||||
dev_info(adev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n",
|
||||
|
@ -679,9 +657,13 @@ void amdgpu_fw_reserve_vram_fini(struct amdgpu_device *adev)
|
|||
*/
|
||||
int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
int r = 0;
|
||||
u64 gpu_addr;
|
||||
int i;
|
||||
u64 vram_size = adev->mc.visible_vram_size;
|
||||
u64 offset = adev->fw_vram_usage.start_offset;
|
||||
u64 size = adev->fw_vram_usage.size;
|
||||
struct amdgpu_bo *bo;
|
||||
|
||||
adev->fw_vram_usage.va = NULL;
|
||||
adev->fw_vram_usage.reserved_bo = NULL;
|
||||
|
@ -690,7 +672,7 @@ int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev)
|
|||
adev->fw_vram_usage.size <= vram_size) {
|
||||
|
||||
r = amdgpu_bo_create(adev, adev->fw_vram_usage.size,
|
||||
PAGE_SIZE, true, 0,
|
||||
PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM,
|
||||
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
|
||||
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, 0,
|
||||
&adev->fw_vram_usage.reserved_bo);
|
||||
|
@ -700,11 +682,28 @@ int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev)
|
|||
r = amdgpu_bo_reserve(adev->fw_vram_usage.reserved_bo, false);
|
||||
if (r)
|
||||
goto error_reserve;
|
||||
|
||||
/* remove the original mem node and create a new one at the
|
||||
* request position
|
||||
*/
|
||||
bo = adev->fw_vram_usage.reserved_bo;
|
||||
offset = ALIGN(offset, PAGE_SIZE);
|
||||
for (i = 0; i < bo->placement.num_placement; ++i) {
|
||||
bo->placements[i].fpfn = offset >> PAGE_SHIFT;
|
||||
bo->placements[i].lpfn = (offset + size) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
ttm_bo_mem_put(&bo->tbo, &bo->tbo.mem);
|
||||
r = ttm_bo_mem_space(&bo->tbo, &bo->placement,
|
||||
&bo->tbo.mem, &ctx);
|
||||
if (r)
|
||||
goto error_pin;
|
||||
|
||||
r = amdgpu_bo_pin_restricted(adev->fw_vram_usage.reserved_bo,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
adev->fw_vram_usage.start_offset,
|
||||
(adev->fw_vram_usage.start_offset +
|
||||
adev->fw_vram_usage.size), &gpu_addr);
|
||||
adev->fw_vram_usage.size), NULL);
|
||||
if (r)
|
||||
goto error_pin;
|
||||
r = amdgpu_bo_kmap(adev->fw_vram_usage.reserved_bo,
|
||||
|
@ -728,6 +727,75 @@ int amdgpu_fw_reserve_vram_init(struct amdgpu_device *adev)
|
|||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_resize_fb_bar - try to resize FB BAR
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Try to resize FB BAR to make all VRAM CPU accessible. We try very hard not
|
||||
* to fail, but if any of the BARs is not accessible after the size we abort
|
||||
* driver loading by returning -ENODEV.
|
||||
*/
|
||||
int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev)
|
||||
{
|
||||
u64 space_needed = roundup_pow_of_two(adev->mc.real_vram_size);
|
||||
u32 rbar_size = order_base_2(((space_needed >> 20) | 1)) - 1;
|
||||
struct pci_bus *root;
|
||||
struct resource *res;
|
||||
unsigned i;
|
||||
u16 cmd;
|
||||
int r;
|
||||
|
||||
/* Bypass for VF */
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
/* Check if the root BUS has 64bit memory resources */
|
||||
root = adev->pdev->bus;
|
||||
while (root->parent)
|
||||
root = root->parent;
|
||||
|
||||
pci_bus_for_each_resource(root, res, i) {
|
||||
if (res && res->flags & IORESOURCE_MEM_64 &&
|
||||
res->start > 0x100000000ull)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Trying to resize is pointless without a root hub window above 4GB */
|
||||
if (!res)
|
||||
return 0;
|
||||
|
||||
/* Disable memory decoding while we change the BAR addresses and size */
|
||||
pci_read_config_word(adev->pdev, PCI_COMMAND, &cmd);
|
||||
pci_write_config_word(adev->pdev, PCI_COMMAND,
|
||||
cmd & ~PCI_COMMAND_MEMORY);
|
||||
|
||||
/* Free the VRAM and doorbell BAR, we most likely need to move both. */
|
||||
amdgpu_doorbell_fini(adev);
|
||||
if (adev->asic_type >= CHIP_BONAIRE)
|
||||
pci_release_resource(adev->pdev, 2);
|
||||
|
||||
pci_release_resource(adev->pdev, 0);
|
||||
|
||||
r = pci_resize_resource(adev->pdev, 0, rbar_size);
|
||||
if (r == -ENOSPC)
|
||||
DRM_INFO("Not enough PCI address space for a large BAR.");
|
||||
else if (r && r != -ENOTSUPP)
|
||||
DRM_ERROR("Problem resizing BAR0 (%d).", r);
|
||||
|
||||
pci_assign_unassigned_bus_resources(adev->pdev->bus);
|
||||
|
||||
/* When the doorbell or fb BAR isn't available we have no chance of
|
||||
* using the device.
|
||||
*/
|
||||
r = amdgpu_doorbell_init(adev);
|
||||
if (r || (pci_resource_flags(adev->pdev, 0) & IORESOURCE_UNSET))
|
||||
return -ENODEV;
|
||||
|
||||
pci_write_config_word(adev->pdev, PCI_COMMAND, cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* GPU helpers function.
|
||||
|
@ -1029,7 +1097,7 @@ static int amdgpu_atombios_init(struct amdgpu_device *adev)
|
|||
atom_card_info->ioreg_read = cail_ioreg_read;
|
||||
atom_card_info->ioreg_write = cail_ioreg_write;
|
||||
} else {
|
||||
DRM_INFO("PCI I/O BAR is not found. Using MMIO to access ATOM BIOS\n");
|
||||
DRM_DEBUG("PCI I/O BAR is not found. Using MMIO to access ATOM BIOS\n");
|
||||
atom_card_info->ioreg_read = cail_reg_read;
|
||||
atom_card_info->ioreg_write = cail_reg_write;
|
||||
}
|
||||
|
@ -1094,20 +1162,8 @@ static void amdgpu_check_block_size(struct amdgpu_device *adev)
|
|||
if (amdgpu_vm_block_size < 9) {
|
||||
dev_warn(adev->dev, "VM page table size (%d) too small\n",
|
||||
amdgpu_vm_block_size);
|
||||
goto def_value;
|
||||
amdgpu_vm_block_size = -1;
|
||||
}
|
||||
|
||||
if (amdgpu_vm_block_size > 24 ||
|
||||
(amdgpu_vm_size * 1024) < (1ull << amdgpu_vm_block_size)) {
|
||||
dev_warn(adev->dev, "VM page table size (%d) too large\n",
|
||||
amdgpu_vm_block_size);
|
||||
goto def_value;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
def_value:
|
||||
amdgpu_vm_block_size = -1;
|
||||
}
|
||||
|
||||
static void amdgpu_check_vm_size(struct amdgpu_device *adev)
|
||||
|
@ -1116,31 +1172,11 @@ static void amdgpu_check_vm_size(struct amdgpu_device *adev)
|
|||
if (amdgpu_vm_size == -1)
|
||||
return;
|
||||
|
||||
if (!is_power_of_2(amdgpu_vm_size)) {
|
||||
dev_warn(adev->dev, "VM size (%d) must be a power of 2\n",
|
||||
amdgpu_vm_size);
|
||||
goto def_value;
|
||||
}
|
||||
|
||||
if (amdgpu_vm_size < 1) {
|
||||
dev_warn(adev->dev, "VM size (%d) too small, min is 1GB\n",
|
||||
amdgpu_vm_size);
|
||||
goto def_value;
|
||||
amdgpu_vm_size = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Max GPUVM size for Cayman, SI, CI VI are 40 bits.
|
||||
*/
|
||||
if (amdgpu_vm_size > 1024) {
|
||||
dev_warn(adev->dev, "VM size (%d) too large, max is 1TB\n",
|
||||
amdgpu_vm_size);
|
||||
goto def_value;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
def_value:
|
||||
amdgpu_vm_size = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1622,10 +1658,12 @@ static int amdgpu_early_init(struct amdgpu_device *adev)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_amdkfd_device_probe(adev);
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
r = amdgpu_virt_request_full_gpu(adev, true);
|
||||
if (r)
|
||||
return r;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
|
@ -1716,6 +1754,11 @@ static int amdgpu_init(struct amdgpu_device *adev)
|
|||
adev->ip_blocks[i].status.hw = true;
|
||||
}
|
||||
|
||||
amdgpu_amdkfd_device_init(adev);
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_virt_release_full_gpu(adev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1783,6 +1826,7 @@ static int amdgpu_fini(struct amdgpu_device *adev)
|
|||
{
|
||||
int i, r;
|
||||
|
||||
amdgpu_amdkfd_device_fini(adev);
|
||||
/* need to disable SMC first */
|
||||
for (i = 0; i < adev->num_ip_blocks; i++) {
|
||||
if (!adev->ip_blocks[i].status.hw)
|
||||
|
@ -1811,6 +1855,7 @@ static int amdgpu_fini(struct amdgpu_device *adev)
|
|||
if (!adev->ip_blocks[i].status.hw)
|
||||
continue;
|
||||
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
|
||||
amdgpu_free_static_csa(adev);
|
||||
amdgpu_wb_fini(adev);
|
||||
amdgpu_vram_scratch_fini(adev);
|
||||
}
|
||||
|
@ -1859,7 +1904,8 @@ static int amdgpu_fini(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_virt_release_full_gpu(adev, false);
|
||||
if (amdgpu_virt_release_full_gpu(adev, false))
|
||||
DRM_ERROR("failed to release exclusive mode on fini\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2163,6 +2209,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
mutex_init(&adev->mn_lock);
|
||||
mutex_init(&adev->virt.vf_errors.lock);
|
||||
hash_init(adev->mn_hash);
|
||||
mutex_init(&adev->lock_reset);
|
||||
|
||||
amdgpu_check_arguments(adev);
|
||||
|
||||
|
@ -2179,9 +2226,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
INIT_LIST_HEAD(&adev->shadow_list);
|
||||
mutex_init(&adev->shadow_list_lock);
|
||||
|
||||
INIT_LIST_HEAD(&adev->gtt_list);
|
||||
spin_lock_init(&adev->gtt_list_lock);
|
||||
|
||||
INIT_LIST_HEAD(&adev->ring_lru_list);
|
||||
spin_lock_init(&adev->ring_lru_list_lock);
|
||||
|
||||
|
@ -2267,8 +2311,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
dev_err(adev->dev, "gpu post error!\n");
|
||||
goto failed;
|
||||
}
|
||||
} else {
|
||||
DRM_INFO("GPU post is not needed\n");
|
||||
}
|
||||
|
||||
if (adev->is_atom_fw) {
|
||||
|
@ -2305,6 +2347,18 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
|
||||
r = amdgpu_init(adev);
|
||||
if (r) {
|
||||
/* failed in exclusive mode due to timeout */
|
||||
if (amdgpu_sriov_vf(adev) &&
|
||||
!amdgpu_sriov_runtime(adev) &&
|
||||
amdgpu_virt_mmio_blocked(adev) &&
|
||||
!amdgpu_virt_wait_reset(adev)) {
|
||||
dev_err(adev->dev, "VF exclusive mode timeout\n");
|
||||
/* Don't send request since VF is inactive. */
|
||||
adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME;
|
||||
adev->virt.ops = NULL;
|
||||
r = -EAGAIN;
|
||||
goto failed;
|
||||
}
|
||||
dev_err(adev->dev, "amdgpu_init failed\n");
|
||||
amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0);
|
||||
amdgpu_fini(adev);
|
||||
|
@ -2392,6 +2446,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
amdgpu_vf_error_trans_all(adev);
|
||||
if (runtime)
|
||||
vga_switcheroo_fini_domain_pm_ops(adev->dev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -2414,7 +2469,6 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
|
|||
/* evict vram memory */
|
||||
amdgpu_bo_evict_vram(adev);
|
||||
amdgpu_ib_pool_fini(adev);
|
||||
amdgpu_fw_reserve_vram_fini(adev);
|
||||
amdgpu_fence_driver_fini(adev);
|
||||
amdgpu_fbdev_fini(adev);
|
||||
r = amdgpu_fini(adev);
|
||||
|
@ -2819,181 +2873,19 @@ static int amdgpu_recover_vram_from_shadow(struct amdgpu_device *adev,
|
|||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_sriov_gpu_reset - reset the asic
|
||||
/*
|
||||
* amdgpu_reset - reset ASIC/GPU for bare-metal or passthrough
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @job: which job trigger hang
|
||||
* @reset_flags: output param tells caller the reset result
|
||||
*
|
||||
* Attempt the reset the GPU if it has hung (all asics).
|
||||
* for SRIOV case.
|
||||
* Returns 0 for success or an error on failure.
|
||||
*/
|
||||
int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job)
|
||||
* attempt to do soft-reset or full-reset and reinitialize Asic
|
||||
* return 0 means successed otherwise failed
|
||||
*/
|
||||
static int amdgpu_reset(struct amdgpu_device *adev, uint64_t* reset_flags)
|
||||
{
|
||||
int i, j, r = 0;
|
||||
int resched;
|
||||
struct amdgpu_bo *bo, *tmp;
|
||||
struct amdgpu_ring *ring;
|
||||
struct dma_fence *fence = NULL, *next = NULL;
|
||||
|
||||
mutex_lock(&adev->virt.lock_reset);
|
||||
atomic_inc(&adev->gpu_reset_counter);
|
||||
adev->in_sriov_reset = true;
|
||||
|
||||
/* block TTM */
|
||||
resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
|
||||
|
||||
/* we start from the ring trigger GPU hang */
|
||||
j = job ? job->ring->idx : 0;
|
||||
|
||||
/* block scheduler */
|
||||
for (i = j; i < j + AMDGPU_MAX_RINGS; ++i) {
|
||||
ring = adev->rings[i % AMDGPU_MAX_RINGS];
|
||||
if (!ring || !ring->sched.thread)
|
||||
continue;
|
||||
|
||||
kthread_park(ring->sched.thread);
|
||||
|
||||
if (job && j != i)
|
||||
continue;
|
||||
|
||||
/* here give the last chance to check if job removed from mirror-list
|
||||
* since we already pay some time on kthread_park */
|
||||
if (job && list_empty(&job->base.node)) {
|
||||
kthread_unpark(ring->sched.thread);
|
||||
goto give_up_reset;
|
||||
}
|
||||
|
||||
if (amd_sched_invalidate_job(&job->base, amdgpu_job_hang_limit))
|
||||
amd_sched_job_kickout(&job->base);
|
||||
|
||||
/* only do job_reset on the hang ring if @job not NULL */
|
||||
amd_sched_hw_job_reset(&ring->sched);
|
||||
|
||||
/* after all hw jobs are reset, hw fence is meaningless, so force_completion */
|
||||
amdgpu_fence_driver_force_completion_ring(ring);
|
||||
}
|
||||
|
||||
/* request to take full control of GPU before re-initialization */
|
||||
if (job)
|
||||
amdgpu_virt_reset_gpu(adev);
|
||||
else
|
||||
amdgpu_virt_request_full_gpu(adev, true);
|
||||
|
||||
|
||||
/* Resume IP prior to SMC */
|
||||
amdgpu_sriov_reinit_early(adev);
|
||||
|
||||
/* we need recover gart prior to run SMC/CP/SDMA resume */
|
||||
amdgpu_ttm_recover_gart(adev);
|
||||
|
||||
/* now we are okay to resume SMC/CP/SDMA */
|
||||
amdgpu_sriov_reinit_late(adev);
|
||||
|
||||
amdgpu_irq_gpu_reset_resume_helper(adev);
|
||||
|
||||
if (amdgpu_ib_ring_tests(adev))
|
||||
dev_err(adev->dev, "[GPU_RESET] ib ring test failed (%d).\n", r);
|
||||
|
||||
/* release full control of GPU after ib test */
|
||||
amdgpu_virt_release_full_gpu(adev, true);
|
||||
|
||||
DRM_INFO("recover vram bo from shadow\n");
|
||||
|
||||
ring = adev->mman.buffer_funcs_ring;
|
||||
mutex_lock(&adev->shadow_list_lock);
|
||||
list_for_each_entry_safe(bo, tmp, &adev->shadow_list, shadow_list) {
|
||||
next = NULL;
|
||||
amdgpu_recover_vram_from_shadow(adev, ring, bo, &next);
|
||||
if (fence) {
|
||||
r = dma_fence_wait(fence, false);
|
||||
if (r) {
|
||||
WARN(r, "recovery from shadow isn't completed\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dma_fence_put(fence);
|
||||
fence = next;
|
||||
}
|
||||
mutex_unlock(&adev->shadow_list_lock);
|
||||
|
||||
if (fence) {
|
||||
r = dma_fence_wait(fence, false);
|
||||
if (r)
|
||||
WARN(r, "recovery from shadow isn't completed\n");
|
||||
}
|
||||
dma_fence_put(fence);
|
||||
|
||||
for (i = j; i < j + AMDGPU_MAX_RINGS; ++i) {
|
||||
ring = adev->rings[i % AMDGPU_MAX_RINGS];
|
||||
if (!ring || !ring->sched.thread)
|
||||
continue;
|
||||
|
||||
if (job && j != i) {
|
||||
kthread_unpark(ring->sched.thread);
|
||||
continue;
|
||||
}
|
||||
|
||||
amd_sched_job_recovery(&ring->sched);
|
||||
kthread_unpark(ring->sched.thread);
|
||||
}
|
||||
|
||||
drm_helper_resume_force_mode(adev->ddev);
|
||||
give_up_reset:
|
||||
ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
|
||||
if (r) {
|
||||
/* bad news, how to tell it to userspace ? */
|
||||
dev_info(adev->dev, "GPU reset failed\n");
|
||||
} else {
|
||||
dev_info(adev->dev, "GPU reset successed!\n");
|
||||
}
|
||||
|
||||
adev->in_sriov_reset = false;
|
||||
mutex_unlock(&adev->virt.lock_reset);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gpu_reset - reset the asic
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
*
|
||||
* Attempt the reset the GPU if it has hung (all asics).
|
||||
* Returns 0 for success or an error on failure.
|
||||
*/
|
||||
int amdgpu_gpu_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
struct drm_atomic_state *state = NULL;
|
||||
int i, r;
|
||||
int resched;
|
||||
bool need_full_reset, vram_lost = false;
|
||||
|
||||
if (!amdgpu_check_soft_reset(adev)) {
|
||||
DRM_INFO("No hardware hang detected. Did some blocks stall?\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
atomic_inc(&adev->gpu_reset_counter);
|
||||
|
||||
/* block TTM */
|
||||
resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
|
||||
/* store modesetting */
|
||||
if (amdgpu_device_has_dc_support(adev))
|
||||
state = drm_atomic_helper_suspend(adev->ddev);
|
||||
|
||||
/* block scheduler */
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !ring->sched.thread)
|
||||
continue;
|
||||
kthread_park(ring->sched.thread);
|
||||
amd_sched_hw_job_reset(&ring->sched);
|
||||
}
|
||||
/* after all hw jobs are reset, hw fence is meaningless, so force_completion */
|
||||
amdgpu_fence_driver_force_completion(adev);
|
||||
bool need_full_reset, vram_lost = 0;
|
||||
int r;
|
||||
|
||||
need_full_reset = amdgpu_need_full_reset(adev);
|
||||
|
||||
|
@ -3005,6 +2897,7 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
|
|||
DRM_INFO("soft reset failed, will fallback to full reset!\n");
|
||||
need_full_reset = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (need_full_reset) {
|
||||
|
@ -3022,21 +2915,27 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
|
|||
r = amdgpu_resume_phase1(adev);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
vram_lost = amdgpu_check_vram_lost(adev);
|
||||
if (vram_lost) {
|
||||
DRM_ERROR("VRAM is lost!\n");
|
||||
atomic_inc(&adev->vram_lost_counter);
|
||||
}
|
||||
r = amdgpu_ttm_recover_gart(adev);
|
||||
|
||||
r = amdgpu_gtt_mgr_recover(
|
||||
&adev->mman.bdev.man[TTM_PL_TT]);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
r = amdgpu_resume_phase2(adev);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
if (vram_lost)
|
||||
amdgpu_fill_reset_magic(adev);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (!r) {
|
||||
amdgpu_irq_gpu_reset_resume_helper(adev);
|
||||
|
@ -3047,11 +2946,132 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
|
|||
need_full_reset = true;
|
||||
goto retry;
|
||||
}
|
||||
/**
|
||||
* recovery vm page tables, since we cannot depend on VRAM is
|
||||
* consistent after gpu full reset.
|
||||
*/
|
||||
if (need_full_reset && amdgpu_need_backup(adev)) {
|
||||
}
|
||||
|
||||
if (reset_flags) {
|
||||
if (vram_lost)
|
||||
(*reset_flags) |= AMDGPU_RESET_INFO_VRAM_LOST;
|
||||
|
||||
if (need_full_reset)
|
||||
(*reset_flags) |= AMDGPU_RESET_INFO_FULLRESET;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* amdgpu_reset_sriov - reset ASIC for SR-IOV vf
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @reset_flags: output param tells caller the reset result
|
||||
*
|
||||
* do VF FLR and reinitialize Asic
|
||||
* return 0 means successed otherwise failed
|
||||
*/
|
||||
static int amdgpu_reset_sriov(struct amdgpu_device *adev, uint64_t *reset_flags, bool from_hypervisor)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (from_hypervisor)
|
||||
r = amdgpu_virt_request_full_gpu(adev, true);
|
||||
else
|
||||
r = amdgpu_virt_reset_gpu(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Resume IP prior to SMC */
|
||||
r = amdgpu_sriov_reinit_early(adev);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
/* we need recover gart prior to run SMC/CP/SDMA resume */
|
||||
amdgpu_gtt_mgr_recover(&adev->mman.bdev.man[TTM_PL_TT]);
|
||||
|
||||
/* now we are okay to resume SMC/CP/SDMA */
|
||||
r = amdgpu_sriov_reinit_late(adev);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
amdgpu_irq_gpu_reset_resume_helper(adev);
|
||||
r = amdgpu_ib_ring_tests(adev);
|
||||
if (r)
|
||||
dev_err(adev->dev, "[GPU_RESET] ib ring test failed (%d).\n", r);
|
||||
|
||||
error:
|
||||
/* release full control of GPU after ib test */
|
||||
amdgpu_virt_release_full_gpu(adev, true);
|
||||
|
||||
if (reset_flags) {
|
||||
if (adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
|
||||
(*reset_flags) |= AMDGPU_RESET_INFO_VRAM_LOST;
|
||||
atomic_inc(&adev->vram_lost_counter);
|
||||
}
|
||||
|
||||
/* VF FLR or hotlink reset is always full-reset */
|
||||
(*reset_flags) |= AMDGPU_RESET_INFO_FULLRESET;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gpu_recover - reset the asic and recover scheduler
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @job: which job trigger hang
|
||||
*
|
||||
* Attempt to reset the GPU if it has hung (all asics).
|
||||
* Returns 0 for success or an error on failure.
|
||||
*/
|
||||
int amdgpu_gpu_recover(struct amdgpu_device *adev, struct amdgpu_job *job)
|
||||
{
|
||||
struct drm_atomic_state *state = NULL;
|
||||
uint64_t reset_flags = 0;
|
||||
int i, r, resched;
|
||||
|
||||
if (!amdgpu_check_soft_reset(adev)) {
|
||||
DRM_INFO("No hardware hang detected. Did some blocks stall?\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_info(adev->dev, "GPU reset begin!\n");
|
||||
|
||||
mutex_lock(&adev->lock_reset);
|
||||
atomic_inc(&adev->gpu_reset_counter);
|
||||
adev->in_gpu_reset = 1;
|
||||
|
||||
/* block TTM */
|
||||
resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
|
||||
/* store modesetting */
|
||||
if (amdgpu_device_has_dc_support(adev))
|
||||
state = drm_atomic_helper_suspend(adev->ddev);
|
||||
|
||||
/* block scheduler */
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !ring->sched.thread)
|
||||
continue;
|
||||
|
||||
/* only focus on the ring hit timeout if &job not NULL */
|
||||
if (job && job->ring->idx != i)
|
||||
continue;
|
||||
|
||||
kthread_park(ring->sched.thread);
|
||||
amd_sched_hw_job_reset(&ring->sched, &job->base);
|
||||
|
||||
/* after all hw jobs are reset, hw fence is meaningless, so force_completion */
|
||||
amdgpu_fence_driver_force_completion(ring);
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
r = amdgpu_reset_sriov(adev, &reset_flags, job ? false : true);
|
||||
else
|
||||
r = amdgpu_reset(adev, &reset_flags);
|
||||
|
||||
if (!r) {
|
||||
if (((reset_flags & AMDGPU_RESET_INFO_FULLRESET) && !(adev->flags & AMD_IS_APU)) ||
|
||||
(reset_flags & AMDGPU_RESET_INFO_VRAM_LOST)) {
|
||||
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
|
||||
struct amdgpu_bo *bo, *tmp;
|
||||
struct dma_fence *fence = NULL, *next = NULL;
|
||||
|
@ -3080,40 +3100,56 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev)
|
|||
}
|
||||
dma_fence_put(fence);
|
||||
}
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !ring->sched.thread)
|
||||
continue;
|
||||
|
||||
/* only focus on the ring hit timeout if &job not NULL */
|
||||
if (job && job->ring->idx != i)
|
||||
continue;
|
||||
|
||||
amd_sched_job_recovery(&ring->sched);
|
||||
kthread_unpark(ring->sched.thread);
|
||||
}
|
||||
} else {
|
||||
dev_err(adev->dev, "asic resume failed (%d).\n", r);
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
|
||||
if (adev->rings[i] && adev->rings[i]->sched.thread) {
|
||||
kthread_unpark(adev->rings[i]->sched.thread);
|
||||
}
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
||||
if (!ring || !ring->sched.thread)
|
||||
continue;
|
||||
|
||||
/* only focus on the ring hit timeout if &job not NULL */
|
||||
if (job && job->ring->idx != i)
|
||||
continue;
|
||||
|
||||
kthread_unpark(adev->rings[i]->sched.thread);
|
||||
}
|
||||
}
|
||||
|
||||
if (amdgpu_device_has_dc_support(adev)) {
|
||||
r = drm_atomic_helper_resume(adev->ddev, state);
|
||||
if (drm_atomic_helper_resume(adev->ddev, state))
|
||||
dev_info(adev->dev, "drm resume failed:%d\n", r);
|
||||
amdgpu_dm_display_resume(adev);
|
||||
} else
|
||||
} else {
|
||||
drm_helper_resume_force_mode(adev->ddev);
|
||||
}
|
||||
|
||||
ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched);
|
||||
|
||||
if (r) {
|
||||
/* bad news, how to tell it to userspace ? */
|
||||
dev_info(adev->dev, "GPU reset failed\n");
|
||||
}
|
||||
else {
|
||||
dev_info(adev->dev, "GPU reset successed!\n");
|
||||
dev_info(adev->dev, "GPU reset(%d) failed\n", atomic_read(&adev->gpu_reset_counter));
|
||||
amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r);
|
||||
} else {
|
||||
dev_info(adev->dev, "GPU reset(%d) successed!\n",atomic_read(&adev->gpu_reset_counter));
|
||||
}
|
||||
|
||||
amdgpu_vf_error_trans_all(adev);
|
||||
adev->in_gpu_reset = 0;
|
||||
mutex_unlock(&adev->lock_reset);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <linux/pm_runtime.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
|
||||
static void amdgpu_flip_callback(struct dma_fence *f, struct dma_fence_cb *cb)
|
||||
{
|
||||
|
@ -556,15 +557,9 @@ amdgpu_user_framebuffer_create(struct drm_device *dev,
|
|||
return &amdgpu_fb->base;
|
||||
}
|
||||
|
||||
void amdgpu_output_poll_changed(struct drm_device *dev)
|
||||
{
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
amdgpu_fb_output_poll_changed(adev);
|
||||
}
|
||||
|
||||
const struct drm_mode_config_funcs amdgpu_mode_funcs = {
|
||||
.fb_create = amdgpu_user_framebuffer_create,
|
||||
.output_poll_changed = amdgpu_output_poll_changed
|
||||
.output_poll_changed = drm_fb_helper_output_poll_changed,
|
||||
};
|
||||
|
||||
static const struct drm_prop_enum_list amdgpu_underscan_enum_list[] =
|
||||
|
|
|
@ -25,9 +25,7 @@
|
|||
|
||||
struct drm_framebuffer *
|
||||
amdgpu_user_framebuffer_create(struct drm_device *dev,
|
||||
struct drm_file *file_priv,
|
||||
const struct drm_mode_fb_cmd2 *mode_cmd);
|
||||
|
||||
void amdgpu_output_poll_changed(struct drm_device *dev);
|
||||
struct drm_file *file_priv,
|
||||
const struct drm_mode_fb_cmd2 *mode_cmd);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -360,6 +360,12 @@ enum amdgpu_pcie_gen {
|
|||
((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\
|
||||
(adev)->powerplay.pp_handle, msg_id))
|
||||
|
||||
#define amdgpu_dpm_notify_smu_memory_info(adev, virtual_addr_low, \
|
||||
virtual_addr_hi, mc_addr_low, mc_addr_hi, size) \
|
||||
((adev)->powerplay.pp_funcs->notify_smu_memory_info)( \
|
||||
(adev)->powerplay.pp_handle, virtual_addr_low, \
|
||||
virtual_addr_hi, mc_addr_low, mc_addr_hi, size)
|
||||
|
||||
struct amdgpu_dpm {
|
||||
struct amdgpu_ps *ps;
|
||||
/* number of valid power states */
|
||||
|
|
|
@ -216,7 +216,7 @@ module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444);
|
|||
MODULE_PARM_DESC(dc, "Display Core driver (1 = enable, 0 = disable, -1 = auto (default))");
|
||||
module_param_named(dc, amdgpu_dc, int, 0444);
|
||||
|
||||
MODULE_PARM_DESC(dc, "Display Core Log Level (0 = minimal (default), 1 = chatty");
|
||||
MODULE_PARM_DESC(dc_log, "Display Core Log Level (0 = minimal (default), 1 = chatty");
|
||||
module_param_named(dc_log, amdgpu_dc_log, int, 0444);
|
||||
|
||||
MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 32)");
|
||||
|
@ -306,7 +306,6 @@ MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)
|
|||
module_param_named(cik_support, amdgpu_cik_support, int, 0444);
|
||||
#endif
|
||||
|
||||
|
||||
static const struct pci_device_id pciidlist[] = {
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
{0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
|
||||
|
@ -566,12 +565,13 @@ static int amdgpu_kick_out_firmware_fb(struct pci_dev *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int amdgpu_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
struct drm_device *dev;
|
||||
unsigned long flags = ent->driver_data;
|
||||
int ret;
|
||||
int ret, retry = 0;
|
||||
|
||||
if ((flags & AMD_EXP_HW_SUPPORT) && !amdgpu_exp_hw_support) {
|
||||
DRM_INFO("This hardware requires experimental hardware support.\n"
|
||||
|
@ -604,8 +604,14 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
|
|||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
||||
retry_init:
|
||||
ret = drm_dev_register(dev, ent->driver_data);
|
||||
if (ret)
|
||||
if (ret == -EAGAIN && ++retry <= 3) {
|
||||
DRM_INFO("retry init %d\n", retry);
|
||||
/* Don't request EX mode too frequently which is attacking */
|
||||
msleep(5000);
|
||||
goto retry_init;
|
||||
} else if (ret)
|
||||
goto err_pci;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -283,12 +283,6 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
|
|||
return ret;
|
||||
}
|
||||
|
||||
void amdgpu_fb_output_poll_changed(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->mode_info.rfbdev)
|
||||
drm_fb_helper_hotplug_event(&adev->mode_info.rfbdev->helper);
|
||||
}
|
||||
|
||||
static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfbdev)
|
||||
{
|
||||
struct amdgpu_framebuffer *rfb = &rfbdev->rfb;
|
||||
|
@ -393,24 +387,3 @@ bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_fbdev *afbdev;
|
||||
struct drm_fb_helper *fb_helper;
|
||||
int ret;
|
||||
|
||||
if (!adev)
|
||||
return;
|
||||
|
||||
afbdev = adev->mode_info.rfbdev;
|
||||
|
||||
if (!afbdev)
|
||||
return;
|
||||
|
||||
fb_helper = &afbdev->helper;
|
||||
|
||||
ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
|
||||
if (ret)
|
||||
DRM_DEBUG("failed to restore crtc mode\n");
|
||||
}
|
||||
|
|
|
@ -391,9 +391,9 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
|
|||
ring->fence_drv.irq_type = irq_type;
|
||||
ring->fence_drv.initialized = true;
|
||||
|
||||
dev_info(adev->dev, "fence driver on ring %d use gpu addr 0x%016llx, "
|
||||
"cpu addr 0x%p\n", ring->idx,
|
||||
ring->fence_drv.gpu_addr, ring->fence_drv.cpu_addr);
|
||||
dev_dbg(adev->dev, "fence driver on ring %d use gpu addr 0x%016llx, "
|
||||
"cpu addr 0x%p\n", ring->idx,
|
||||
ring->fence_drv.gpu_addr, ring->fence_drv.cpu_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -446,7 +446,7 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
|
|||
timeout = MAX_SCHEDULE_TIMEOUT;
|
||||
}
|
||||
r = amd_sched_init(&ring->sched, &amdgpu_sched_ops,
|
||||
num_hw_submission,
|
||||
num_hw_submission, amdgpu_job_hang_limit,
|
||||
timeout, ring->name);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed to create scheduler on ring %s.\n",
|
||||
|
@ -499,7 +499,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
|
|||
r = amdgpu_fence_wait_empty(ring);
|
||||
if (r) {
|
||||
/* no need to trigger GPU reset as we are unloading */
|
||||
amdgpu_fence_driver_force_completion(adev);
|
||||
amdgpu_fence_driver_force_completion(ring);
|
||||
}
|
||||
amdgpu_irq_put(adev, ring->fence_drv.irq_src,
|
||||
ring->fence_drv.irq_type);
|
||||
|
@ -534,7 +534,7 @@ void amdgpu_fence_driver_suspend(struct amdgpu_device *adev)
|
|||
r = amdgpu_fence_wait_empty(ring);
|
||||
if (r) {
|
||||
/* delay GPU reset to resume */
|
||||
amdgpu_fence_driver_force_completion(adev);
|
||||
amdgpu_fence_driver_force_completion(ring);
|
||||
}
|
||||
|
||||
/* disable the interrupt */
|
||||
|
@ -571,30 +571,15 @@ void amdgpu_fence_driver_resume(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_driver_force_completion - force all fence waiter to complete
|
||||
* amdgpu_fence_driver_force_completion - force signal latest fence of ring
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
* @ring: fence of the ring to signal
|
||||
*
|
||||
* In case of GPU reset failure make sure no process keep waiting on fence
|
||||
* that will never complete.
|
||||
*/
|
||||
void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev)
|
||||
void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
if (!ring || !ring->fence_drv.initialized)
|
||||
continue;
|
||||
|
||||
amdgpu_fence_write(ring, ring->fence_drv.sync_seq);
|
||||
}
|
||||
}
|
||||
|
||||
void amdgpu_fence_driver_force_completion_ring(struct amdgpu_ring *ring)
|
||||
{
|
||||
if (ring)
|
||||
amdgpu_fence_write(ring, ring->fence_drv.sync_seq);
|
||||
amdgpu_fence_write(ring, ring->fence_drv.sync_seq);
|
||||
amdgpu_fence_process(ring);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -709,25 +694,25 @@ static int amdgpu_debugfs_fence_info(struct seq_file *m, void *data)
|
|||
}
|
||||
|
||||
/**
|
||||
* amdgpu_debugfs_gpu_reset - manually trigger a gpu reset
|
||||
* amdgpu_debugfs_gpu_recover - manually trigger a gpu reset & recover
|
||||
*
|
||||
* Manually trigger a gpu reset at the next fence wait.
|
||||
*/
|
||||
static int amdgpu_debugfs_gpu_reset(struct seq_file *m, void *data)
|
||||
static int amdgpu_debugfs_gpu_recover(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||
struct drm_device *dev = node->minor->dev;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
|
||||
seq_printf(m, "gpu reset\n");
|
||||
amdgpu_gpu_reset(adev);
|
||||
seq_printf(m, "gpu recover\n");
|
||||
amdgpu_gpu_recover(adev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_info_list amdgpu_debugfs_fence_list[] = {
|
||||
{"amdgpu_fence_info", &amdgpu_debugfs_fence_info, 0, NULL},
|
||||
{"amdgpu_gpu_reset", &amdgpu_debugfs_gpu_reset, 0, NULL}
|
||||
{"amdgpu_gpu_recover", &amdgpu_debugfs_gpu_recover, 0, NULL}
|
||||
};
|
||||
|
||||
static const struct drm_info_list amdgpu_debugfs_fence_list_sriov[] = {
|
||||
|
|
|
@ -56,63 +56,6 @@
|
|||
* Common GART table functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* amdgpu_gart_table_ram_alloc - allocate system ram for gart page table
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Allocate system memory for GART page table
|
||||
* (r1xx-r3xx, non-pcie r4xx, rs400). These asics require the
|
||||
* gart table to be in system memory.
|
||||
* Returns 0 for success, -ENOMEM for failure.
|
||||
*/
|
||||
int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = pci_alloc_consistent(adev->pdev, adev->gart.table_size,
|
||||
&adev->gart.table_addr);
|
||||
if (ptr == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
#ifdef CONFIG_X86
|
||||
if (0) {
|
||||
set_memory_uc((unsigned long)ptr,
|
||||
adev->gart.table_size >> PAGE_SHIFT);
|
||||
}
|
||||
#endif
|
||||
adev->gart.ptr = ptr;
|
||||
memset((void *)adev->gart.ptr, 0, adev->gart.table_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gart_table_ram_free - free system ram for gart page table
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Free system memory for GART page table
|
||||
* (r1xx-r3xx, non-pcie r4xx, rs400). These asics require the
|
||||
* gart table to be in system memory.
|
||||
*/
|
||||
void amdgpu_gart_table_ram_free(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->gart.ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
#ifdef CONFIG_X86
|
||||
if (0) {
|
||||
set_memory_wb((unsigned long)adev->gart.ptr,
|
||||
adev->gart.table_size >> PAGE_SHIFT);
|
||||
}
|
||||
#endif
|
||||
pci_free_consistent(adev->pdev, adev->gart.table_size,
|
||||
(void *)adev->gart.ptr,
|
||||
adev->gart.table_addr);
|
||||
adev->gart.ptr = NULL;
|
||||
adev->gart.table_addr = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gart_table_vram_alloc - allocate vram for gart page table
|
||||
*
|
||||
|
@ -377,10 +320,8 @@ int amdgpu_gart_init(struct amdgpu_device *adev)
|
|||
#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
|
||||
/* Allocate pages table */
|
||||
adev->gart.pages = vzalloc(sizeof(void *) * adev->gart.num_cpu_pages);
|
||||
if (adev->gart.pages == NULL) {
|
||||
amdgpu_gart_fini(adev);
|
||||
if (adev->gart.pages == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -395,11 +336,6 @@ int amdgpu_gart_init(struct amdgpu_device *adev)
|
|||
*/
|
||||
void amdgpu_gart_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
if (adev->gart.ready) {
|
||||
/* unbind pages */
|
||||
amdgpu_gart_unbind(adev, 0, adev->gart.num_cpu_pages);
|
||||
}
|
||||
adev->gart.ready = false;
|
||||
#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
|
||||
vfree(adev->gart.pages);
|
||||
adev->gart.pages = NULL;
|
||||
|
|
|
@ -39,7 +39,7 @@ struct amdgpu_gart_funcs;
|
|||
#define AMDGPU_GPU_PAGE_ALIGN(a) (((a) + AMDGPU_GPU_PAGE_MASK) & ~AMDGPU_GPU_PAGE_MASK)
|
||||
|
||||
struct amdgpu_gart {
|
||||
dma_addr_t table_addr;
|
||||
u64 table_addr;
|
||||
struct amdgpu_bo *robj;
|
||||
void *ptr;
|
||||
unsigned num_gpu_pages;
|
||||
|
@ -56,8 +56,6 @@ struct amdgpu_gart {
|
|||
const struct amdgpu_gart_funcs *gart_funcs;
|
||||
};
|
||||
|
||||
int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev);
|
||||
void amdgpu_gart_table_ram_free(struct amdgpu_device *adev);
|
||||
int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
|
||||
void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
|
||||
int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
|
||||
|
|
|
@ -72,7 +72,7 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
|
|||
initial_domain |= AMDGPU_GEM_DOMAIN_GTT;
|
||||
goto retry;
|
||||
}
|
||||
DRM_ERROR("Failed to allocate GEM object (%ld, %d, %u, %d)\n",
|
||||
DRM_DEBUG("Failed to allocate GEM object (%ld, %d, %u, %d)\n",
|
||||
size, initial_domain, alignment, r);
|
||||
}
|
||||
return r;
|
||||
|
@ -282,6 +282,7 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
|
|||
int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *filp)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = { true, false };
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
struct drm_amdgpu_gem_userptr *args = data;
|
||||
struct drm_gem_object *gobj;
|
||||
|
@ -335,7 +336,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
|
|||
goto free_pages;
|
||||
|
||||
amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
amdgpu_bo_unreserve(bo);
|
||||
if (r)
|
||||
goto free_pages;
|
||||
|
@ -557,14 +558,25 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
|
|||
int r = 0;
|
||||
|
||||
if (args->va_address < AMDGPU_VA_RESERVED_SIZE) {
|
||||
dev_err(&dev->pdev->dev,
|
||||
dev_dbg(&dev->pdev->dev,
|
||||
"va_address 0x%LX is in reserved area 0x%LX\n",
|
||||
args->va_address, AMDGPU_VA_RESERVED_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (args->va_address >= AMDGPU_VA_HOLE_START &&
|
||||
args->va_address < AMDGPU_VA_HOLE_END) {
|
||||
dev_dbg(&dev->pdev->dev,
|
||||
"va_address 0x%LX is in VA hole 0x%LX-0x%LX\n",
|
||||
args->va_address, AMDGPU_VA_HOLE_START,
|
||||
AMDGPU_VA_HOLE_END);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
args->va_address &= AMDGPU_VA_HOLE_MASK;
|
||||
|
||||
if ((args->flags & ~valid_flags) && (args->flags & ~prt_flags)) {
|
||||
dev_err(&dev->pdev->dev, "invalid flags combination 0x%08X\n",
|
||||
dev_dbg(&dev->pdev->dev, "invalid flags combination 0x%08X\n",
|
||||
args->flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -576,7 +588,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
|
|||
case AMDGPU_VA_OP_REPLACE:
|
||||
break;
|
||||
default:
|
||||
dev_err(&dev->pdev->dev, "unsupported operation %d\n",
|
||||
dev_dbg(&dev->pdev->dev, "unsupported operation %d\n",
|
||||
args->operation);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,11 @@ struct amdgpu_gtt_mgr {
|
|||
atomic64_t available;
|
||||
};
|
||||
|
||||
struct amdgpu_gtt_node {
|
||||
struct drm_mm_node node;
|
||||
struct ttm_buffer_object *tbo;
|
||||
};
|
||||
|
||||
/**
|
||||
* amdgpu_gtt_mgr_init - init GTT manager and DRM MM
|
||||
*
|
||||
|
@ -79,17 +84,17 @@ static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man)
|
|||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gtt_mgr_is_allocated - Check if mem has address space
|
||||
* amdgpu_gtt_mgr_has_gart_addr - Check if mem has address space
|
||||
*
|
||||
* @mem: the mem object to check
|
||||
*
|
||||
* Check if a mem object has already address space allocated.
|
||||
*/
|
||||
bool amdgpu_gtt_mgr_is_allocated(struct ttm_mem_reg *mem)
|
||||
bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_mem_reg *mem)
|
||||
{
|
||||
struct drm_mm_node *node = mem->mm_node;
|
||||
struct amdgpu_gtt_node *node = mem->mm_node;
|
||||
|
||||
return (node->start != AMDGPU_BO_INVALID_OFFSET);
|
||||
return (node->node.start != AMDGPU_BO_INVALID_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,12 +114,12 @@ static int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
|
|||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);
|
||||
struct amdgpu_gtt_mgr *mgr = man->priv;
|
||||
struct drm_mm_node *node = mem->mm_node;
|
||||
struct amdgpu_gtt_node *node = mem->mm_node;
|
||||
enum drm_mm_insert_mode mode;
|
||||
unsigned long fpfn, lpfn;
|
||||
int r;
|
||||
|
||||
if (amdgpu_gtt_mgr_is_allocated(mem))
|
||||
if (amdgpu_gtt_mgr_has_gart_addr(mem))
|
||||
return 0;
|
||||
|
||||
if (place)
|
||||
|
@ -132,13 +137,13 @@ static int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man,
|
|||
mode = DRM_MM_INSERT_HIGH;
|
||||
|
||||
spin_lock(&mgr->lock);
|
||||
r = drm_mm_insert_node_in_range(&mgr->mm, node,
|
||||
mem->num_pages, mem->page_alignment, 0,
|
||||
fpfn, lpfn, mode);
|
||||
r = drm_mm_insert_node_in_range(&mgr->mm, &node->node, mem->num_pages,
|
||||
mem->page_alignment, 0, fpfn, lpfn,
|
||||
mode);
|
||||
spin_unlock(&mgr->lock);
|
||||
|
||||
if (!r)
|
||||
mem->start = node->start;
|
||||
mem->start = node->node.start;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -159,7 +164,7 @@ static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man,
|
|||
struct ttm_mem_reg *mem)
|
||||
{
|
||||
struct amdgpu_gtt_mgr *mgr = man->priv;
|
||||
struct drm_mm_node *node;
|
||||
struct amdgpu_gtt_node *node;
|
||||
int r;
|
||||
|
||||
spin_lock(&mgr->lock);
|
||||
|
@ -177,8 +182,9 @@ static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man,
|
|||
goto err_out;
|
||||
}
|
||||
|
||||
node->start = AMDGPU_BO_INVALID_OFFSET;
|
||||
node->size = mem->num_pages;
|
||||
node->node.start = AMDGPU_BO_INVALID_OFFSET;
|
||||
node->node.size = mem->num_pages;
|
||||
node->tbo = tbo;
|
||||
mem->mm_node = node;
|
||||
|
||||
if (place->fpfn || place->lpfn || place->flags & TTM_PL_FLAG_TOPDOWN) {
|
||||
|
@ -190,7 +196,7 @@ static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man,
|
|||
goto err_out;
|
||||
}
|
||||
} else {
|
||||
mem->start = node->start;
|
||||
mem->start = node->node.start;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -214,14 +220,14 @@ static void amdgpu_gtt_mgr_del(struct ttm_mem_type_manager *man,
|
|||
struct ttm_mem_reg *mem)
|
||||
{
|
||||
struct amdgpu_gtt_mgr *mgr = man->priv;
|
||||
struct drm_mm_node *node = mem->mm_node;
|
||||
struct amdgpu_gtt_node *node = mem->mm_node;
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
spin_lock(&mgr->lock);
|
||||
if (node->start != AMDGPU_BO_INVALID_OFFSET)
|
||||
drm_mm_remove_node(node);
|
||||
if (node->node.start != AMDGPU_BO_INVALID_OFFSET)
|
||||
drm_mm_remove_node(&node->node);
|
||||
spin_unlock(&mgr->lock);
|
||||
atomic64_add(mem->num_pages, &mgr->available);
|
||||
|
||||
|
@ -244,6 +250,25 @@ uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man)
|
|||
return (result > 0 ? result : 0) * PAGE_SIZE;
|
||||
}
|
||||
|
||||
int amdgpu_gtt_mgr_recover(struct ttm_mem_type_manager *man)
|
||||
{
|
||||
struct amdgpu_gtt_mgr *mgr = man->priv;
|
||||
struct amdgpu_gtt_node *node;
|
||||
struct drm_mm_node *mm_node;
|
||||
int r = 0;
|
||||
|
||||
spin_lock(&mgr->lock);
|
||||
drm_mm_for_each_node(mm_node, &mgr->mm) {
|
||||
node = container_of(mm_node, struct amdgpu_gtt_node, node);
|
||||
r = amdgpu_ttm_recover_gart(node->tbo);
|
||||
if (r)
|
||||
break;
|
||||
}
|
||||
spin_unlock(&mgr->lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gtt_mgr_debug - dump VRAM table
|
||||
*
|
||||
|
|
|
@ -164,7 +164,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
}
|
||||
|
||||
if (ring->funcs->emit_pipeline_sync && job &&
|
||||
((tmp = amdgpu_sync_get_fence(&job->sched_sync)) ||
|
||||
((tmp = amdgpu_sync_get_fence(&job->sched_sync, NULL)) ||
|
||||
amdgpu_vm_need_pipeline_sync(ring, job))) {
|
||||
need_pipe_sync = true;
|
||||
dma_fence_put(tmp);
|
||||
|
|
|
@ -88,7 +88,7 @@ static void amdgpu_irq_reset_work_func(struct work_struct *work)
|
|||
reset_work);
|
||||
|
||||
if (!amdgpu_sriov_vf(adev))
|
||||
amdgpu_gpu_reset(adev);
|
||||
amdgpu_gpu_recover(adev, NULL);
|
||||
}
|
||||
|
||||
/* Disable *all* interrupts */
|
||||
|
@ -232,7 +232,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
|
|||
int ret = pci_enable_msi(adev->pdev);
|
||||
if (!ret) {
|
||||
adev->irq.msi_enabled = true;
|
||||
dev_info(adev->dev, "amdgpu: using MSI.\n");
|
||||
dev_dbg(adev->dev, "amdgpu: using MSI.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +262,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
|
|||
return r;
|
||||
}
|
||||
|
||||
DRM_INFO("amdgpu: irq initialized.\n");
|
||||
DRM_DEBUG("amdgpu: irq initialized.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,10 +37,7 @@ static void amdgpu_job_timedout(struct amd_sched_job *s_job)
|
|||
atomic_read(&job->ring->fence_drv.last_seq),
|
||||
job->ring->fence_drv.sync_seq);
|
||||
|
||||
if (amdgpu_sriov_vf(job->adev))
|
||||
amdgpu_sriov_gpu_reset(job->adev, job);
|
||||
else
|
||||
amdgpu_gpu_reset(job->adev);
|
||||
amdgpu_gpu_recover(job->adev, job);
|
||||
}
|
||||
|
||||
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
||||
|
@ -63,7 +60,6 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,
|
|||
(*job)->num_ibs = num_ibs;
|
||||
|
||||
amdgpu_sync_create(&(*job)->sync);
|
||||
amdgpu_sync_create(&(*job)->dep_sync);
|
||||
amdgpu_sync_create(&(*job)->sched_sync);
|
||||
(*job)->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
|
||||
|
||||
|
@ -104,10 +100,9 @@ static void amdgpu_job_free_cb(struct amd_sched_job *s_job)
|
|||
{
|
||||
struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base);
|
||||
|
||||
amdgpu_ring_priority_put(job->ring, amd_sched_get_job_priority(s_job));
|
||||
amdgpu_ring_priority_put(job->ring, s_job->s_priority);
|
||||
dma_fence_put(job->fence);
|
||||
amdgpu_sync_free(&job->sync);
|
||||
amdgpu_sync_free(&job->dep_sync);
|
||||
amdgpu_sync_free(&job->sched_sync);
|
||||
kfree(job);
|
||||
}
|
||||
|
@ -118,7 +113,6 @@ void amdgpu_job_free(struct amdgpu_job *job)
|
|||
|
||||
dma_fence_put(job->fence);
|
||||
amdgpu_sync_free(&job->sync);
|
||||
amdgpu_sync_free(&job->dep_sync);
|
||||
amdgpu_sync_free(&job->sched_sync);
|
||||
kfree(job);
|
||||
}
|
||||
|
@ -141,28 +135,29 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring,
|
|||
job->fence_ctx = entity->fence_context;
|
||||
*f = dma_fence_get(&job->base.s_fence->finished);
|
||||
amdgpu_job_free_resources(job);
|
||||
amdgpu_ring_priority_get(job->ring,
|
||||
amd_sched_get_job_priority(&job->base));
|
||||
amd_sched_entity_push_job(&job->base);
|
||||
amdgpu_ring_priority_get(job->ring, job->base.s_priority);
|
||||
amd_sched_entity_push_job(&job->base, entity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dma_fence *amdgpu_job_dependency(struct amd_sched_job *sched_job)
|
||||
static struct dma_fence *amdgpu_job_dependency(struct amd_sched_job *sched_job,
|
||||
struct amd_sched_entity *s_entity)
|
||||
{
|
||||
struct amdgpu_job *job = to_amdgpu_job(sched_job);
|
||||
struct amdgpu_vm *vm = job->vm;
|
||||
|
||||
struct dma_fence *fence = amdgpu_sync_get_fence(&job->dep_sync);
|
||||
bool explicit = false;
|
||||
int r;
|
||||
struct dma_fence *fence = amdgpu_sync_get_fence(&job->sync, &explicit);
|
||||
|
||||
if (amd_sched_dependency_optimized(fence, sched_job->s_entity)) {
|
||||
r = amdgpu_sync_fence(job->adev, &job->sched_sync, fence);
|
||||
if (r)
|
||||
DRM_ERROR("Error adding fence to sync (%d)\n", r);
|
||||
if (fence && explicit) {
|
||||
if (amd_sched_dependency_optimized(fence, s_entity)) {
|
||||
r = amdgpu_sync_fence(job->adev, &job->sched_sync, fence, false);
|
||||
if (r)
|
||||
DRM_ERROR("Error adding fence to sync (%d)\n", r);
|
||||
}
|
||||
}
|
||||
if (!fence)
|
||||
fence = amdgpu_sync_get_fence(&job->sync);
|
||||
|
||||
while (fence == NULL && vm && !job->vm_id) {
|
||||
struct amdgpu_ring *ring = job->ring;
|
||||
|
||||
|
@ -172,7 +167,7 @@ static struct dma_fence *amdgpu_job_dependency(struct amd_sched_job *sched_job)
|
|||
if (r)
|
||||
DRM_ERROR("Error getting VM ID (%d)\n", r);
|
||||
|
||||
fence = amdgpu_sync_get_fence(&job->sync);
|
||||
fence = amdgpu_sync_get_fence(&job->sync, NULL);
|
||||
}
|
||||
|
||||
return fence;
|
||||
|
@ -180,7 +175,7 @@ static struct dma_fence *amdgpu_job_dependency(struct amd_sched_job *sched_job)
|
|||
|
||||
static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job)
|
||||
{
|
||||
struct dma_fence *fence = NULL;
|
||||
struct dma_fence *fence = NULL, *finished;
|
||||
struct amdgpu_device *adev;
|
||||
struct amdgpu_job *job;
|
||||
int r;
|
||||
|
@ -190,15 +185,18 @@ static struct dma_fence *amdgpu_job_run(struct amd_sched_job *sched_job)
|
|||
return NULL;
|
||||
}
|
||||
job = to_amdgpu_job(sched_job);
|
||||
finished = &job->base.s_fence->finished;
|
||||
adev = job->adev;
|
||||
|
||||
BUG_ON(amdgpu_sync_peek_fence(&job->sync, NULL));
|
||||
|
||||
trace_amdgpu_sched_run_job(job);
|
||||
/* skip ib schedule when vram is lost */
|
||||
if (job->vram_lost_counter != atomic_read(&adev->vram_lost_counter)) {
|
||||
dma_fence_set_error(&job->base.s_fence->finished, -ECANCELED);
|
||||
DRM_ERROR("Skip scheduling IBs!\n");
|
||||
|
||||
if (job->vram_lost_counter != atomic_read(&adev->vram_lost_counter))
|
||||
dma_fence_set_error(finished, -ECANCELED);/* skip IB as well if VRAM lost */
|
||||
|
||||
if (finished->error < 0) {
|
||||
DRM_INFO("Skip scheduling IBs!\n");
|
||||
} else {
|
||||
r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, job,
|
||||
&fence);
|
||||
|
|
|
@ -63,8 +63,6 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
|
|||
pm_runtime_forbid(dev->dev);
|
||||
}
|
||||
|
||||
amdgpu_amdkfd_device_fini(adev);
|
||||
|
||||
amdgpu_acpi_fini(adev);
|
||||
|
||||
amdgpu_device_fini(adev);
|
||||
|
@ -159,9 +157,6 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
|
|||
"Error during ACPI methods call\n");
|
||||
}
|
||||
|
||||
amdgpu_amdkfd_device_probe(adev);
|
||||
amdgpu_amdkfd_device_init(adev);
|
||||
|
||||
if (amdgpu_device_is_px(dev)) {
|
||||
pm_runtime_use_autosuspend(dev->dev);
|
||||
pm_runtime_set_autosuspend_delay(dev->dev, 5000);
|
||||
|
@ -171,9 +166,6 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
|
|||
pm_runtime_put_autosuspend(dev->dev);
|
||||
}
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_virt_release_full_gpu(adev, true);
|
||||
|
||||
out:
|
||||
if (r) {
|
||||
/* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */
|
||||
|
@ -558,6 +550,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
}
|
||||
case AMDGPU_INFO_DEV_INFO: {
|
||||
struct drm_amdgpu_info_device dev_info = {};
|
||||
uint64_t vm_size;
|
||||
|
||||
dev_info.device_id = dev->pdev->device;
|
||||
dev_info.chip_rev = adev->rev_id;
|
||||
|
@ -585,8 +578,17 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
dev_info.ids_flags |= AMDGPU_IDS_FLAGS_FUSION;
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
dev_info.ids_flags |= AMDGPU_IDS_FLAGS_PREEMPTION;
|
||||
|
||||
vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
|
||||
dev_info.virtual_address_offset = AMDGPU_VA_RESERVED_SIZE;
|
||||
dev_info.virtual_address_max = (uint64_t)adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
|
||||
dev_info.virtual_address_max =
|
||||
min(vm_size, AMDGPU_VA_HOLE_START);
|
||||
|
||||
vm_size -= AMDGPU_VA_RESERVED_SIZE;
|
||||
if (vm_size > AMDGPU_VA_HOLE_START) {
|
||||
dev_info.high_va_offset = AMDGPU_VA_HOLE_END;
|
||||
dev_info.high_va_max = AMDGPU_VA_HOLE_END | vm_size;
|
||||
}
|
||||
dev_info.virtual_address_alignment = max((int)PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE);
|
||||
dev_info.pte_fragment_size = (1 << adev->vm_manager.fragment_size) * AMDGPU_GPU_PAGE_SIZE;
|
||||
dev_info.gart_page_size = AMDGPU_GPU_PAGE_SIZE;
|
||||
|
@ -786,9 +788,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
*/
|
||||
void amdgpu_driver_lastclose_kms(struct drm_device *dev)
|
||||
{
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
|
||||
amdgpu_fbdev_restore_mode(adev);
|
||||
drm_fb_helper_lastclose(dev);
|
||||
vga_switcheroo_process_delayed_switch();
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,6 @@ enum amdgpu_hpd_id {
|
|||
AMDGPU_HPD_4,
|
||||
AMDGPU_HPD_5,
|
||||
AMDGPU_HPD_6,
|
||||
AMDGPU_HPD_LAST,
|
||||
AMDGPU_HPD_NONE = 0xff,
|
||||
};
|
||||
|
||||
|
@ -106,7 +105,6 @@ enum amdgpu_crtc_irq {
|
|||
AMDGPU_CRTC_IRQ_VLINE4,
|
||||
AMDGPU_CRTC_IRQ_VLINE5,
|
||||
AMDGPU_CRTC_IRQ_VLINE6,
|
||||
AMDGPU_CRTC_IRQ_LAST,
|
||||
AMDGPU_CRTC_IRQ_NONE = 0xff
|
||||
};
|
||||
|
||||
|
@ -117,7 +115,6 @@ enum amdgpu_pageflip_irq {
|
|||
AMDGPU_PAGEFLIP_IRQ_D4,
|
||||
AMDGPU_PAGEFLIP_IRQ_D5,
|
||||
AMDGPU_PAGEFLIP_IRQ_D6,
|
||||
AMDGPU_PAGEFLIP_IRQ_LAST,
|
||||
AMDGPU_PAGEFLIP_IRQ_NONE = 0xff
|
||||
};
|
||||
|
||||
|
@ -661,10 +658,6 @@ void amdgpu_fbdev_fini(struct amdgpu_device *adev);
|
|||
void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state);
|
||||
int amdgpu_fbdev_total_size(struct amdgpu_device *adev);
|
||||
bool amdgpu_fbdev_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj);
|
||||
void amdgpu_fbdev_restore_mode(struct amdgpu_device *adev);
|
||||
|
||||
void amdgpu_fb_output_poll_changed(struct amdgpu_device *adev);
|
||||
|
||||
|
||||
int amdgpu_align_pitch(struct amdgpu_device *adev, int width, int bpp, bool tiled);
|
||||
|
||||
|
|
|
@ -281,6 +281,44 @@ void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr,
|
|||
*cpu_addr = NULL;
|
||||
}
|
||||
|
||||
/* Validate bo size is bit bigger then the request domain */
|
||||
static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
|
||||
unsigned long size, u32 domain)
|
||||
{
|
||||
struct ttm_mem_type_manager *man = NULL;
|
||||
|
||||
/*
|
||||
* If GTT is part of requested domains the check must succeed to
|
||||
* allow fall back to GTT
|
||||
*/
|
||||
if (domain & AMDGPU_GEM_DOMAIN_GTT) {
|
||||
man = &adev->mman.bdev.man[TTM_PL_TT];
|
||||
|
||||
if (size < (man->size << PAGE_SHIFT))
|
||||
return true;
|
||||
else
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (domain & AMDGPU_GEM_DOMAIN_VRAM) {
|
||||
man = &adev->mman.bdev.man[TTM_PL_VRAM];
|
||||
|
||||
if (size < (man->size << PAGE_SHIFT))
|
||||
return true;
|
||||
else
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
|
||||
return true;
|
||||
|
||||
fail:
|
||||
DRM_DEBUG("BO size %lu > total memory in domain: %llu\n", size,
|
||||
man->size << PAGE_SHIFT);
|
||||
return false;
|
||||
}
|
||||
|
||||
static int amdgpu_bo_do_create(struct amdgpu_device *adev,
|
||||
unsigned long size, int byte_align,
|
||||
bool kernel, u32 domain, u64 flags,
|
||||
|
@ -289,16 +327,19 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
|
|||
uint64_t init_value,
|
||||
struct amdgpu_bo **bo_ptr)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = { !kernel, false };
|
||||
struct amdgpu_bo *bo;
|
||||
enum ttm_bo_type type;
|
||||
unsigned long page_align;
|
||||
u64 initial_bytes_moved, bytes_moved;
|
||||
size_t acc_size;
|
||||
int r;
|
||||
|
||||
page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT;
|
||||
size = ALIGN(size, PAGE_SIZE);
|
||||
|
||||
if (!amdgpu_bo_validate_size(adev, size, domain))
|
||||
return -ENOMEM;
|
||||
|
||||
if (kernel) {
|
||||
type = ttm_bo_type_kernel;
|
||||
} else if (sg) {
|
||||
|
@ -364,22 +405,19 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
|
|||
bo->tbo.bdev = &adev->mman.bdev;
|
||||
amdgpu_ttm_placement_from_domain(bo, domain);
|
||||
|
||||
initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
|
||||
/* Kernel allocation are uninterruptible */
|
||||
r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type,
|
||||
&bo->placement, page_align, !kernel, NULL,
|
||||
&bo->placement, page_align, &ctx, NULL,
|
||||
acc_size, sg, resv, &amdgpu_ttm_bo_destroy);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
|
||||
bytes_moved = atomic64_read(&adev->num_bytes_moved) -
|
||||
initial_bytes_moved;
|
||||
if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
|
||||
bo->tbo.mem.mem_type == TTM_PL_VRAM &&
|
||||
bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT)
|
||||
amdgpu_cs_report_moved_bytes(adev, bytes_moved, bytes_moved);
|
||||
amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved,
|
||||
ctx.bytes_moved);
|
||||
else
|
||||
amdgpu_cs_report_moved_bytes(adev, bytes_moved, 0);
|
||||
amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved, 0);
|
||||
|
||||
if (kernel)
|
||||
bo->tbo.priority = 1;
|
||||
|
@ -511,6 +549,7 @@ int amdgpu_bo_backup_to_shadow(struct amdgpu_device *adev,
|
|||
|
||||
int amdgpu_bo_validate(struct amdgpu_bo *bo)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
uint32_t domain;
|
||||
int r;
|
||||
|
||||
|
@ -521,7 +560,7 @@ int amdgpu_bo_validate(struct amdgpu_bo *bo)
|
|||
|
||||
retry:
|
||||
amdgpu_ttm_placement_from_domain(bo, domain);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
|
||||
domain = bo->allowed_domains;
|
||||
goto retry;
|
||||
|
@ -632,6 +671,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
|
|||
u64 *gpu_addr)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
int r, i;
|
||||
|
||||
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
|
||||
|
@ -647,7 +687,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
|
|||
if (bo->pin_count) {
|
||||
uint32_t mem_type = bo->tbo.mem.mem_type;
|
||||
|
||||
if (domain != amdgpu_mem_type_to_domain(mem_type))
|
||||
if (!(domain & amdgpu_mem_type_to_domain(mem_type)))
|
||||
return -EINVAL;
|
||||
|
||||
bo->pin_count++;
|
||||
|
@ -682,21 +722,23 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
|
|||
bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
|
||||
}
|
||||
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
if (unlikely(r)) {
|
||||
dev_err(adev->dev, "%p pin failed\n", bo);
|
||||
goto error;
|
||||
}
|
||||
|
||||
bo->pin_count = 1;
|
||||
if (gpu_addr != NULL) {
|
||||
r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem);
|
||||
if (unlikely(r)) {
|
||||
dev_err(adev->dev, "%p bind failed\n", bo);
|
||||
goto error;
|
||||
}
|
||||
*gpu_addr = amdgpu_bo_gpu_offset(bo);
|
||||
r = amdgpu_ttm_alloc_gart(&bo->tbo);
|
||||
if (unlikely(r)) {
|
||||
dev_err(adev->dev, "%p bind failed\n", bo);
|
||||
goto error;
|
||||
}
|
||||
|
||||
bo->pin_count = 1;
|
||||
if (gpu_addr != NULL)
|
||||
*gpu_addr = amdgpu_bo_gpu_offset(bo);
|
||||
|
||||
domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
|
||||
if (domain == AMDGPU_GEM_DOMAIN_VRAM) {
|
||||
adev->vram_pin_size += amdgpu_bo_size(bo);
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
|
||||
|
@ -717,6 +759,7 @@ int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain, u64 *gpu_addr)
|
|||
int amdgpu_bo_unpin(struct amdgpu_bo *bo)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
int r, i;
|
||||
|
||||
if (!bo->pin_count) {
|
||||
|
@ -730,7 +773,7 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo)
|
|||
bo->placements[i].lpfn = 0;
|
||||
bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
|
||||
}
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
if (unlikely(r)) {
|
||||
dev_err(adev->dev, "%p validate failed for unpin\n", bo);
|
||||
goto error;
|
||||
|
@ -779,8 +822,8 @@ int amdgpu_bo_init(struct amdgpu_device *adev)
|
|||
adev->mc.vram_mtrr = arch_phys_wc_add(adev->mc.aper_base,
|
||||
adev->mc.aper_size);
|
||||
DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
|
||||
adev->mc.mc_vram_size >> 20,
|
||||
(unsigned long long)adev->mc.aper_size >> 20);
|
||||
adev->mc.mc_vram_size >> 20,
|
||||
(unsigned long long)adev->mc.aper_size >> 20);
|
||||
DRM_INFO("RAM width %dbits %s\n",
|
||||
adev->mc.vram_width, amdgpu_vram_names[adev->mc.vram_type]);
|
||||
return amdgpu_ttm_init(adev);
|
||||
|
@ -902,6 +945,7 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
|
|||
int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
struct amdgpu_bo *abo;
|
||||
unsigned long offset, size;
|
||||
int r;
|
||||
|
@ -935,7 +979,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
|
|||
abo->placement.num_busy_placement = 1;
|
||||
abo->placement.busy_placement = &abo->placements[1];
|
||||
|
||||
r = ttm_bo_validate(bo, &abo->placement, false, false);
|
||||
r = ttm_bo_validate(bo, &abo->placement, &ctx);
|
||||
if (unlikely(r != 0))
|
||||
return r;
|
||||
|
||||
|
@ -980,7 +1024,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo)
|
|||
{
|
||||
WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM);
|
||||
WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_TT &&
|
||||
!amdgpu_ttm_is_bound(bo->tbo.ttm));
|
||||
!amdgpu_gtt_mgr_has_gart_addr(&bo->tbo.mem));
|
||||
WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) &&
|
||||
!bo->pin_count);
|
||||
WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET);
|
||||
|
|
|
@ -187,7 +187,7 @@ static inline u64 amdgpu_bo_mmap_offset(struct amdgpu_bo *bo)
|
|||
static inline bool amdgpu_bo_gpu_accessible(struct amdgpu_bo *bo)
|
||||
{
|
||||
switch (bo->tbo.mem.mem_type) {
|
||||
case TTM_PL_TT: return amdgpu_ttm_is_bound(bo->tbo.ttm);
|
||||
case TTM_PL_TT: return amdgpu_gtt_mgr_has_gart_addr(&bo->tbo.mem);
|
||||
case TTM_PL_VRAM: return true;
|
||||
default: return false;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
|
||||
#include "amd_powerplay.h"
|
||||
|
||||
static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev);
|
||||
|
||||
|
|
|
@ -264,7 +264,7 @@ static int psp_hw_start(struct psp_context *psp)
|
|||
struct amdgpu_device *adev = psp->adev;
|
||||
int ret;
|
||||
|
||||
if (!amdgpu_sriov_vf(adev) || !adev->in_sriov_reset) {
|
||||
if (!amdgpu_sriov_vf(adev) || !adev->in_gpu_reset) {
|
||||
ret = psp_bootloader_load_sysdrv(psp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -334,23 +334,26 @@ static int psp_load_fw(struct amdgpu_device *adev)
|
|||
int ret;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
|
||||
if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset != 0)
|
||||
goto skip_memalloc;
|
||||
|
||||
psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!psp->cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG,
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&psp->fw_pri_bo,
|
||||
&psp->fw_pri_mc_addr,
|
||||
&psp->fw_pri_buf);
|
||||
AMDGPU_GEM_DOMAIN_GTT,
|
||||
&psp->fw_pri_bo,
|
||||
&psp->fw_pri_mc_addr,
|
||||
&psp->fw_pri_buf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&psp->fence_buf_bo,
|
||||
&psp->fence_buf_mc_addr,
|
||||
&psp->fence_buf);
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
&psp->fence_buf_bo,
|
||||
&psp->fence_buf_mc_addr,
|
||||
&psp->fence_buf);
|
||||
if (ret)
|
||||
goto failed_mem2;
|
||||
|
||||
|
@ -375,6 +378,7 @@ static int psp_load_fw(struct amdgpu_device *adev)
|
|||
if (ret)
|
||||
goto failed_mem;
|
||||
|
||||
skip_memalloc:
|
||||
ret = psp_hw_start(psp);
|
||||
if (ret)
|
||||
goto failed_mem;
|
||||
|
|
|
@ -225,7 +225,7 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev,
|
|||
|
||||
/* Right now all IPs have only one instance - multiple rings. */
|
||||
if (instance != 0) {
|
||||
DRM_ERROR("invalid ip instance: %d\n", instance);
|
||||
DRM_DEBUG("invalid ip instance: %d\n", instance);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -255,13 +255,13 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev,
|
|||
ip_num_rings = adev->vcn.num_enc_rings;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("unknown ip type: %d\n", hw_ip);
|
||||
DRM_DEBUG("unknown ip type: %d\n", hw_ip);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ring >= ip_num_rings) {
|
||||
DRM_ERROR("Ring index:%d exceeds maximum:%d for ip:%d\n",
|
||||
ring, ip_num_rings, hw_ip);
|
||||
DRM_DEBUG("Ring index:%d exceeds maximum:%d for ip:%d\n",
|
||||
ring, ip_num_rings, hw_ip);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -292,7 +292,7 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev,
|
|||
default:
|
||||
*out_ring = NULL;
|
||||
r = -EINVAL;
|
||||
DRM_ERROR("unknown HW IP type: %d\n", mapper->hw_ip);
|
||||
DRM_DEBUG("unknown HW IP type: %d\n", mapper->hw_ip);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
|
|
|
@ -79,8 +79,7 @@ struct amdgpu_fence_driver {
|
|||
|
||||
int amdgpu_fence_driver_init(struct amdgpu_device *adev);
|
||||
void amdgpu_fence_driver_fini(struct amdgpu_device *adev);
|
||||
void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev);
|
||||
void amdgpu_fence_driver_force_completion_ring(struct amdgpu_ring *ring);
|
||||
void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
|
||||
|
||||
int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
|
||||
unsigned num_hw_submission);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
struct amdgpu_sync_entry {
|
||||
struct hlist_node node;
|
||||
struct dma_fence *fence;
|
||||
bool explicit;
|
||||
};
|
||||
|
||||
static struct kmem_cache *amdgpu_sync_slab;
|
||||
|
@ -141,7 +142,7 @@ static bool amdgpu_sync_add_later(struct amdgpu_sync *sync, struct dma_fence *f)
|
|||
*
|
||||
*/
|
||||
int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
|
||||
struct dma_fence *f)
|
||||
struct dma_fence *f, bool explicit)
|
||||
{
|
||||
struct amdgpu_sync_entry *e;
|
||||
|
||||
|
@ -159,6 +160,8 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
|
|||
if (!e)
|
||||
return -ENOMEM;
|
||||
|
||||
e->explicit = explicit;
|
||||
|
||||
hash_add(sync->fences, &e->node, f->context);
|
||||
e->fence = dma_fence_get(f);
|
||||
return 0;
|
||||
|
@ -189,10 +192,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
|
|||
|
||||
/* always sync to the exclusive fence */
|
||||
f = reservation_object_get_excl(resv);
|
||||
r = amdgpu_sync_fence(adev, sync, f);
|
||||
|
||||
if (explicit_sync)
|
||||
return r;
|
||||
r = amdgpu_sync_fence(adev, sync, f, false);
|
||||
|
||||
flist = reservation_object_get_list(resv);
|
||||
if (!flist || r)
|
||||
|
@ -212,15 +212,15 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
|
|||
(fence_owner == AMDGPU_FENCE_OWNER_VM)))
|
||||
continue;
|
||||
|
||||
/* Ignore fence from the same owner as
|
||||
/* Ignore fence from the same owner and explicit one as
|
||||
* long as it isn't undefined.
|
||||
*/
|
||||
if (owner != AMDGPU_FENCE_OWNER_UNDEFINED &&
|
||||
fence_owner == owner)
|
||||
(fence_owner == owner || explicit_sync))
|
||||
continue;
|
||||
}
|
||||
|
||||
r = amdgpu_sync_fence(adev, sync, f);
|
||||
r = amdgpu_sync_fence(adev, sync, f, false);
|
||||
if (r)
|
||||
break;
|
||||
}
|
||||
|
@ -275,19 +275,21 @@ struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
|
|||
* amdgpu_sync_get_fence - get the next fence from the sync object
|
||||
*
|
||||
* @sync: sync object to use
|
||||
* @explicit: true if the next fence is explicit
|
||||
*
|
||||
* Get and removes the next fence from the sync object not signaled yet.
|
||||
*/
|
||||
struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync)
|
||||
struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync, bool *explicit)
|
||||
{
|
||||
struct amdgpu_sync_entry *e;
|
||||
struct hlist_node *tmp;
|
||||
struct dma_fence *f;
|
||||
int i;
|
||||
|
||||
hash_for_each_safe(sync->fences, i, tmp, e, node) {
|
||||
|
||||
f = e->fence;
|
||||
if (explicit)
|
||||
*explicit = e->explicit;
|
||||
|
||||
hash_del(&e->node);
|
||||
kmem_cache_free(amdgpu_sync_slab, e);
|
||||
|
|
|
@ -41,7 +41,7 @@ struct amdgpu_sync {
|
|||
|
||||
void amdgpu_sync_create(struct amdgpu_sync *sync);
|
||||
int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
|
||||
struct dma_fence *f);
|
||||
struct dma_fence *f, bool explicit);
|
||||
int amdgpu_sync_resv(struct amdgpu_device *adev,
|
||||
struct amdgpu_sync *sync,
|
||||
struct reservation_object *resv,
|
||||
|
@ -49,7 +49,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
|
|||
bool explicit_sync);
|
||||
struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
|
||||
struct amdgpu_ring *ring);
|
||||
struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync);
|
||||
struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync, bool *explicit);
|
||||
int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr);
|
||||
void amdgpu_sync_free(struct amdgpu_sync *sync);
|
||||
int amdgpu_sync_init(void);
|
||||
|
|
|
@ -110,7 +110,7 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev)
|
|||
ring = adev->mman.buffer_funcs_ring;
|
||||
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_KERNEL];
|
||||
r = amd_sched_entity_init(&ring->sched, &adev->mman.entity,
|
||||
rq, amdgpu_sched_jobs);
|
||||
rq, amdgpu_sched_jobs, NULL);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed setting up TTM BO move run queue.\n");
|
||||
goto error_entity;
|
||||
|
@ -282,8 +282,7 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
|
|||
{
|
||||
uint64_t addr = 0;
|
||||
|
||||
if (mem->mem_type != TTM_PL_TT ||
|
||||
amdgpu_gtt_mgr_is_allocated(mem)) {
|
||||
if (mem->mem_type != TTM_PL_TT || amdgpu_gtt_mgr_has_gart_addr(mem)) {
|
||||
addr = mm_node->start << PAGE_SHIFT;
|
||||
addr += bo->bdev->man[mem->mem_type].gpu_offset;
|
||||
}
|
||||
|
@ -369,7 +368,7 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
|||
* dst to window 1
|
||||
*/
|
||||
if (src->mem->mem_type == TTM_PL_TT &&
|
||||
!amdgpu_gtt_mgr_is_allocated(src->mem)) {
|
||||
!amdgpu_gtt_mgr_has_gart_addr(src->mem)) {
|
||||
r = amdgpu_map_buffer(src->bo, src->mem,
|
||||
PFN_UP(cur_size + src_page_offset),
|
||||
src_node_start, 0, ring,
|
||||
|
@ -383,7 +382,7 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
|
|||
}
|
||||
|
||||
if (dst->mem->mem_type == TTM_PL_TT &&
|
||||
!amdgpu_gtt_mgr_is_allocated(dst->mem)) {
|
||||
!amdgpu_gtt_mgr_has_gart_addr(dst->mem)) {
|
||||
r = amdgpu_map_buffer(dst->bo, dst->mem,
|
||||
PFN_UP(cur_size + dst_page_offset),
|
||||
dst_node_start, 1, ring,
|
||||
|
@ -467,9 +466,8 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
|
|||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo,
|
||||
bool evict, bool interruptible,
|
||||
bool no_wait_gpu,
|
||||
static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict,
|
||||
struct ttm_operation_ctx *ctx,
|
||||
struct ttm_mem_reg *new_mem)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
|
@ -489,8 +487,7 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo,
|
|||
placements.fpfn = 0;
|
||||
placements.lpfn = 0;
|
||||
placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
|
||||
r = ttm_bo_mem_space(bo, &placement, &tmp_mem,
|
||||
interruptible, no_wait_gpu);
|
||||
r = ttm_bo_mem_space(bo, &placement, &tmp_mem, ctx);
|
||||
if (unlikely(r)) {
|
||||
return r;
|
||||
}
|
||||
|
@ -504,19 +501,18 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo,
|
|||
if (unlikely(r)) {
|
||||
goto out_cleanup;
|
||||
}
|
||||
r = amdgpu_move_blit(bo, true, no_wait_gpu, &tmp_mem, old_mem);
|
||||
r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, &tmp_mem, old_mem);
|
||||
if (unlikely(r)) {
|
||||
goto out_cleanup;
|
||||
}
|
||||
r = ttm_bo_move_ttm(bo, interruptible, no_wait_gpu, new_mem);
|
||||
r = ttm_bo_move_ttm(bo, ctx->interruptible, ctx->no_wait_gpu, new_mem);
|
||||
out_cleanup:
|
||||
ttm_bo_mem_put(bo, &tmp_mem);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo,
|
||||
bool evict, bool interruptible,
|
||||
bool no_wait_gpu,
|
||||
static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict,
|
||||
struct ttm_operation_ctx *ctx,
|
||||
struct ttm_mem_reg *new_mem)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
|
@ -536,16 +532,15 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo,
|
|||
placements.fpfn = 0;
|
||||
placements.lpfn = 0;
|
||||
placements.flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
|
||||
r = ttm_bo_mem_space(bo, &placement, &tmp_mem,
|
||||
interruptible, no_wait_gpu);
|
||||
r = ttm_bo_mem_space(bo, &placement, &tmp_mem, ctx);
|
||||
if (unlikely(r)) {
|
||||
return r;
|
||||
}
|
||||
r = ttm_bo_move_ttm(bo, interruptible, no_wait_gpu, &tmp_mem);
|
||||
r = ttm_bo_move_ttm(bo, ctx->interruptible, ctx->no_wait_gpu, &tmp_mem);
|
||||
if (unlikely(r)) {
|
||||
goto out_cleanup;
|
||||
}
|
||||
r = amdgpu_move_blit(bo, true, no_wait_gpu, new_mem, old_mem);
|
||||
r = amdgpu_move_blit(bo, true, ctx->no_wait_gpu, new_mem, old_mem);
|
||||
if (unlikely(r)) {
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
@ -554,10 +549,9 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo,
|
|||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_bo_move(struct ttm_buffer_object *bo,
|
||||
bool evict, bool interruptible,
|
||||
bool no_wait_gpu,
|
||||
struct ttm_mem_reg *new_mem)
|
||||
static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
||||
struct ttm_operation_ctx *ctx,
|
||||
struct ttm_mem_reg *new_mem)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct amdgpu_bo *abo;
|
||||
|
@ -592,19 +586,19 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo,
|
|||
|
||||
if (old_mem->mem_type == TTM_PL_VRAM &&
|
||||
new_mem->mem_type == TTM_PL_SYSTEM) {
|
||||
r = amdgpu_move_vram_ram(bo, evict, interruptible,
|
||||
no_wait_gpu, new_mem);
|
||||
r = amdgpu_move_vram_ram(bo, evict, ctx, new_mem);
|
||||
} else if (old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
new_mem->mem_type == TTM_PL_VRAM) {
|
||||
r = amdgpu_move_ram_vram(bo, evict, interruptible,
|
||||
no_wait_gpu, new_mem);
|
||||
r = amdgpu_move_ram_vram(bo, evict, ctx, new_mem);
|
||||
} else {
|
||||
r = amdgpu_move_blit(bo, evict, no_wait_gpu, new_mem, old_mem);
|
||||
r = amdgpu_move_blit(bo, evict, ctx->no_wait_gpu,
|
||||
new_mem, old_mem);
|
||||
}
|
||||
|
||||
if (r) {
|
||||
memcpy:
|
||||
r = ttm_bo_move_memcpy(bo, interruptible, no_wait_gpu, new_mem);
|
||||
r = ttm_bo_move_memcpy(bo, ctx->interruptible,
|
||||
ctx->no_wait_gpu, new_mem);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
|
@ -690,7 +684,6 @@ struct amdgpu_ttm_tt {
|
|||
struct list_head guptasks;
|
||||
atomic_t mmu_invalidations;
|
||||
uint32_t last_set_pages;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
|
||||
|
@ -861,44 +854,35 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
|
|||
bo_mem->mem_type == AMDGPU_PL_OA)
|
||||
return -EINVAL;
|
||||
|
||||
if (!amdgpu_gtt_mgr_is_allocated(bo_mem))
|
||||
if (!amdgpu_gtt_mgr_has_gart_addr(bo_mem)) {
|
||||
gtt->offset = AMDGPU_BO_INVALID_OFFSET;
|
||||
return 0;
|
||||
}
|
||||
|
||||
spin_lock(>t->adev->gtt_list_lock);
|
||||
flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem);
|
||||
gtt->offset = (u64)bo_mem->start << PAGE_SHIFT;
|
||||
r = amdgpu_gart_bind(gtt->adev, gtt->offset, ttm->num_pages,
|
||||
ttm->pages, gtt->ttm.dma_address, flags);
|
||||
|
||||
if (r) {
|
||||
if (r)
|
||||
DRM_ERROR("failed to bind %lu pages at 0x%08llX\n",
|
||||
ttm->num_pages, gtt->offset);
|
||||
goto error_gart_bind;
|
||||
}
|
||||
|
||||
list_add_tail(>t->list, >t->adev->gtt_list);
|
||||
error_gart_bind:
|
||||
spin_unlock(>t->adev->gtt_list_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
bool amdgpu_ttm_is_bound(struct ttm_tt *ttm)
|
||||
{
|
||||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||
|
||||
return gtt && !list_empty(>t->list);
|
||||
}
|
||||
|
||||
int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem)
|
||||
int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
|
||||
struct ttm_tt *ttm = bo->ttm;
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
struct amdgpu_ttm_tt *gtt = (void*)bo->ttm;
|
||||
struct ttm_mem_reg tmp;
|
||||
struct ttm_placement placement;
|
||||
struct ttm_place placements;
|
||||
uint64_t flags;
|
||||
int r;
|
||||
|
||||
if (!ttm || amdgpu_ttm_is_bound(ttm))
|
||||
if (bo->mem.mem_type != TTM_PL_TT ||
|
||||
amdgpu_gtt_mgr_has_gart_addr(&bo->mem))
|
||||
return 0;
|
||||
|
||||
tmp = bo->mem;
|
||||
|
@ -912,43 +896,44 @@ int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem)
|
|||
placements.flags = (bo->mem.placement & ~TTM_PL_MASK_MEM) |
|
||||
TTM_PL_FLAG_TT;
|
||||
|
||||
r = ttm_bo_mem_space(bo, &placement, &tmp, true, false);
|
||||
r = ttm_bo_mem_space(bo, &placement, &tmp, &ctx);
|
||||
if (unlikely(r))
|
||||
return r;
|
||||
|
||||
r = ttm_bo_move_ttm(bo, true, false, &tmp);
|
||||
if (unlikely(r))
|
||||
flags = amdgpu_ttm_tt_pte_flags(adev, bo->ttm, &tmp);
|
||||
gtt->offset = (u64)tmp.start << PAGE_SHIFT;
|
||||
r = amdgpu_gart_bind(adev, gtt->offset, bo->ttm->num_pages,
|
||||
bo->ttm->pages, gtt->ttm.dma_address, flags);
|
||||
if (unlikely(r)) {
|
||||
ttm_bo_mem_put(bo, &tmp);
|
||||
else
|
||||
bo->offset = (bo->mem.start << PAGE_SHIFT) +
|
||||
bo->bdev->man[bo->mem.mem_type].gpu_offset;
|
||||
return r;
|
||||
}
|
||||
|
||||
return r;
|
||||
ttm_bo_mem_put(bo, &bo->mem);
|
||||
bo->mem = tmp;
|
||||
bo->offset = (bo->mem.start << PAGE_SHIFT) +
|
||||
bo->bdev->man[bo->mem.mem_type].gpu_offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_ttm_recover_gart(struct amdgpu_device *adev)
|
||||
int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo)
|
||||
{
|
||||
struct amdgpu_ttm_tt *gtt, *tmp;
|
||||
struct ttm_mem_reg bo_mem;
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
|
||||
struct amdgpu_ttm_tt *gtt = (void *)tbo->ttm;
|
||||
uint64_t flags;
|
||||
int r;
|
||||
|
||||
bo_mem.mem_type = TTM_PL_TT;
|
||||
spin_lock(&adev->gtt_list_lock);
|
||||
list_for_each_entry_safe(gtt, tmp, &adev->gtt_list, list) {
|
||||
flags = amdgpu_ttm_tt_pte_flags(gtt->adev, >t->ttm.ttm, &bo_mem);
|
||||
r = amdgpu_gart_bind(adev, gtt->offset, gtt->ttm.ttm.num_pages,
|
||||
gtt->ttm.ttm.pages, gtt->ttm.dma_address,
|
||||
flags);
|
||||
if (r) {
|
||||
spin_unlock(&adev->gtt_list_lock);
|
||||
DRM_ERROR("failed to bind %lu pages at 0x%08llX\n",
|
||||
gtt->ttm.ttm.num_pages, gtt->offset);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
spin_unlock(&adev->gtt_list_lock);
|
||||
return 0;
|
||||
if (!gtt)
|
||||
return 0;
|
||||
|
||||
flags = amdgpu_ttm_tt_pte_flags(adev, >t->ttm.ttm, &tbo->mem);
|
||||
r = amdgpu_gart_bind(adev, gtt->offset, gtt->ttm.ttm.num_pages,
|
||||
gtt->ttm.ttm.pages, gtt->ttm.dma_address, flags);
|
||||
if (r)
|
||||
DRM_ERROR("failed to bind %lu pages at 0x%08llX\n",
|
||||
gtt->ttm.ttm.num_pages, gtt->offset);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_ttm_backend_unbind(struct ttm_tt *ttm)
|
||||
|
@ -959,20 +944,14 @@ static int amdgpu_ttm_backend_unbind(struct ttm_tt *ttm)
|
|||
if (gtt->userptr)
|
||||
amdgpu_ttm_tt_unpin_userptr(ttm);
|
||||
|
||||
if (!amdgpu_ttm_is_bound(ttm))
|
||||
if (gtt->offset == AMDGPU_BO_INVALID_OFFSET)
|
||||
return 0;
|
||||
|
||||
/* unbind shouldn't be done for GDS/GWS/OA in ttm_bo_clean_mm */
|
||||
spin_lock(>t->adev->gtt_list_lock);
|
||||
r = amdgpu_gart_unbind(gtt->adev, gtt->offset, ttm->num_pages);
|
||||
if (r) {
|
||||
if (r)
|
||||
DRM_ERROR("failed to unbind %lu pages at 0x%08llX\n",
|
||||
gtt->ttm.ttm.num_pages, gtt->offset);
|
||||
goto error_unbind;
|
||||
}
|
||||
list_del_init(>t->list);
|
||||
error_unbind:
|
||||
spin_unlock(>t->adev->gtt_list_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -1009,7 +988,6 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_bo_device *bdev,
|
|||
kfree(gtt);
|
||||
return NULL;
|
||||
}
|
||||
INIT_LIST_HEAD(>t->list);
|
||||
return >t->ttm.ttm;
|
||||
}
|
||||
|
||||
|
@ -1348,10 +1326,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
|||
DRM_INFO("amdgpu: %uM of VRAM memory ready\n",
|
||||
(unsigned) (adev->mc.real_vram_size / (1024 * 1024)));
|
||||
|
||||
if (amdgpu_gtt_size == -1)
|
||||
gtt_size = max((AMDGPU_DEFAULT_GTT_SIZE_MB << 20),
|
||||
adev->mc.mc_vram_size);
|
||||
else
|
||||
if (amdgpu_gtt_size == -1) {
|
||||
struct sysinfo si;
|
||||
|
||||
si_meminfo(&si);
|
||||
gtt_size = max(AMDGPU_DEFAULT_GTT_SIZE_MB << 20,
|
||||
(uint64_t)si.totalram * si.mem_unit * 3/4);
|
||||
} else
|
||||
gtt_size = (uint64_t)amdgpu_gtt_size << 20;
|
||||
r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT);
|
||||
if (r) {
|
||||
|
@ -1410,19 +1391,13 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
|
|||
|
||||
void amdgpu_ttm_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!adev->mman.initialized)
|
||||
return;
|
||||
|
||||
amdgpu_ttm_debugfs_fini(adev);
|
||||
if (adev->stolen_vga_memory) {
|
||||
r = amdgpu_bo_reserve(adev->stolen_vga_memory, true);
|
||||
if (r == 0) {
|
||||
amdgpu_bo_unpin(adev->stolen_vga_memory);
|
||||
amdgpu_bo_unreserve(adev->stolen_vga_memory);
|
||||
}
|
||||
amdgpu_bo_unref(&adev->stolen_vga_memory);
|
||||
}
|
||||
amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, NULL);
|
||||
amdgpu_fw_reserve_vram_fini(adev);
|
||||
|
||||
ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_VRAM);
|
||||
ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_TT);
|
||||
if (adev->gds.mem.total_size)
|
||||
|
@ -1432,7 +1407,6 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
|
|||
if (adev->gds.oa.total_size)
|
||||
ttm_bo_clean_mm(&adev->mman.bdev, AMDGPU_PL_OA);
|
||||
ttm_bo_device_release(&adev->mman.bdev);
|
||||
amdgpu_gart_fini(adev);
|
||||
amdgpu_ttm_global_fini(adev);
|
||||
adev->mman.initialized = false;
|
||||
DRM_INFO("amdgpu: ttm finalized\n");
|
||||
|
@ -1628,7 +1602,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
|
|||
}
|
||||
|
||||
if (bo->tbo.mem.mem_type == TTM_PL_TT) {
|
||||
r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem);
|
||||
r = amdgpu_ttm_alloc_gart(&bo->tbo);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -67,8 +67,9 @@ struct amdgpu_copy_mem {
|
|||
extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func;
|
||||
extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func;
|
||||
|
||||
bool amdgpu_gtt_mgr_is_allocated(struct ttm_mem_reg *mem);
|
||||
bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_mem_reg *mem);
|
||||
uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man);
|
||||
int amdgpu_gtt_mgr_recover(struct ttm_mem_type_manager *man);
|
||||
|
||||
uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man);
|
||||
uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man);
|
||||
|
@ -90,9 +91,8 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
|
|||
struct dma_fence **fence);
|
||||
|
||||
int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
|
||||
bool amdgpu_ttm_is_bound(struct ttm_tt *ttm);
|
||||
int amdgpu_ttm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *bo_mem);
|
||||
int amdgpu_ttm_recover_gart(struct amdgpu_device *adev);
|
||||
int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);
|
||||
int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
|
||||
|
||||
int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages);
|
||||
void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages);
|
||||
|
|
|
@ -359,7 +359,6 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode,
|
|||
|
||||
int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_bo **bo = &adev->firmware.fw_buf;
|
||||
uint64_t fw_offset = 0;
|
||||
int i, err;
|
||||
struct amdgpu_firmware_info *ucode = NULL;
|
||||
|
@ -370,36 +369,16 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!amdgpu_sriov_vf(adev) || !adev->in_sriov_reset) {
|
||||
err = amdgpu_bo_create(adev, adev->firmware.fw_size, PAGE_SIZE, true,
|
||||
if (!adev->in_gpu_reset) {
|
||||
err = amdgpu_bo_create_kernel(adev, adev->firmware.fw_size, PAGE_SIZE,
|
||||
amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
|
||||
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
|
||||
NULL, NULL, 0, bo);
|
||||
&adev->firmware.fw_buf,
|
||||
&adev->firmware.fw_buf_mc,
|
||||
&adev->firmware.fw_buf_ptr);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "(%d) Firmware buffer allocate failed\n", err);
|
||||
dev_err(adev->dev, "failed to create kernel buffer for firmware.fw_buf\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
err = amdgpu_bo_reserve(*bo, false);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "(%d) Firmware buffer reserve failed\n", err);
|
||||
goto failed_reserve;
|
||||
}
|
||||
|
||||
err = amdgpu_bo_pin(*bo, amdgpu_sriov_vf(adev) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT,
|
||||
&adev->firmware.fw_buf_mc);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "(%d) Firmware buffer pin failed\n", err);
|
||||
goto failed_pin;
|
||||
}
|
||||
|
||||
err = amdgpu_bo_kmap(*bo, &adev->firmware.fw_buf_ptr);
|
||||
if (err) {
|
||||
dev_err(adev->dev, "(%d) Firmware buffer kmap failed\n", err);
|
||||
goto failed_kmap;
|
||||
}
|
||||
|
||||
amdgpu_bo_unreserve(*bo);
|
||||
}
|
||||
|
||||
memset(adev->firmware.fw_buf_ptr, 0, adev->firmware.fw_size);
|
||||
|
@ -436,12 +415,6 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev)
|
|||
}
|
||||
return 0;
|
||||
|
||||
failed_kmap:
|
||||
amdgpu_bo_unpin(*bo);
|
||||
failed_pin:
|
||||
amdgpu_bo_unreserve(*bo);
|
||||
failed_reserve:
|
||||
amdgpu_bo_unref(bo);
|
||||
failed:
|
||||
if (err)
|
||||
adev->firmware.load_type = AMDGPU_FW_LOAD_DIRECT;
|
||||
|
@ -464,8 +437,10 @@ int amdgpu_ucode_fini_bo(struct amdgpu_device *adev)
|
|||
ucode->kaddr = NULL;
|
||||
}
|
||||
}
|
||||
amdgpu_bo_unref(&adev->firmware.fw_buf);
|
||||
adev->firmware.fw_buf = NULL;
|
||||
|
||||
amdgpu_bo_free_kernel(&adev->firmware.fw_buf,
|
||||
&adev->firmware.fw_buf_mc,
|
||||
&adev->firmware.fw_buf_ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -232,7 +232,7 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev)
|
|||
ring = &adev->uvd.ring;
|
||||
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL];
|
||||
r = amd_sched_entity_init(&ring->sched, &adev->uvd.entity,
|
||||
rq, amdgpu_sched_jobs);
|
||||
rq, amdgpu_sched_jobs, NULL);
|
||||
if (r != 0) {
|
||||
DRM_ERROR("Failed setting up UVD run queue.\n");
|
||||
return r;
|
||||
|
@ -408,6 +408,7 @@ static u64 amdgpu_uvd_get_addr_from_ctx(struct amdgpu_uvd_cs_ctx *ctx)
|
|||
*/
|
||||
static int amdgpu_uvd_cs_pass1(struct amdgpu_uvd_cs_ctx *ctx)
|
||||
{
|
||||
struct ttm_operation_ctx tctx = { false, false };
|
||||
struct amdgpu_bo_va_mapping *mapping;
|
||||
struct amdgpu_bo *bo;
|
||||
uint32_t cmd;
|
||||
|
@ -430,7 +431,7 @@ static int amdgpu_uvd_cs_pass1(struct amdgpu_uvd_cs_ctx *ctx)
|
|||
}
|
||||
amdgpu_uvd_force_into_uvd_segment(bo);
|
||||
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &tctx);
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -949,6 +950,7 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx)
|
|||
static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
||||
bool direct, struct dma_fence **fence)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = { true, false };
|
||||
struct ttm_validate_buffer tv;
|
||||
struct ww_acquire_ctx ticket;
|
||||
struct list_head head;
|
||||
|
@ -975,7 +977,7 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
|||
amdgpu_uvd_force_into_uvd_segment(bo);
|
||||
}
|
||||
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
@ -1218,7 +1220,7 @@ int amdgpu_uvd_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
} else if (r < 0) {
|
||||
DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
|
||||
} else {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
#define AMDGPU_UVD_SESSION_SIZE (50*1024)
|
||||
#define AMDGPU_UVD_FIRMWARE_OFFSET 256
|
||||
|
||||
#define AMDGPU_UVD_FIRMWARE_SIZE(adev) \
|
||||
(AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(((const struct common_firmware_header *)(adev)->uvd.fw->data)->ucode_size_bytes) + \
|
||||
8) - AMDGPU_UVD_FIRMWARE_OFFSET)
|
||||
|
||||
struct amdgpu_uvd {
|
||||
struct amdgpu_bo *vcpu_bo;
|
||||
void *cpu_addr;
|
||||
|
|
|
@ -176,7 +176,7 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
|
|||
ring = &adev->vce.ring[0];
|
||||
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL];
|
||||
r = amd_sched_entity_init(&ring->sched, &adev->vce.entity,
|
||||
rq, amdgpu_sched_jobs);
|
||||
rq, amdgpu_sched_jobs, NULL);
|
||||
if (r != 0) {
|
||||
DRM_ERROR("Failed setting up VCE run queue.\n");
|
||||
return r;
|
||||
|
@ -543,6 +543,55 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
|
|||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vce_cs_validate_bo - make sure not to cross 4GB boundary
|
||||
*
|
||||
* @p: parser context
|
||||
* @lo: address of lower dword
|
||||
* @hi: address of higher dword
|
||||
* @size: minimum size
|
||||
* @index: bs/fb index
|
||||
*
|
||||
* Make sure that no BO cross a 4GB boundary.
|
||||
*/
|
||||
static int amdgpu_vce_validate_bo(struct amdgpu_cs_parser *p, uint32_t ib_idx,
|
||||
int lo, int hi, unsigned size, int32_t index)
|
||||
{
|
||||
int64_t offset = ((uint64_t)size) * ((int64_t)index);
|
||||
struct ttm_operation_ctx ctx = { false, false };
|
||||
struct amdgpu_bo_va_mapping *mapping;
|
||||
unsigned i, fpfn, lpfn;
|
||||
struct amdgpu_bo *bo;
|
||||
uint64_t addr;
|
||||
int r;
|
||||
|
||||
addr = ((uint64_t)amdgpu_get_ib_value(p, ib_idx, lo)) |
|
||||
((uint64_t)amdgpu_get_ib_value(p, ib_idx, hi)) << 32;
|
||||
if (index >= 0) {
|
||||
addr += offset;
|
||||
fpfn = PAGE_ALIGN(offset) >> PAGE_SHIFT;
|
||||
lpfn = 0x100000000ULL >> PAGE_SHIFT;
|
||||
} else {
|
||||
fpfn = 0;
|
||||
lpfn = (0x100000000ULL - PAGE_ALIGN(offset)) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
r = amdgpu_cs_find_mapping(p, addr, &bo, &mapping);
|
||||
if (r) {
|
||||
DRM_ERROR("Can't find BO for addr 0x%010Lx %d %d %d %d\n",
|
||||
addr, lo, hi, size, index);
|
||||
return r;
|
||||
}
|
||||
|
||||
for (i = 0; i < bo->placement.num_placement; ++i) {
|
||||
bo->placements[i].fpfn = max(bo->placements[i].fpfn, fpfn);
|
||||
bo->placements[i].lpfn = bo->placements[i].fpfn ?
|
||||
min(bo->placements[i].fpfn, lpfn) : lpfn;
|
||||
}
|
||||
return ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* amdgpu_vce_cs_reloc - command submission relocation
|
||||
*
|
||||
|
@ -648,12 +697,13 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
|
|||
uint32_t allocated = 0;
|
||||
uint32_t tmp, handle = 0;
|
||||
uint32_t *size = &tmp;
|
||||
int i, r = 0, idx = 0;
|
||||
unsigned idx;
|
||||
int i, r = 0;
|
||||
|
||||
p->job->vm = NULL;
|
||||
ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo);
|
||||
|
||||
while (idx < ib->length_dw) {
|
||||
for (idx = 0; idx < ib->length_dw;) {
|
||||
uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
|
||||
uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
|
||||
|
||||
|
@ -663,6 +713,54 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
|
|||
goto out;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case 0x00000002: /* task info */
|
||||
fb_idx = amdgpu_get_ib_value(p, ib_idx, idx + 6);
|
||||
bs_idx = amdgpu_get_ib_value(p, ib_idx, idx + 7);
|
||||
break;
|
||||
|
||||
case 0x03000001: /* encode */
|
||||
r = amdgpu_vce_validate_bo(p, ib_idx, idx + 10,
|
||||
idx + 9, 0, 0);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
r = amdgpu_vce_validate_bo(p, ib_idx, idx + 12,
|
||||
idx + 11, 0, 0);
|
||||
if (r)
|
||||
goto out;
|
||||
break;
|
||||
|
||||
case 0x05000001: /* context buffer */
|
||||
r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3,
|
||||
idx + 2, 0, 0);
|
||||
if (r)
|
||||
goto out;
|
||||
break;
|
||||
|
||||
case 0x05000004: /* video bitstream buffer */
|
||||
tmp = amdgpu_get_ib_value(p, ib_idx, idx + 4);
|
||||
r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3, idx + 2,
|
||||
tmp, bs_idx);
|
||||
if (r)
|
||||
goto out;
|
||||
break;
|
||||
|
||||
case 0x05000005: /* feedback buffer */
|
||||
r = amdgpu_vce_validate_bo(p, ib_idx, idx + 3, idx + 2,
|
||||
4096, fb_idx);
|
||||
if (r)
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
||||
idx += len / 4;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < ib->length_dw;) {
|
||||
uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
|
||||
uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1);
|
||||
|
||||
switch (cmd) {
|
||||
case 0x00000001: /* session */
|
||||
handle = amdgpu_get_ib_value(p, ib_idx, idx + 2);
|
||||
|
@ -954,7 +1052,7 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed\n",
|
||||
|
@ -999,7 +1097,7 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
} else if (r < 0) {
|
||||
DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
|
||||
} else {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
}
|
||||
error:
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
#include "soc15d.h"
|
||||
#include "soc15_common.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "raven1/VCN/vcn_1_0_offset.h"
|
||||
#include "soc15ip.h"
|
||||
#include "vcn/vcn_1_0_offset.h"
|
||||
|
||||
/* 1 second timeout */
|
||||
#define VCN_IDLE_TIMEOUT msecs_to_jiffies(1000)
|
||||
|
@ -106,7 +106,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||
ring = &adev->vcn.ring_dec;
|
||||
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL];
|
||||
r = amd_sched_entity_init(&ring->sched, &adev->vcn.entity_dec,
|
||||
rq, amdgpu_sched_jobs);
|
||||
rq, amdgpu_sched_jobs, NULL);
|
||||
if (r != 0) {
|
||||
DRM_ERROR("Failed setting up VCN dec run queue.\n");
|
||||
return r;
|
||||
|
@ -115,7 +115,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
|
|||
ring = &adev->vcn.ring_enc[0];
|
||||
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL];
|
||||
r = amd_sched_entity_init(&ring->sched, &adev->vcn.entity_enc,
|
||||
rq, amdgpu_sched_jobs);
|
||||
rq, amdgpu_sched_jobs, NULL);
|
||||
if (r != 0) {
|
||||
DRM_ERROR("Failed setting up VCN enc run queue.\n");
|
||||
return r;
|
||||
|
@ -261,7 +261,7 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
|
||||
|
@ -274,6 +274,7 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
|
|||
static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo,
|
||||
bool direct, struct dma_fence **fence)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = { true, false };
|
||||
struct ttm_validate_buffer tv;
|
||||
struct ww_acquire_ctx ticket;
|
||||
struct list_head head;
|
||||
|
@ -294,7 +295,7 @@ static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *b
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
|
@ -467,7 +468,7 @@ int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
} else if (r < 0) {
|
||||
DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
|
||||
} else {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
}
|
||||
|
||||
|
@ -500,7 +501,7 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed\n",
|
||||
|
@ -643,7 +644,7 @@ int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
} else if (r < 0) {
|
||||
DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
|
||||
} else {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
}
|
||||
error:
|
||||
|
|
|
@ -24,6 +24,14 @@
|
|||
#include "amdgpu.h"
|
||||
#define MAX_KIQ_REG_WAIT 100000000 /* in usecs */
|
||||
|
||||
bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev)
|
||||
{
|
||||
/* By now all MMIO pages except mailbox are blocked */
|
||||
/* if blocking is enabled in hypervisor. Choose the */
|
||||
/* SCRATCH_REG0 to test. */
|
||||
return RREG32_NO_KIQ(0xc040) == 0xffffffff;
|
||||
}
|
||||
|
||||
int amdgpu_allocate_static_csa(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
@ -39,6 +47,12 @@ int amdgpu_allocate_static_csa(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void amdgpu_free_static_csa(struct amdgpu_device *adev) {
|
||||
amdgpu_bo_free_kernel(&adev->virt.csa_obj,
|
||||
&adev->virt.csa_vmid0_addr,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* amdgpu_map_static_csa should be called during amdgpu_vm_init
|
||||
* it maps virtual address "AMDGPU_VA_RESERVED_SIZE - AMDGPU_CSA_SIZE"
|
||||
|
@ -107,8 +121,6 @@ void amdgpu_virt_init_setting(struct amdgpu_device *adev)
|
|||
adev->enable_virtual_display = true;
|
||||
adev->cg_flags = 0;
|
||||
adev->pg_flags = 0;
|
||||
|
||||
mutex_init(&adev->virt.lock_reset);
|
||||
}
|
||||
|
||||
uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
|
||||
|
@ -227,6 +239,22 @@ int amdgpu_virt_reset_gpu(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_virt_wait_reset() - wait for reset gpu completed
|
||||
* @amdgpu: amdgpu device.
|
||||
* Wait for GPU reset completed.
|
||||
* Return: Zero if reset success, otherwise will return error.
|
||||
*/
|
||||
int amdgpu_virt_wait_reset(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_virt *virt = &adev->virt;
|
||||
|
||||
if (!virt->ops || !virt->ops->wait_reset)
|
||||
return -EINVAL;
|
||||
|
||||
return virt->ops->wait_reset(adev);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_virt_alloc_mm_table() - alloc memory for mm table
|
||||
* @amdgpu: amdgpu device.
|
||||
|
@ -296,7 +324,6 @@ int amdgpu_virt_fw_reserve_get_checksum(void *obj,
|
|||
|
||||
void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t pf2vf_ver = 0;
|
||||
uint32_t pf2vf_size = 0;
|
||||
uint32_t checksum = 0;
|
||||
uint32_t checkval;
|
||||
|
@ -309,9 +336,9 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev)
|
|||
adev->virt.fw_reserve.p_pf2vf =
|
||||
(struct amdgim_pf2vf_info_header *)(
|
||||
adev->fw_vram_usage.va + AMDGIM_DATAEXCHANGE_OFFSET);
|
||||
pf2vf_ver = adev->virt.fw_reserve.p_pf2vf->version;
|
||||
AMDGPU_FW_VRAM_PF2VF_READ(adev, header.size, &pf2vf_size);
|
||||
AMDGPU_FW_VRAM_PF2VF_READ(adev, checksum, &checksum);
|
||||
AMDGPU_FW_VRAM_PF2VF_READ(adev, feature_flags, &adev->virt.gim_feature);
|
||||
|
||||
/* pf2vf message must be in 4K */
|
||||
if (pf2vf_size > 0 && pf2vf_size < 4096) {
|
||||
|
|
|
@ -55,6 +55,7 @@ struct amdgpu_virt_ops {
|
|||
int (*req_full_gpu)(struct amdgpu_device *adev, bool init);
|
||||
int (*rel_full_gpu)(struct amdgpu_device *adev, bool init);
|
||||
int (*reset_gpu)(struct amdgpu_device *adev);
|
||||
int (*wait_reset)(struct amdgpu_device *adev);
|
||||
void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
|
||||
};
|
||||
|
||||
|
@ -80,6 +81,8 @@ enum AMDGIM_FEATURE_FLAG {
|
|||
AMDGIM_FEATURE_ERROR_LOG_COLLECT = 0x1,
|
||||
/* GIM supports feature of loading uCodes */
|
||||
AMDGIM_FEATURE_GIM_LOAD_UCODES = 0x2,
|
||||
/* VRAM LOST by GIM */
|
||||
AMDGIM_FEATURE_GIM_FLR_VRAMLOST = 0x4,
|
||||
};
|
||||
|
||||
struct amdgim_pf2vf_info_header {
|
||||
|
@ -238,7 +241,6 @@ struct amdgpu_virt {
|
|||
uint64_t csa_vmid0_addr;
|
||||
bool chained_ib_support;
|
||||
uint32_t reg_val_offs;
|
||||
struct mutex lock_reset;
|
||||
struct amdgpu_irq_src ack_irq;
|
||||
struct amdgpu_irq_src rcv_irq;
|
||||
struct work_struct flr_work;
|
||||
|
@ -246,6 +248,7 @@ struct amdgpu_virt {
|
|||
const struct amdgpu_virt_ops *ops;
|
||||
struct amdgpu_vf_error_buffer vf_errors;
|
||||
struct amdgpu_virt_fw_reserve fw_reserve;
|
||||
uint32_t gim_feature;
|
||||
};
|
||||
|
||||
#define AMDGPU_CSA_SIZE (8 * 1024)
|
||||
|
@ -276,16 +279,18 @@ static inline bool is_virtual_machine(void)
|
|||
}
|
||||
|
||||
struct amdgpu_vm;
|
||||
bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
|
||||
int amdgpu_allocate_static_csa(struct amdgpu_device *adev);
|
||||
int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
||||
struct amdgpu_bo_va **bo_va);
|
||||
void amdgpu_free_static_csa(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_init_setting(struct amdgpu_device *adev);
|
||||
uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
|
||||
void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
|
||||
int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init);
|
||||
int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init);
|
||||
int amdgpu_virt_reset_gpu(struct amdgpu_device *adev);
|
||||
int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job);
|
||||
int amdgpu_virt_wait_reset(struct amdgpu_device *adev);
|
||||
int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_free_mm_table(struct amdgpu_device *adev);
|
||||
int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size,
|
||||
|
|
|
@ -138,6 +138,24 @@ struct amdgpu_prt_cb {
|
|||
struct dma_fence_cb cb;
|
||||
};
|
||||
|
||||
/**
|
||||
* amdgpu_vm_level_shift - return the addr shift for each level
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Returns the number of bits the pfn needs to be right shifted for a level.
|
||||
*/
|
||||
static unsigned amdgpu_vm_level_shift(struct amdgpu_device *adev,
|
||||
unsigned level)
|
||||
{
|
||||
if (level != adev->vm_manager.num_level)
|
||||
return 9 * (adev->vm_manager.num_level - level - 1) +
|
||||
adev->vm_manager.block_size;
|
||||
else
|
||||
/* For the page tables on the leaves */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_num_entries - return the number of entries in a PD/PT
|
||||
*
|
||||
|
@ -148,17 +166,17 @@ struct amdgpu_prt_cb {
|
|||
static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev,
|
||||
unsigned level)
|
||||
{
|
||||
unsigned shift = amdgpu_vm_level_shift(adev, 0);
|
||||
|
||||
if (level == 0)
|
||||
/* For the root directory */
|
||||
return adev->vm_manager.max_pfn >>
|
||||
(adev->vm_manager.block_size *
|
||||
adev->vm_manager.num_level);
|
||||
else if (level == adev->vm_manager.num_level)
|
||||
return round_up(adev->vm_manager.max_pfn, 1 << shift) >> shift;
|
||||
else if (level != adev->vm_manager.num_level)
|
||||
/* Everything in between */
|
||||
return 512;
|
||||
else
|
||||
/* For the page tables on the leaves */
|
||||
return AMDGPU_VM_PTE_COUNT(adev);
|
||||
else
|
||||
/* Everything in between */
|
||||
return 1 << adev->vm_manager.block_size;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -288,8 +306,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
|
|||
uint64_t saddr, uint64_t eaddr,
|
||||
unsigned level)
|
||||
{
|
||||
unsigned shift = (adev->vm_manager.num_level - level) *
|
||||
adev->vm_manager.block_size;
|
||||
unsigned shift = amdgpu_vm_level_shift(adev, level);
|
||||
unsigned pt_idx, from, to;
|
||||
int r;
|
||||
u64 flags;
|
||||
|
@ -471,7 +488,7 @@ static int amdgpu_vm_grab_reserved_vmid_locked(struct amdgpu_vm *vm,
|
|||
id->pd_gpu_addr = 0;
|
||||
tmp = amdgpu_sync_peek_fence(&id->active, ring);
|
||||
if (tmp) {
|
||||
r = amdgpu_sync_fence(adev, sync, tmp);
|
||||
r = amdgpu_sync_fence(adev, sync, tmp, false);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +496,7 @@ static int amdgpu_vm_grab_reserved_vmid_locked(struct amdgpu_vm *vm,
|
|||
/* Good we can use this VMID. Remember this submission as
|
||||
* user of the VMID.
|
||||
*/
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence);
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
|
@ -566,7 +583,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
|||
}
|
||||
|
||||
|
||||
r = amdgpu_sync_fence(ring->adev, sync, &array->base);
|
||||
r = amdgpu_sync_fence(ring->adev, sync, &array->base, false);
|
||||
dma_fence_put(&array->base);
|
||||
if (r)
|
||||
goto error;
|
||||
|
@ -609,7 +626,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
|||
/* Good we can use this VMID. Remember this submission as
|
||||
* user of the VMID.
|
||||
*/
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence);
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
|
@ -629,7 +646,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
|||
id = idle;
|
||||
|
||||
/* Remember this submission as user of the VMID */
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence);
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
|
@ -1302,18 +1319,19 @@ void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr,
|
|||
struct amdgpu_vm_pt **entry,
|
||||
struct amdgpu_vm_pt **parent)
|
||||
{
|
||||
unsigned idx, level = p->adev->vm_manager.num_level;
|
||||
unsigned level = 0;
|
||||
|
||||
*parent = NULL;
|
||||
*entry = &p->vm->root;
|
||||
while ((*entry)->entries) {
|
||||
idx = addr >> (p->adev->vm_manager.block_size * level--);
|
||||
unsigned idx = addr >> amdgpu_vm_level_shift(p->adev, level++);
|
||||
|
||||
idx %= amdgpu_bo_size((*entry)->base.bo) / 8;
|
||||
*parent = *entry;
|
||||
*entry = &(*entry)->entries[idx];
|
||||
}
|
||||
|
||||
if (level)
|
||||
if (level != p->adev->vm_manager.num_level)
|
||||
*entry = NULL;
|
||||
}
|
||||
|
||||
|
@ -1639,7 +1657,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
|||
addr = 0;
|
||||
}
|
||||
|
||||
r = amdgpu_sync_fence(adev, &job->sync, exclusive);
|
||||
r = amdgpu_sync_fence(adev, &job->sync, exclusive, false);
|
||||
if (r)
|
||||
goto error_free;
|
||||
|
||||
|
@ -2555,48 +2573,58 @@ static uint32_t amdgpu_vm_get_block_size(uint64_t vm_size)
|
|||
return ((bits + 3) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_set_fragment_size - adjust fragment size in PTE
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @fragment_size_default: the default fragment size if it's set auto
|
||||
*/
|
||||
void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,
|
||||
uint32_t fragment_size_default)
|
||||
{
|
||||
if (amdgpu_vm_fragment_size == -1)
|
||||
adev->vm_manager.fragment_size = fragment_size_default;
|
||||
else
|
||||
adev->vm_manager.fragment_size = amdgpu_vm_fragment_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_adjust_size - adjust vm size, block size and fragment size
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @vm_size: the default vm size if it's set auto
|
||||
*/
|
||||
void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size,
|
||||
uint32_t fragment_size_default)
|
||||
void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size,
|
||||
uint32_t fragment_size_default, unsigned max_level,
|
||||
unsigned max_bits)
|
||||
{
|
||||
/* adjust vm size firstly */
|
||||
if (amdgpu_vm_size == -1)
|
||||
adev->vm_manager.vm_size = vm_size;
|
||||
else
|
||||
adev->vm_manager.vm_size = amdgpu_vm_size;
|
||||
uint64_t tmp;
|
||||
|
||||
/* block size depends on vm size */
|
||||
if (amdgpu_vm_block_size == -1)
|
||||
/* adjust vm size first */
|
||||
if (amdgpu_vm_size != -1) {
|
||||
unsigned max_size = 1 << (max_bits - 30);
|
||||
|
||||
vm_size = amdgpu_vm_size;
|
||||
if (vm_size > max_size) {
|
||||
dev_warn(adev->dev, "VM size (%d) too large, max is %u GB\n",
|
||||
amdgpu_vm_size, max_size);
|
||||
vm_size = max_size;
|
||||
}
|
||||
}
|
||||
|
||||
adev->vm_manager.max_pfn = (uint64_t)vm_size << 18;
|
||||
|
||||
tmp = roundup_pow_of_two(adev->vm_manager.max_pfn);
|
||||
if (amdgpu_vm_block_size != -1)
|
||||
tmp >>= amdgpu_vm_block_size - 9;
|
||||
tmp = DIV_ROUND_UP(fls64(tmp) - 1, 9) - 1;
|
||||
adev->vm_manager.num_level = min(max_level, (unsigned)tmp);
|
||||
|
||||
/* block size depends on vm size and hw setup*/
|
||||
if (amdgpu_vm_block_size != -1)
|
||||
adev->vm_manager.block_size =
|
||||
amdgpu_vm_get_block_size(adev->vm_manager.vm_size);
|
||||
min((unsigned)amdgpu_vm_block_size, max_bits
|
||||
- AMDGPU_GPU_PAGE_SHIFT
|
||||
- 9 * adev->vm_manager.num_level);
|
||||
else if (adev->vm_manager.num_level > 1)
|
||||
adev->vm_manager.block_size = 9;
|
||||
else
|
||||
adev->vm_manager.block_size = amdgpu_vm_block_size;
|
||||
adev->vm_manager.block_size = amdgpu_vm_get_block_size(tmp);
|
||||
|
||||
amdgpu_vm_set_fragment_size(adev, fragment_size_default);
|
||||
if (amdgpu_vm_fragment_size == -1)
|
||||
adev->vm_manager.fragment_size = fragment_size_default;
|
||||
else
|
||||
adev->vm_manager.fragment_size = amdgpu_vm_fragment_size;
|
||||
|
||||
DRM_INFO("vm size is %llu GB, block size is %u-bit, fragment size is %u-bit\n",
|
||||
adev->vm_manager.vm_size, adev->vm_manager.block_size,
|
||||
adev->vm_manager.fragment_size);
|
||||
DRM_INFO("vm size is %u GB, %u levels, block size is %u-bit, fragment size is %u-bit\n",
|
||||
vm_size, adev->vm_manager.num_level + 1,
|
||||
adev->vm_manager.block_size,
|
||||
adev->vm_manager.fragment_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2637,7 +2665,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
ring = adev->vm_manager.vm_pte_rings[ring_instance];
|
||||
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_KERNEL];
|
||||
r = amd_sched_entity_init(&ring->sched, &vm->entity,
|
||||
rq, amdgpu_sched_jobs);
|
||||
rq, amdgpu_sched_jobs, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -96,6 +96,19 @@ struct amdgpu_bo_list_entry;
|
|||
/* hardcode that limit for now */
|
||||
#define AMDGPU_VA_RESERVED_SIZE (8ULL << 20)
|
||||
|
||||
/* VA hole for 48bit addresses on Vega10 */
|
||||
#define AMDGPU_VA_HOLE_START 0x0000800000000000ULL
|
||||
#define AMDGPU_VA_HOLE_END 0xffff800000000000ULL
|
||||
|
||||
/*
|
||||
* Hardware is programmed as if the hole doesn't exists with start and end
|
||||
* address values.
|
||||
*
|
||||
* This mask is used to remove the upper 16bits of the VA and so come up with
|
||||
* the linear addr value.
|
||||
*/
|
||||
#define AMDGPU_VA_HOLE_MASK 0x0000ffffffffffffULL
|
||||
|
||||
/* max vmids dedicated for process */
|
||||
#define AMDGPU_VM_MAX_RESERVED_VMID 1
|
||||
|
||||
|
@ -221,7 +234,6 @@ struct amdgpu_vm_manager {
|
|||
|
||||
uint64_t max_pfn;
|
||||
uint32_t num_level;
|
||||
uint64_t vm_size;
|
||||
uint32_t block_size;
|
||||
uint32_t fragment_size;
|
||||
/* vram base address for page table entry */
|
||||
|
@ -312,10 +324,9 @@ struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
|
|||
uint64_t addr);
|
||||
void amdgpu_vm_bo_rmv(struct amdgpu_device *adev,
|
||||
struct amdgpu_bo_va *bo_va);
|
||||
void amdgpu_vm_set_fragment_size(struct amdgpu_device *adev,
|
||||
uint32_t fragment_size_default);
|
||||
void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint64_t vm_size,
|
||||
uint32_t fragment_size_default);
|
||||
void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size,
|
||||
uint32_t fragment_size_default, unsigned max_level,
|
||||
unsigned max_bits);
|
||||
int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
|
||||
bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring,
|
||||
struct amdgpu_job *job);
|
||||
|
|
|
@ -65,8 +65,15 @@ static int amdgpu_atombios_i2c_process_i2c_ch(struct amdgpu_i2c_chan *chan,
|
|||
args.ucRegIndex = buf[0];
|
||||
if (num)
|
||||
num--;
|
||||
if (num)
|
||||
memcpy(&out, &buf[1], num);
|
||||
if (num) {
|
||||
if (buf) {
|
||||
memcpy(&out, &buf[1], num);
|
||||
} else {
|
||||
DRM_ERROR("hw i2c: missing buf with num > 1\n");
|
||||
r = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
args.lpI2CDataOut = cpu_to_le16(out);
|
||||
} else {
|
||||
if (num > ATOM_MAX_HW_I2C_READ) {
|
||||
|
|
|
@ -4540,9 +4540,9 @@ static int ci_set_mc_special_registers(struct amdgpu_device *adev,
|
|||
((temp_reg & 0xffff0000)) | ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
|
||||
}
|
||||
j++;
|
||||
|
||||
if (j >= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
temp_reg = RREG32(mmMC_PMG_CMD_MRS);
|
||||
table->mc_reg_address[j].s1 = mmMC_PMG_CMD_MRS;
|
||||
table->mc_reg_address[j].s0 = mmMC_SEQ_PMG_CMD_MRS_LP;
|
||||
|
@ -4553,10 +4553,10 @@ static int ci_set_mc_special_registers(struct amdgpu_device *adev,
|
|||
table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
|
||||
}
|
||||
j++;
|
||||
if (j > SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (adev->mc.vram_type != AMDGPU_VRAM_TYPE_GDDR5) {
|
||||
if (j >= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE)
|
||||
return -EINVAL;
|
||||
table->mc_reg_address[j].s1 = mmMC_PMG_AUTO_CMD;
|
||||
table->mc_reg_address[j].s0 = mmMC_PMG_AUTO_CMD;
|
||||
for (k = 0; k < table->num_entries; k++) {
|
||||
|
@ -4564,8 +4564,6 @@ static int ci_set_mc_special_registers(struct amdgpu_device *adev,
|
|||
(table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16;
|
||||
}
|
||||
j++;
|
||||
if (j > SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE)
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case mmMC_SEQ_RESERVE_M:
|
||||
|
@ -4577,8 +4575,6 @@ static int ci_set_mc_special_registers(struct amdgpu_device *adev,
|
|||
(temp_reg & 0xffff0000) | (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
|
||||
}
|
||||
j++;
|
||||
if (j > SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -6625,9 +6621,9 @@ static int ci_dpm_print_clock_levels(void *handle,
|
|||
|
||||
for (i = 0; i < pcie_table->count; i++)
|
||||
size += sprintf(buf + size, "%d: %s %s\n", i,
|
||||
(pcie_table->dpm_levels[i].value == 0) ? "2.5GB, x1" :
|
||||
(pcie_table->dpm_levels[i].value == 1) ? "5.0GB, x16" :
|
||||
(pcie_table->dpm_levels[i].value == 2) ? "8.0GB, x16" : "",
|
||||
(pcie_table->dpm_levels[i].value == 0) ? "2.5GT/s, x1" :
|
||||
(pcie_table->dpm_levels[i].value == 1) ? "5.0GT/s, x16" :
|
||||
(pcie_table->dpm_levels[i].value == 2) ? "8.0GT/s, x16" : "",
|
||||
(i == now) ? "*" : "");
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -757,72 +757,72 @@ static void cik_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_BONAIRE:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
bonaire_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(bonaire_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(bonaire_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
bonaire_golden_registers,
|
||||
(const u32)ARRAY_SIZE(bonaire_golden_registers));
|
||||
ARRAY_SIZE(bonaire_golden_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
bonaire_golden_common_registers,
|
||||
(const u32)ARRAY_SIZE(bonaire_golden_common_registers));
|
||||
ARRAY_SIZE(bonaire_golden_common_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
bonaire_golden_spm_registers,
|
||||
(const u32)ARRAY_SIZE(bonaire_golden_spm_registers));
|
||||
ARRAY_SIZE(bonaire_golden_spm_registers));
|
||||
break;
|
||||
case CHIP_KABINI:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
kalindi_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(kalindi_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
kalindi_golden_registers,
|
||||
(const u32)ARRAY_SIZE(kalindi_golden_registers));
|
||||
ARRAY_SIZE(kalindi_golden_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
kalindi_golden_common_registers,
|
||||
(const u32)ARRAY_SIZE(kalindi_golden_common_registers));
|
||||
ARRAY_SIZE(kalindi_golden_common_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
kalindi_golden_spm_registers,
|
||||
(const u32)ARRAY_SIZE(kalindi_golden_spm_registers));
|
||||
ARRAY_SIZE(kalindi_golden_spm_registers));
|
||||
break;
|
||||
case CHIP_MULLINS:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
kalindi_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(kalindi_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
godavari_golden_registers,
|
||||
(const u32)ARRAY_SIZE(godavari_golden_registers));
|
||||
ARRAY_SIZE(godavari_golden_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
kalindi_golden_common_registers,
|
||||
(const u32)ARRAY_SIZE(kalindi_golden_common_registers));
|
||||
ARRAY_SIZE(kalindi_golden_common_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
kalindi_golden_spm_registers,
|
||||
(const u32)ARRAY_SIZE(kalindi_golden_spm_registers));
|
||||
ARRAY_SIZE(kalindi_golden_spm_registers));
|
||||
break;
|
||||
case CHIP_KAVERI:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
spectre_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(spectre_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(spectre_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
spectre_golden_registers,
|
||||
(const u32)ARRAY_SIZE(spectre_golden_registers));
|
||||
ARRAY_SIZE(spectre_golden_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
spectre_golden_common_registers,
|
||||
(const u32)ARRAY_SIZE(spectre_golden_common_registers));
|
||||
ARRAY_SIZE(spectre_golden_common_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
spectre_golden_spm_registers,
|
||||
(const u32)ARRAY_SIZE(spectre_golden_spm_registers));
|
||||
ARRAY_SIZE(spectre_golden_spm_registers));
|
||||
break;
|
||||
case CHIP_HAWAII:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
hawaii_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(hawaii_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(hawaii_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
hawaii_golden_registers,
|
||||
(const u32)ARRAY_SIZE(hawaii_golden_registers));
|
||||
ARRAY_SIZE(hawaii_golden_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
hawaii_golden_common_registers,
|
||||
(const u32)ARRAY_SIZE(hawaii_golden_common_registers));
|
||||
ARRAY_SIZE(hawaii_golden_common_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
hawaii_golden_spm_registers,
|
||||
(const u32)ARRAY_SIZE(hawaii_golden_spm_registers));
|
||||
ARRAY_SIZE(hawaii_golden_spm_registers));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -657,7 +657,7 @@ static int cik_sdma_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
|
||||
ring->idx, tmp);
|
||||
|
@ -724,7 +724,7 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
}
|
||||
tmp = le32_to_cpu(adev->wb.wb[index]);
|
||||
if (tmp == 0xDEADBEEF) {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp);
|
||||
|
|
|
@ -147,18 +147,18 @@ static void dce_v10_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_FIJI:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
fiji_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(fiji_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(fiji_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_fiji_a10,
|
||||
(const u32)ARRAY_SIZE(golden_settings_fiji_a10));
|
||||
ARRAY_SIZE(golden_settings_fiji_a10));
|
||||
break;
|
||||
case CHIP_TONGA:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
tonga_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(tonga_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(tonga_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_tonga_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -2773,7 +2773,6 @@ static int dce_v10_0_early_init(void *handle)
|
|||
adev->audio_endpt_wreg = &dce_v10_0_audio_endpt_wreg;
|
||||
|
||||
dce_v10_0_set_display_funcs(adev);
|
||||
dce_v10_0_set_irq_funcs(adev);
|
||||
|
||||
adev->mode_info.num_crtc = dce_v10_0_get_num_crtc(adev);
|
||||
|
||||
|
@ -2788,6 +2787,8 @@ static int dce_v10_0_early_init(void *handle)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
dce_v10_0_set_irq_funcs(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3635,13 +3636,16 @@ static const struct amdgpu_irq_src_funcs dce_v10_0_hpd_irq_funcs = {
|
|||
|
||||
static void dce_v10_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_LAST;
|
||||
if (adev->mode_info.num_crtc > 0)
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VLINE1 + adev->mode_info.num_crtc;
|
||||
else
|
||||
adev->crtc_irq.num_types = 0;
|
||||
adev->crtc_irq.funcs = &dce_v10_0_crtc_irq_funcs;
|
||||
|
||||
adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST;
|
||||
adev->pageflip_irq.num_types = adev->mode_info.num_crtc;
|
||||
adev->pageflip_irq.funcs = &dce_v10_0_pageflip_irq_funcs;
|
||||
|
||||
adev->hpd_irq.num_types = AMDGPU_HPD_LAST;
|
||||
adev->hpd_irq.num_types = adev->mode_info.num_hpd;
|
||||
adev->hpd_irq.funcs = &dce_v10_0_hpd_irq_funcs;
|
||||
}
|
||||
|
||||
|
|
|
@ -156,26 +156,26 @@ static void dce_v11_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_CARRIZO:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
cz_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(cz_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(cz_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
cz_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(cz_golden_settings_a11));
|
||||
ARRAY_SIZE(cz_golden_settings_a11));
|
||||
break;
|
||||
case CHIP_STONEY:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
stoney_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(stoney_golden_settings_a11));
|
||||
ARRAY_SIZE(stoney_golden_settings_a11));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
polaris11_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(polaris11_golden_settings_a11));
|
||||
ARRAY_SIZE(polaris11_golden_settings_a11));
|
||||
break;
|
||||
case CHIP_POLARIS10:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
polaris10_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(polaris10_golden_settings_a11));
|
||||
ARRAY_SIZE(polaris10_golden_settings_a11));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -2876,7 +2876,6 @@ static int dce_v11_0_early_init(void *handle)
|
|||
adev->audio_endpt_wreg = &dce_v11_0_audio_endpt_wreg;
|
||||
|
||||
dce_v11_0_set_display_funcs(adev);
|
||||
dce_v11_0_set_irq_funcs(adev);
|
||||
|
||||
adev->mode_info.num_crtc = dce_v11_0_get_num_crtc(adev);
|
||||
|
||||
|
@ -2903,6 +2902,8 @@ static int dce_v11_0_early_init(void *handle)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
dce_v11_0_set_irq_funcs(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3759,13 +3760,16 @@ static const struct amdgpu_irq_src_funcs dce_v11_0_hpd_irq_funcs = {
|
|||
|
||||
static void dce_v11_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_LAST;
|
||||
if (adev->mode_info.num_crtc > 0)
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VLINE1 + adev->mode_info.num_crtc;
|
||||
else
|
||||
adev->crtc_irq.num_types = 0;
|
||||
adev->crtc_irq.funcs = &dce_v11_0_crtc_irq_funcs;
|
||||
|
||||
adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST;
|
||||
adev->pageflip_irq.num_types = adev->mode_info.num_crtc;
|
||||
adev->pageflip_irq.funcs = &dce_v11_0_pageflip_irq_funcs;
|
||||
|
||||
adev->hpd_irq.num_types = AMDGPU_HPD_LAST;
|
||||
adev->hpd_irq.num_types = adev->mode_info.num_hpd;
|
||||
adev->hpd_irq.funcs = &dce_v11_0_hpd_irq_funcs;
|
||||
}
|
||||
|
||||
|
|
|
@ -2639,7 +2639,6 @@ static int dce_v6_0_early_init(void *handle)
|
|||
adev->audio_endpt_wreg = &dce_v6_0_audio_endpt_wreg;
|
||||
|
||||
dce_v6_0_set_display_funcs(adev);
|
||||
dce_v6_0_set_irq_funcs(adev);
|
||||
|
||||
adev->mode_info.num_crtc = dce_v6_0_get_num_crtc(adev);
|
||||
|
||||
|
@ -2658,6 +2657,8 @@ static int dce_v6_0_early_init(void *handle)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
dce_v6_0_set_irq_funcs(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3441,13 +3442,16 @@ static const struct amdgpu_irq_src_funcs dce_v6_0_hpd_irq_funcs = {
|
|||
|
||||
static void dce_v6_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_LAST;
|
||||
if (adev->mode_info.num_crtc > 0)
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VLINE1 + adev->mode_info.num_crtc;
|
||||
else
|
||||
adev->crtc_irq.num_types = 0;
|
||||
adev->crtc_irq.funcs = &dce_v6_0_crtc_irq_funcs;
|
||||
|
||||
adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST;
|
||||
adev->pageflip_irq.num_types = adev->mode_info.num_crtc;
|
||||
adev->pageflip_irq.funcs = &dce_v6_0_pageflip_irq_funcs;
|
||||
|
||||
adev->hpd_irq.num_types = AMDGPU_HPD_LAST;
|
||||
adev->hpd_irq.num_types = adev->mode_info.num_hpd;
|
||||
adev->hpd_irq.funcs = &dce_v6_0_hpd_irq_funcs;
|
||||
}
|
||||
|
||||
|
|
|
@ -2664,7 +2664,6 @@ static int dce_v8_0_early_init(void *handle)
|
|||
adev->audio_endpt_wreg = &dce_v8_0_audio_endpt_wreg;
|
||||
|
||||
dce_v8_0_set_display_funcs(adev);
|
||||
dce_v8_0_set_irq_funcs(adev);
|
||||
|
||||
adev->mode_info.num_crtc = dce_v8_0_get_num_crtc(adev);
|
||||
|
||||
|
@ -2688,6 +2687,8 @@ static int dce_v8_0_early_init(void *handle)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
dce_v8_0_set_irq_funcs(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3525,13 +3526,16 @@ static const struct amdgpu_irq_src_funcs dce_v8_0_hpd_irq_funcs = {
|
|||
|
||||
static void dce_v8_0_set_irq_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_LAST;
|
||||
if (adev->mode_info.num_crtc > 0)
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VLINE1 + adev->mode_info.num_crtc;
|
||||
else
|
||||
adev->crtc_irq.num_types = 0;
|
||||
adev->crtc_irq.funcs = &dce_v8_0_crtc_irq_funcs;
|
||||
|
||||
adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST;
|
||||
adev->pageflip_irq.num_types = adev->mode_info.num_crtc;
|
||||
adev->pageflip_irq.funcs = &dce_v8_0_pageflip_irq_funcs;
|
||||
|
||||
adev->hpd_irq.num_types = AMDGPU_HPD_LAST;
|
||||
adev->hpd_irq.num_types = adev->mode_info.num_hpd;
|
||||
adev->hpd_irq.funcs = &dce_v8_0_hpd_irq_funcs;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,9 @@ static void dce_virtual_set_display_funcs(struct amdgpu_device *adev);
|
|||
static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
|
||||
int index);
|
||||
static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
|
||||
int crtc,
|
||||
enum amdgpu_interrupt_state state);
|
||||
|
||||
/**
|
||||
* dce_virtual_vblank_wait - vblank wait asic callback.
|
||||
|
@ -437,6 +440,8 @@ static int dce_virtual_sw_fini(void *handle)
|
|||
drm_kms_helper_poll_fini(adev->ddev);
|
||||
|
||||
drm_mode_config_cleanup(adev->ddev);
|
||||
/* clear crtcs pointer to avoid dce irq finish routine access freed data */
|
||||
memset(adev->mode_info.crtcs, 0, sizeof(adev->mode_info.crtcs[0]) * AMDGPU_MAX_CRTCS);
|
||||
adev->mode_info.mode_config_initialized = false;
|
||||
return 0;
|
||||
}
|
||||
|
@ -489,6 +494,13 @@ static int dce_virtual_hw_init(void *handle)
|
|||
|
||||
static int dce_virtual_hw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i<adev->mode_info.num_crtc; i++)
|
||||
if (adev->mode_info.crtcs[i])
|
||||
dce_virtual_set_crtc_vblank_interrupt_state(adev, i, AMDGPU_IRQ_STATE_DISABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -723,7 +735,7 @@ static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *ad
|
|||
int crtc,
|
||||
enum amdgpu_interrupt_state state)
|
||||
{
|
||||
if (crtc >= adev->mode_info.num_crtc) {
|
||||
if (crtc >= adev->mode_info.num_crtc || !adev->mode_info.crtcs[crtc]) {
|
||||
DRM_DEBUG("invalid crtc %d\n", crtc);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1798,7 +1798,7 @@ static int gfx_v6_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
DRM_UDELAY(1);
|
||||
}
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (scratch(0x%04X)=0x%08X)\n",
|
||||
ring->idx, scratch, tmp);
|
||||
|
@ -1951,7 +1951,7 @@ static int gfx_v6_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
}
|
||||
tmp = RREG32(scratch);
|
||||
if (tmp == 0xDEADBEEF) {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n",
|
||||
|
@ -2962,25 +2962,7 @@ static void gfx_v6_0_get_csb_buffer(struct amdgpu_device *adev,
|
|||
|
||||
buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1));
|
||||
buffer[count++] = cpu_to_le32(mmPA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_TAHITI:
|
||||
case CHIP_PITCAIRN:
|
||||
buffer[count++] = cpu_to_le32(0x2a00126a);
|
||||
break;
|
||||
case CHIP_VERDE:
|
||||
buffer[count++] = cpu_to_le32(0x0000124a);
|
||||
break;
|
||||
case CHIP_OLAND:
|
||||
buffer[count++] = cpu_to_le32(0x00000082);
|
||||
break;
|
||||
case CHIP_HAINAN:
|
||||
buffer[count++] = cpu_to_le32(0x00000000);
|
||||
break;
|
||||
default:
|
||||
buffer[count++] = cpu_to_le32(0x00000000);
|
||||
break;
|
||||
}
|
||||
buffer[count++] = cpu_to_le32(adev->gfx.config.rb_config[0][0].raster_config);
|
||||
|
||||
buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
|
||||
buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE);
|
||||
|
|
|
@ -2085,7 +2085,7 @@ static int gfx_v7_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
DRM_UDELAY(1);
|
||||
}
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (scratch(0x%04X)=0x%08X)\n",
|
||||
ring->idx, scratch, tmp);
|
||||
|
@ -2365,7 +2365,7 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
}
|
||||
tmp = RREG32(scratch);
|
||||
if (tmp == 0xDEADBEEF) {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n",
|
||||
|
@ -2551,29 +2551,8 @@ static int gfx_v7_0_cp_gfx_start(struct amdgpu_device *adev)
|
|||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
|
||||
amdgpu_ring_write(ring, mmPA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_BONAIRE:
|
||||
amdgpu_ring_write(ring, 0x16000012);
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
break;
|
||||
case CHIP_KAVERI:
|
||||
amdgpu_ring_write(ring, 0x00000000); /* XXX */
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
break;
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
amdgpu_ring_write(ring, 0x00000000); /* XXX */
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
break;
|
||||
case CHIP_HAWAII:
|
||||
amdgpu_ring_write(ring, 0x3a00161a);
|
||||
amdgpu_ring_write(ring, 0x0000002e);
|
||||
break;
|
||||
default:
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
break;
|
||||
}
|
||||
amdgpu_ring_write(ring, adev->gfx.config.rb_config[0][0].raster_config);
|
||||
amdgpu_ring_write(ring, adev->gfx.config.rb_config[0][0].raster_config_1);
|
||||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
|
||||
amdgpu_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
|
||||
|
|
|
@ -681,53 +681,53 @@ static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_TOPAZ:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
iceland_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(iceland_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(iceland_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_iceland_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_iceland_a11));
|
||||
ARRAY_SIZE(golden_settings_iceland_a11));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
iceland_golden_common_all,
|
||||
(const u32)ARRAY_SIZE(iceland_golden_common_all));
|
||||
ARRAY_SIZE(iceland_golden_common_all));
|
||||
break;
|
||||
case CHIP_FIJI:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
fiji_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(fiji_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(fiji_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_fiji_a10,
|
||||
(const u32)ARRAY_SIZE(golden_settings_fiji_a10));
|
||||
ARRAY_SIZE(golden_settings_fiji_a10));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
fiji_golden_common_all,
|
||||
(const u32)ARRAY_SIZE(fiji_golden_common_all));
|
||||
ARRAY_SIZE(fiji_golden_common_all));
|
||||
break;
|
||||
|
||||
case CHIP_TONGA:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
tonga_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(tonga_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(tonga_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_tonga_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
tonga_golden_common_all,
|
||||
(const u32)ARRAY_SIZE(tonga_golden_common_all));
|
||||
ARRAY_SIZE(tonga_golden_common_all));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris11_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
polaris11_golden_common_all,
|
||||
(const u32)ARRAY_SIZE(polaris11_golden_common_all));
|
||||
ARRAY_SIZE(polaris11_golden_common_all));
|
||||
break;
|
||||
case CHIP_POLARIS10:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris10_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris10_a11));
|
||||
ARRAY_SIZE(golden_settings_polaris10_a11));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
polaris10_golden_common_all,
|
||||
(const u32)ARRAY_SIZE(polaris10_golden_common_all));
|
||||
ARRAY_SIZE(polaris10_golden_common_all));
|
||||
WREG32_SMC(ixCG_ACLK_CNTL, 0x0000001C);
|
||||
if (adev->pdev->revision == 0xc7 &&
|
||||
((adev->pdev->subsystem_device == 0xb37 && adev->pdev->subsystem_vendor == 0x1002) ||
|
||||
|
@ -740,24 +740,24 @@ static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_CARRIZO:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
cz_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(cz_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(cz_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
cz_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(cz_golden_settings_a11));
|
||||
ARRAY_SIZE(cz_golden_settings_a11));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
cz_golden_common_all,
|
||||
(const u32)ARRAY_SIZE(cz_golden_common_all));
|
||||
ARRAY_SIZE(cz_golden_common_all));
|
||||
break;
|
||||
case CHIP_STONEY:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
stoney_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(stoney_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(stoney_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
stoney_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(stoney_golden_settings_a11));
|
||||
ARRAY_SIZE(stoney_golden_settings_a11));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
stoney_golden_common_all,
|
||||
(const u32)ARRAY_SIZE(stoney_golden_common_all));
|
||||
ARRAY_SIZE(stoney_golden_common_all));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -804,7 +804,7 @@ static int gfx_v8_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
DRM_UDELAY(1);
|
||||
}
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (scratch(0x%04X)=0x%08X)\n",
|
||||
|
@ -856,7 +856,7 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
}
|
||||
tmp = RREG32(scratch);
|
||||
if (tmp == 0xDEADBEEF) {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n",
|
||||
|
@ -2114,7 +2114,6 @@ static int gfx_v8_0_sw_fini(void *handle)
|
|||
amdgpu_gfx_compute_mqd_sw_fini(adev);
|
||||
amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring, &adev->gfx.kiq.irq);
|
||||
amdgpu_gfx_kiq_fini(adev);
|
||||
amdgpu_bo_free_kernel(&adev->virt.csa_obj, &adev->virt.csa_vmid0_addr, NULL);
|
||||
|
||||
gfx_v8_0_mec_fini(adev);
|
||||
gfx_v8_0_rlc_fini(adev);
|
||||
|
@ -3851,6 +3850,14 @@ static void gfx_v8_0_wait_for_rlc_serdes(struct amdgpu_device *adev)
|
|||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (k == adev->usec_timeout) {
|
||||
gfx_v8_0_select_se_sh(adev, 0xffffffff,
|
||||
0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
DRM_INFO("Timeout wait for RLC serdes %u,%u\n",
|
||||
i, j);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
@ -4305,37 +4312,8 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev)
|
|||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
|
||||
amdgpu_ring_write(ring, mmPA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_TONGA:
|
||||
case CHIP_POLARIS10:
|
||||
amdgpu_ring_write(ring, 0x16000012);
|
||||
amdgpu_ring_write(ring, 0x0000002A);
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
amdgpu_ring_write(ring, 0x16000012);
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
break;
|
||||
case CHIP_FIJI:
|
||||
amdgpu_ring_write(ring, 0x3a00161a);
|
||||
amdgpu_ring_write(ring, 0x0000002e);
|
||||
break;
|
||||
case CHIP_CARRIZO:
|
||||
amdgpu_ring_write(ring, 0x00000002);
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
break;
|
||||
case CHIP_TOPAZ:
|
||||
amdgpu_ring_write(ring, adev->gfx.config.num_rbs == 1 ?
|
||||
0x00000000 : 0x00000002);
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
break;
|
||||
case CHIP_STONEY:
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
amdgpu_ring_write(ring, 0x00000000);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
amdgpu_ring_write(ring, adev->gfx.config.rb_config[0][0].raster_config);
|
||||
amdgpu_ring_write(ring, adev->gfx.config.rb_config[0][0].raster_config_1);
|
||||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
|
||||
amdgpu_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
|
||||
|
@ -4816,7 +4794,7 @@ static int gfx_v8_0_kiq_init_queue(struct amdgpu_ring *ring)
|
|||
|
||||
gfx_v8_0_kiq_setting(ring);
|
||||
|
||||
if (adev->in_sriov_reset) { /* for GPU_RESET case */
|
||||
if (adev->in_gpu_reset) { /* for GPU_RESET case */
|
||||
/* reset MQD to a clean status */
|
||||
if (adev->gfx.mec.mqd_backup[mqd_idx])
|
||||
memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct vi_mqd_allocation));
|
||||
|
@ -4853,7 +4831,7 @@ static int gfx_v8_0_kcq_init_queue(struct amdgpu_ring *ring)
|
|||
struct vi_mqd *mqd = ring->mqd_ptr;
|
||||
int mqd_idx = ring - &adev->gfx.compute_ring[0];
|
||||
|
||||
if (!adev->in_sriov_reset && !adev->gfx.in_suspend) {
|
||||
if (!adev->in_gpu_reset && !adev->gfx.in_suspend) {
|
||||
memset((void *)mqd, 0, sizeof(struct vi_mqd_allocation));
|
||||
((struct vi_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF;
|
||||
((struct vi_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF;
|
||||
|
@ -4865,13 +4843,10 @@ static int gfx_v8_0_kcq_init_queue(struct amdgpu_ring *ring)
|
|||
|
||||
if (adev->gfx.mec.mqd_backup[mqd_idx])
|
||||
memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(struct vi_mqd_allocation));
|
||||
} else if (adev->in_sriov_reset) { /* for GPU_RESET case */
|
||||
} else if (adev->in_gpu_reset) { /* for GPU_RESET case */
|
||||
/* reset MQD to a clean status */
|
||||
if (adev->gfx.mec.mqd_backup[mqd_idx])
|
||||
memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct vi_mqd_allocation));
|
||||
/* reset ring buffer */
|
||||
ring->wptr = 0;
|
||||
amdgpu_ring_clear_ring(ring);
|
||||
} else {
|
||||
amdgpu_ring_clear_ring(ring);
|
||||
}
|
||||
|
@ -4946,6 +4921,13 @@ static int gfx_v8_0_kiq_resume(struct amdgpu_device *adev)
|
|||
/* Test KCQs */
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
|
||||
ring = &adev->gfx.compute_ring[i];
|
||||
if (adev->in_gpu_reset) {
|
||||
/* move reset ring buffer to here to workaround
|
||||
* compute ring test failed
|
||||
*/
|
||||
ring->wptr = 0;
|
||||
amdgpu_ring_clear_ring(ring);
|
||||
}
|
||||
ring->ready = true;
|
||||
r = amdgpu_ring_test_ring(ring);
|
||||
if (r)
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
#include "soc15.h"
|
||||
#include "soc15d.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/GC/gc_9_0_offset.h"
|
||||
#include "vega10/GC/gc_9_0_sh_mask.h"
|
||||
#include "vega10/vega10_enum.h"
|
||||
#include "vega10/HDP/hdp_4_0_offset.h"
|
||||
#include "soc15ip.h"
|
||||
#include "gc/gc_9_0_offset.h"
|
||||
#include "gc/gc_9_0_sh_mask.h"
|
||||
#include "vega10_enum.h"
|
||||
#include "hdp/hdp_4_0_offset.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "clearstate_gfx9.h"
|
||||
|
@ -232,18 +232,18 @@ static void gfx_v9_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_VEGA10:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_gc_9_0,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_9_0));
|
||||
ARRAY_SIZE(golden_settings_gc_9_0));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_gc_9_0_vg10,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_9_0_vg10));
|
||||
ARRAY_SIZE(golden_settings_gc_9_0_vg10));
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_gc_9_1,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_9_1));
|
||||
ARRAY_SIZE(golden_settings_gc_9_1));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_gc_9_1_rv1,
|
||||
(const u32)ARRAY_SIZE(golden_settings_gc_9_1_rv1));
|
||||
ARRAY_SIZE(golden_settings_gc_9_1_rv1));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -327,7 +327,7 @@ static int gfx_v9_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
DRM_UDELAY(1);
|
||||
}
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (scratch(0x%04X)=0x%08X)\n",
|
||||
|
@ -379,7 +379,7 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
}
|
||||
tmp = RREG32(scratch);
|
||||
if (tmp == 0xDEADBEEF) {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n",
|
||||
|
@ -1464,7 +1464,6 @@ static int gfx_v9_0_sw_fini(void *handle)
|
|||
amdgpu_gfx_compute_mqd_sw_fini(adev);
|
||||
amdgpu_gfx_kiq_free_ring(&adev->gfx.kiq.ring, &adev->gfx.kiq.irq);
|
||||
amdgpu_gfx_kiq_fini(adev);
|
||||
amdgpu_bo_free_kernel(&adev->virt.csa_obj, &adev->virt.csa_vmid0_addr, NULL);
|
||||
|
||||
gfx_v9_0_mec_fini(adev);
|
||||
gfx_v9_0_ngg_fini(adev);
|
||||
|
@ -1645,6 +1644,14 @@ static void gfx_v9_0_wait_for_rlc_serdes(struct amdgpu_device *adev)
|
|||
break;
|
||||
udelay(1);
|
||||
}
|
||||
if (k == adev->usec_timeout) {
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff,
|
||||
0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
DRM_INFO("Timeout wait for RLC serdes %u,%u\n",
|
||||
i, j);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
gfx_v9_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
|
@ -2749,7 +2756,7 @@ static int gfx_v9_0_kiq_init_queue(struct amdgpu_ring *ring)
|
|||
|
||||
gfx_v9_0_kiq_setting(ring);
|
||||
|
||||
if (adev->in_sriov_reset) { /* for GPU_RESET case */
|
||||
if (adev->in_gpu_reset) { /* for GPU_RESET case */
|
||||
/* reset MQD to a clean status */
|
||||
if (adev->gfx.mec.mqd_backup[mqd_idx])
|
||||
memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct v9_mqd_allocation));
|
||||
|
@ -2787,7 +2794,7 @@ static int gfx_v9_0_kcq_init_queue(struct amdgpu_ring *ring)
|
|||
struct v9_mqd *mqd = ring->mqd_ptr;
|
||||
int mqd_idx = ring - &adev->gfx.compute_ring[0];
|
||||
|
||||
if (!adev->in_sriov_reset && !adev->gfx.in_suspend) {
|
||||
if (!adev->in_gpu_reset && !adev->gfx.in_suspend) {
|
||||
memset((void *)mqd, 0, sizeof(struct v9_mqd_allocation));
|
||||
((struct v9_mqd_allocation *)mqd)->dynamic_cu_mask = 0xFFFFFFFF;
|
||||
((struct v9_mqd_allocation *)mqd)->dynamic_rb_mask = 0xFFFFFFFF;
|
||||
|
@ -2799,7 +2806,7 @@ static int gfx_v9_0_kcq_init_queue(struct amdgpu_ring *ring)
|
|||
|
||||
if (adev->gfx.mec.mqd_backup[mqd_idx])
|
||||
memcpy(adev->gfx.mec.mqd_backup[mqd_idx], mqd, sizeof(struct v9_mqd_allocation));
|
||||
} else if (adev->in_sriov_reset) { /* for GPU_RESET case */
|
||||
} else if (adev->in_gpu_reset) { /* for GPU_RESET case */
|
||||
/* reset MQD to a clean status */
|
||||
if (adev->gfx.mec.mqd_backup[mqd_idx])
|
||||
memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], sizeof(struct v9_mqd_allocation));
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
#include "amdgpu.h"
|
||||
#include "gfxhub_v1_0.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/GC/gc_9_0_offset.h"
|
||||
#include "vega10/GC/gc_9_0_sh_mask.h"
|
||||
#include "vega10/GC/gc_9_0_default.h"
|
||||
#include "vega10/vega10_enum.h"
|
||||
#include "soc15ip.h"
|
||||
#include "gc/gc_9_0_offset.h"
|
||||
#include "gc/gc_9_0_sh_mask.h"
|
||||
#include "gc/gc_9_0_default.h"
|
||||
#include "vega10_enum.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
|
||||
|
|
|
@ -222,11 +222,6 @@ static void gmc_v6_0_vram_gtt_location(struct amdgpu_device *adev,
|
|||
u64 base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
|
||||
base <<= 24;
|
||||
|
||||
if (mc->mc_vram_size > 0xFFC0000000ULL) {
|
||||
dev_warn(adev->dev, "limiting VRAM\n");
|
||||
mc->real_vram_size = 0xFFC0000000ULL;
|
||||
mc->mc_vram_size = 0xFFC0000000ULL;
|
||||
}
|
||||
amdgpu_vram_location(adev, &adev->mc, base);
|
||||
amdgpu_gart_location(adev, mc);
|
||||
}
|
||||
|
@ -283,6 +278,7 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev)
|
|||
|
||||
u32 tmp;
|
||||
int chansize, numchan;
|
||||
int r;
|
||||
|
||||
tmp = RREG32(mmMC_ARB_RAMCFG);
|
||||
if (tmp & (1 << 11)) {
|
||||
|
@ -324,12 +320,17 @@ static int gmc_v6_0_mc_init(struct amdgpu_device *adev)
|
|||
break;
|
||||
}
|
||||
adev->mc.vram_width = numchan * chansize;
|
||||
/* Could aper size report 0 ? */
|
||||
adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
|
||||
adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
|
||||
/* size in MB on si */
|
||||
adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
|
||||
adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
|
||||
|
||||
if (!(adev->flags & AMD_IS_APU)) {
|
||||
r = amdgpu_device_resize_fb_bar(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
|
||||
adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
|
||||
adev->mc.visible_vram_size = adev->mc.aper_size;
|
||||
|
||||
/* set the gart size */
|
||||
|
@ -831,8 +832,7 @@ static int gmc_v6_0_sw_init(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_vm_adjust_size(adev, 64, 9);
|
||||
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
|
||||
amdgpu_vm_adjust_size(adev, 64, 9, 1, 40);
|
||||
|
||||
adev->mc.mc_mask = 0xffffffffffULL;
|
||||
|
||||
|
@ -877,7 +877,6 @@ static int gmc_v6_0_sw_init(void *handle)
|
|||
* amdkfd will use VMIDs 8-15
|
||||
*/
|
||||
adev->vm_manager.id_mgr[0].num_ids = AMDGPU_NUM_OF_VMIDS;
|
||||
adev->vm_manager.num_level = 1;
|
||||
amdgpu_vm_manager_init(adev);
|
||||
|
||||
/* base offset of vram pages */
|
||||
|
@ -897,9 +896,9 @@ static int gmc_v6_0_sw_fini(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_gem_force_release(adev);
|
||||
amdgpu_vm_manager_fini(adev);
|
||||
gmc_v6_0_gart_fini(adev);
|
||||
amdgpu_gem_force_release(adev);
|
||||
amdgpu_bo_fini(adev);
|
||||
release_firmware(adev->mc.fw);
|
||||
adev->mc.fw = NULL;
|
||||
|
|
|
@ -69,10 +69,10 @@ static void gmc_v7_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_TOPAZ:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
iceland_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(iceland_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(iceland_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_iceland_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_iceland_a11));
|
||||
ARRAY_SIZE(golden_settings_iceland_a11));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -240,12 +240,6 @@ static void gmc_v7_0_vram_gtt_location(struct amdgpu_device *adev,
|
|||
u64 base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
|
||||
base <<= 24;
|
||||
|
||||
if (mc->mc_vram_size > 0xFFC0000000ULL) {
|
||||
/* leave room for at least 1024M GTT */
|
||||
dev_warn(adev->dev, "limiting VRAM\n");
|
||||
mc->real_vram_size = 0xFFC0000000ULL;
|
||||
mc->mc_vram_size = 0xFFC0000000ULL;
|
||||
}
|
||||
amdgpu_vram_location(adev, &adev->mc, base);
|
||||
amdgpu_gart_location(adev, mc);
|
||||
}
|
||||
|
@ -322,6 +316,8 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev)
|
|||
*/
|
||||
static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
||||
adev->mc.vram_width = amdgpu_atombios_get_vram_width(adev);
|
||||
if (!adev->mc.vram_width) {
|
||||
u32 tmp;
|
||||
|
@ -367,13 +363,18 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
|
|||
}
|
||||
adev->mc.vram_width = numchan * chansize;
|
||||
}
|
||||
/* Could aper size report 0 ? */
|
||||
adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
|
||||
adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
|
||||
/* size in MB on si */
|
||||
adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
|
||||
adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
|
||||
|
||||
if (!(adev->flags & AMD_IS_APU)) {
|
||||
r = amdgpu_device_resize_fb_bar(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
|
||||
adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->mc.aper_base = ((u64)RREG32(mmMC_VM_FB_OFFSET)) << 22;
|
||||
|
@ -970,8 +971,7 @@ static int gmc_v7_0_sw_init(void *handle)
|
|||
* Currently set to 4GB ((1 << 20) 4k pages).
|
||||
* Max GPUVM size for cayman and SI is 40 bits.
|
||||
*/
|
||||
amdgpu_vm_adjust_size(adev, 64, 9);
|
||||
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
|
||||
amdgpu_vm_adjust_size(adev, 64, 9, 1, 40);
|
||||
|
||||
/* Set the internal MC address mask
|
||||
* This is the max address of the GPU's
|
||||
|
@ -1026,7 +1026,6 @@ static int gmc_v7_0_sw_init(void *handle)
|
|||
* amdkfd will use VMIDs 8-15
|
||||
*/
|
||||
adev->vm_manager.id_mgr[0].num_ids = AMDGPU_NUM_OF_VMIDS;
|
||||
adev->vm_manager.num_level = 1;
|
||||
amdgpu_vm_manager_init(adev);
|
||||
|
||||
/* base offset of vram pages */
|
||||
|
@ -1046,9 +1045,9 @@ static int gmc_v7_0_sw_fini(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_gem_force_release(adev);
|
||||
amdgpu_vm_manager_fini(adev);
|
||||
gmc_v7_0_gart_fini(adev);
|
||||
amdgpu_gem_force_release(adev);
|
||||
amdgpu_bo_fini(adev);
|
||||
release_firmware(adev->mc.fw);
|
||||
adev->mc.fw = NULL;
|
||||
|
|
|
@ -122,42 +122,42 @@ static void gmc_v8_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_FIJI:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
fiji_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(fiji_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(fiji_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_fiji_a10,
|
||||
(const u32)ARRAY_SIZE(golden_settings_fiji_a10));
|
||||
ARRAY_SIZE(golden_settings_fiji_a10));
|
||||
break;
|
||||
case CHIP_TONGA:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
tonga_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(tonga_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(tonga_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_tonga_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris11_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
break;
|
||||
case CHIP_POLARIS10:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris10_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris10_a11));
|
||||
ARRAY_SIZE(golden_settings_polaris10_a11));
|
||||
break;
|
||||
case CHIP_CARRIZO:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
cz_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(cz_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(cz_mgcg_cgcg_init));
|
||||
break;
|
||||
case CHIP_STONEY:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
stoney_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(stoney_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(stoney_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_stoney_common,
|
||||
(const u32)ARRAY_SIZE(golden_settings_stoney_common));
|
||||
ARRAY_SIZE(golden_settings_stoney_common));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -405,12 +405,6 @@ static void gmc_v8_0_vram_gtt_location(struct amdgpu_device *adev,
|
|||
base = RREG32(mmMC_VM_FB_LOCATION) & 0xFFFF;
|
||||
base <<= 24;
|
||||
|
||||
if (mc->mc_vram_size > 0xFFC0000000ULL) {
|
||||
/* leave room for at least 1024M GTT */
|
||||
dev_warn(adev->dev, "limiting VRAM\n");
|
||||
mc->real_vram_size = 0xFFC0000000ULL;
|
||||
mc->mc_vram_size = 0xFFC0000000ULL;
|
||||
}
|
||||
amdgpu_vram_location(adev, &adev->mc, base);
|
||||
amdgpu_gart_location(adev, mc);
|
||||
}
|
||||
|
@ -498,6 +492,8 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev)
|
|||
*/
|
||||
static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
|
||||
{
|
||||
int r;
|
||||
|
||||
adev->mc.vram_width = amdgpu_atombios_get_vram_width(adev);
|
||||
if (!adev->mc.vram_width) {
|
||||
u32 tmp;
|
||||
|
@ -543,13 +539,18 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev)
|
|||
}
|
||||
adev->mc.vram_width = numchan * chansize;
|
||||
}
|
||||
/* Could aper size report 0 ? */
|
||||
adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
|
||||
adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
|
||||
/* size in MB on si */
|
||||
adev->mc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
|
||||
adev->mc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL;
|
||||
|
||||
if (!(adev->flags & AMD_IS_APU)) {
|
||||
r = amdgpu_device_resize_fb_bar(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
|
||||
adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->mc.aper_base = ((u64)RREG32(mmMC_VM_FB_OFFSET)) << 22;
|
||||
|
@ -1067,8 +1068,7 @@ static int gmc_v8_0_sw_init(void *handle)
|
|||
* Currently set to 4GB ((1 << 20) 4k pages).
|
||||
* Max GPUVM size for cayman and SI is 40 bits.
|
||||
*/
|
||||
amdgpu_vm_adjust_size(adev, 64, 9);
|
||||
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
|
||||
amdgpu_vm_adjust_size(adev, 64, 9, 1, 40);
|
||||
|
||||
/* Set the internal MC address mask
|
||||
* This is the max address of the GPU's
|
||||
|
@ -1123,7 +1123,6 @@ static int gmc_v8_0_sw_init(void *handle)
|
|||
* amdkfd will use VMIDs 8-15
|
||||
*/
|
||||
adev->vm_manager.id_mgr[0].num_ids = AMDGPU_NUM_OF_VMIDS;
|
||||
adev->vm_manager.num_level = 1;
|
||||
amdgpu_vm_manager_init(adev);
|
||||
|
||||
/* base offset of vram pages */
|
||||
|
@ -1143,9 +1142,9 @@ static int gmc_v8_0_sw_fini(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_gem_force_release(adev);
|
||||
amdgpu_vm_manager_fini(adev);
|
||||
gmc_v8_0_gart_fini(adev);
|
||||
amdgpu_gem_force_release(adev);
|
||||
amdgpu_bo_fini(adev);
|
||||
release_firmware(adev->mc.fw);
|
||||
adev->mc.fw = NULL;
|
||||
|
|
|
@ -25,17 +25,18 @@
|
|||
#include "gmc_v9_0.h"
|
||||
#include "amdgpu_atomfirmware.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/HDP/hdp_4_0_offset.h"
|
||||
#include "vega10/HDP/hdp_4_0_sh_mask.h"
|
||||
#include "vega10/GC/gc_9_0_sh_mask.h"
|
||||
#include "vega10/DC/dce_12_0_offset.h"
|
||||
#include "vega10/DC/dce_12_0_sh_mask.h"
|
||||
#include "vega10/vega10_enum.h"
|
||||
#include "vega10/MMHUB/mmhub_1_0_offset.h"
|
||||
#include "vega10/ATHUB/athub_1_0_offset.h"
|
||||
#include "soc15ip.h"
|
||||
#include "hdp/hdp_4_0_offset.h"
|
||||
#include "hdp/hdp_4_0_sh_mask.h"
|
||||
#include "gc/gc_9_0_sh_mask.h"
|
||||
#include "dce/dce_12_0_offset.h"
|
||||
#include "dce/dce_12_0_sh_mask.h"
|
||||
#include "vega10_enum.h"
|
||||
#include "mmhub/mmhub_1_0_offset.h"
|
||||
#include "athub/athub_1_0_offset.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "umc/umc_6_0_sh_mask.h"
|
||||
|
||||
#include "nbio_v6_1.h"
|
||||
#include "nbio_v7_0.h"
|
||||
|
@ -85,6 +86,121 @@ static const u32 golden_settings_athub_1_0_0[] =
|
|||
SOC15_REG_OFFSET(ATHUB, 0, mmRPB_ARB_CNTL2), 0x00ff00ff, 0x00080008
|
||||
};
|
||||
|
||||
/* Ecc related register addresses, (BASE + reg offset) */
|
||||
/* Universal Memory Controller caps (may be fused). */
|
||||
/* UMCCH:UmcLocalCap */
|
||||
#define UMCLOCALCAPS_ADDR0 (0x00014306 + 0x00000000)
|
||||
#define UMCLOCALCAPS_ADDR1 (0x00014306 + 0x00000800)
|
||||
#define UMCLOCALCAPS_ADDR2 (0x00014306 + 0x00001000)
|
||||
#define UMCLOCALCAPS_ADDR3 (0x00014306 + 0x00001800)
|
||||
#define UMCLOCALCAPS_ADDR4 (0x00054306 + 0x00000000)
|
||||
#define UMCLOCALCAPS_ADDR5 (0x00054306 + 0x00000800)
|
||||
#define UMCLOCALCAPS_ADDR6 (0x00054306 + 0x00001000)
|
||||
#define UMCLOCALCAPS_ADDR7 (0x00054306 + 0x00001800)
|
||||
#define UMCLOCALCAPS_ADDR8 (0x00094306 + 0x00000000)
|
||||
#define UMCLOCALCAPS_ADDR9 (0x00094306 + 0x00000800)
|
||||
#define UMCLOCALCAPS_ADDR10 (0x00094306 + 0x00001000)
|
||||
#define UMCLOCALCAPS_ADDR11 (0x00094306 + 0x00001800)
|
||||
#define UMCLOCALCAPS_ADDR12 (0x000d4306 + 0x00000000)
|
||||
#define UMCLOCALCAPS_ADDR13 (0x000d4306 + 0x00000800)
|
||||
#define UMCLOCALCAPS_ADDR14 (0x000d4306 + 0x00001000)
|
||||
#define UMCLOCALCAPS_ADDR15 (0x000d4306 + 0x00001800)
|
||||
|
||||
/* Universal Memory Controller Channel config. */
|
||||
/* UMCCH:UMC_CONFIG */
|
||||
#define UMCCH_UMC_CONFIG_ADDR0 (0x00014040 + 0x00000000)
|
||||
#define UMCCH_UMC_CONFIG_ADDR1 (0x00014040 + 0x00000800)
|
||||
#define UMCCH_UMC_CONFIG_ADDR2 (0x00014040 + 0x00001000)
|
||||
#define UMCCH_UMC_CONFIG_ADDR3 (0x00014040 + 0x00001800)
|
||||
#define UMCCH_UMC_CONFIG_ADDR4 (0x00054040 + 0x00000000)
|
||||
#define UMCCH_UMC_CONFIG_ADDR5 (0x00054040 + 0x00000800)
|
||||
#define UMCCH_UMC_CONFIG_ADDR6 (0x00054040 + 0x00001000)
|
||||
#define UMCCH_UMC_CONFIG_ADDR7 (0x00054040 + 0x00001800)
|
||||
#define UMCCH_UMC_CONFIG_ADDR8 (0x00094040 + 0x00000000)
|
||||
#define UMCCH_UMC_CONFIG_ADDR9 (0x00094040 + 0x00000800)
|
||||
#define UMCCH_UMC_CONFIG_ADDR10 (0x00094040 + 0x00001000)
|
||||
#define UMCCH_UMC_CONFIG_ADDR11 (0x00094040 + 0x00001800)
|
||||
#define UMCCH_UMC_CONFIG_ADDR12 (0x000d4040 + 0x00000000)
|
||||
#define UMCCH_UMC_CONFIG_ADDR13 (0x000d4040 + 0x00000800)
|
||||
#define UMCCH_UMC_CONFIG_ADDR14 (0x000d4040 + 0x00001000)
|
||||
#define UMCCH_UMC_CONFIG_ADDR15 (0x000d4040 + 0x00001800)
|
||||
|
||||
/* Universal Memory Controller Channel Ecc config. */
|
||||
/* UMCCH:EccCtrl */
|
||||
#define UMCCH_ECCCTRL_ADDR0 (0x00014053 + 0x00000000)
|
||||
#define UMCCH_ECCCTRL_ADDR1 (0x00014053 + 0x00000800)
|
||||
#define UMCCH_ECCCTRL_ADDR2 (0x00014053 + 0x00001000)
|
||||
#define UMCCH_ECCCTRL_ADDR3 (0x00014053 + 0x00001800)
|
||||
#define UMCCH_ECCCTRL_ADDR4 (0x00054053 + 0x00000000)
|
||||
#define UMCCH_ECCCTRL_ADDR5 (0x00054053 + 0x00000800)
|
||||
#define UMCCH_ECCCTRL_ADDR6 (0x00054053 + 0x00001000)
|
||||
#define UMCCH_ECCCTRL_ADDR7 (0x00054053 + 0x00001800)
|
||||
#define UMCCH_ECCCTRL_ADDR8 (0x00094053 + 0x00000000)
|
||||
#define UMCCH_ECCCTRL_ADDR9 (0x00094053 + 0x00000800)
|
||||
#define UMCCH_ECCCTRL_ADDR10 (0x00094053 + 0x00001000)
|
||||
#define UMCCH_ECCCTRL_ADDR11 (0x00094053 + 0x00001800)
|
||||
#define UMCCH_ECCCTRL_ADDR12 (0x000d4053 + 0x00000000)
|
||||
#define UMCCH_ECCCTRL_ADDR13 (0x000d4053 + 0x00000800)
|
||||
#define UMCCH_ECCCTRL_ADDR14 (0x000d4053 + 0x00001000)
|
||||
#define UMCCH_ECCCTRL_ADDR15 (0x000d4053 + 0x00001800)
|
||||
|
||||
static const uint32_t ecc_umclocalcap_addrs[] = {
|
||||
UMCLOCALCAPS_ADDR0,
|
||||
UMCLOCALCAPS_ADDR1,
|
||||
UMCLOCALCAPS_ADDR2,
|
||||
UMCLOCALCAPS_ADDR3,
|
||||
UMCLOCALCAPS_ADDR4,
|
||||
UMCLOCALCAPS_ADDR5,
|
||||
UMCLOCALCAPS_ADDR6,
|
||||
UMCLOCALCAPS_ADDR7,
|
||||
UMCLOCALCAPS_ADDR8,
|
||||
UMCLOCALCAPS_ADDR9,
|
||||
UMCLOCALCAPS_ADDR10,
|
||||
UMCLOCALCAPS_ADDR11,
|
||||
UMCLOCALCAPS_ADDR12,
|
||||
UMCLOCALCAPS_ADDR13,
|
||||
UMCLOCALCAPS_ADDR14,
|
||||
UMCLOCALCAPS_ADDR15,
|
||||
};
|
||||
|
||||
static const uint32_t ecc_umcch_umc_config_addrs[] = {
|
||||
UMCCH_UMC_CONFIG_ADDR0,
|
||||
UMCCH_UMC_CONFIG_ADDR1,
|
||||
UMCCH_UMC_CONFIG_ADDR2,
|
||||
UMCCH_UMC_CONFIG_ADDR3,
|
||||
UMCCH_UMC_CONFIG_ADDR4,
|
||||
UMCCH_UMC_CONFIG_ADDR5,
|
||||
UMCCH_UMC_CONFIG_ADDR6,
|
||||
UMCCH_UMC_CONFIG_ADDR7,
|
||||
UMCCH_UMC_CONFIG_ADDR8,
|
||||
UMCCH_UMC_CONFIG_ADDR9,
|
||||
UMCCH_UMC_CONFIG_ADDR10,
|
||||
UMCCH_UMC_CONFIG_ADDR11,
|
||||
UMCCH_UMC_CONFIG_ADDR12,
|
||||
UMCCH_UMC_CONFIG_ADDR13,
|
||||
UMCCH_UMC_CONFIG_ADDR14,
|
||||
UMCCH_UMC_CONFIG_ADDR15,
|
||||
};
|
||||
|
||||
static const uint32_t ecc_umcch_eccctrl_addrs[] = {
|
||||
UMCCH_ECCCTRL_ADDR0,
|
||||
UMCCH_ECCCTRL_ADDR1,
|
||||
UMCCH_ECCCTRL_ADDR2,
|
||||
UMCCH_ECCCTRL_ADDR3,
|
||||
UMCCH_ECCCTRL_ADDR4,
|
||||
UMCCH_ECCCTRL_ADDR5,
|
||||
UMCCH_ECCCTRL_ADDR6,
|
||||
UMCCH_ECCCTRL_ADDR7,
|
||||
UMCCH_ECCCTRL_ADDR8,
|
||||
UMCCH_ECCCTRL_ADDR9,
|
||||
UMCCH_ECCCTRL_ADDR10,
|
||||
UMCCH_ECCCTRL_ADDR11,
|
||||
UMCCH_ECCCTRL_ADDR12,
|
||||
UMCCH_ECCCTRL_ADDR13,
|
||||
UMCCH_ECCCTRL_ADDR14,
|
||||
UMCCH_ECCCTRL_ADDR15,
|
||||
};
|
||||
|
||||
static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *src,
|
||||
unsigned type,
|
||||
|
@ -389,6 +505,85 @@ static int gmc_v9_0_early_init(void *handle)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gmc_v9_0_ecc_available(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t reg_val;
|
||||
uint32_t reg_addr;
|
||||
uint32_t field_val;
|
||||
size_t i;
|
||||
uint32_t fv2;
|
||||
size_t lost_sheep;
|
||||
|
||||
DRM_DEBUG("ecc: gmc_v9_0_ecc_available()\n");
|
||||
|
||||
lost_sheep = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(ecc_umclocalcap_addrs); ++i) {
|
||||
reg_addr = ecc_umclocalcap_addrs[i];
|
||||
DRM_DEBUG("ecc: "
|
||||
"UMCCH_UmcLocalCap[%zu]: reg_addr: 0x%08x\n",
|
||||
i, reg_addr);
|
||||
reg_val = RREG32(reg_addr);
|
||||
field_val = REG_GET_FIELD(reg_val, UMCCH0_0_UmcLocalCap,
|
||||
EccDis);
|
||||
DRM_DEBUG("ecc: "
|
||||
"reg_val: 0x%08x, "
|
||||
"EccDis: 0x%08x, ",
|
||||
reg_val, field_val);
|
||||
if (field_val) {
|
||||
DRM_ERROR("ecc: UmcLocalCap:EccDis is set.\n");
|
||||
++lost_sheep;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ecc_umcch_umc_config_addrs); ++i) {
|
||||
reg_addr = ecc_umcch_umc_config_addrs[i];
|
||||
DRM_DEBUG("ecc: "
|
||||
"UMCCH0_0_UMC_CONFIG[%zu]: reg_addr: 0x%08x",
|
||||
i, reg_addr);
|
||||
reg_val = RREG32(reg_addr);
|
||||
field_val = REG_GET_FIELD(reg_val, UMCCH0_0_UMC_CONFIG,
|
||||
DramReady);
|
||||
DRM_DEBUG("ecc: "
|
||||
"reg_val: 0x%08x, "
|
||||
"DramReady: 0x%08x\n",
|
||||
reg_val, field_val);
|
||||
|
||||
if (!field_val) {
|
||||
DRM_ERROR("ecc: UMC_CONFIG:DramReady is not set.\n");
|
||||
++lost_sheep;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ecc_umcch_eccctrl_addrs); ++i) {
|
||||
reg_addr = ecc_umcch_eccctrl_addrs[i];
|
||||
DRM_DEBUG("ecc: "
|
||||
"UMCCH_EccCtrl[%zu]: reg_addr: 0x%08x, ",
|
||||
i, reg_addr);
|
||||
reg_val = RREG32(reg_addr);
|
||||
field_val = REG_GET_FIELD(reg_val, UMCCH0_0_EccCtrl,
|
||||
WrEccEn);
|
||||
fv2 = REG_GET_FIELD(reg_val, UMCCH0_0_EccCtrl,
|
||||
RdEccEn);
|
||||
DRM_DEBUG("ecc: "
|
||||
"reg_val: 0x%08x, "
|
||||
"WrEccEn: 0x%08x, "
|
||||
"RdEccEn: 0x%08x\n",
|
||||
reg_val, field_val, fv2);
|
||||
|
||||
if (!field_val) {
|
||||
DRM_DEBUG("ecc: WrEccEn is not set\n");
|
||||
++lost_sheep;
|
||||
}
|
||||
if (!fv2) {
|
||||
DRM_DEBUG("ecc: RdEccEn is not set\n");
|
||||
++lost_sheep;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_DEBUG("ecc: lost_sheep: %zu\n", lost_sheep);
|
||||
return lost_sheep == 0;
|
||||
}
|
||||
|
||||
static int gmc_v9_0_late_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
@ -403,6 +598,7 @@ static int gmc_v9_0_late_init(void *handle)
|
|||
*/
|
||||
unsigned vm_inv_eng[AMDGPU_MAX_VMHUBS] = { 4, 4 };
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
for(i = 0; i < adev->num_rings; ++i) {
|
||||
struct amdgpu_ring *ring = adev->rings[i];
|
||||
|
@ -418,6 +614,16 @@ static int gmc_v9_0_late_init(void *handle)
|
|||
for(i = 0; i < AMDGPU_MAX_VMHUBS; ++i)
|
||||
BUG_ON(vm_inv_eng[i] > 16);
|
||||
|
||||
r = gmc_v9_0_ecc_available(adev);
|
||||
if (r == 1) {
|
||||
DRM_INFO("ECC is active.\n");
|
||||
} else if (r == 0) {
|
||||
DRM_INFO("ECC is not present.\n");
|
||||
} else {
|
||||
DRM_ERROR("gmc_v9_0_ecc_available() failed. r: %d\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
|
||||
}
|
||||
|
||||
|
@ -449,6 +655,7 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
|
|||
{
|
||||
u32 tmp;
|
||||
int chansize, numchan;
|
||||
int r;
|
||||
|
||||
adev->mc.vram_width = amdgpu_atomfirmware_get_vram_width(adev);
|
||||
if (!adev->mc.vram_width) {
|
||||
|
@ -491,17 +698,22 @@ static int gmc_v9_0_mc_init(struct amdgpu_device *adev)
|
|||
adev->mc.vram_width = numchan * chansize;
|
||||
}
|
||||
|
||||
/* Could aper size report 0 ? */
|
||||
adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
|
||||
adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
|
||||
/* size in MB on si */
|
||||
adev->mc.mc_vram_size =
|
||||
((adev->flags & AMD_IS_APU) ? nbio_v7_0_get_memsize(adev) :
|
||||
nbio_v6_1_get_memsize(adev)) * 1024ULL * 1024ULL;
|
||||
adev->mc.real_vram_size = adev->mc.mc_vram_size;
|
||||
adev->mc.visible_vram_size = adev->mc.aper_size;
|
||||
|
||||
if (!(adev->flags & AMD_IS_APU)) {
|
||||
r = amdgpu_device_resize_fb_bar(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
adev->mc.aper_base = pci_resource_start(adev->pdev, 0);
|
||||
adev->mc.aper_size = pci_resource_len(adev->pdev, 0);
|
||||
|
||||
/* In case the PCI BAR is larger than the actual amount of vram */
|
||||
adev->mc.visible_vram_size = adev->mc.aper_size;
|
||||
if (adev->mc.visible_vram_size > adev->mc.real_vram_size)
|
||||
adev->mc.visible_vram_size = adev->mc.real_vram_size;
|
||||
|
||||
|
@ -557,16 +769,11 @@ static int gmc_v9_0_sw_init(void *handle)
|
|||
switch (adev->asic_type) {
|
||||
case CHIP_RAVEN:
|
||||
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||
if (adev->rev_id == 0x0 || adev->rev_id == 0x1) {
|
||||
adev->vm_manager.vm_size = 1U << 18;
|
||||
adev->vm_manager.block_size = 9;
|
||||
adev->vm_manager.num_level = 3;
|
||||
amdgpu_vm_set_fragment_size(adev, 9);
|
||||
} else {
|
||||
if (adev->rev_id == 0x0 || adev->rev_id == 0x1)
|
||||
amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48);
|
||||
else
|
||||
/* vm_size is 64GB for legacy 2-level page support */
|
||||
amdgpu_vm_adjust_size(adev, 64, 9);
|
||||
adev->vm_manager.num_level = 1;
|
||||
}
|
||||
amdgpu_vm_adjust_size(adev, 64, 9, 1, 48);
|
||||
break;
|
||||
case CHIP_VEGA10:
|
||||
/* XXX Don't know how to get VRAM type yet. */
|
||||
|
@ -576,20 +783,12 @@ static int gmc_v9_0_sw_init(void *handle)
|
|||
* vm size is 256TB (48bit), maximum size of Vega10,
|
||||
* block size 512 (9bit)
|
||||
*/
|
||||
adev->vm_manager.vm_size = 1U << 18;
|
||||
adev->vm_manager.block_size = 9;
|
||||
adev->vm_manager.num_level = 3;
|
||||
amdgpu_vm_set_fragment_size(adev, 9);
|
||||
amdgpu_vm_adjust_size(adev, 256 * 1024, 9, 3, 48);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DRM_INFO("vm size is %llu GB, block size is %u-bit,fragment size is %u-bit\n",
|
||||
adev->vm_manager.vm_size,
|
||||
adev->vm_manager.block_size,
|
||||
adev->vm_manager.fragment_size);
|
||||
|
||||
/* This interrupt is VMC page fault.*/
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_VMC, 0,
|
||||
&adev->mc.vm_fault);
|
||||
|
@ -599,8 +798,6 @@ static int gmc_v9_0_sw_init(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
adev->vm_manager.max_pfn = adev->vm_manager.vm_size << 18;
|
||||
|
||||
/* Set the internal MC address mask
|
||||
* This is the max address of the GPU's
|
||||
* internal address space.
|
||||
|
@ -660,7 +857,7 @@ static int gmc_v9_0_sw_init(void *handle)
|
|||
}
|
||||
|
||||
/**
|
||||
* gmc_v8_0_gart_fini - vm fini callback
|
||||
* gmc_v9_0_gart_fini - vm fini callback
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
|
@ -676,9 +873,9 @@ static int gmc_v9_0_sw_fini(void *handle)
|
|||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
amdgpu_gem_force_release(adev);
|
||||
amdgpu_vm_manager_fini(adev);
|
||||
gmc_v9_0_gart_fini(adev);
|
||||
amdgpu_gem_force_release(adev);
|
||||
amdgpu_bo_fini(adev);
|
||||
|
||||
return 0;
|
||||
|
@ -690,15 +887,15 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_VEGA10:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_mmhub_1_0_0,
|
||||
(const u32)ARRAY_SIZE(golden_settings_mmhub_1_0_0));
|
||||
ARRAY_SIZE(golden_settings_mmhub_1_0_0));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_athub_1_0_0,
|
||||
(const u32)ARRAY_SIZE(golden_settings_athub_1_0_0));
|
||||
ARRAY_SIZE(golden_settings_athub_1_0_0));
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_athub_1_0_0,
|
||||
(const u32)ARRAY_SIZE(golden_settings_athub_1_0_0));
|
||||
ARRAY_SIZE(golden_settings_athub_1_0_0));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -718,7 +915,7 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev)
|
|||
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_vega10_hdp,
|
||||
(const u32)ARRAY_SIZE(golden_settings_vega10_hdp));
|
||||
ARRAY_SIZE(golden_settings_vega10_hdp));
|
||||
|
||||
if (adev->gart.robj == NULL) {
|
||||
dev_err(adev->dev, "No VRAM object for PCIE GART.\n");
|
||||
|
|
|
@ -23,14 +23,13 @@
|
|||
#include "amdgpu.h"
|
||||
#include "mmhub_v1_0.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/MMHUB/mmhub_1_0_offset.h"
|
||||
#include "vega10/MMHUB/mmhub_1_0_sh_mask.h"
|
||||
#include "vega10/MMHUB/mmhub_1_0_default.h"
|
||||
#include "vega10/ATHUB/athub_1_0_offset.h"
|
||||
#include "vega10/ATHUB/athub_1_0_sh_mask.h"
|
||||
#include "vega10/ATHUB/athub_1_0_default.h"
|
||||
#include "vega10/vega10_enum.h"
|
||||
#include "soc15ip.h"
|
||||
#include "mmhub/mmhub_1_0_offset.h"
|
||||
#include "mmhub/mmhub_1_0_sh_mask.h"
|
||||
#include "mmhub/mmhub_1_0_default.h"
|
||||
#include "athub/athub_1_0_offset.h"
|
||||
#include "athub/athub_1_0_sh_mask.h"
|
||||
#include "vega10_enum.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
*/
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/NBIO/nbio_6_1_offset.h"
|
||||
#include "vega10/NBIO/nbio_6_1_sh_mask.h"
|
||||
#include "vega10/GC/gc_9_0_offset.h"
|
||||
#include "vega10/GC/gc_9_0_sh_mask.h"
|
||||
#include "soc15ip.h"
|
||||
#include "nbio/nbio_6_1_offset.h"
|
||||
#include "nbio/nbio_6_1_sh_mask.h"
|
||||
#include "gc/gc_9_0_offset.h"
|
||||
#include "gc/gc_9_0_sh_mask.h"
|
||||
#include "soc15.h"
|
||||
#include "vega10_ih.h"
|
||||
#include "soc15_common.h"
|
||||
|
@ -254,7 +254,7 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work)
|
|||
}
|
||||
|
||||
/* Trigger recovery due to world switch failure */
|
||||
amdgpu_sriov_gpu_reset(adev, NULL);
|
||||
amdgpu_gpu_recover(adev, NULL);
|
||||
}
|
||||
|
||||
static int xgpu_ai_set_mailbox_rcv_irq(struct amdgpu_device *adev,
|
||||
|
@ -282,9 +282,17 @@ static int xgpu_ai_mailbox_rcv_irq(struct amdgpu_device *adev,
|
|||
/* see what event we get */
|
||||
r = xgpu_ai_mailbox_rcv_msg(adev, IDH_FLR_NOTIFICATION);
|
||||
|
||||
/* only handle FLR_NOTIFY now */
|
||||
if (!r)
|
||||
schedule_work(&adev->virt.flr_work);
|
||||
/* sometimes the interrupt is delayed to inject to VM, so under such case
|
||||
* the IDH_FLR_NOTIFICATION is overwritten by VF FLR from GIM side, thus
|
||||
* above recieve message could be failed, we should schedule the flr_work
|
||||
* anyway
|
||||
*/
|
||||
if (r) {
|
||||
DRM_ERROR("FLR_NOTIFICATION is missed\n");
|
||||
xgpu_ai_mailbox_send_ack(adev);
|
||||
}
|
||||
|
||||
schedule_work(&adev->virt.flr_work);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -353,5 +361,6 @@ const struct amdgpu_virt_ops xgpu_ai_virt_ops = {
|
|||
.req_full_gpu = xgpu_ai_request_full_gpu_access,
|
||||
.rel_full_gpu = xgpu_ai_release_full_gpu_access,
|
||||
.reset_gpu = xgpu_ai_request_reset,
|
||||
.wait_reset = NULL,
|
||||
.trans_msg = xgpu_ai_mailbox_trans_msg,
|
||||
};
|
||||
|
|
|
@ -281,29 +281,29 @@ void xgpu_vi_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_FIJI:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
xgpu_fiji_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(
|
||||
ARRAY_SIZE(
|
||||
xgpu_fiji_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
xgpu_fiji_golden_settings_a10,
|
||||
(const u32)ARRAY_SIZE(
|
||||
ARRAY_SIZE(
|
||||
xgpu_fiji_golden_settings_a10));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
xgpu_fiji_golden_common_all,
|
||||
(const u32)ARRAY_SIZE(
|
||||
ARRAY_SIZE(
|
||||
xgpu_fiji_golden_common_all));
|
||||
break;
|
||||
case CHIP_TONGA:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
xgpu_tonga_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(
|
||||
ARRAY_SIZE(
|
||||
xgpu_tonga_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
xgpu_tonga_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(
|
||||
ARRAY_SIZE(
|
||||
xgpu_tonga_golden_settings_a11));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
xgpu_tonga_golden_common_all,
|
||||
(const u32)ARRAY_SIZE(
|
||||
ARRAY_SIZE(
|
||||
xgpu_tonga_golden_common_all));
|
||||
break;
|
||||
default:
|
||||
|
@ -446,8 +446,10 @@ static int xgpu_vi_send_access_requests(struct amdgpu_device *adev,
|
|||
request == IDH_REQ_GPU_FINI_ACCESS ||
|
||||
request == IDH_REQ_GPU_RESET_ACCESS) {
|
||||
r = xgpu_vi_poll_msg(adev, IDH_READY_TO_ACCESS_GPU);
|
||||
if (r)
|
||||
pr_err("Doesn't get ack from pf, continue\n");
|
||||
if (r) {
|
||||
pr_err("Doesn't get ack from pf, give up\n");
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -458,6 +460,11 @@ static int xgpu_vi_request_reset(struct amdgpu_device *adev)
|
|||
return xgpu_vi_send_access_requests(adev, IDH_REQ_GPU_RESET_ACCESS);
|
||||
}
|
||||
|
||||
static int xgpu_vi_wait_reset_cmpl(struct amdgpu_device *adev)
|
||||
{
|
||||
return xgpu_vi_poll_msg(adev, IDH_FLR_NOTIFICATION_CMPL);
|
||||
}
|
||||
|
||||
static int xgpu_vi_request_full_gpu_access(struct amdgpu_device *adev,
|
||||
bool init)
|
||||
{
|
||||
|
@ -514,7 +521,7 @@ static void xgpu_vi_mailbox_flr_work(struct work_struct *work)
|
|||
}
|
||||
|
||||
/* Trigger recovery due to world switch failure */
|
||||
amdgpu_sriov_gpu_reset(adev, NULL);
|
||||
amdgpu_gpu_recover(adev, NULL);
|
||||
}
|
||||
|
||||
static int xgpu_vi_set_mailbox_rcv_irq(struct amdgpu_device *adev,
|
||||
|
@ -613,5 +620,6 @@ const struct amdgpu_virt_ops xgpu_vi_virt_ops = {
|
|||
.req_full_gpu = xgpu_vi_request_full_gpu_access,
|
||||
.rel_full_gpu = xgpu_vi_release_full_gpu_access,
|
||||
.reset_gpu = xgpu_vi_request_reset,
|
||||
.wait_reset = xgpu_vi_wait_reset_cmpl,
|
||||
.trans_msg = NULL, /* Does not need to trans VF errors to host. */
|
||||
};
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v6_1.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/NBIO/nbio_6_1_default.h"
|
||||
#include "vega10/NBIO/nbio_6_1_offset.h"
|
||||
#include "vega10/NBIO/nbio_6_1_sh_mask.h"
|
||||
#include "vega10/vega10_enum.h"
|
||||
#include "soc15ip.h"
|
||||
#include "nbio/nbio_6_1_default.h"
|
||||
#include "nbio/nbio_6_1_offset.h"
|
||||
#include "nbio/nbio_6_1_sh_mask.h"
|
||||
#include "vega10_enum.h"
|
||||
|
||||
#define smnCPM_CONTROL 0x11180460
|
||||
#define smnPCIE_CNTL2 0x11180070
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
#include "amdgpu_atombios.h"
|
||||
#include "nbio_v7_0.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "raven1/NBIO/nbio_7_0_default.h"
|
||||
#include "raven1/NBIO/nbio_7_0_offset.h"
|
||||
#include "raven1/NBIO/nbio_7_0_sh_mask.h"
|
||||
#include "vega10/vega10_enum.h"
|
||||
#include "soc15ip.h"
|
||||
#include "nbio/nbio_7_0_default.h"
|
||||
#include "nbio/nbio_7_0_offset.h"
|
||||
#include "nbio/nbio_7_0_sh_mask.h"
|
||||
#include "vega10_enum.h"
|
||||
|
||||
#define smnNBIF_MGCG_CTRL_LCLK 0x1013a05c
|
||||
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
#include "soc15_common.h"
|
||||
#include "psp_v10_0.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "raven1/MP/mp_10_0_offset.h"
|
||||
#include "raven1/GC/gc_9_1_offset.h"
|
||||
#include "raven1/SDMA0/sdma0_4_1_offset.h"
|
||||
#include "soc15ip.h"
|
||||
#include "mp/mp_10_0_offset.h"
|
||||
#include "gc/gc_9_1_offset.h"
|
||||
#include "sdma0/sdma0_4_1_offset.h"
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/raven_asd.bin");
|
||||
|
||||
|
|
|
@ -31,12 +31,12 @@
|
|||
#include "soc15_common.h"
|
||||
#include "psp_v3_1.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/MP/mp_9_0_offset.h"
|
||||
#include "vega10/MP/mp_9_0_sh_mask.h"
|
||||
#include "vega10/GC/gc_9_0_offset.h"
|
||||
#include "vega10/SDMA0/sdma0_4_0_offset.h"
|
||||
#include "vega10/NBIO/nbio_6_1_offset.h"
|
||||
#include "soc15ip.h"
|
||||
#include "mp/mp_9_0_offset.h"
|
||||
#include "mp/mp_9_0_sh_mask.h"
|
||||
#include "gc/gc_9_0_offset.h"
|
||||
#include "sdma0/sdma0_4_0_offset.h"
|
||||
#include "nbio/nbio_6_1_offset.h"
|
||||
|
||||
MODULE_FIRMWARE("amdgpu/vega10_sos.bin");
|
||||
MODULE_FIRMWARE("amdgpu/vega10_asd.bin");
|
||||
|
|
|
@ -95,10 +95,10 @@ static void sdma_v2_4_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_TOPAZ:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
iceland_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(iceland_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(iceland_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_iceland_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_iceland_a11));
|
||||
ARRAY_SIZE(golden_settings_iceland_a11));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -633,7 +633,7 @@ static int sdma_v2_4_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
|
||||
ring->idx, tmp);
|
||||
|
@ -704,7 +704,7 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
}
|
||||
tmp = le32_to_cpu(adev->wb.wb[index]);
|
||||
if (tmp == 0xDEADBEEF) {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp);
|
||||
|
|
|
@ -194,45 +194,45 @@ static void sdma_v3_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_FIJI:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
fiji_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(fiji_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(fiji_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_fiji_a10,
|
||||
(const u32)ARRAY_SIZE(golden_settings_fiji_a10));
|
||||
ARRAY_SIZE(golden_settings_fiji_a10));
|
||||
break;
|
||||
case CHIP_TONGA:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
tonga_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(tonga_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(tonga_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_tonga_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
ARRAY_SIZE(golden_settings_tonga_a11));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS12:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris11_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
ARRAY_SIZE(golden_settings_polaris11_a11));
|
||||
break;
|
||||
case CHIP_POLARIS10:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_polaris10_a11,
|
||||
(const u32)ARRAY_SIZE(golden_settings_polaris10_a11));
|
||||
ARRAY_SIZE(golden_settings_polaris10_a11));
|
||||
break;
|
||||
case CHIP_CARRIZO:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
cz_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(cz_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(cz_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
cz_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(cz_golden_settings_a11));
|
||||
ARRAY_SIZE(cz_golden_settings_a11));
|
||||
break;
|
||||
case CHIP_STONEY:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
stoney_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(stoney_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(stoney_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
stoney_golden_settings_a11,
|
||||
(const u32)ARRAY_SIZE(stoney_golden_settings_a11));
|
||||
ARRAY_SIZE(stoney_golden_settings_a11));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -893,7 +893,7 @@ static int sdma_v3_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
|
||||
ring->idx, tmp);
|
||||
|
@ -964,7 +964,7 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
}
|
||||
tmp = le32_to_cpu(adev->wb.wb[index]);
|
||||
if (tmp == 0xDEADBEEF) {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp);
|
||||
|
|
|
@ -27,15 +27,15 @@
|
|||
#include "amdgpu_ucode.h"
|
||||
#include "amdgpu_trace.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/SDMA0/sdma0_4_0_offset.h"
|
||||
#include "vega10/SDMA0/sdma0_4_0_sh_mask.h"
|
||||
#include "vega10/SDMA1/sdma1_4_0_offset.h"
|
||||
#include "vega10/SDMA1/sdma1_4_0_sh_mask.h"
|
||||
#include "vega10/MMHUB/mmhub_1_0_offset.h"
|
||||
#include "vega10/MMHUB/mmhub_1_0_sh_mask.h"
|
||||
#include "vega10/HDP/hdp_4_0_offset.h"
|
||||
#include "raven1/SDMA0/sdma0_4_1_default.h"
|
||||
#include "soc15ip.h"
|
||||
#include "sdma0/sdma0_4_0_offset.h"
|
||||
#include "sdma0/sdma0_4_0_sh_mask.h"
|
||||
#include "sdma1/sdma1_4_0_offset.h"
|
||||
#include "sdma1/sdma1_4_0_sh_mask.h"
|
||||
#include "mmhub/mmhub_1_0_offset.h"
|
||||
#include "mmhub/mmhub_1_0_sh_mask.h"
|
||||
#include "hdp/hdp_4_0_offset.h"
|
||||
#include "sdma0/sdma0_4_1_default.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "soc15.h"
|
||||
|
@ -132,18 +132,18 @@ static void sdma_v4_0_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_VEGA10:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_sdma_4,
|
||||
(const u32)ARRAY_SIZE(golden_settings_sdma_4));
|
||||
ARRAY_SIZE(golden_settings_sdma_4));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_sdma_vg10,
|
||||
(const u32)ARRAY_SIZE(golden_settings_sdma_vg10));
|
||||
ARRAY_SIZE(golden_settings_sdma_vg10));
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_sdma_4_1,
|
||||
(const u32)ARRAY_SIZE(golden_settings_sdma_4_1));
|
||||
ARRAY_SIZE(golden_settings_sdma_4_1));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
golden_settings_sdma_rv1,
|
||||
(const u32)ARRAY_SIZE(golden_settings_sdma_rv1));
|
||||
ARRAY_SIZE(golden_settings_sdma_rv1));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -919,7 +919,7 @@ static int sdma_v4_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
|
||||
ring->idx, tmp);
|
||||
|
@ -990,7 +990,7 @@ static int sdma_v4_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
}
|
||||
tmp = le32_to_cpu(adev->wb.wb[index]);
|
||||
if (tmp == 0xDEADBEEF) {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp);
|
||||
|
|
|
@ -1392,63 +1392,63 @@ static void si_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_TAHITI:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
tahiti_golden_registers,
|
||||
(const u32)ARRAY_SIZE(tahiti_golden_registers));
|
||||
ARRAY_SIZE(tahiti_golden_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
tahiti_golden_rlc_registers,
|
||||
(const u32)ARRAY_SIZE(tahiti_golden_rlc_registers));
|
||||
ARRAY_SIZE(tahiti_golden_rlc_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
tahiti_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(tahiti_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(tahiti_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
tahiti_golden_registers2,
|
||||
(const u32)ARRAY_SIZE(tahiti_golden_registers2));
|
||||
ARRAY_SIZE(tahiti_golden_registers2));
|
||||
break;
|
||||
case CHIP_PITCAIRN:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
pitcairn_golden_registers,
|
||||
(const u32)ARRAY_SIZE(pitcairn_golden_registers));
|
||||
ARRAY_SIZE(pitcairn_golden_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
pitcairn_golden_rlc_registers,
|
||||
(const u32)ARRAY_SIZE(pitcairn_golden_rlc_registers));
|
||||
ARRAY_SIZE(pitcairn_golden_rlc_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
pitcairn_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(pitcairn_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(pitcairn_mgcg_cgcg_init));
|
||||
break;
|
||||
case CHIP_VERDE:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
verde_golden_registers,
|
||||
(const u32)ARRAY_SIZE(verde_golden_registers));
|
||||
ARRAY_SIZE(verde_golden_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
verde_golden_rlc_registers,
|
||||
(const u32)ARRAY_SIZE(verde_golden_rlc_registers));
|
||||
ARRAY_SIZE(verde_golden_rlc_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
verde_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(verde_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(verde_mgcg_cgcg_init));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
verde_pg_init,
|
||||
(const u32)ARRAY_SIZE(verde_pg_init));
|
||||
ARRAY_SIZE(verde_pg_init));
|
||||
break;
|
||||
case CHIP_OLAND:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
oland_golden_registers,
|
||||
(const u32)ARRAY_SIZE(oland_golden_registers));
|
||||
ARRAY_SIZE(oland_golden_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
oland_golden_rlc_registers,
|
||||
(const u32)ARRAY_SIZE(oland_golden_rlc_registers));
|
||||
ARRAY_SIZE(oland_golden_rlc_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
oland_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(oland_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(oland_mgcg_cgcg_init));
|
||||
break;
|
||||
case CHIP_HAINAN:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
hainan_golden_registers,
|
||||
(const u32)ARRAY_SIZE(hainan_golden_registers));
|
||||
ARRAY_SIZE(hainan_golden_registers));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
hainan_golden_registers2,
|
||||
(const u32)ARRAY_SIZE(hainan_golden_registers2));
|
||||
ARRAY_SIZE(hainan_golden_registers2));
|
||||
amdgpu_program_register_sequence(adev,
|
||||
hainan_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(hainan_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(hainan_mgcg_cgcg_init));
|
||||
break;
|
||||
|
||||
|
||||
|
|
|
@ -252,7 +252,7 @@ static int si_dma_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n", ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
|
||||
ring->idx, tmp);
|
||||
|
@ -317,7 +317,7 @@ static int si_dma_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
}
|
||||
tmp = le32_to_cpu(adev->wb.wb[index]);
|
||||
if (tmp == 0xDEADBEEF) {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ib test failed (0x%08X)\n", tmp);
|
||||
|
|
|
@ -5845,9 +5845,9 @@ static int si_set_mc_special_registers(struct amdgpu_device *adev,
|
|||
((temp_reg & 0xffff0000)) |
|
||||
((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
|
||||
j++;
|
||||
|
||||
if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
temp_reg = RREG32(MC_PMG_CMD_MRS);
|
||||
table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS;
|
||||
table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP;
|
||||
|
@ -5859,18 +5859,16 @@ static int si_set_mc_special_registers(struct amdgpu_device *adev,
|
|||
table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
|
||||
}
|
||||
j++;
|
||||
if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (adev->mc.vram_type != AMDGPU_VRAM_TYPE_GDDR5) {
|
||||
if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
|
||||
return -EINVAL;
|
||||
table->mc_reg_address[j].s1 = MC_PMG_AUTO_CMD;
|
||||
table->mc_reg_address[j].s0 = MC_PMG_AUTO_CMD;
|
||||
for (k = 0; k < table->num_entries; k++)
|
||||
table->mc_reg_table_entry[k].mc_data[j] =
|
||||
(table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16;
|
||||
j++;
|
||||
if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case MC_SEQ_RESERVE_M:
|
||||
|
@ -5882,8 +5880,6 @@ static int si_set_mc_special_registers(struct amdgpu_device *adev,
|
|||
(temp_reg & 0xffff0000) |
|
||||
(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
|
||||
j++;
|
||||
if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -34,18 +34,18 @@
|
|||
#include "atom.h"
|
||||
#include "amd_pcie.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/UVD/uvd_7_0_offset.h"
|
||||
#include "vega10/GC/gc_9_0_offset.h"
|
||||
#include "vega10/GC/gc_9_0_sh_mask.h"
|
||||
#include "vega10/SDMA0/sdma0_4_0_offset.h"
|
||||
#include "vega10/SDMA1/sdma1_4_0_offset.h"
|
||||
#include "vega10/HDP/hdp_4_0_offset.h"
|
||||
#include "vega10/HDP/hdp_4_0_sh_mask.h"
|
||||
#include "vega10/MP/mp_9_0_offset.h"
|
||||
#include "vega10/MP/mp_9_0_sh_mask.h"
|
||||
#include "vega10/SMUIO/smuio_9_0_offset.h"
|
||||
#include "vega10/SMUIO/smuio_9_0_sh_mask.h"
|
||||
#include "soc15ip.h"
|
||||
#include "uvd/uvd_7_0_offset.h"
|
||||
#include "gc/gc_9_0_offset.h"
|
||||
#include "gc/gc_9_0_sh_mask.h"
|
||||
#include "sdma0/sdma0_4_0_offset.h"
|
||||
#include "sdma1/sdma1_4_0_offset.h"
|
||||
#include "hdp/hdp_4_0_offset.h"
|
||||
#include "hdp/hdp_4_0_sh_mask.h"
|
||||
#include "mp/mp_9_0_offset.h"
|
||||
#include "mp/mp_9_0_sh_mask.h"
|
||||
#include "smuio/smuio_9_0_offset.h"
|
||||
#include "smuio/smuio_9_0_sh_mask.h"
|
||||
|
||||
#include "soc15.h"
|
||||
#include "soc15_common.h"
|
||||
|
@ -265,12 +265,12 @@ static void soc15_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_VEGA10:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
vega10_golden_init,
|
||||
(const u32)ARRAY_SIZE(vega10_golden_init));
|
||||
ARRAY_SIZE(vega10_golden_init));
|
||||
break;
|
||||
case CHIP_RAVEN:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
raven_golden_init,
|
||||
(const u32)ARRAY_SIZE(raven_golden_init));
|
||||
ARRAY_SIZE(raven_golden_init));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -521,7 +521,7 @@ static int uvd_v4_2_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
|
||||
|
@ -563,7 +563,7 @@ static void uvd_v4_2_mc_resume(struct amdgpu_device *adev)
|
|||
|
||||
/* programm the VCPU memory controller bits 0-27 */
|
||||
addr = (adev->uvd.gpu_addr + AMDGPU_UVD_FIRMWARE_OFFSET) >> 3;
|
||||
size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4) >> 3;
|
||||
size = AMDGPU_UVD_FIRMWARE_SIZE(adev) >> 3;
|
||||
WREG32(mmUVD_VCPU_CACHE_OFFSET0, addr);
|
||||
WREG32(mmUVD_VCPU_CACHE_SIZE0, size);
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ static void uvd_v5_0_mc_resume(struct amdgpu_device *adev)
|
|||
upper_32_bits(adev->uvd.gpu_addr));
|
||||
|
||||
offset = AMDGPU_UVD_FIRMWARE_OFFSET;
|
||||
size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
|
||||
size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
|
||||
WREG32(mmUVD_VCPU_CACHE_OFFSET0, offset >> 3);
|
||||
WREG32(mmUVD_VCPU_CACHE_SIZE0, size);
|
||||
|
||||
|
@ -536,7 +536,7 @@ static int uvd_v5_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
|
||||
|
|
|
@ -184,7 +184,7 @@ static int uvd_v6_0_enc_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed\n",
|
||||
|
@ -360,7 +360,7 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
} else if (r < 0) {
|
||||
DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
|
||||
} else {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
}
|
||||
error:
|
||||
|
@ -416,7 +416,7 @@ static int uvd_v6_0_sw_init(void *handle)
|
|||
ring = &adev->uvd.ring_enc[0];
|
||||
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL];
|
||||
r = amd_sched_entity_init(&ring->sched, &adev->uvd.entity_enc,
|
||||
rq, amdgpu_sched_jobs);
|
||||
rq, amdgpu_sched_jobs, NULL);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed setting up UVD ENC run queue.\n");
|
||||
return r;
|
||||
|
@ -603,7 +603,7 @@ static void uvd_v6_0_mc_resume(struct amdgpu_device *adev)
|
|||
upper_32_bits(adev->uvd.gpu_addr));
|
||||
|
||||
offset = AMDGPU_UVD_FIRMWARE_OFFSET;
|
||||
size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
|
||||
size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
|
||||
WREG32(mmUVD_VCPU_CACHE_OFFSET0, offset >> 3);
|
||||
WREG32(mmUVD_VCPU_CACHE_SIZE0, size);
|
||||
|
||||
|
@ -1008,7 +1008,7 @@ static int uvd_v6_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
|
||||
|
|
|
@ -29,16 +29,16 @@
|
|||
#include "soc15_common.h"
|
||||
#include "mmsch_v1_0.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/UVD/uvd_7_0_offset.h"
|
||||
#include "vega10/UVD/uvd_7_0_sh_mask.h"
|
||||
#include "vega10/VCE/vce_4_0_offset.h"
|
||||
#include "vega10/VCE/vce_4_0_default.h"
|
||||
#include "vega10/VCE/vce_4_0_sh_mask.h"
|
||||
#include "vega10/NBIF/nbif_6_1_offset.h"
|
||||
#include "vega10/HDP/hdp_4_0_offset.h"
|
||||
#include "vega10/MMHUB/mmhub_1_0_offset.h"
|
||||
#include "vega10/MMHUB/mmhub_1_0_sh_mask.h"
|
||||
#include "soc15ip.h"
|
||||
#include "uvd/uvd_7_0_offset.h"
|
||||
#include "uvd/uvd_7_0_sh_mask.h"
|
||||
#include "vce/vce_4_0_offset.h"
|
||||
#include "vce/vce_4_0_default.h"
|
||||
#include "vce/vce_4_0_sh_mask.h"
|
||||
#include "nbif/nbif_6_1_offset.h"
|
||||
#include "hdp/hdp_4_0_offset.h"
|
||||
#include "mmhub/mmhub_1_0_offset.h"
|
||||
#include "mmhub/mmhub_1_0_sh_mask.h"
|
||||
|
||||
static void uvd_v7_0_set_ring_funcs(struct amdgpu_device *adev);
|
||||
static void uvd_v7_0_set_enc_ring_funcs(struct amdgpu_device *adev);
|
||||
|
@ -184,7 +184,7 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed\n",
|
||||
|
@ -359,7 +359,7 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
} else if (r < 0) {
|
||||
DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r);
|
||||
} else {
|
||||
DRM_INFO("ib test on ring %d succeeded\n", ring->idx);
|
||||
DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx);
|
||||
r = 0;
|
||||
}
|
||||
error:
|
||||
|
@ -418,7 +418,7 @@ static int uvd_v7_0_sw_init(void *handle)
|
|||
ring = &adev->uvd.ring_enc[0];
|
||||
rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL];
|
||||
r = amd_sched_entity_init(&ring->sched, &adev->uvd.entity_enc,
|
||||
rq, amdgpu_sched_jobs);
|
||||
rq, amdgpu_sched_jobs, NULL);
|
||||
if (r) {
|
||||
DRM_ERROR("Failed setting up UVD ENC run queue.\n");
|
||||
return r;
|
||||
|
@ -616,7 +616,7 @@ static int uvd_v7_0_resume(void *handle)
|
|||
*/
|
||||
static void uvd_v7_0_mc_resume(struct amdgpu_device *adev)
|
||||
{
|
||||
uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->uvd.fw->size + 4);
|
||||
uint32_t size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
|
||||
uint32_t offset;
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
|
@ -1192,7 +1192,7 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
if (i < adev->usec_timeout) {
|
||||
DRM_INFO("ring test on %d succeeded in %d usecs\n",
|
||||
DRM_DEBUG("ring test on %d succeeded in %d usecs\n",
|
||||
ring->idx, i);
|
||||
} else {
|
||||
DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n",
|
||||
|
|
52
drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
Normal file → Executable file
52
drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
Normal file → Executable file
|
@ -32,12 +32,12 @@
|
|||
#include "soc15_common.h"
|
||||
#include "mmsch_v1_0.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/VCE/vce_4_0_offset.h"
|
||||
#include "vega10/VCE/vce_4_0_default.h"
|
||||
#include "vega10/VCE/vce_4_0_sh_mask.h"
|
||||
#include "vega10/MMHUB/mmhub_1_0_offset.h"
|
||||
#include "vega10/MMHUB/mmhub_1_0_sh_mask.h"
|
||||
#include "soc15ip.h"
|
||||
#include "vce/vce_4_0_offset.h"
|
||||
#include "vce/vce_4_0_default.h"
|
||||
#include "vce/vce_4_0_sh_mask.h"
|
||||
#include "mmhub/mmhub_1_0_offset.h"
|
||||
#include "mmhub/mmhub_1_0_sh_mask.h"
|
||||
|
||||
#define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK 0x02
|
||||
|
||||
|
@ -243,37 +243,49 @@ static int vce_v4_0_sriov_start(struct amdgpu_device *adev)
|
|||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_VM_CTRL), 0);
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_VCPU_CACHE_40BIT_BAR0),
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCE].mc_addr >> 8);
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_VCPU_CACHE_40BIT_BAR1),
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCE].mc_addr >> 8);
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_VCPU_CACHE_40BIT_BAR2),
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0,
|
||||
mmVCE_LMI_VCPU_CACHE_40BIT_BAR0),
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCE].mc_addr >> 8);
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0,
|
||||
mmVCE_LMI_VCPU_CACHE_64BIT_BAR0),
|
||||
(adev->firmware.ucode[AMDGPU_UCODE_ID_VCE].mc_addr >> 40) & 0xff);
|
||||
} else {
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_VCPU_CACHE_40BIT_BAR0),
|
||||
adev->vce.gpu_addr >> 8);
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_VCPU_CACHE_40BIT_BAR1),
|
||||
adev->vce.gpu_addr >> 8);
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_VCPU_CACHE_40BIT_BAR2),
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0,
|
||||
mmVCE_LMI_VCPU_CACHE_40BIT_BAR0),
|
||||
adev->vce.gpu_addr >> 8);
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0,
|
||||
mmVCE_LMI_VCPU_CACHE_64BIT_BAR0),
|
||||
(adev->vce.gpu_addr >> 40) & 0xff);
|
||||
}
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0,
|
||||
mmVCE_LMI_VCPU_CACHE_40BIT_BAR1),
|
||||
adev->vce.gpu_addr >> 8);
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0,
|
||||
mmVCE_LMI_VCPU_CACHE_64BIT_BAR1),
|
||||
(adev->vce.gpu_addr >> 40) & 0xff);
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0,
|
||||
mmVCE_LMI_VCPU_CACHE_40BIT_BAR2),
|
||||
adev->vce.gpu_addr >> 8);
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0,
|
||||
mmVCE_LMI_VCPU_CACHE_64BIT_BAR2),
|
||||
(adev->vce.gpu_addr >> 40) & 0xff);
|
||||
|
||||
offset = AMDGPU_VCE_FIRMWARE_OFFSET;
|
||||
size = VCE_V4_0_FW_SIZE;
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_OFFSET0),
|
||||
offset & 0x7FFFFFFF);
|
||||
offset & ~0x0f000000);
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_SIZE0), size);
|
||||
|
||||
offset += size;
|
||||
offset = (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) ? offset + size : 0;
|
||||
size = VCE_V4_0_STACK_SIZE;
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_OFFSET1),
|
||||
offset & 0x7FFFFFFF);
|
||||
(offset & ~0x0f000000) | (1 << 24));
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_SIZE1), size);
|
||||
|
||||
offset += size;
|
||||
size = VCE_V4_0_DATA_SIZE;
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_OFFSET2),
|
||||
offset & 0x7FFFFFFF);
|
||||
(offset & ~0x0f000000) | (2 << 24));
|
||||
MMSCH_V1_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CACHE_SIZE2), size);
|
||||
|
||||
MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCE, 0, mmVCE_LMI_CTRL2), ~0x100, 0);
|
||||
|
|
|
@ -28,12 +28,12 @@
|
|||
#include "soc15d.h"
|
||||
#include "soc15_common.h"
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "raven1/VCN/vcn_1_0_offset.h"
|
||||
#include "raven1/VCN/vcn_1_0_sh_mask.h"
|
||||
#include "vega10/HDP/hdp_4_0_offset.h"
|
||||
#include "raven1/MMHUB/mmhub_9_1_offset.h"
|
||||
#include "raven1/MMHUB/mmhub_9_1_sh_mask.h"
|
||||
#include "soc15ip.h"
|
||||
#include "vcn/vcn_1_0_offset.h"
|
||||
#include "vcn/vcn_1_0_sh_mask.h"
|
||||
#include "hdp/hdp_4_0_offset.h"
|
||||
#include "mmhub/mmhub_9_1_offset.h"
|
||||
#include "mmhub/mmhub_9_1_sh_mask.h"
|
||||
|
||||
static int vcn_v1_0_start(struct amdgpu_device *adev);
|
||||
static int vcn_v1_0_stop(struct amdgpu_device *adev);
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
#include "soc15.h"
|
||||
|
||||
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "vega10/OSSSYS/osssys_4_0_offset.h"
|
||||
#include "vega10/OSSSYS/osssys_4_0_sh_mask.h"
|
||||
#include "soc15ip.h"
|
||||
#include "oss/osssys_4_0_offset.h"
|
||||
#include "oss/osssys_4_0_sh_mask.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#include "vega10_ih.h"
|
||||
|
@ -46,11 +46,11 @@ static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev);
|
|||
*/
|
||||
static void vega10_ih_enable_interrupts(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 ih_rb_cntl = RREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL));
|
||||
u32 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
|
||||
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 1);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1);
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), ih_rb_cntl);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
adev->irq.ih.enabled = true;
|
||||
}
|
||||
|
||||
|
@ -63,14 +63,14 @@ static void vega10_ih_enable_interrupts(struct amdgpu_device *adev)
|
|||
*/
|
||||
static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 ih_rb_cntl = RREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL));
|
||||
u32 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
|
||||
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 0);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 0);
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), ih_rb_cntl);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
/* set rptr, wptr to 0 */
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR), 0);
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR), 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
|
||||
adev->irq.ih.enabled = false;
|
||||
adev->irq.ih.rptr = 0;
|
||||
}
|
||||
|
@ -102,15 +102,15 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
|||
else
|
||||
nbio_v6_1_ih_control(adev);
|
||||
|
||||
ih_rb_cntl = RREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL));
|
||||
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
|
||||
/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
|
||||
if (adev->irq.ih.use_bus_addr) {
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE), adev->irq.ih.rb_dma_addr >> 8);
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE_HI), ((u64)adev->irq.ih.rb_dma_addr >> 40) & 0xff);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.rb_dma_addr >> 8);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, ((u64)adev->irq.ih.rb_dma_addr >> 40) & 0xff);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE, 1);
|
||||
} else {
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE), adev->irq.ih.gpu_addr >> 8);
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE_HI), (adev->irq.ih.gpu_addr >> 40) & 0xff);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (adev->irq.ih.gpu_addr >> 40) & 0xff);
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE, 4);
|
||||
}
|
||||
rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
|
||||
|
@ -126,21 +126,21 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
|||
if (adev->irq.msi_enabled)
|
||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM, 1);
|
||||
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), ih_rb_cntl);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||
|
||||
/* set the writeback address whether it's enabled or not */
|
||||
if (adev->irq.ih.use_bus_addr)
|
||||
wptr_off = adev->irq.ih.rb_dma_addr + (adev->irq.ih.wptr_offs * 4);
|
||||
else
|
||||
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO), lower_32_bits(wptr_off));
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI), upper_32_bits(wptr_off) & 0xFF);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
|
||||
|
||||
/* set rptr, wptr to 0 */
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR), 0);
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR), 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0);
|
||||
|
||||
ih_doorbell_rtpr = RREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_DOORBELL_RPTR));
|
||||
ih_doorbell_rtpr = RREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR);
|
||||
if (adev->irq.ih.use_doorbell) {
|
||||
ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
|
||||
OFFSET, adev->irq.ih.doorbell_index);
|
||||
|
@ -150,20 +150,20 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
|||
ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, IH_DOORBELL_RPTR,
|
||||
ENABLE, 0);
|
||||
}
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_DOORBELL_RPTR), ih_doorbell_rtpr);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR, ih_doorbell_rtpr);
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
nbio_v7_0_ih_doorbell_range(adev, adev->irq.ih.use_doorbell, adev->irq.ih.doorbell_index);
|
||||
else
|
||||
nbio_v6_1_ih_doorbell_range(adev, adev->irq.ih.use_doorbell, adev->irq.ih.doorbell_index);
|
||||
|
||||
tmp = RREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL));
|
||||
tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL,
|
||||
CLIENT18_IS_STORM_CLIENT, 1);
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL), tmp);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp);
|
||||
|
||||
tmp = RREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_INT_FLOOD_CNTL));
|
||||
tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL);
|
||||
tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1);
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_INT_FLOOD_CNTL), tmp);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp);
|
||||
|
||||
pci_set_master(adev->pdev);
|
||||
|
||||
|
@ -367,7 +367,7 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev)
|
|||
adev->wb.wb[adev->irq.ih.rptr_offs] = adev->irq.ih.rptr;
|
||||
WDOORBELL32(adev->irq.ih.doorbell_index, adev->irq.ih.rptr);
|
||||
} else {
|
||||
WREG32(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR), adev->irq.ih.rptr);
|
||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, adev->irq.ih.rptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -284,27 +284,27 @@ static void vi_init_golden_registers(struct amdgpu_device *adev)
|
|||
case CHIP_TOPAZ:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
iceland_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(iceland_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(iceland_mgcg_cgcg_init));
|
||||
break;
|
||||
case CHIP_FIJI:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
fiji_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(fiji_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(fiji_mgcg_cgcg_init));
|
||||
break;
|
||||
case CHIP_TONGA:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
tonga_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(tonga_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(tonga_mgcg_cgcg_init));
|
||||
break;
|
||||
case CHIP_CARRIZO:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
cz_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(cz_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(cz_mgcg_cgcg_init));
|
||||
break;
|
||||
case CHIP_STONEY:
|
||||
amdgpu_program_register_sequence(adev,
|
||||
stoney_mgcg_cgcg_init,
|
||||
(const u32)ARRAY_SIZE(stoney_mgcg_cgcg_init));
|
||||
ARRAY_SIZE(stoney_mgcg_cgcg_init));
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_POLARIS10:
|
||||
|
|
|
@ -59,9 +59,9 @@
|
|||
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
|
||||
#include "ivsrcid/irqsrcs_dcn_1_0.h"
|
||||
|
||||
#include "raven1/DCN/dcn_1_0_offset.h"
|
||||
#include "raven1/DCN/dcn_1_0_sh_mask.h"
|
||||
#include "vega10/soc15ip.h"
|
||||
#include "dcn/dcn_1_0_offset.h"
|
||||
#include "dcn/dcn_1_0_sh_mask.h"
|
||||
#include "soc15ip.h"
|
||||
|
||||
#include "soc15_common.h"
|
||||
#endif
|
||||
|
@ -792,7 +792,7 @@ dm_atomic_state_alloc_free(struct drm_atomic_state *state)
|
|||
|
||||
static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = {
|
||||
.fb_create = amdgpu_user_framebuffer_create,
|
||||
.output_poll_changed = amdgpu_output_poll_changed,
|
||||
.output_poll_changed = drm_fb_helper_output_poll_changed,
|
||||
.atomic_check = amdgpu_dm_atomic_check,
|
||||
.atomic_commit = amdgpu_dm_atomic_commit,
|
||||
.atomic_state_alloc = dm_atomic_state_alloc,
|
||||
|
@ -1590,7 +1590,6 @@ static int dm_early_init(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev->ddev->driver->driver_features |= DRIVER_ATOMIC;
|
||||
amdgpu_dm_set_irq_funcs(adev);
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_BONAIRE:
|
||||
|
@ -1664,6 +1663,8 @@ static int dm_early_init(void *handle)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
amdgpu_dm_set_irq_funcs(adev);
|
||||
|
||||
if (adev->mode_info.funcs == NULL)
|
||||
adev->mode_info.funcs = &dm_display_funcs;
|
||||
|
||||
|
@ -1679,18 +1680,6 @@ static int dm_early_init(void *handle)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct dm_connector_state {
|
||||
struct drm_connector_state base;
|
||||
|
||||
enum amdgpu_rmx_type scaling;
|
||||
uint8_t underscan_vborder;
|
||||
uint8_t underscan_hborder;
|
||||
bool underscan_enable;
|
||||
};
|
||||
|
||||
#define to_dm_connector_state(x)\
|
||||
container_of((x), struct dm_connector_state, base)
|
||||
|
||||
static bool modeset_required(struct drm_crtc_state *crtc_state,
|
||||
struct dc_stream_state *new_stream,
|
||||
struct dc_stream_state *old_stream)
|
||||
|
@ -1773,8 +1762,7 @@ static bool fill_rects_from_plane_state(const struct drm_plane_state *state,
|
|||
return true;
|
||||
}
|
||||
static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
|
||||
uint64_t *tiling_flags,
|
||||
uint64_t *fb_location)
|
||||
uint64_t *tiling_flags)
|
||||
{
|
||||
struct amdgpu_bo *rbo = gem_to_amdgpu_bo(amdgpu_fb->obj);
|
||||
int r = amdgpu_bo_reserve(rbo, false);
|
||||
|
@ -1786,9 +1774,6 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
|
|||
return r;
|
||||
}
|
||||
|
||||
if (fb_location)
|
||||
*fb_location = amdgpu_bo_gpu_offset(rbo);
|
||||
|
||||
if (tiling_flags)
|
||||
amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
|
||||
|
||||
|
@ -1799,12 +1784,9 @@ static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
|
|||
|
||||
static int fill_plane_attributes_from_fb(struct amdgpu_device *adev,
|
||||
struct dc_plane_state *plane_state,
|
||||
const struct amdgpu_framebuffer *amdgpu_fb,
|
||||
bool addReq)
|
||||
const struct amdgpu_framebuffer *amdgpu_fb)
|
||||
{
|
||||
uint64_t tiling_flags;
|
||||
uint64_t fb_location = 0;
|
||||
uint64_t chroma_addr = 0;
|
||||
unsigned int awidth;
|
||||
const struct drm_framebuffer *fb = &amdgpu_fb->base;
|
||||
int ret = 0;
|
||||
|
@ -1812,8 +1794,7 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev,
|
|||
|
||||
ret = get_fb_info(
|
||||
amdgpu_fb,
|
||||
&tiling_flags,
|
||||
addReq == true ? &fb_location:NULL);
|
||||
&tiling_flags);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -1851,8 +1832,6 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev,
|
|||
|
||||
if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
|
||||
plane_state->address.type = PLN_ADDR_TYPE_GRAPHICS;
|
||||
plane_state->address.grph.addr.low_part = lower_32_bits(fb_location);
|
||||
plane_state->address.grph.addr.high_part = upper_32_bits(fb_location);
|
||||
plane_state->plane_size.grph.surface_size.x = 0;
|
||||
plane_state->plane_size.grph.surface_size.y = 0;
|
||||
plane_state->plane_size.grph.surface_size.width = fb->width;
|
||||
|
@ -1865,15 +1844,6 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev,
|
|||
} else {
|
||||
awidth = ALIGN(fb->width, 64);
|
||||
plane_state->address.type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
|
||||
plane_state->address.video_progressive.luma_addr.low_part
|
||||
= lower_32_bits(fb_location);
|
||||
plane_state->address.video_progressive.luma_addr.high_part
|
||||
= upper_32_bits(fb_location);
|
||||
chroma_addr = fb_location + (u64)(awidth * fb->height);
|
||||
plane_state->address.video_progressive.chroma_addr.low_part
|
||||
= lower_32_bits(chroma_addr);
|
||||
plane_state->address.video_progressive.chroma_addr.high_part
|
||||
= upper_32_bits(chroma_addr);
|
||||
plane_state->plane_size.video.luma_size.x = 0;
|
||||
plane_state->plane_size.video.luma_size.y = 0;
|
||||
plane_state->plane_size.video.luma_size.width = awidth;
|
||||
|
@ -1983,8 +1953,7 @@ static void fill_gamma_from_crtc_state(const struct drm_crtc_state *crtc_state,
|
|||
static int fill_plane_attributes(struct amdgpu_device *adev,
|
||||
struct dc_plane_state *dc_plane_state,
|
||||
struct drm_plane_state *plane_state,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
bool addrReq)
|
||||
struct drm_crtc_state *crtc_state)
|
||||
{
|
||||
const struct amdgpu_framebuffer *amdgpu_fb =
|
||||
to_amdgpu_framebuffer(plane_state->fb);
|
||||
|
@ -1998,8 +1967,7 @@ static int fill_plane_attributes(struct amdgpu_device *adev,
|
|||
ret = fill_plane_attributes_from_fb(
|
||||
crtc->dev->dev_private,
|
||||
dc_plane_state,
|
||||
amdgpu_fb,
|
||||
addrReq);
|
||||
amdgpu_fb);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -2174,6 +2142,7 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
|
|||
const struct drm_connector *connector)
|
||||
{
|
||||
struct dc_crtc_timing *timing_out = &stream->timing;
|
||||
struct dc_transfer_func *tf = dc_create_transfer_func();
|
||||
|
||||
memset(timing_out, 0, sizeof(struct dc_crtc_timing));
|
||||
|
||||
|
@ -2217,13 +2186,9 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
|
|||
|
||||
stream->output_color_space = get_output_color_space(timing_out);
|
||||
|
||||
{
|
||||
struct dc_transfer_func *tf = dc_create_transfer_func();
|
||||
|
||||
tf->type = TF_TYPE_PREDEFINED;
|
||||
tf->tf = TRANSFER_FUNCTION_SRGB;
|
||||
stream->out_transfer_func = tf;
|
||||
}
|
||||
tf->type = TF_TYPE_PREDEFINED;
|
||||
tf->tf = TRANSFER_FUNCTION_SRGB;
|
||||
stream->out_transfer_func = tf;
|
||||
}
|
||||
|
||||
static void fill_audio_info(struct audio_info *audio_info,
|
||||
|
@ -2330,6 +2295,56 @@ static int create_fake_sink(struct amdgpu_dm_connector *aconnector)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void set_multisync_trigger_params(
|
||||
struct dc_stream_state *stream)
|
||||
{
|
||||
if (stream->triggered_crtc_reset.enabled) {
|
||||
stream->triggered_crtc_reset.event = CRTC_EVENT_VSYNC_RISING;
|
||||
stream->triggered_crtc_reset.delay = TRIGGER_DELAY_NEXT_LINE;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_master_stream(struct dc_stream_state *stream_set[],
|
||||
int stream_count)
|
||||
{
|
||||
int j, highest_rfr = 0, master_stream = 0;
|
||||
|
||||
for (j = 0; j < stream_count; j++) {
|
||||
if (stream_set[j] && stream_set[j]->triggered_crtc_reset.enabled) {
|
||||
int refresh_rate = 0;
|
||||
|
||||
refresh_rate = (stream_set[j]->timing.pix_clk_khz*1000)/
|
||||
(stream_set[j]->timing.h_total*stream_set[j]->timing.v_total);
|
||||
if (refresh_rate > highest_rfr) {
|
||||
highest_rfr = refresh_rate;
|
||||
master_stream = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (j = 0; j < stream_count; j++) {
|
||||
if (stream_set[j] && j != master_stream)
|
||||
stream_set[j]->triggered_crtc_reset.event_source = stream_set[master_stream];
|
||||
}
|
||||
}
|
||||
|
||||
static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (context->stream_count < 2)
|
||||
return;
|
||||
for (i = 0; i < context->stream_count ; i++) {
|
||||
if (!context->streams[i])
|
||||
continue;
|
||||
/* TODO: add a function to read AMD VSDB bits and will set
|
||||
* crtc_sync_master.multi_sync_enabled flag
|
||||
* For now its set to false
|
||||
*/
|
||||
set_multisync_trigger_params(context->streams[i]);
|
||||
}
|
||||
set_master_stream(context->streams, context->stream_count);
|
||||
}
|
||||
|
||||
static struct dc_stream_state *
|
||||
create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||
const struct drm_display_mode *drm_mode,
|
||||
|
@ -2986,7 +3001,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
|||
= lower_32_bits(afb->address);
|
||||
plane_state->address.video_progressive.luma_addr.high_part
|
||||
= upper_32_bits(afb->address);
|
||||
chroma_addr = afb->address + (u64)(awidth * new_state->fb->height);
|
||||
chroma_addr = afb->address + (u64)awidth * new_state->fb->height;
|
||||
plane_state->address.video_progressive.chroma_addr.low_part
|
||||
= lower_32_bits(chroma_addr);
|
||||
plane_state->address.video_progressive.chroma_addr.high_part
|
||||
|
@ -3994,6 +4009,19 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_dm_crtc_copy_transient_flags - copy mirrored flags from DRM to DC
|
||||
* @crtc_state: the DRM CRTC state
|
||||
* @stream_state: the DC stream state.
|
||||
*
|
||||
* Copy the mirrored transient state flags from DRM, to DC. It is used to bring
|
||||
* a dc_stream_state's flags in sync with a drm_crtc_state's flags.
|
||||
*/
|
||||
static void amdgpu_dm_crtc_copy_transient_flags(struct drm_crtc_state *crtc_state,
|
||||
struct dc_stream_state *stream_state)
|
||||
{
|
||||
stream_state->mode_changed = crtc_state->mode_changed;
|
||||
}
|
||||
|
||||
static int amdgpu_dm_atomic_commit(struct drm_device *dev,
|
||||
struct drm_atomic_state *state,
|
||||
|
@ -4033,11 +4061,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
struct amdgpu_display_manager *dm = &adev->dm;
|
||||
struct dm_atomic_state *dm_state;
|
||||
uint32_t i, j;
|
||||
uint32_t new_crtcs_count = 0;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
|
||||
struct amdgpu_crtc *new_crtcs[MAX_STREAMS];
|
||||
struct dc_stream_state *new_stream = NULL;
|
||||
unsigned long flags;
|
||||
bool wait_for_vblank = true;
|
||||
struct drm_connector *connector;
|
||||
|
@ -4067,6 +4092,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
new_crtc_state->active_changed,
|
||||
new_crtc_state->connectors_changed);
|
||||
|
||||
/* Copy all transient state flags into dc state */
|
||||
if (dm_new_crtc_state->stream) {
|
||||
amdgpu_dm_crtc_copy_transient_flags(&dm_new_crtc_state->base,
|
||||
dm_new_crtc_state->stream);
|
||||
}
|
||||
|
||||
/* handles headless hotplug case, updating new_state and
|
||||
* aconnector as needed
|
||||
*/
|
||||
|
@ -4096,25 +4127,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (dm_old_crtc_state->stream)
|
||||
remove_stream(adev, acrtc, dm_old_crtc_state->stream);
|
||||
|
||||
|
||||
/*
|
||||
* this loop saves set mode crtcs
|
||||
* we needed to enable vblanks once all
|
||||
* resources acquired in dc after dc_commit_streams
|
||||
*/
|
||||
|
||||
/*TODO move all this into dm_crtc_state, get rid of
|
||||
* new_crtcs array and use old and new atomic states
|
||||
* instead
|
||||
*/
|
||||
new_crtcs[new_crtcs_count] = acrtc;
|
||||
new_crtcs_count++;
|
||||
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
|
||||
acrtc->enabled = true;
|
||||
acrtc->hw_mode = new_crtc_state->mode;
|
||||
crtc->hwmode = new_crtc_state->mode;
|
||||
|
@ -4132,31 +4147,61 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
* are removed from freesync module
|
||||
*/
|
||||
if (adev->dm.freesync_module) {
|
||||
for (i = 0; i < new_crtcs_count; i++) {
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
struct amdgpu_dm_connector *aconnector = NULL;
|
||||
struct dm_connector_state *dm_new_con_state = NULL;
|
||||
struct amdgpu_crtc *acrtc = NULL;
|
||||
bool modeset_needed;
|
||||
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state,
|
||||
&new_crtcs[i]->base);
|
||||
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
|
||||
modeset_needed = modeset_required(
|
||||
new_crtc_state,
|
||||
dm_new_crtc_state->stream,
|
||||
dm_old_crtc_state->stream);
|
||||
/* We add stream to freesync if:
|
||||
* 1. Said stream is not null, and
|
||||
* 2. A modeset is requested. This means that the
|
||||
* stream was removed previously, and needs to be
|
||||
* replaced.
|
||||
*/
|
||||
if (dm_new_crtc_state->stream == NULL ||
|
||||
!modeset_needed)
|
||||
continue;
|
||||
|
||||
new_stream = dm_new_crtc_state->stream;
|
||||
aconnector = amdgpu_dm_find_first_crtc_matching_connector(
|
||||
state,
|
||||
&new_crtcs[i]->base);
|
||||
acrtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
aconnector =
|
||||
amdgpu_dm_find_first_crtc_matching_connector(
|
||||
state, crtc);
|
||||
if (!aconnector) {
|
||||
DRM_DEBUG_DRIVER("Atomic commit: Failed to find connector for acrtc id:%d "
|
||||
"skipping freesync init\n",
|
||||
new_crtcs[i]->crtc_id);
|
||||
DRM_DEBUG_DRIVER("Atomic commit: Failed to "
|
||||
"find connector for acrtc "
|
||||
"id:%d skipping freesync "
|
||||
"init\n",
|
||||
acrtc->crtc_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
mod_freesync_add_stream(adev->dm.freesync_module,
|
||||
new_stream, &aconnector->caps);
|
||||
dm_new_crtc_state->stream,
|
||||
&aconnector->caps);
|
||||
new_con_state = drm_atomic_get_new_connector_state(
|
||||
state, &aconnector->base);
|
||||
dm_new_con_state = to_dm_connector_state(new_con_state);
|
||||
|
||||
mod_freesync_set_user_enable(adev->dm.freesync_module,
|
||||
&dm_new_crtc_state->stream,
|
||||
1,
|
||||
&dm_new_con_state->user_enable);
|
||||
}
|
||||
}
|
||||
|
||||
if (dm_state->context)
|
||||
if (dm_state->context) {
|
||||
dm_enable_per_frame_crtc_master_sync(dm_state->context);
|
||||
WARN_ON(!dc_commit_state(dm->dc, dm_state->context));
|
||||
}
|
||||
|
||||
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
|
||||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
@ -4214,18 +4259,28 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
|
|||
dm_error("%s: Failed to update stream scaling!\n", __func__);
|
||||
}
|
||||
|
||||
for (i = 0; i < new_crtcs_count; i++) {
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
/*
|
||||
* loop to enable interrupts on newly arrived crtc
|
||||
*/
|
||||
struct amdgpu_crtc *acrtc = new_crtcs[i];
|
||||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
bool modeset_needed;
|
||||
|
||||
new_crtc_state = drm_atomic_get_new_crtc_state(state, &acrtc->base);
|
||||
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
|
||||
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
|
||||
modeset_needed = modeset_required(
|
||||
new_crtc_state,
|
||||
dm_new_crtc_state->stream,
|
||||
dm_old_crtc_state->stream);
|
||||
|
||||
if (dm_new_crtc_state->stream == NULL || !modeset_needed)
|
||||
continue;
|
||||
|
||||
if (adev->dm.freesync_module)
|
||||
mod_freesync_notify_mode_change(
|
||||
adev->dm.freesync_module, &dm_new_crtc_state->stream, 1);
|
||||
adev->dm.freesync_module,
|
||||
&dm_new_crtc_state->stream, 1);
|
||||
|
||||
manage_dm_interrupts(adev, acrtc, true);
|
||||
}
|
||||
|
@ -4527,6 +4582,7 @@ static int dm_update_crtcs_state(struct dc *dc,
|
|||
WARN_ON(dm_new_crtc_state->stream);
|
||||
|
||||
dm_new_crtc_state->stream = new_stream;
|
||||
|
||||
dc_stream_retain(new_stream);
|
||||
|
||||
DRM_DEBUG_DRIVER("Enabling DRM crtc: %d\n",
|
||||
|
@ -4652,8 +4708,7 @@ static int dm_update_planes_state(struct dc *dc,
|
|||
new_plane_crtc->dev->dev_private,
|
||||
dm_new_plane_state->dc_state,
|
||||
new_plane_state,
|
||||
new_crtc_state,
|
||||
false);
|
||||
new_crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -4668,6 +4723,11 @@ static int dm_update_planes_state(struct dc *dc,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Tell DC to do a full surface update every time there
|
||||
* is a plane change. Inefficient, but works for now.
|
||||
*/
|
||||
dm_new_plane_state->dc_state->update_flags.bits.full_update = 1;
|
||||
|
||||
*lock_and_validation_needed = true;
|
||||
}
|
||||
}
|
||||
|
@ -4679,8 +4739,6 @@ static int dm_update_planes_state(struct dc *dc,
|
|||
static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
struct amdgpu_device *adev = dev->dev_private;
|
||||
struct dc *dc = adev->dm.dc;
|
||||
struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
|
||||
|
@ -4688,6 +4746,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
struct drm_connector_state *old_con_state, *new_con_state;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
|
||||
int ret, i;
|
||||
|
||||
/*
|
||||
* This bool will be set for true for any modeset/reset
|
||||
|
@ -4699,37 +4758,21 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
|||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* legacy_cursor_update should be made false for SoC's having
|
||||
* a dedicated hardware plane for cursor in amdgpu_dm_atomic_commit(),
|
||||
* otherwise for software cursor plane,
|
||||
* we should not add it to list of affected planes.
|
||||
*/
|
||||
if (state->legacy_cursor_update) {
|
||||
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
|
||||
if (new_crtc_state->color_mgmt_changed) {
|
||||
ret = drm_atomic_add_affected_planes(state, crtc);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
|
||||
!new_crtc_state->color_mgmt_changed)
|
||||
continue;
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||
if (!drm_atomic_crtc_needs_modeset(new_crtc_state) &&
|
||||
!new_crtc_state->color_mgmt_changed)
|
||||
continue;
|
||||
|
||||
if (!new_crtc_state->enable)
|
||||
continue;
|
||||
if (!new_crtc_state->enable)
|
||||
continue;
|
||||
|
||||
ret = drm_atomic_add_affected_connectors(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = drm_atomic_add_affected_connectors(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drm_atomic_add_affected_planes(state, crtc);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
ret = drm_atomic_add_affected_planes(state, crtc);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dm_state->context = dc_create_state();
|
||||
|
|
|
@ -220,6 +220,18 @@ struct dm_atomic_state {
|
|||
|
||||
#define to_dm_atomic_state(x) container_of(x, struct dm_atomic_state, base)
|
||||
|
||||
struct dm_connector_state {
|
||||
struct drm_connector_state base;
|
||||
|
||||
enum amdgpu_rmx_type scaling;
|
||||
uint8_t underscan_vborder;
|
||||
uint8_t underscan_hborder;
|
||||
bool underscan_enable;
|
||||
struct mod_freesync_user_enable user_enable;
|
||||
};
|
||||
|
||||
#define to_dm_connector_state(x)\
|
||||
container_of((x), struct dm_connector_state, base)
|
||||
|
||||
void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector);
|
||||
struct drm_connector_state *
|
||||
|
|
|
@ -683,13 +683,16 @@ static const struct amdgpu_irq_src_funcs dm_hpd_irq_funcs = {
|
|||
|
||||
void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_LAST;
|
||||
if (adev->mode_info.num_crtc > 0)
|
||||
adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VLINE1 + adev->mode_info.num_crtc;
|
||||
else
|
||||
adev->crtc_irq.num_types = 0;
|
||||
adev->crtc_irq.funcs = &dm_crtc_irq_funcs;
|
||||
|
||||
adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST;
|
||||
adev->pageflip_irq.num_types = adev->mode_info.num_crtc;
|
||||
adev->pageflip_irq.funcs = &dm_pageflip_irq_funcs;
|
||||
|
||||
adev->hpd_irq.num_types = AMDGPU_HPD_LAST;
|
||||
adev->hpd_irq.num_types = adev->mode_info.num_hpd;
|
||||
adev->hpd_irq.funcs = &dm_hpd_irq_funcs;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,10 @@ unsigned long long dm_get_timestamp(struct dc_context *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void dm_perf_trace_timestamp(const char *func_name, unsigned int line)
|
||||
{
|
||||
}
|
||||
|
||||
bool dm_write_persistent_data(struct dc_context *ctx,
|
||||
const struct dc_sink *sink,
|
||||
const char *module_name,
|
||||
|
@ -131,11 +135,12 @@ bool dm_pp_apply_display_requirements(
|
|||
adev->pm.pm_display_cfg.min_bus_bandwidth = 0;
|
||||
|
||||
/* TODO: complete implementation of
|
||||
* amd_powerplay_display_configuration_change().
|
||||
* pp_display_configuration_change().
|
||||
* Follow example of:
|
||||
* PHM_StoreDALConfigurationData - powerplay\hwmgr\hardwaremanager.c
|
||||
* PP_IRI_DisplayConfigurationChange - powerplay\eventmgr\iri.c */
|
||||
amd_powerplay_display_configuration_change(
|
||||
if (adev->powerplay.pp_funcs->display_configuration_change)
|
||||
adev->powerplay.pp_funcs->display_configuration_change(
|
||||
adev->powerplay.pp_handle,
|
||||
&adev->pm.pm_display_cfg);
|
||||
|
||||
|
@ -264,22 +269,26 @@ bool dm_pp_get_clock_levels_by_type(
|
|||
struct amd_pp_simple_clock_info validation_clks = { 0 };
|
||||
uint32_t i;
|
||||
|
||||
if (amd_powerplay_get_clock_by_type(pp_handle,
|
||||
if (adev->powerplay.pp_funcs->get_clock_by_type) {
|
||||
if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle,
|
||||
dc_to_pp_clock_type(clk_type), &pp_clks)) {
|
||||
/* Error in pplib. Provide default values. */
|
||||
get_default_clock_levels(clk_type, dc_clks);
|
||||
return true;
|
||||
get_default_clock_levels(clk_type, dc_clks);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type);
|
||||
|
||||
if (amd_powerplay_get_display_mode_validation_clocks(pp_handle,
|
||||
&validation_clks)) {
|
||||
/* Error in pplib. Provide default values. */
|
||||
DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
|
||||
validation_clks.engine_max_clock = 72000;
|
||||
validation_clks.memory_max_clock = 80000;
|
||||
validation_clks.level = 0;
|
||||
if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks) {
|
||||
if (adev->powerplay.pp_funcs->get_display_mode_validation_clocks(
|
||||
pp_handle, &validation_clks)) {
|
||||
/* Error in pplib. Provide default values. */
|
||||
DRM_INFO("DM_PPLIB: Warning: using default validation clocks!\n");
|
||||
validation_clks.engine_max_clock = 72000;
|
||||
validation_clks.memory_max_clock = 80000;
|
||||
validation_clks.level = 0;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_INFO("DM_PPLIB: Validation clocks:\n");
|
||||
|
|
|
@ -83,15 +83,11 @@ void dc_conn_log(struct dc_context *ctx,
|
|||
link->link_index);
|
||||
|
||||
va_start(args, msg);
|
||||
entry.buf_offset += dm_log_to_buffer(
|
||||
&entry.buf[entry.buf_offset],
|
||||
LOG_MAX_LINE_SIZE - entry.buf_offset,
|
||||
msg, args);
|
||||
dm_logger_append_va(&entry, msg, args);
|
||||
|
||||
if (entry.buf[strlen(entry.buf) - 1] == '\n') {
|
||||
entry.buf[strlen(entry.buf) - 1] = '\0';
|
||||
if (entry.buf_offset > 0 &&
|
||||
entry.buf[entry.buf_offset - 1] == '\n')
|
||||
entry.buf_offset--;
|
||||
}
|
||||
|
||||
if (hex_data)
|
||||
for (i = 0; i < hex_data_count; i++)
|
||||
|
|
|
@ -70,9 +70,8 @@ static bool construct(struct dc_context *ctx, struct dal_logger *logger,
|
|||
{
|
||||
/* malloc buffer and init offsets */
|
||||
logger->log_buffer_size = DAL_LOGGER_BUFFER_MAX_SIZE;
|
||||
logger->log_buffer = (char *)kzalloc(logger->log_buffer_size * sizeof(char),
|
||||
GFP_KERNEL);
|
||||
|
||||
logger->log_buffer = kcalloc(logger->log_buffer_size, sizeof(char),
|
||||
GFP_KERNEL);
|
||||
if (!logger->log_buffer)
|
||||
return false;
|
||||
|
||||
|
@ -312,6 +311,18 @@ void dm_logger_append(
|
|||
struct log_entry *entry,
|
||||
const char *msg,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, msg);
|
||||
dm_logger_append_va(entry, msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void dm_logger_append_va(
|
||||
struct log_entry *entry,
|
||||
const char *msg,
|
||||
va_list args)
|
||||
{
|
||||
struct dal_logger *logger;
|
||||
|
||||
|
@ -326,11 +337,8 @@ void dm_logger_append(
|
|||
dal_logger_should_log(logger, entry->type)) {
|
||||
|
||||
uint32_t size;
|
||||
va_list args;
|
||||
char buffer[LOG_MAX_LINE_SIZE];
|
||||
|
||||
va_start(args, msg);
|
||||
|
||||
size = dm_log_to_buffer(
|
||||
buffer, LOG_MAX_LINE_SIZE, msg, args);
|
||||
|
||||
|
@ -339,8 +347,6 @@ void dm_logger_append(
|
|||
} else {
|
||||
append_entry(entry, "LOG_ERROR, line too long\n", 27);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -432,25 +432,13 @@ static void dcn_bw_calc_rq_dlg_ttu(
|
|||
input.clks_cfg.dcfclk_mhz = v->dcfclk;
|
||||
input.clks_cfg.dispclk_mhz = v->dispclk;
|
||||
input.clks_cfg.dppclk_mhz = v->dppclk;
|
||||
input.clks_cfg.refclk_mhz = dc->res_pool->ref_clock_inKhz/1000;
|
||||
input.clks_cfg.refclk_mhz = dc->res_pool->ref_clock_inKhz / 1000.0;
|
||||
input.clks_cfg.socclk_mhz = v->socclk;
|
||||
input.clks_cfg.voltage = v->voltage_level;
|
||||
// dc->dml.logger = pool->base.logger;
|
||||
input.dout.output_format = (v->output_format[in_idx] == dcn_bw_420) ? dm_420 : dm_444;
|
||||
input.dout.output_type = (v->output[in_idx] == dcn_bw_hdmi) ? dm_hdmi : dm_dp;
|
||||
//input[in_idx].dout.output_standard;
|
||||
switch (v->output_deep_color[in_idx]) {
|
||||
case dcn_bw_encoder_12bpc:
|
||||
input.dout.output_bpc = dm_out_12;
|
||||
break;
|
||||
case dcn_bw_encoder_10bpc:
|
||||
input.dout.output_bpc = dm_out_10;
|
||||
break;
|
||||
case dcn_bw_encoder_8bpc:
|
||||
default:
|
||||
input.dout.output_bpc = dm_out_8;
|
||||
break;
|
||||
}
|
||||
|
||||
/*todo: soc->sr_enter_plus_exit_time??*/
|
||||
dlg_sys_param.t_srx_delay_us = dc->dcn_ip->dcfclk_cstate_latency / v->dcf_clk_deep_sleep;
|
||||
|
@ -1025,6 +1013,8 @@ bool dcn_validate_bandwidth(
|
|||
if (pipe->plane_state) {
|
||||
struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe;
|
||||
|
||||
pipe->plane_state->update_flags.bits.full_update = 1;
|
||||
|
||||
if (v->dpp_per_plane[input_idx] == 2 ||
|
||||
((pipe->stream->view_format ==
|
||||
VIEW_3D_FORMAT_SIDE_BY_SIDE ||
|
||||
|
@ -1064,6 +1054,9 @@ bool dcn_validate_bandwidth(
|
|||
hsplit_pipe->stream = NULL;
|
||||
hsplit_pipe->top_pipe = NULL;
|
||||
hsplit_pipe->bottom_pipe = NULL;
|
||||
/* Clear plane_res and stream_res */
|
||||
memset(&hsplit_pipe->plane_res, 0, sizeof(hsplit_pipe->plane_res));
|
||||
memset(&hsplit_pipe->stream_res, 0, sizeof(hsplit_pipe->stream_res));
|
||||
resource_build_scaling_params(pipe);
|
||||
}
|
||||
/* for now important to do this after pipe split for building e2e params */
|
||||
|
@ -1231,40 +1224,62 @@ unsigned int dcn_find_dcfclk_suits_all(
|
|||
return dcf_clk;
|
||||
}
|
||||
|
||||
static bool verify_clock_values(struct dm_pp_clock_levels_with_voltage *clks)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (clks->num_levels == 0)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < clks->num_levels; i++)
|
||||
/* Ensure that the result is sane */
|
||||
if (clks->data[i].clocks_in_khz == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcn_bw_update_from_pplib(struct dc *dc)
|
||||
{
|
||||
struct dc_context *ctx = dc->ctx;
|
||||
struct dm_pp_clock_levels_with_voltage clks = {0};
|
||||
struct dm_pp_clock_levels_with_voltage fclks = {0}, dcfclks = {0};
|
||||
bool res;
|
||||
|
||||
kernel_fpu_begin();
|
||||
|
||||
/* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */
|
||||
res = dm_pp_get_clock_levels_by_type_with_voltage(
|
||||
ctx, DM_PP_CLOCK_TYPE_FCLK, &fclks);
|
||||
|
||||
if (dm_pp_get_clock_levels_by_type_with_voltage(
|
||||
ctx, DM_PP_CLOCK_TYPE_FCLK, &clks) &&
|
||||
clks.num_levels != 0) {
|
||||
ASSERT(clks.num_levels >= 3);
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = 32 * (clks.data[0].clocks_in_khz / 1000.0) / 1000.0;
|
||||
if (clks.num_levels > 2) {
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc->number_of_channels *
|
||||
(clks.data[clks.num_levels - 3].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0;
|
||||
} else {
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc->number_of_channels *
|
||||
(clks.data[clks.num_levels - 2].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0;
|
||||
}
|
||||
if (res)
|
||||
res = verify_clock_values(&fclks);
|
||||
|
||||
if (res) {
|
||||
ASSERT(fclks.num_levels >= 3);
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = 32 * (fclks.data[0].clocks_in_khz / 1000.0) / 1000.0;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc->number_of_channels *
|
||||
(fclks.data[fclks.num_levels - (fclks.num_levels > 2 ? 3 : 2)].clocks_in_khz / 1000.0)
|
||||
* ddr4_dram_factor_single_Channel / 1000.0;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 = dc->dcn_soc->number_of_channels *
|
||||
(clks.data[clks.num_levels - 2].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0;
|
||||
(fclks.data[fclks.num_levels - 2].clocks_in_khz / 1000.0)
|
||||
* ddr4_dram_factor_single_Channel / 1000.0;
|
||||
dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = dc->dcn_soc->number_of_channels *
|
||||
(clks.data[clks.num_levels - 1].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0;
|
||||
(fclks.data[fclks.num_levels - 1].clocks_in_khz / 1000.0)
|
||||
* ddr4_dram_factor_single_Channel / 1000.0;
|
||||
} else
|
||||
BREAK_TO_DEBUGGER();
|
||||
if (dm_pp_get_clock_levels_by_type_with_voltage(
|
||||
ctx, DM_PP_CLOCK_TYPE_DCFCLK, &clks) &&
|
||||
clks.num_levels >= 3) {
|
||||
dc->dcn_soc->dcfclkv_min0p65 = clks.data[0].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_mid0p72 = clks.data[clks.num_levels - 3].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_nom0p8 = clks.data[clks.num_levels - 2].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_max0p9 = clks.data[clks.num_levels - 1].clocks_in_khz / 1000.0;
|
||||
|
||||
res = dm_pp_get_clock_levels_by_type_with_voltage(
|
||||
ctx, DM_PP_CLOCK_TYPE_DCFCLK, &dcfclks);
|
||||
|
||||
if (res)
|
||||
res = verify_clock_values(&dcfclks);
|
||||
|
||||
if (res && dcfclks.num_levels >= 3) {
|
||||
dc->dcn_soc->dcfclkv_min0p65 = dcfclks.data[0].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_mid0p72 = dcfclks.data[dcfclks.num_levels - 3].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_nom0p8 = dcfclks.data[dcfclks.num_levels - 2].clocks_in_khz / 1000.0;
|
||||
dc->dcn_soc->dcfclkv_max0p9 = dcfclks.data[dcfclks.num_levels - 1].clocks_in_khz / 1000.0;
|
||||
} else
|
||||
BREAK_TO_DEBUGGER();
|
||||
|
||||
|
|
|
@ -54,6 +54,13 @@
|
|||
/*******************************************************************************
|
||||
* Private functions
|
||||
******************************************************************************/
|
||||
|
||||
static inline void elevate_update_type(enum surface_update_type *original, enum surface_update_type new)
|
||||
{
|
||||
if (new > *original)
|
||||
*original = new;
|
||||
}
|
||||
|
||||
static void destroy_links(struct dc *dc)
|
||||
{
|
||||
uint32_t i;
|
||||
|
@ -157,7 +164,7 @@ static bool create_links(
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool stream_adjust_vmin_vmax(struct dc *dc,
|
||||
bool dc_stream_adjust_vmin_vmax(struct dc *dc,
|
||||
struct dc_stream_state **streams, int num_streams,
|
||||
int vmin, int vmax)
|
||||
{
|
||||
|
@ -182,7 +189,7 @@ static bool stream_adjust_vmin_vmax(struct dc *dc,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool stream_get_crtc_position(struct dc *dc,
|
||||
bool dc_stream_get_crtc_position(struct dc *dc,
|
||||
struct dc_stream_state **streams, int num_streams,
|
||||
unsigned int *v_pos, unsigned int *nom_v_pos)
|
||||
{
|
||||
|
@ -207,45 +214,7 @@ static bool stream_get_crtc_position(struct dc *dc,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool set_gamut_remap(struct dc *dc, const struct dc_stream_state *stream)
|
||||
{
|
||||
int i = 0;
|
||||
bool ret = false;
|
||||
struct pipe_ctx *pipes;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
|
||||
pipes = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
dc->hwss.program_gamut_remap(pipes);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool program_csc_matrix(struct dc *dc, struct dc_stream_state *stream)
|
||||
{
|
||||
int i = 0;
|
||||
bool ret = false;
|
||||
struct pipe_ctx *pipes;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
if (dc->current_state->res_ctx.pipe_ctx[i].stream
|
||||
== stream) {
|
||||
|
||||
pipes = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
dc->hwss.program_csc_matrix(pipes,
|
||||
stream->output_color_space,
|
||||
stream->csc_color_matrix.matrix);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void set_static_screen_events(struct dc *dc,
|
||||
void dc_stream_set_static_screen_events(struct dc *dc,
|
||||
struct dc_stream_state **streams,
|
||||
int num_streams,
|
||||
const struct dc_static_screen_events *events)
|
||||
|
@ -270,177 +239,6 @@ static void set_static_screen_events(struct dc *dc,
|
|||
dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, events);
|
||||
}
|
||||
|
||||
static void set_drive_settings(struct dc *dc,
|
||||
struct link_training_settings *lt_settings,
|
||||
const struct dc_link *link)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dc->link_count; i++) {
|
||||
if (dc->links[i] == link)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= dc->link_count)
|
||||
ASSERT_CRITICAL(false);
|
||||
|
||||
dc_link_dp_set_drive_settings(dc->links[i], lt_settings);
|
||||
}
|
||||
|
||||
static void perform_link_training(struct dc *dc,
|
||||
struct dc_link_settings *link_setting,
|
||||
bool skip_video_pattern)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dc->link_count; i++)
|
||||
dc_link_dp_perform_link_training(
|
||||
dc->links[i],
|
||||
link_setting,
|
||||
skip_video_pattern);
|
||||
}
|
||||
|
||||
static void set_preferred_link_settings(struct dc *dc,
|
||||
struct dc_link_settings *link_setting,
|
||||
struct dc_link *link)
|
||||
{
|
||||
link->preferred_link_setting = *link_setting;
|
||||
dp_retrain_link_dp_test(link, link_setting, false);
|
||||
}
|
||||
|
||||
static void enable_hpd(const struct dc_link *link)
|
||||
{
|
||||
dc_link_dp_enable_hpd(link);
|
||||
}
|
||||
|
||||
static void disable_hpd(const struct dc_link *link)
|
||||
{
|
||||
dc_link_dp_disable_hpd(link);
|
||||
}
|
||||
|
||||
|
||||
static void set_test_pattern(
|
||||
struct dc_link *link,
|
||||
enum dp_test_pattern test_pattern,
|
||||
const struct link_training_settings *p_link_settings,
|
||||
const unsigned char *p_custom_pattern,
|
||||
unsigned int cust_pattern_size)
|
||||
{
|
||||
if (link != NULL)
|
||||
dc_link_dp_set_test_pattern(
|
||||
link,
|
||||
test_pattern,
|
||||
p_link_settings,
|
||||
p_custom_pattern,
|
||||
cust_pattern_size);
|
||||
}
|
||||
|
||||
static void set_dither_option(struct dc_stream_state *stream,
|
||||
enum dc_dither_option option)
|
||||
{
|
||||
struct bit_depth_reduction_params params;
|
||||
struct dc_link *link = stream->status.link;
|
||||
struct pipe_ctx *pipes = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
if (link->dc->current_state->res_ctx.pipe_ctx[i].stream ==
|
||||
stream) {
|
||||
pipes = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
if (!pipes)
|
||||
return;
|
||||
if (option > DITHER_OPTION_MAX)
|
||||
return;
|
||||
|
||||
stream->dither_option = option;
|
||||
|
||||
resource_build_bit_depth_reduction_params(stream,
|
||||
¶ms);
|
||||
stream->bit_depth_params = params;
|
||||
pipes->stream_res.opp->funcs->
|
||||
opp_program_bit_depth_reduction(pipes->stream_res.opp, ¶ms);
|
||||
}
|
||||
|
||||
void set_dpms(
|
||||
struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
bool dpms_off)
|
||||
{
|
||||
struct pipe_ctx *pipe_ctx = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
|
||||
pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pipe_ctx) {
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (stream->dpms_off != dpms_off) {
|
||||
stream->dpms_off = dpms_off;
|
||||
if (dpms_off)
|
||||
core_link_disable_stream(pipe_ctx,
|
||||
KEEP_ACQUIRED_RESOURCE);
|
||||
else
|
||||
core_link_enable_stream(dc->current_state, pipe_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void allocate_dc_stream_funcs(struct dc *dc)
|
||||
{
|
||||
if (dc->hwss.set_drr != NULL) {
|
||||
dc->stream_funcs.adjust_vmin_vmax =
|
||||
stream_adjust_vmin_vmax;
|
||||
}
|
||||
|
||||
dc->stream_funcs.set_static_screen_events =
|
||||
set_static_screen_events;
|
||||
|
||||
dc->stream_funcs.get_crtc_position =
|
||||
stream_get_crtc_position;
|
||||
|
||||
dc->stream_funcs.set_gamut_remap =
|
||||
set_gamut_remap;
|
||||
|
||||
dc->stream_funcs.program_csc_matrix =
|
||||
program_csc_matrix;
|
||||
|
||||
dc->stream_funcs.set_dither_option =
|
||||
set_dither_option;
|
||||
|
||||
dc->stream_funcs.set_dpms =
|
||||
set_dpms;
|
||||
|
||||
dc->link_funcs.set_drive_settings =
|
||||
set_drive_settings;
|
||||
|
||||
dc->link_funcs.perform_link_training =
|
||||
perform_link_training;
|
||||
|
||||
dc->link_funcs.set_preferred_link_settings =
|
||||
set_preferred_link_settings;
|
||||
|
||||
dc->link_funcs.enable_hpd =
|
||||
enable_hpd;
|
||||
|
||||
dc->link_funcs.disable_hpd =
|
||||
disable_hpd;
|
||||
|
||||
dc->link_funcs.set_test_pattern =
|
||||
set_test_pattern;
|
||||
}
|
||||
|
||||
static void destruct(struct dc *dc)
|
||||
{
|
||||
dc_release_state(dc->current_state);
|
||||
|
@ -558,6 +356,7 @@ static bool construct(struct dc *dc,
|
|||
|
||||
dc_version = resource_parse_asic_id(init_params->asic_id);
|
||||
dc->ctx->dce_version = dc_version;
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_FBC)
|
||||
dc->ctx->fbc_gpu_addr = init_params->fbc_gpu_addr;
|
||||
#endif
|
||||
|
@ -616,8 +415,6 @@ static bool construct(struct dc *dc,
|
|||
if (!create_links(dc, init_params->num_virtual_links))
|
||||
goto fail;
|
||||
|
||||
allocate_dc_stream_funcs(dc);
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
|
@ -686,6 +483,7 @@ struct dc *dc_create(const struct dc_init_data *init_params)
|
|||
|
||||
dc->caps.max_links = dc->link_count;
|
||||
dc->caps.max_audios = dc->res_pool->audio_count;
|
||||
dc->caps.linear_pitch_alignment = 64;
|
||||
|
||||
dc->config = init_params->flags;
|
||||
|
||||
|
@ -712,6 +510,28 @@ void dc_destroy(struct dc **dc)
|
|||
*dc = NULL;
|
||||
}
|
||||
|
||||
static void enable_timing_multisync(
|
||||
struct dc *dc,
|
||||
struct dc_state *ctx)
|
||||
{
|
||||
int i = 0, multisync_count = 0;
|
||||
int pipe_count = dc->res_pool->pipe_count;
|
||||
struct pipe_ctx *multisync_pipes[MAX_PIPES] = { NULL };
|
||||
|
||||
for (i = 0; i < pipe_count; i++) {
|
||||
if (!ctx->res_ctx.pipe_ctx[i].stream ||
|
||||
!ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.enabled)
|
||||
continue;
|
||||
multisync_pipes[multisync_count] = &ctx->res_ctx.pipe_ctx[i];
|
||||
multisync_count++;
|
||||
}
|
||||
|
||||
if (multisync_count > 1) {
|
||||
dc->hwss.enable_per_frame_crtc_position_reset(
|
||||
dc, multisync_count, multisync_pipes);
|
||||
}
|
||||
}
|
||||
|
||||
static void program_timing_sync(
|
||||
struct dc *dc,
|
||||
struct dc_state *ctx)
|
||||
|
@ -838,7 +658,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
|||
struct dc_bios *dcb = dc->ctx->dc_bios;
|
||||
enum dc_status result = DC_ERROR_UNEXPECTED;
|
||||
struct pipe_ctx *pipe;
|
||||
int i, j, k, l;
|
||||
int i, k, l;
|
||||
struct dc_stream_state *dc_streams[MAX_STREAMS] = {0};
|
||||
|
||||
disable_dangling_plane(dc, context);
|
||||
|
@ -849,9 +669,44 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
|||
if (!dcb->funcs->is_accelerated_mode(dcb))
|
||||
dc->hwss.enable_accelerated_mode(dc);
|
||||
|
||||
/* re-program planes for existing stream, in case we need to
|
||||
* free up plane resource for later use
|
||||
*/
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
if (context->streams[i]->mode_changed)
|
||||
continue;
|
||||
|
||||
dc->hwss.apply_ctx_for_surface(
|
||||
dc, context->streams[i],
|
||||
context->stream_status[i].plane_count,
|
||||
context); /* use new pipe config in new context */
|
||||
}
|
||||
|
||||
/* Program hardware */
|
||||
dc->hwss.ready_shared_resources(dc, context);
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
pipe = &context->res_ctx.pipe_ctx[i];
|
||||
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
|
||||
}
|
||||
|
||||
result = dc->hwss.apply_ctx_to_hw(dc, context);
|
||||
|
||||
if (result != DC_OK)
|
||||
return result;
|
||||
|
||||
if (context->stream_count > 1) {
|
||||
enable_timing_multisync(dc, context);
|
||||
program_timing_sync(dc, context);
|
||||
}
|
||||
|
||||
/* Program all planes within new context*/
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
const struct dc_sink *sink = context->streams[i]->sink;
|
||||
|
||||
if (!context->streams[i]->mode_changed)
|
||||
continue;
|
||||
|
||||
dc->hwss.apply_ctx_for_surface(
|
||||
dc, context->streams[i],
|
||||
context->stream_status[i].plane_count,
|
||||
|
@ -880,27 +735,8 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
|
|||
context->streams[i]->timing.pix_clk_khz);
|
||||
}
|
||||
|
||||
dc->hwss.ready_shared_resources(dc, context);
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
pipe = &context->res_ctx.pipe_ctx[i];
|
||||
dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe);
|
||||
}
|
||||
result = dc->hwss.apply_ctx_to_hw(dc, context);
|
||||
|
||||
program_timing_sync(dc, context);
|
||||
|
||||
dc_enable_stereo(dc, context, dc_streams, context->stream_count);
|
||||
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
for (j = 0; j < MAX_PIPES; j++) {
|
||||
pipe = &context->res_ctx.pipe_ctx[j];
|
||||
|
||||
if (!pipe->top_pipe && pipe->stream == context->streams[i])
|
||||
dc->hwss.pipe_control_lock(dc, pipe, false);
|
||||
}
|
||||
}
|
||||
|
||||
dc_release_state(dc->current_state);
|
||||
|
||||
dc->current_state = context;
|
||||
|
@ -936,7 +772,6 @@ bool dc_commit_state(struct dc *dc, struct dc_state *context)
|
|||
return (result == DC_OK);
|
||||
}
|
||||
|
||||
|
||||
bool dc_post_update_surfaces_to_stream(struct dc *dc)
|
||||
{
|
||||
int i;
|
||||
|
@ -945,9 +780,11 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
|
|||
post_surface_trace(dc);
|
||||
|
||||
for (i = 0; i < dc->res_pool->pipe_count; i++)
|
||||
if (context->res_ctx.pipe_ctx[i].stream == NULL
|
||||
|| context->res_ctx.pipe_ctx[i].plane_state == NULL)
|
||||
dc->hwss.power_down_front_end(dc, i);
|
||||
if (context->res_ctx.pipe_ctx[i].stream == NULL ||
|
||||
context->res_ctx.pipe_ctx[i].plane_state == NULL) {
|
||||
context->res_ctx.pipe_ctx[i].pipe_idx = i;
|
||||
dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
|
||||
}
|
||||
|
||||
/* 3rd param should be true, temp w/a for RV*/
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN1_0)
|
||||
|
@ -1014,6 +851,7 @@ bool dc_commit_planes_to_stream(
|
|||
flip_addr[i].address = plane_states[i]->address;
|
||||
flip_addr[i].flip_immediate = plane_states[i]->flip_immediate;
|
||||
plane_info[i].color_space = plane_states[i]->color_space;
|
||||
plane_info[i].input_tf = plane_states[i]->input_tf;
|
||||
plane_info[i].format = plane_states[i]->format;
|
||||
plane_info[i].plane_size = plane_states[i]->plane_size;
|
||||
plane_info[i].rotation = plane_states[i]->rotation;
|
||||
|
@ -1118,79 +956,91 @@ static unsigned int pixel_format_to_bpp(enum surface_pixel_format format)
|
|||
}
|
||||
}
|
||||
|
||||
static enum surface_update_type get_plane_info_update_type(
|
||||
const struct dc_surface_update *u,
|
||||
int surface_index)
|
||||
static enum surface_update_type get_plane_info_update_type(const struct dc_surface_update *u)
|
||||
{
|
||||
struct dc_plane_info temp_plane_info;
|
||||
memset(&temp_plane_info, 0, sizeof(temp_plane_info));
|
||||
union surface_update_flags *update_flags = &u->surface->update_flags;
|
||||
|
||||
if (!u->plane_info)
|
||||
return UPDATE_TYPE_FAST;
|
||||
|
||||
temp_plane_info = *u->plane_info;
|
||||
if (u->plane_info->color_space != u->surface->color_space)
|
||||
update_flags->bits.color_space_change = 1;
|
||||
|
||||
/* Copy all parameters that will cause a full update
|
||||
* from current surface, the rest of the parameters
|
||||
* from provided plane configuration.
|
||||
* Perform memory compare and special validation
|
||||
* for those that can cause fast/medium updates
|
||||
*/
|
||||
if (u->plane_info->input_tf != u->surface->input_tf)
|
||||
update_flags->bits.input_tf_change = 1;
|
||||
|
||||
/* Full update parameters */
|
||||
temp_plane_info.color_space = u->surface->color_space;
|
||||
temp_plane_info.dcc = u->surface->dcc;
|
||||
temp_plane_info.horizontal_mirror = u->surface->horizontal_mirror;
|
||||
temp_plane_info.plane_size = u->surface->plane_size;
|
||||
temp_plane_info.rotation = u->surface->rotation;
|
||||
temp_plane_info.stereo_format = u->surface->stereo_format;
|
||||
if (u->plane_info->horizontal_mirror != u->surface->horizontal_mirror)
|
||||
update_flags->bits.horizontal_mirror_change = 1;
|
||||
|
||||
if (surface_index == 0)
|
||||
temp_plane_info.visible = u->plane_info->visible;
|
||||
else
|
||||
temp_plane_info.visible = u->surface->visible;
|
||||
if (u->plane_info->rotation != u->surface->rotation)
|
||||
update_flags->bits.rotation_change = 1;
|
||||
|
||||
if (memcmp(u->plane_info, &temp_plane_info,
|
||||
sizeof(struct dc_plane_info)) != 0)
|
||||
return UPDATE_TYPE_FULL;
|
||||
if (u->plane_info->stereo_format != u->surface->stereo_format)
|
||||
update_flags->bits.stereo_format_change = 1;
|
||||
|
||||
if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha)
|
||||
update_flags->bits.per_pixel_alpha_change = 1;
|
||||
|
||||
if (pixel_format_to_bpp(u->plane_info->format) !=
|
||||
pixel_format_to_bpp(u->surface->format)) {
|
||||
pixel_format_to_bpp(u->surface->format))
|
||||
/* different bytes per element will require full bandwidth
|
||||
* and DML calculation
|
||||
*/
|
||||
return UPDATE_TYPE_FULL;
|
||||
}
|
||||
update_flags->bits.bpp_change = 1;
|
||||
|
||||
if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info,
|
||||
sizeof(union dc_tiling_info)) != 0) {
|
||||
update_flags->bits.swizzle_change = 1;
|
||||
/* todo: below are HW dependent, we should add a hook to
|
||||
* DCE/N resource and validated there.
|
||||
*/
|
||||
if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) {
|
||||
if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR)
|
||||
/* swizzled mode requires RQ to be setup properly,
|
||||
* thus need to run DML to calculate RQ settings
|
||||
*/
|
||||
return UPDATE_TYPE_FULL;
|
||||
}
|
||||
update_flags->bits.bandwidth_change = 1;
|
||||
}
|
||||
|
||||
if (update_flags->bits.rotation_change
|
||||
|| update_flags->bits.stereo_format_change
|
||||
|| update_flags->bits.bpp_change
|
||||
|| update_flags->bits.bandwidth_change)
|
||||
return UPDATE_TYPE_FULL;
|
||||
|
||||
return UPDATE_TYPE_MED;
|
||||
}
|
||||
|
||||
static enum surface_update_type get_scaling_info_update_type(
|
||||
static enum surface_update_type get_scaling_info_update_type(
|
||||
const struct dc_surface_update *u)
|
||||
{
|
||||
union surface_update_flags *update_flags = &u->surface->update_flags;
|
||||
|
||||
if (!u->scaling_info)
|
||||
return UPDATE_TYPE_FAST;
|
||||
|
||||
if (u->scaling_info->src_rect.width != u->surface->src_rect.width
|
||||
|| u->scaling_info->src_rect.height != u->surface->src_rect.height
|
||||
|| u->scaling_info->clip_rect.width != u->surface->clip_rect.width
|
||||
if (u->scaling_info->clip_rect.width != u->surface->clip_rect.width
|
||||
|| u->scaling_info->clip_rect.height != u->surface->clip_rect.height
|
||||
|| u->scaling_info->dst_rect.width != u->surface->dst_rect.width
|
||||
|| u->scaling_info->dst_rect.height != u->surface->dst_rect.height)
|
||||
return UPDATE_TYPE_FULL;
|
||||
|| u->scaling_info->dst_rect.height != u->surface->dst_rect.height) {
|
||||
update_flags->bits.scaling_change = 1;
|
||||
|
||||
if ((u->scaling_info->dst_rect.width < u->surface->dst_rect.width
|
||||
|| u->scaling_info->dst_rect.height < u->surface->dst_rect.height)
|
||||
&& (u->scaling_info->dst_rect.width < u->surface->src_rect.width
|
||||
|| u->scaling_info->dst_rect.height < u->surface->src_rect.height))
|
||||
/* Making dst rect smaller requires a bandwidth change */
|
||||
update_flags->bits.bandwidth_change = 1;
|
||||
}
|
||||
|
||||
if (u->scaling_info->src_rect.width != u->surface->src_rect.width
|
||||
|| u->scaling_info->src_rect.height != u->surface->src_rect.height) {
|
||||
|
||||
update_flags->bits.scaling_change = 1;
|
||||
if (u->scaling_info->src_rect.width > u->surface->src_rect.width
|
||||
&& u->scaling_info->src_rect.height > u->surface->src_rect.height)
|
||||
/* Making src rect bigger requires a bandwidth change */
|
||||
update_flags->bits.clock_change = 1;
|
||||
}
|
||||
|
||||
if (u->scaling_info->src_rect.x != u->surface->src_rect.x
|
||||
|| u->scaling_info->src_rect.y != u->surface->src_rect.y
|
||||
|
@ -1198,41 +1048,56 @@ static enum surface_update_type get_scaling_info_update_type(
|
|||
|| u->scaling_info->clip_rect.y != u->surface->clip_rect.y
|
||||
|| u->scaling_info->dst_rect.x != u->surface->dst_rect.x
|
||||
|| u->scaling_info->dst_rect.y != u->surface->dst_rect.y)
|
||||
update_flags->bits.position_change = 1;
|
||||
|
||||
if (update_flags->bits.clock_change
|
||||
|| update_flags->bits.bandwidth_change)
|
||||
return UPDATE_TYPE_FULL;
|
||||
|
||||
if (update_flags->bits.scaling_change
|
||||
|| update_flags->bits.position_change)
|
||||
return UPDATE_TYPE_MED;
|
||||
|
||||
return UPDATE_TYPE_FAST;
|
||||
}
|
||||
|
||||
static enum surface_update_type det_surface_update(
|
||||
const struct dc *dc,
|
||||
const struct dc_surface_update *u,
|
||||
int surface_index)
|
||||
static enum surface_update_type det_surface_update(const struct dc *dc,
|
||||
const struct dc_surface_update *u)
|
||||
{
|
||||
const struct dc_state *context = dc->current_state;
|
||||
enum surface_update_type type = UPDATE_TYPE_FAST;
|
||||
enum surface_update_type type;
|
||||
enum surface_update_type overall_type = UPDATE_TYPE_FAST;
|
||||
union surface_update_flags *update_flags = &u->surface->update_flags;
|
||||
|
||||
if (!is_surface_in_context(context, u->surface))
|
||||
update_flags->raw = 0; // Reset all flags
|
||||
|
||||
if (!is_surface_in_context(context, u->surface)) {
|
||||
update_flags->bits.new_plane = 1;
|
||||
return UPDATE_TYPE_FULL;
|
||||
}
|
||||
|
||||
type = get_plane_info_update_type(u, surface_index);
|
||||
if (overall_type < type)
|
||||
overall_type = type;
|
||||
type = get_plane_info_update_type(u);
|
||||
elevate_update_type(&overall_type, type);
|
||||
|
||||
type = get_scaling_info_update_type(u);
|
||||
if (overall_type < type)
|
||||
overall_type = type;
|
||||
elevate_update_type(&overall_type, type);
|
||||
|
||||
if (u->in_transfer_func ||
|
||||
u->hdr_static_metadata) {
|
||||
if (overall_type < UPDATE_TYPE_MED)
|
||||
overall_type = UPDATE_TYPE_MED;
|
||||
if (u->in_transfer_func)
|
||||
update_flags->bits.in_transfer_func = 1;
|
||||
|
||||
if (u->input_csc_color_matrix)
|
||||
update_flags->bits.input_csc_change = 1;
|
||||
|
||||
if (update_flags->bits.in_transfer_func
|
||||
|| update_flags->bits.input_csc_change) {
|
||||
type = UPDATE_TYPE_MED;
|
||||
elevate_update_type(&overall_type, type);
|
||||
}
|
||||
|
||||
return overall_type;
|
||||
}
|
||||
|
||||
enum surface_update_type dc_check_update_surfaces_for_stream(
|
||||
static enum surface_update_type check_update_surfaces_for_stream(
|
||||
struct dc *dc,
|
||||
struct dc_surface_update *updates,
|
||||
int surface_count,
|
||||
|
@ -1250,18 +1115,38 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
|
|||
|
||||
for (i = 0 ; i < surface_count; i++) {
|
||||
enum surface_update_type type =
|
||||
det_surface_update(dc, &updates[i], i);
|
||||
det_surface_update(dc, &updates[i]);
|
||||
|
||||
if (type == UPDATE_TYPE_FULL)
|
||||
return type;
|
||||
|
||||
if (overall_type < type)
|
||||
overall_type = type;
|
||||
elevate_update_type(&overall_type, type);
|
||||
}
|
||||
|
||||
return overall_type;
|
||||
}
|
||||
|
||||
enum surface_update_type dc_check_update_surfaces_for_stream(
|
||||
struct dc *dc,
|
||||
struct dc_surface_update *updates,
|
||||
int surface_count,
|
||||
struct dc_stream_update *stream_update,
|
||||
const struct dc_stream_status *stream_status)
|
||||
{
|
||||
int i;
|
||||
enum surface_update_type type;
|
||||
|
||||
for (i = 0; i < surface_count; i++)
|
||||
updates[i].surface->update_flags.raw = 0;
|
||||
|
||||
type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status);
|
||||
if (type == UPDATE_TYPE_FULL)
|
||||
for (i = 0; i < surface_count; i++)
|
||||
updates[i].surface->update_flags.bits.full_update = 1;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static struct dc_stream_status *stream_get_status(
|
||||
struct dc_state *ctx,
|
||||
struct dc_stream_state *stream)
|
||||
|
@ -1293,9 +1178,7 @@ static void commit_planes_for_stream(struct dc *dc,
|
|||
if (update_type == UPDATE_TYPE_FULL) {
|
||||
dc->hwss.set_bandwidth(dc, context, false);
|
||||
context_clock_trace(dc, context);
|
||||
}
|
||||
|
||||
if (update_type > UPDATE_TYPE_FAST) {
|
||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
||||
|
||||
|
@ -1312,103 +1195,58 @@ static void commit_planes_for_stream(struct dc *dc,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Lock pipes for provided surfaces, or all active if full update*/
|
||||
for (i = 0; i < surface_count; i++) {
|
||||
struct dc_plane_state *plane_state = srf_updates[i].surface;
|
||||
|
||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
||||
|
||||
if (update_type != UPDATE_TYPE_FULL && pipe_ctx->plane_state != plane_state)
|
||||
continue;
|
||||
if (!pipe_ctx->plane_state || pipe_ctx->top_pipe)
|
||||
continue;
|
||||
|
||||
dc->hwss.pipe_control_lock(
|
||||
dc,
|
||||
pipe_ctx,
|
||||
true);
|
||||
}
|
||||
if (update_type == UPDATE_TYPE_FULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Full fe update*/
|
||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
||||
|
||||
if (update_type != UPDATE_TYPE_FULL || !pipe_ctx->plane_state)
|
||||
if (update_type == UPDATE_TYPE_FAST || !pipe_ctx->plane_state)
|
||||
continue;
|
||||
|
||||
if (!pipe_ctx->top_pipe && pipe_ctx->stream) {
|
||||
struct dc_stream_status *stream_status = stream_get_status(context, pipe_ctx->stream);
|
||||
if (!pipe_ctx->top_pipe &&
|
||||
pipe_ctx->stream &&
|
||||
pipe_ctx->stream == stream) {
|
||||
struct dc_stream_status *stream_status =
|
||||
stream_get_status(context, pipe_ctx->stream);
|
||||
|
||||
dc->hwss.apply_ctx_for_surface(
|
||||
dc, pipe_ctx->stream, stream_status->plane_count, context);
|
||||
}
|
||||
}
|
||||
|
||||
if (update_type > UPDATE_TYPE_FAST)
|
||||
if (update_type == UPDATE_TYPE_FULL)
|
||||
context_timing_trace(dc, &context->res_ctx);
|
||||
|
||||
/* Perform requested Updates */
|
||||
for (i = 0; i < surface_count; i++) {
|
||||
struct dc_plane_state *plane_state = srf_updates[i].surface;
|
||||
|
||||
if (update_type == UPDATE_TYPE_MED)
|
||||
dc->hwss.apply_ctx_for_surface(
|
||||
dc, stream, surface_count, context);
|
||||
|
||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
|
||||
|
||||
if (pipe_ctx->stream != stream)
|
||||
continue;
|
||||
|
||||
if (pipe_ctx->plane_state != plane_state)
|
||||
continue;
|
||||
|
||||
if (srf_updates[i].flip_addr)
|
||||
dc->hwss.update_plane_addr(dc, pipe_ctx);
|
||||
if (update_type == UPDATE_TYPE_FAST && srf_updates[i].flip_addr)
|
||||
dc->hwss.update_plane_addr(dc, pipe_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
if (update_type == UPDATE_TYPE_FAST)
|
||||
if (stream && stream_update && update_type > UPDATE_TYPE_FAST)
|
||||
for (j = 0; j < dc->res_pool->pipe_count; j++) {
|
||||
struct pipe_ctx *pipe_ctx =
|
||||
&context->res_ctx.pipe_ctx[j];
|
||||
|
||||
if (pipe_ctx->stream != stream)
|
||||
continue;
|
||||
|
||||
/* work around to program degamma regs for split pipe after set mode. */
|
||||
if (srf_updates[i].in_transfer_func || (pipe_ctx->top_pipe &&
|
||||
pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state))
|
||||
dc->hwss.set_input_transfer_func(
|
||||
pipe_ctx, pipe_ctx->plane_state);
|
||||
|
||||
if (stream_update != NULL &&
|
||||
stream_update->out_transfer_func != NULL) {
|
||||
dc->hwss.set_output_transfer_func(
|
||||
pipe_ctx, pipe_ctx->stream);
|
||||
}
|
||||
|
||||
if (srf_updates[i].hdr_static_metadata) {
|
||||
if (stream_update->hdr_static_metadata) {
|
||||
resource_build_info_frame(pipe_ctx);
|
||||
dc->hwss.update_info_frame(pipe_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlock pipes */
|
||||
for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) {
|
||||
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
for (j = 0; j < surface_count; j++) {
|
||||
if (update_type != UPDATE_TYPE_FULL &&
|
||||
srf_updates[j].surface != pipe_ctx->plane_state)
|
||||
continue;
|
||||
if (!pipe_ctx->plane_state || pipe_ctx->top_pipe)
|
||||
continue;
|
||||
|
||||
dc->hwss.pipe_control_lock(
|
||||
dc,
|
||||
pipe_ctx,
|
||||
false);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dc_commit_updates_for_stream(struct dc *dc,
|
||||
|
@ -1480,10 +1318,7 @@ void dc_commit_updates_for_stream(struct dc *dc,
|
|||
stream_update,
|
||||
update_type,
|
||||
context);
|
||||
|
||||
if (update_type >= UPDATE_TYPE_FULL)
|
||||
dc_post_update_surfaces_to_stream(dc);
|
||||
|
||||
/*update current_State*/
|
||||
if (dc->current_state != context) {
|
||||
|
||||
struct dc_state *old = dc->current_state;
|
||||
|
@ -1492,6 +1327,9 @@ void dc_commit_updates_for_stream(struct dc *dc,
|
|||
dc_release_state(old);
|
||||
|
||||
}
|
||||
/*let's use current_state to update watermark etc*/
|
||||
if (update_type >= UPDATE_TYPE_FULL)
|
||||
dc_post_update_surfaces_to_stream(dc);
|
||||
|
||||
return;
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ void pre_surface_trace(
|
|||
"plane_state->tiling_info.gfx8.pipe_config = %d;\n"
|
||||
"plane_state->tiling_info.gfx8.array_mode = %d;\n"
|
||||
"plane_state->color_space = %d;\n"
|
||||
"plane_state->input_tf = %d;\n"
|
||||
"plane_state->dcc.enable = %d;\n"
|
||||
"plane_state->format = %d;\n"
|
||||
"plane_state->rotation = %d;\n"
|
||||
|
@ -144,6 +145,7 @@ void pre_surface_trace(
|
|||
plane_state->tiling_info.gfx8.pipe_config,
|
||||
plane_state->tiling_info.gfx8.array_mode,
|
||||
plane_state->color_space,
|
||||
plane_state->input_tf,
|
||||
plane_state->dcc.enable,
|
||||
plane_state->format,
|
||||
plane_state->rotation,
|
||||
|
@ -184,6 +186,7 @@ void update_surface_trace(
|
|||
if (update->plane_info) {
|
||||
SURFACE_TRACE(
|
||||
"plane_info->color_space = %d;\n"
|
||||
"plane_info->input_tf = %d;\n"
|
||||
"plane_info->format = %d;\n"
|
||||
"plane_info->plane_size.grph.surface_pitch = %d;\n"
|
||||
"plane_info->plane_size.grph.surface_size.height = %d;\n"
|
||||
|
@ -192,6 +195,7 @@ void update_surface_trace(
|
|||
"plane_info->plane_size.grph.surface_size.y = %d;\n"
|
||||
"plane_info->rotation = %d;\n",
|
||||
update->plane_info->color_space,
|
||||
update->plane_info->input_tf,
|
||||
update->plane_info->format,
|
||||
update->plane_info->plane_size.grph.surface_pitch,
|
||||
update->plane_info->plane_size.grph.surface_size.height,
|
||||
|
|
|
@ -1798,7 +1798,7 @@ static void disable_link(struct dc_link *link, enum signal_type signal)
|
|||
else
|
||||
dp_disable_link_phy_mst(link, signal);
|
||||
} else
|
||||
link->link_enc->funcs->disable_output(link->link_enc, signal, link);
|
||||
link->link_enc->funcs->disable_output(link->link_enc, signal);
|
||||
}
|
||||
|
||||
bool dp_active_dongle_validate_timing(
|
||||
|
@ -1869,7 +1869,7 @@ enum dc_status dc_link_validate_mode_timing(
|
|||
const struct dc_crtc_timing *timing)
|
||||
{
|
||||
uint32_t max_pix_clk = stream->sink->dongle_max_pix_clk;
|
||||
struct dc_dongle_caps *dongle_caps = &link->link_status.dpcd_caps->dongle_caps;
|
||||
struct dc_dongle_caps *dongle_caps = &link->dpcd_caps.dongle_caps;
|
||||
|
||||
/* A hack to avoid failing any modes for EDID override feature on
|
||||
* topology change such as lower quality cable for DP or different dongle
|
||||
|
|
|
@ -220,8 +220,7 @@ static void dpcd_set_lt_pattern_and_lane_settings(
|
|||
size_in_bytes);
|
||||
|
||||
dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
|
||||
"%s:\n %x VS set = %x PE set = %x \
|
||||
max VS Reached = %x max PE Reached = %x\n",
|
||||
"%s:\n %x VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
|
||||
__func__,
|
||||
DP_TRAINING_LANE0_SET,
|
||||
dpcd_lane[0].bits.VOLTAGE_SWING_SET,
|
||||
|
@ -558,8 +557,7 @@ static void dpcd_set_lane_settings(
|
|||
*/
|
||||
|
||||
dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
|
||||
"%s\n %x VS set = %x PE set = %x \
|
||||
max VS Reached = %x max PE Reached = %x\n",
|
||||
"%s\n %x VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
|
||||
__func__,
|
||||
DP_TRAINING_LANE0_SET,
|
||||
dpcd_lane[0].bits.VOLTAGE_SWING_SET,
|
||||
|
@ -872,9 +870,8 @@ static bool perform_clock_recovery_sequence(
|
|||
if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) {
|
||||
ASSERT(0);
|
||||
dm_logger_write(link->ctx->logger, LOG_ERROR,
|
||||
"%s: Link Training Error, could not \
|
||||
get CR after %d tries. \
|
||||
Possibly voltage swing issue", __func__,
|
||||
"%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue",
|
||||
__func__,
|
||||
LINK_TRAINING_MAX_CR_RETRY);
|
||||
|
||||
}
|
||||
|
@ -2127,7 +2124,7 @@ static void get_active_converter_info(
|
|||
|
||||
union dwnstream_port_caps_byte3_hdmi
|
||||
hdmi_caps = {.raw = det_caps[3] };
|
||||
union dwnstream_port_caps_byte1
|
||||
union dwnstream_port_caps_byte2
|
||||
hdmi_color_caps = {.raw = det_caps[2] };
|
||||
link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk =
|
||||
det_caps[1] * 25000;
|
||||
|
|
|
@ -89,7 +89,7 @@ void dp_enable_link_phy(
|
|||
|
||||
if (dc_is_dp_sst_signal(signal)) {
|
||||
if (signal == SIGNAL_TYPE_EDP) {
|
||||
link->dc->hwss.edp_power_control(link->link_enc, true);
|
||||
link->dc->hwss.edp_power_control(link, true);
|
||||
link_enc->funcs->enable_dp_output(
|
||||
link_enc,
|
||||
link_settings,
|
||||
|
@ -140,10 +140,10 @@ void dp_disable_link_phy(struct dc_link *link, enum signal_type signal)
|
|||
if (signal == SIGNAL_TYPE_EDP) {
|
||||
link->dc->hwss.edp_backlight_control(link, false);
|
||||
edp_receiver_ready_T9(link);
|
||||
link->link_enc->funcs->disable_output(link->link_enc, signal, link);
|
||||
link->dc->hwss.edp_power_control(link->link_enc, false);
|
||||
link->link_enc->funcs->disable_output(link->link_enc, signal);
|
||||
link->dc->hwss.edp_power_control(link, false);
|
||||
} else
|
||||
link->link_enc->funcs->disable_output(link->link_enc, signal, link);
|
||||
link->link_enc->funcs->disable_output(link->link_enc, signal);
|
||||
|
||||
/* Clear current link setting.*/
|
||||
memset(&link->cur_link_settings, 0,
|
||||
|
@ -286,8 +286,7 @@ void dp_retrain_link_dp_test(struct dc_link *link,
|
|||
|
||||
link->link_enc->funcs->disable_output(
|
||||
link->link_enc,
|
||||
SIGNAL_TYPE_DISPLAY_PORT,
|
||||
link);
|
||||
SIGNAL_TYPE_DISPLAY_PORT);
|
||||
|
||||
/* Clear current link setting. */
|
||||
memset(&link->cur_link_settings, 0,
|
||||
|
|
|
@ -426,15 +426,8 @@ static enum pixel_format convert_pixel_format_to_dalsurface(
|
|||
|
||||
static void rect_swap_helper(struct rect *rect)
|
||||
{
|
||||
uint32_t temp = 0;
|
||||
|
||||
temp = rect->height;
|
||||
rect->height = rect->width;
|
||||
rect->width = temp;
|
||||
|
||||
temp = rect->x;
|
||||
rect->x = rect->y;
|
||||
rect->y = temp;
|
||||
swap(rect->height, rect->width);
|
||||
swap(rect->x, rect->y);
|
||||
}
|
||||
|
||||
static void calculate_viewport(struct pipe_ctx *pipe_ctx)
|
||||
|
@ -2319,20 +2312,13 @@ static void set_spd_info_packet(
|
|||
|
||||
static void set_hdr_static_info_packet(
|
||||
struct encoder_info_packet *info_packet,
|
||||
struct dc_plane_state *plane_state,
|
||||
struct dc_stream_state *stream)
|
||||
{
|
||||
uint16_t i = 0;
|
||||
enum signal_type signal = stream->signal;
|
||||
struct dc_hdr_static_metadata hdr_metadata;
|
||||
uint32_t data;
|
||||
|
||||
if (!plane_state)
|
||||
return;
|
||||
|
||||
hdr_metadata = plane_state->hdr_static_ctx;
|
||||
|
||||
if (!hdr_metadata.hdr_supported)
|
||||
if (!stream->hdr_static_metadata.hdr_supported)
|
||||
return;
|
||||
|
||||
if (dc_is_hdmi_signal(signal)) {
|
||||
|
@ -2352,55 +2338,55 @@ static void set_hdr_static_info_packet(
|
|||
i = 2;
|
||||
}
|
||||
|
||||
data = hdr_metadata.is_hdr;
|
||||
data = stream->hdr_static_metadata.is_hdr;
|
||||
info_packet->sb[i++] = data ? 0x02 : 0x00;
|
||||
info_packet->sb[i++] = 0x00;
|
||||
|
||||
data = hdr_metadata.chromaticity_green_x / 2;
|
||||
data = stream->hdr_static_metadata.chromaticity_green_x / 2;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.chromaticity_green_y / 2;
|
||||
data = stream->hdr_static_metadata.chromaticity_green_y / 2;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.chromaticity_blue_x / 2;
|
||||
data = stream->hdr_static_metadata.chromaticity_blue_x / 2;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.chromaticity_blue_y / 2;
|
||||
data = stream->hdr_static_metadata.chromaticity_blue_y / 2;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.chromaticity_red_x / 2;
|
||||
data = stream->hdr_static_metadata.chromaticity_red_x / 2;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.chromaticity_red_y / 2;
|
||||
data = stream->hdr_static_metadata.chromaticity_red_y / 2;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.chromaticity_white_point_x / 2;
|
||||
data = stream->hdr_static_metadata.chromaticity_white_point_x / 2;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.chromaticity_white_point_y / 2;
|
||||
data = stream->hdr_static_metadata.chromaticity_white_point_y / 2;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.max_luminance;
|
||||
data = stream->hdr_static_metadata.max_luminance;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.min_luminance;
|
||||
data = stream->hdr_static_metadata.min_luminance;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.maximum_content_light_level;
|
||||
data = stream->hdr_static_metadata.maximum_content_light_level;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
data = hdr_metadata.maximum_frame_average_light_level;
|
||||
data = stream->hdr_static_metadata.maximum_frame_average_light_level;
|
||||
info_packet->sb[i++] = data & 0xFF;
|
||||
info_packet->sb[i++] = (data & 0xFF00) >> 8;
|
||||
|
||||
|
@ -2551,16 +2537,14 @@ void resource_build_info_frame(struct pipe_ctx *pipe_ctx)
|
|||
|
||||
set_spd_info_packet(&info->spd, pipe_ctx->stream);
|
||||
|
||||
set_hdr_static_info_packet(&info->hdrsmd,
|
||||
pipe_ctx->plane_state, pipe_ctx->stream);
|
||||
set_hdr_static_info_packet(&info->hdrsmd, pipe_ctx->stream);
|
||||
|
||||
} else if (dc_is_dp_signal(signal)) {
|
||||
set_vsc_info_packet(&info->vsc, pipe_ctx->stream);
|
||||
|
||||
set_spd_info_packet(&info->spd, pipe_ctx->stream);
|
||||
|
||||
set_hdr_static_info_packet(&info->hdrsmd,
|
||||
pipe_ctx->plane_state, pipe_ctx->stream);
|
||||
set_hdr_static_info_packet(&info->hdrsmd, pipe_ctx->stream);
|
||||
}
|
||||
|
||||
patch_gamut_packet_checksum(&info->gamut);
|
||||
|
|
|
@ -36,16 +36,13 @@
|
|||
#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST 297000
|
||||
static void update_stream_signal(struct dc_stream_state *stream)
|
||||
{
|
||||
if (stream->output_signal == SIGNAL_TYPE_NONE) {
|
||||
struct dc_sink *dc_sink = stream->sink;
|
||||
|
||||
if (dc_sink->sink_signal == SIGNAL_TYPE_NONE)
|
||||
stream->signal = stream->sink->link->connector_signal;
|
||||
else
|
||||
stream->signal = dc_sink->sink_signal;
|
||||
} else {
|
||||
stream->signal = stream->output_signal;
|
||||
}
|
||||
struct dc_sink *dc_sink = stream->sink;
|
||||
|
||||
if (dc_sink->sink_signal == SIGNAL_TYPE_NONE)
|
||||
stream->signal = stream->sink->link->connector_signal;
|
||||
else
|
||||
stream->signal = dc_sink->sink_signal;
|
||||
|
||||
if (dc_is_dvi_signal(stream->signal)) {
|
||||
if (stream->timing.pix_clk_khz > TMDS_MAX_PIXEL_CLOCK_IN_KHZ_UPMOST &&
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "inc/compressor.h"
|
||||
#include "dml/display_mode_lib.h"
|
||||
|
||||
#define DC_VER "3.1.07"
|
||||
#define DC_VER "3.1.20"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_STREAMS 6
|
||||
|
@ -58,8 +58,10 @@ struct dc_caps {
|
|||
uint32_t i2c_speed_in_khz;
|
||||
unsigned int max_cursor_size;
|
||||
unsigned int max_video_width;
|
||||
int linear_pitch_alignment;
|
||||
bool dcc_const_color;
|
||||
bool dynamic_audio;
|
||||
bool is_apu;
|
||||
};
|
||||
|
||||
struct dc_dcc_surface_param {
|
||||
|
@ -97,69 +99,53 @@ struct dc_static_screen_events {
|
|||
bool overlay_update;
|
||||
};
|
||||
|
||||
|
||||
/* Surface update type is used by dc_update_surfaces_and_stream
|
||||
* The update type is determined at the very beginning of the function based
|
||||
* on parameters passed in and decides how much programming (or updating) is
|
||||
* going to be done during the call.
|
||||
*
|
||||
* UPDATE_TYPE_FAST is used for really fast updates that do not require much
|
||||
* logical calculations or hardware register programming. This update MUST be
|
||||
* ISR safe on windows. Currently fast update will only be used to flip surface
|
||||
* address.
|
||||
*
|
||||
* UPDATE_TYPE_MED is used for slower updates which require significant hw
|
||||
* re-programming however do not affect bandwidth consumption or clock
|
||||
* requirements. At present, this is the level at which front end updates
|
||||
* that do not require us to run bw_calcs happen. These are in/out transfer func
|
||||
* updates, viewport offset changes, recout size changes and pixel depth changes.
|
||||
* This update can be done at ISR, but we want to minimize how often this happens.
|
||||
*
|
||||
* UPDATE_TYPE_FULL is slow. Really slow. This requires us to recalculate our
|
||||
* bandwidth and clocks, possibly rearrange some pipes and reprogram anything front
|
||||
* end related. Any time viewport dimensions, recout dimensions, scaling ratios or
|
||||
* gamma need to be adjusted or pipe needs to be turned on (or disconnected) we do
|
||||
* a full update. This cannot be done at ISR level and should be a rare event.
|
||||
* Unless someone is stress testing mpo enter/exit, playing with colour or adjusting
|
||||
* underscan we don't expect to see this call at all.
|
||||
*/
|
||||
|
||||
enum surface_update_type {
|
||||
UPDATE_TYPE_FAST, /* super fast, safe to execute in isr */
|
||||
UPDATE_TYPE_MED, /* ISR safe, most of programming needed, no bw/clk change*/
|
||||
UPDATE_TYPE_FULL, /* may need to shuffle resources */
|
||||
};
|
||||
|
||||
/* Forward declaration*/
|
||||
struct dc;
|
||||
struct dc_plane_state;
|
||||
struct dc_state;
|
||||
|
||||
|
||||
struct dc_cap_funcs {
|
||||
bool (*get_dcc_compression_cap)(const struct dc *dc,
|
||||
const struct dc_dcc_surface_param *input,
|
||||
struct dc_surface_dcc_cap *output);
|
||||
};
|
||||
|
||||
struct dc_stream_state_funcs {
|
||||
bool (*adjust_vmin_vmax)(struct dc *dc,
|
||||
struct dc_stream_state **stream,
|
||||
int num_streams,
|
||||
int vmin,
|
||||
int vmax);
|
||||
bool (*get_crtc_position)(struct dc *dc,
|
||||
struct dc_stream_state **stream,
|
||||
int num_streams,
|
||||
unsigned int *v_pos,
|
||||
unsigned int *nom_v_pos);
|
||||
|
||||
bool (*set_gamut_remap)(struct dc *dc,
|
||||
const struct dc_stream_state *stream);
|
||||
|
||||
bool (*program_csc_matrix)(struct dc *dc,
|
||||
struct dc_stream_state *stream);
|
||||
|
||||
void (*set_static_screen_events)(struct dc *dc,
|
||||
struct dc_stream_state **stream,
|
||||
int num_streams,
|
||||
const struct dc_static_screen_events *events);
|
||||
|
||||
void (*set_dither_option)(struct dc_stream_state *stream,
|
||||
enum dc_dither_option option);
|
||||
|
||||
void (*set_dpms)(struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
bool dpms_off);
|
||||
};
|
||||
|
||||
struct link_training_settings;
|
||||
|
||||
struct dc_link_funcs {
|
||||
void (*set_drive_settings)(struct dc *dc,
|
||||
struct link_training_settings *lt_settings,
|
||||
const struct dc_link *link);
|
||||
void (*perform_link_training)(struct dc *dc,
|
||||
struct dc_link_settings *link_setting,
|
||||
bool skip_video_pattern);
|
||||
void (*set_preferred_link_settings)(struct dc *dc,
|
||||
struct dc_link_settings *link_setting,
|
||||
struct dc_link *link);
|
||||
void (*enable_hpd)(const struct dc_link *link);
|
||||
void (*disable_hpd)(const struct dc_link *link);
|
||||
void (*set_test_pattern)(
|
||||
struct dc_link *link,
|
||||
enum dp_test_pattern test_pattern,
|
||||
const struct link_training_settings *p_link_settings,
|
||||
const unsigned char *p_custom_pattern,
|
||||
unsigned int cust_pattern_size);
|
||||
};
|
||||
|
||||
/* Structure to hold configuration flags set by dm at dc creation. */
|
||||
struct dc_config {
|
||||
|
@ -232,8 +218,6 @@ struct dce_hwseq;
|
|||
struct dc {
|
||||
struct dc_caps caps;
|
||||
struct dc_cap_funcs cap_funcs;
|
||||
struct dc_stream_state_funcs stream_funcs;
|
||||
struct dc_link_funcs link_funcs;
|
||||
struct dc_config config;
|
||||
struct dc_debug debug;
|
||||
|
||||
|
@ -333,24 +317,6 @@ enum color_transfer_func {
|
|||
transfer_func_gamma_26
|
||||
};
|
||||
|
||||
enum color_color_space {
|
||||
color_space_unsupported,
|
||||
color_space_srgb,
|
||||
color_space_bt601,
|
||||
color_space_bt709,
|
||||
color_space_xv_ycc_bt601,
|
||||
color_space_xv_ycc_bt709,
|
||||
color_space_xr_rgb,
|
||||
color_space_bt2020,
|
||||
color_space_adobe,
|
||||
color_space_dci_p3,
|
||||
color_space_sc_rgb_ms_ref,
|
||||
color_space_display_native,
|
||||
color_space_app_ctrl,
|
||||
color_space_dolby_vision,
|
||||
color_space_custom_coordinates
|
||||
};
|
||||
|
||||
struct dc_hdr_static_metadata {
|
||||
/* display chromaticities and white point in units of 0.00001 */
|
||||
unsigned int chromaticity_green_x;
|
||||
|
@ -415,6 +381,33 @@ struct dc_plane_status {
|
|||
bool is_right_eye;
|
||||
};
|
||||
|
||||
union surface_update_flags {
|
||||
|
||||
struct {
|
||||
/* Medium updates */
|
||||
uint32_t color_space_change:1;
|
||||
uint32_t input_tf_change:1;
|
||||
uint32_t horizontal_mirror_change:1;
|
||||
uint32_t per_pixel_alpha_change:1;
|
||||
uint32_t rotation_change:1;
|
||||
uint32_t swizzle_change:1;
|
||||
uint32_t scaling_change:1;
|
||||
uint32_t position_change:1;
|
||||
uint32_t in_transfer_func:1;
|
||||
uint32_t input_csc_change:1;
|
||||
|
||||
/* Full updates */
|
||||
uint32_t new_plane:1;
|
||||
uint32_t bpp_change:1;
|
||||
uint32_t bandwidth_change:1;
|
||||
uint32_t clock_change:1;
|
||||
uint32_t stereo_format_change:1;
|
||||
uint32_t full_update:1;
|
||||
} bits;
|
||||
|
||||
uint32_t raw;
|
||||
};
|
||||
|
||||
struct dc_plane_state {
|
||||
struct dc_plane_address address;
|
||||
struct scaling_taps scaling_quality;
|
||||
|
@ -426,18 +419,19 @@ struct dc_plane_state {
|
|||
union dc_tiling_info tiling_info;
|
||||
|
||||
struct dc_plane_dcc_param dcc;
|
||||
struct dc_hdr_static_metadata hdr_static_ctx;
|
||||
|
||||
struct dc_gamma *gamma_correction;
|
||||
struct dc_transfer_func *in_transfer_func;
|
||||
struct dc_bias_and_scale *bias_and_scale;
|
||||
struct csc_transform input_csc_color_matrix;
|
||||
struct fixed31_32 coeff_reduction_factor;
|
||||
|
||||
// sourceContentAttribute cache
|
||||
bool is_source_input_valid;
|
||||
struct dc_hdr_static_metadata source_input_mastering_info;
|
||||
enum color_color_space source_input_color_space;
|
||||
enum color_transfer_func source_input_tf;
|
||||
// TODO: No longer used, remove
|
||||
struct dc_hdr_static_metadata hdr_static_ctx;
|
||||
|
||||
enum dc_color_space color_space;
|
||||
enum color_transfer_func input_tf;
|
||||
|
||||
enum surface_pixel_format format;
|
||||
enum dc_rotation_angle rotation;
|
||||
enum plane_stereo_format stereo_format;
|
||||
|
@ -447,6 +441,7 @@ struct dc_plane_state {
|
|||
bool flip_immediate;
|
||||
bool horizontal_mirror;
|
||||
|
||||
union surface_update_flags update_flags;
|
||||
/* private to DC core */
|
||||
struct dc_plane_status status;
|
||||
struct dc_context *ctx;
|
||||
|
@ -463,10 +458,12 @@ struct dc_plane_info {
|
|||
enum surface_pixel_format format;
|
||||
enum dc_rotation_angle rotation;
|
||||
enum plane_stereo_format stereo_format;
|
||||
enum dc_color_space color_space; /*todo: wrong place, fits in scaling info*/
|
||||
enum dc_color_space color_space;
|
||||
enum color_transfer_func input_tf;
|
||||
bool horizontal_mirror;
|
||||
bool visible;
|
||||
bool per_pixel_alpha;
|
||||
bool input_csc_enabled;
|
||||
};
|
||||
|
||||
struct dc_scaling_info {
|
||||
|
@ -483,13 +480,18 @@ struct dc_surface_update {
|
|||
struct dc_flip_addrs *flip_addr;
|
||||
struct dc_plane_info *plane_info;
|
||||
struct dc_scaling_info *scaling_info;
|
||||
|
||||
/* following updates require alloc/sleep/spin that is not isr safe,
|
||||
* null means no updates
|
||||
*/
|
||||
/* gamma TO BE REMOVED */
|
||||
struct dc_gamma *gamma;
|
||||
enum color_transfer_func color_input_tf;
|
||||
enum color_transfer_func color_output_tf;
|
||||
struct dc_transfer_func *in_transfer_func;
|
||||
struct dc_hdr_static_metadata *hdr_static_metadata;
|
||||
|
||||
struct csc_transform *input_csc_color_matrix;
|
||||
struct fixed31_32 *coeff_reduction_factor;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -524,197 +526,7 @@ struct dc_flip_addrs {
|
|||
bool dc_post_update_surfaces_to_stream(
|
||||
struct dc *dc);
|
||||
|
||||
/* Surface update type is used by dc_update_surfaces_and_stream
|
||||
* The update type is determined at the very beginning of the function based
|
||||
* on parameters passed in and decides how much programming (or updating) is
|
||||
* going to be done during the call.
|
||||
*
|
||||
* UPDATE_TYPE_FAST is used for really fast updates that do not require much
|
||||
* logical calculations or hardware register programming. This update MUST be
|
||||
* ISR safe on windows. Currently fast update will only be used to flip surface
|
||||
* address.
|
||||
*
|
||||
* UPDATE_TYPE_MED is used for slower updates which require significant hw
|
||||
* re-programming however do not affect bandwidth consumption or clock
|
||||
* requirements. At present, this is the level at which front end updates
|
||||
* that do not require us to run bw_calcs happen. These are in/out transfer func
|
||||
* updates, viewport offset changes, recout size changes and pixel depth changes.
|
||||
* This update can be done at ISR, but we want to minimize how often this happens.
|
||||
*
|
||||
* UPDATE_TYPE_FULL is slow. Really slow. This requires us to recalculate our
|
||||
* bandwidth and clocks, possibly rearrange some pipes and reprogram anything front
|
||||
* end related. Any time viewport dimensions, recout dimensions, scaling ratios or
|
||||
* gamma need to be adjusted or pipe needs to be turned on (or disconnected) we do
|
||||
* a full update. This cannot be done at ISR level and should be a rare event.
|
||||
* Unless someone is stress testing mpo enter/exit, playing with colour or adjusting
|
||||
* underscan we don't expect to see this call at all.
|
||||
*/
|
||||
|
||||
enum surface_update_type {
|
||||
UPDATE_TYPE_FAST, /* super fast, safe to execute in isr */
|
||||
UPDATE_TYPE_MED, /* ISR safe, most of programming needed, no bw/clk change*/
|
||||
UPDATE_TYPE_FULL, /* may need to shuffle resources */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Stream Interfaces
|
||||
******************************************************************************/
|
||||
|
||||
struct dc_stream_status {
|
||||
int primary_otg_inst;
|
||||
int stream_enc_inst;
|
||||
int plane_count;
|
||||
struct dc_plane_state *plane_states[MAX_SURFACE_NUM];
|
||||
|
||||
/*
|
||||
* link this stream passes through
|
||||
*/
|
||||
struct dc_link *link;
|
||||
};
|
||||
|
||||
struct dc_stream_state {
|
||||
struct dc_sink *sink;
|
||||
struct dc_crtc_timing timing;
|
||||
|
||||
struct rect src; /* composition area */
|
||||
struct rect dst; /* stream addressable area */
|
||||
|
||||
struct audio_info audio_info;
|
||||
|
||||
struct freesync_context freesync_ctx;
|
||||
|
||||
struct dc_transfer_func *out_transfer_func;
|
||||
struct colorspace_transform gamut_remap_matrix;
|
||||
struct csc_transform csc_color_matrix;
|
||||
|
||||
enum signal_type output_signal;
|
||||
|
||||
enum dc_color_space output_color_space;
|
||||
enum dc_dither_option dither_option;
|
||||
|
||||
enum view_3d_format view_format;
|
||||
|
||||
bool ignore_msa_timing_param;
|
||||
/* TODO: custom INFO packets */
|
||||
/* TODO: ABM info (DMCU) */
|
||||
/* TODO: PSR info */
|
||||
/* TODO: CEA VIC */
|
||||
|
||||
/* from core_stream struct */
|
||||
struct dc_context *ctx;
|
||||
|
||||
/* used by DCP and FMT */
|
||||
struct bit_depth_reduction_params bit_depth_params;
|
||||
struct clamping_and_pixel_encoding_params clamping;
|
||||
|
||||
int phy_pix_clk;
|
||||
enum signal_type signal;
|
||||
bool dpms_off;
|
||||
|
||||
struct dc_stream_status status;
|
||||
|
||||
struct dc_cursor_attributes cursor_attributes;
|
||||
|
||||
/* from stream struct */
|
||||
struct kref refcount;
|
||||
};
|
||||
|
||||
struct dc_stream_update {
|
||||
struct rect src;
|
||||
struct rect dst;
|
||||
struct dc_transfer_func *out_transfer_func;
|
||||
};
|
||||
|
||||
bool dc_is_stream_unchanged(
|
||||
struct dc_stream_state *old_stream, struct dc_stream_state *stream);
|
||||
bool dc_is_stream_scaling_unchanged(
|
||||
struct dc_stream_state *old_stream, struct dc_stream_state *stream);
|
||||
|
||||
/*
|
||||
* Set up surface attributes and associate to a stream
|
||||
* The surfaces parameter is an absolute set of all surface active for the stream.
|
||||
* If no surfaces are provided, the stream will be blanked; no memory read.
|
||||
* Any flip related attribute changes must be done through this interface.
|
||||
*
|
||||
* After this call:
|
||||
* Surfaces attributes are programmed and configured to be composed into stream.
|
||||
* This does not trigger a flip. No surface address is programmed.
|
||||
*/
|
||||
|
||||
bool dc_commit_planes_to_stream(
|
||||
struct dc *dc,
|
||||
struct dc_plane_state **plane_states,
|
||||
uint8_t new_plane_count,
|
||||
struct dc_stream_state *dc_stream,
|
||||
struct dc_state *state);
|
||||
|
||||
void dc_commit_updates_for_stream(struct dc *dc,
|
||||
struct dc_surface_update *srf_updates,
|
||||
int surface_count,
|
||||
struct dc_stream_state *stream,
|
||||
struct dc_stream_update *stream_update,
|
||||
struct dc_plane_state **plane_states,
|
||||
struct dc_state *state);
|
||||
/*
|
||||
* Log the current stream state.
|
||||
*/
|
||||
void dc_stream_log(
|
||||
const struct dc_stream_state *stream,
|
||||
struct dal_logger *dc_logger,
|
||||
enum dc_log_type log_type);
|
||||
|
||||
uint8_t dc_get_current_stream_count(struct dc *dc);
|
||||
struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i);
|
||||
|
||||
/*
|
||||
* Return the current frame counter.
|
||||
*/
|
||||
uint32_t dc_stream_get_vblank_counter(const struct dc_stream_state *stream);
|
||||
|
||||
/* TODO: Return parsed values rather than direct register read
|
||||
* This has a dependency on the caller (amdgpu_get_crtc_scanoutpos)
|
||||
* being refactored properly to be dce-specific
|
||||
*/
|
||||
bool dc_stream_get_scanoutpos(const struct dc_stream_state *stream,
|
||||
uint32_t *v_blank_start,
|
||||
uint32_t *v_blank_end,
|
||||
uint32_t *h_position,
|
||||
uint32_t *v_position);
|
||||
|
||||
enum dc_status dc_add_stream_to_ctx(
|
||||
struct dc *dc,
|
||||
struct dc_state *new_ctx,
|
||||
struct dc_stream_state *stream);
|
||||
|
||||
enum dc_status dc_remove_stream_from_ctx(
|
||||
struct dc *dc,
|
||||
struct dc_state *new_ctx,
|
||||
struct dc_stream_state *stream);
|
||||
|
||||
|
||||
bool dc_add_plane_to_context(
|
||||
const struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
struct dc_plane_state *plane_state,
|
||||
struct dc_state *context);
|
||||
|
||||
bool dc_remove_plane_from_context(
|
||||
const struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
struct dc_plane_state *plane_state,
|
||||
struct dc_state *context);
|
||||
|
||||
bool dc_rem_all_planes_for_stream(
|
||||
const struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
struct dc_state *context);
|
||||
|
||||
bool dc_add_all_planes_for_stream(
|
||||
const struct dc *dc,
|
||||
struct dc_stream_state *stream,
|
||||
struct dc_plane_state * const *plane_states,
|
||||
int plane_count,
|
||||
struct dc_state *context);
|
||||
#include "dc_stream.h"
|
||||
|
||||
/*
|
||||
* Structure to store surface/stream associations for validation
|
||||
|
@ -725,22 +537,12 @@ struct dc_validation_set {
|
|||
uint8_t plane_count;
|
||||
};
|
||||
|
||||
enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream);
|
||||
|
||||
enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state);
|
||||
|
||||
enum dc_status dc_validate_global_state(
|
||||
struct dc *dc,
|
||||
struct dc_state *new_ctx);
|
||||
|
||||
/*
|
||||
* This function takes a stream and checks if it is guaranteed to be supported.
|
||||
* Guaranteed means that MAX_COFUNC similar streams are supported.
|
||||
*
|
||||
* After this call:
|
||||
* No hardware is programmed for call. Only validation is done.
|
||||
*/
|
||||
|
||||
|
||||
void dc_resource_state_construct(
|
||||
const struct dc *dc,
|
||||
|
@ -767,42 +569,6 @@ void dc_resource_state_destruct(struct dc_state *context);
|
|||
*/
|
||||
bool dc_commit_state(struct dc *dc, struct dc_state *context);
|
||||
|
||||
/*
|
||||
* Set up streams and links associated to drive sinks
|
||||
* The streams parameter is an absolute set of all active streams.
|
||||
*
|
||||
* After this call:
|
||||
* Phy, Encoder, Timing Generator are programmed and enabled.
|
||||
* New streams are enabled with blank stream; no memory read.
|
||||
*/
|
||||
/*
|
||||
* Enable stereo when commit_streams is not required,
|
||||
* for example, frame alternate.
|
||||
*/
|
||||
bool dc_enable_stereo(
|
||||
struct dc *dc,
|
||||
struct dc_state *context,
|
||||
struct dc_stream_state *streams[],
|
||||
uint8_t stream_count);
|
||||
|
||||
/**
|
||||
* Create a new default stream for the requested sink
|
||||
*/
|
||||
struct dc_stream_state *dc_create_stream_for_sink(struct dc_sink *dc_sink);
|
||||
|
||||
void dc_stream_retain(struct dc_stream_state *dc_stream);
|
||||
void dc_stream_release(struct dc_stream_state *dc_stream);
|
||||
|
||||
struct dc_stream_status *dc_stream_get_status(
|
||||
struct dc_stream_state *dc_stream);
|
||||
|
||||
enum surface_update_type dc_check_update_surfaces_for_stream(
|
||||
struct dc *dc,
|
||||
struct dc_surface_update *updates,
|
||||
int surface_count,
|
||||
struct dc_stream_update *stream_update,
|
||||
const struct dc_stream_status *stream_status);
|
||||
|
||||
|
||||
struct dc_state *dc_create_state(void);
|
||||
void dc_retain_state(struct dc_state *context);
|
||||
|
@ -835,171 +601,7 @@ struct dpcd_caps {
|
|||
bool dpcd_display_control_capable;
|
||||
};
|
||||
|
||||
struct dc_link_status {
|
||||
struct dpcd_caps *dpcd_caps;
|
||||
};
|
||||
|
||||
/* DP MST stream allocation (payload bandwidth number) */
|
||||
struct link_mst_stream_allocation {
|
||||
/* DIG front */
|
||||
const struct stream_encoder *stream_enc;
|
||||
/* associate DRM payload table with DC stream encoder */
|
||||
uint8_t vcp_id;
|
||||
/* number of slots required for the DP stream in transport packet */
|
||||
uint8_t slot_count;
|
||||
};
|
||||
|
||||
/* DP MST stream allocation table */
|
||||
struct link_mst_stream_allocation_table {
|
||||
/* number of DP video streams */
|
||||
int stream_count;
|
||||
/* array of stream allocations */
|
||||
struct link_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM];
|
||||
};
|
||||
|
||||
/*
|
||||
* A link contains one or more sinks and their connected status.
|
||||
* The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
|
||||
*/
|
||||
struct dc_link {
|
||||
struct dc_sink *remote_sinks[MAX_SINKS_PER_LINK];
|
||||
unsigned int sink_count;
|
||||
struct dc_sink *local_sink;
|
||||
unsigned int link_index;
|
||||
enum dc_connection_type type;
|
||||
enum signal_type connector_signal;
|
||||
enum dc_irq_source irq_source_hpd;
|
||||
enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse */
|
||||
/* caps is the same as reported_link_cap. link_traing use
|
||||
* reported_link_cap. Will clean up. TODO
|
||||
*/
|
||||
struct dc_link_settings reported_link_cap;
|
||||
struct dc_link_settings verified_link_cap;
|
||||
struct dc_link_settings cur_link_settings;
|
||||
struct dc_lane_settings cur_lane_setting;
|
||||
struct dc_link_settings preferred_link_setting;
|
||||
|
||||
uint8_t ddc_hw_inst;
|
||||
|
||||
uint8_t hpd_src;
|
||||
|
||||
uint8_t link_enc_hw_inst;
|
||||
|
||||
bool test_pattern_enabled;
|
||||
union compliance_test_state compliance_test_state;
|
||||
|
||||
void *priv;
|
||||
|
||||
struct ddc_service *ddc;
|
||||
|
||||
bool aux_mode;
|
||||
|
||||
/* Private to DC core */
|
||||
|
||||
const struct dc *dc;
|
||||
|
||||
struct dc_context *ctx;
|
||||
|
||||
struct link_encoder *link_enc;
|
||||
struct graphics_object_id link_id;
|
||||
union ddi_channel_mapping ddi_channel_mapping;
|
||||
struct connector_device_tag_info device_tag;
|
||||
struct dpcd_caps dpcd_caps;
|
||||
unsigned short chip_caps;
|
||||
unsigned int dpcd_sink_count;
|
||||
enum edp_revision edp_revision;
|
||||
bool psr_enabled;
|
||||
|
||||
/* MST record stream using this link */
|
||||
struct link_flags {
|
||||
bool dp_keep_receiver_powered;
|
||||
} wa_flags;
|
||||
struct link_mst_stream_allocation_table mst_stream_alloc_table;
|
||||
|
||||
struct dc_link_status link_status;
|
||||
|
||||
};
|
||||
|
||||
const struct dc_link_status *dc_link_get_status(const struct dc_link *dc_link);
|
||||
|
||||
/*
|
||||
* Return an enumerated dc_link. dc_link order is constant and determined at
|
||||
* boot time. They cannot be created or destroyed.
|
||||
* Use dc_get_caps() to get number of links.
|
||||
*/
|
||||
static inline struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index)
|
||||
{
|
||||
return dc->links[link_index];
|
||||
}
|
||||
|
||||
/* Set backlight level of an embedded panel (eDP, LVDS). */
|
||||
bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level,
|
||||
uint32_t frame_ramp, const struct dc_stream_state *stream);
|
||||
|
||||
bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable, bool wait);
|
||||
|
||||
bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);
|
||||
|
||||
bool dc_link_setup_psr(struct dc_link *dc_link,
|
||||
const struct dc_stream_state *stream, struct psr_config *psr_config,
|
||||
struct psr_context *psr_context);
|
||||
|
||||
/* Request DC to detect if there is a Panel connected.
|
||||
* boot - If this call is during initial boot.
|
||||
* Return false for any type of detection failure or MST detection
|
||||
* true otherwise. True meaning further action is required (status update
|
||||
* and OS notification).
|
||||
*/
|
||||
enum dc_detect_reason {
|
||||
DETECT_REASON_BOOT,
|
||||
DETECT_REASON_HPD,
|
||||
DETECT_REASON_HPDRX,
|
||||
};
|
||||
|
||||
bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
|
||||
|
||||
/* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
|
||||
* Return:
|
||||
* true - Downstream port status changed. DM should call DC to do the
|
||||
* detection.
|
||||
* false - no change in Downstream port status. No further action required
|
||||
* from DM. */
|
||||
bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link,
|
||||
union hpd_irq_data *hpd_irq_dpcd_data);
|
||||
|
||||
struct dc_sink_init_data;
|
||||
|
||||
struct dc_sink *dc_link_add_remote_sink(
|
||||
struct dc_link *dc_link,
|
||||
const uint8_t *edid,
|
||||
int len,
|
||||
struct dc_sink_init_data *init_data);
|
||||
|
||||
void dc_link_remove_remote_sink(
|
||||
struct dc_link *link,
|
||||
struct dc_sink *sink);
|
||||
|
||||
/* Used by diagnostics for virtual link at the moment */
|
||||
|
||||
void dc_link_dp_set_drive_settings(
|
||||
struct dc_link *link,
|
||||
struct link_training_settings *lt_settings);
|
||||
|
||||
enum link_training_result dc_link_dp_perform_link_training(
|
||||
struct dc_link *link,
|
||||
const struct dc_link_settings *link_setting,
|
||||
bool skip_video_pattern);
|
||||
|
||||
void dc_link_dp_enable_hpd(const struct dc_link *link);
|
||||
|
||||
void dc_link_dp_disable_hpd(const struct dc_link *link);
|
||||
|
||||
bool dc_link_dp_set_test_pattern(
|
||||
struct dc_link *link,
|
||||
enum dp_test_pattern test_pattern,
|
||||
const struct link_training_settings *p_link_settings,
|
||||
const unsigned char *p_custom_pattern,
|
||||
unsigned int cust_pattern_size);
|
||||
#include "dc_link.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Sink Interfaces - A sink corresponds to a display output device
|
||||
|
@ -1037,6 +639,7 @@ struct dc_sink {
|
|||
|
||||
/* private to dc_sink.c */
|
||||
struct kref refcount;
|
||||
|
||||
};
|
||||
|
||||
void dc_sink_retain(struct dc_sink *sink);
|
||||
|
@ -1051,18 +654,6 @@ struct dc_sink_init_data {
|
|||
|
||||
struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params);
|
||||
|
||||
/*******************************************************************************
|
||||
* Cursor interfaces - To manages the cursor within a stream
|
||||
******************************************************************************/
|
||||
/* TODO: Deprecated once we switch to dc_set_cursor_position */
|
||||
bool dc_stream_set_cursor_attributes(
|
||||
struct dc_stream_state *stream,
|
||||
const struct dc_cursor_attributes *attributes);
|
||||
|
||||
bool dc_stream_set_cursor_position(
|
||||
struct dc_stream_state *stream,
|
||||
const struct dc_cursor_position *position);
|
||||
|
||||
/* Newer interfaces */
|
||||
struct dc_cursor {
|
||||
struct dc_plane_address address;
|
||||
|
@ -1090,14 +681,4 @@ void dc_set_power_state(
|
|||
enum dc_acpi_cm_power_state power_state);
|
||||
void dc_resume(struct dc *dc);
|
||||
|
||||
/*
|
||||
* DPCD access interfaces
|
||||
*/
|
||||
|
||||
bool dc_submit_i2c(
|
||||
struct dc *dc,
|
||||
uint32_t link_index,
|
||||
struct i2c_command *cmd);
|
||||
|
||||
|
||||
#endif /* DC_INTERFACE_H_ */
|
||||
|
|
|
@ -255,7 +255,7 @@ enum dpcd_downstream_port_detailed_type {
|
|||
DOWN_STREAM_DETAILED_DP_PLUS_PLUS
|
||||
};
|
||||
|
||||
union dwnstream_port_caps_byte1 {
|
||||
union dwnstream_port_caps_byte2 {
|
||||
struct {
|
||||
uint8_t MAX_BITS_PER_COLOR_COMPONENT:2;
|
||||
uint8_t RESERVED:6;
|
||||
|
@ -298,6 +298,32 @@ union dwnstream_port_caps_byte3_hdmi {
|
|||
|
||||
/*4-byte structure for detailed capabilities of a down-stream port
|
||||
(DP-to-TMDS converter).*/
|
||||
union dwnstream_portxcaps {
|
||||
struct {
|
||||
union dwnstream_port_caps_byte0 byte0;
|
||||
unsigned char max_TMDS_clock; //byte1
|
||||
union dwnstream_port_caps_byte2 byte2;
|
||||
|
||||
union {
|
||||
union dwnstream_port_caps_byte3_dvi byteDVI;
|
||||
union dwnstream_port_caps_byte3_hdmi byteHDMI;
|
||||
} byte3;
|
||||
} bytes;
|
||||
|
||||
unsigned char raw[4];
|
||||
};
|
||||
|
||||
union downstream_port {
|
||||
struct {
|
||||
unsigned char present:1;
|
||||
unsigned char type:2;
|
||||
unsigned char format_conv:1;
|
||||
unsigned char detailed_caps:1;
|
||||
unsigned char reserved:3;
|
||||
} bits;
|
||||
unsigned char raw;
|
||||
};
|
||||
|
||||
|
||||
union sink_status {
|
||||
struct {
|
||||
|
|
|
@ -156,8 +156,13 @@ uint32_t generic_reg_wait(const struct dc_context *ctx,
|
|||
|
||||
field_value = get_reg_field_value_ex(reg_val, mask, shift);
|
||||
|
||||
if (field_value == condition_value)
|
||||
if (field_value == condition_value) {
|
||||
if (i * delay_between_poll_us > 1000)
|
||||
dm_output_to_console("REG_WAIT taking a while: %dms in %s line:%d\n",
|
||||
delay_between_poll_us * i / 1000,
|
||||
func_name, line);
|
||||
return reg_val;
|
||||
}
|
||||
}
|
||||
|
||||
dm_error("REG_WAIT timeout %dus * %d tries - %s line:%d\n",
|
||||
|
|
|
@ -492,15 +492,24 @@ struct dc_cursor_attributes {
|
|||
enum dc_color_space {
|
||||
COLOR_SPACE_UNKNOWN,
|
||||
COLOR_SPACE_SRGB,
|
||||
COLOR_SPACE_XR_RGB,
|
||||
COLOR_SPACE_SRGB_LIMITED,
|
||||
COLOR_SPACE_MSREF_SCRGB,
|
||||
COLOR_SPACE_YCBCR601,
|
||||
COLOR_SPACE_YCBCR709,
|
||||
COLOR_SPACE_XV_YCC_709,
|
||||
COLOR_SPACE_XV_YCC_601,
|
||||
COLOR_SPACE_YCBCR601_LIMITED,
|
||||
COLOR_SPACE_YCBCR709_LIMITED,
|
||||
COLOR_SPACE_2020_RGB_FULLRANGE,
|
||||
COLOR_SPACE_2020_RGB_LIMITEDRANGE,
|
||||
COLOR_SPACE_2020_YCBCR,
|
||||
COLOR_SPACE_ADOBERGB,
|
||||
COLOR_SPACE_DCIP3,
|
||||
COLOR_SPACE_DISPLAYNATIVE,
|
||||
COLOR_SPACE_DOLBYVISION,
|
||||
COLOR_SPACE_APPCTRL,
|
||||
COLOR_SPACE_CUSTOMPOINTS,
|
||||
};
|
||||
|
||||
enum dc_dither_option {
|
||||
|
@ -664,6 +673,22 @@ enum dc_timing_3d_format {
|
|||
TIMING_3D_FORMAT_MAX,
|
||||
};
|
||||
|
||||
enum trigger_delay {
|
||||
TRIGGER_DELAY_NEXT_PIXEL = 0,
|
||||
TRIGGER_DELAY_NEXT_LINE,
|
||||
};
|
||||
|
||||
enum crtc_event {
|
||||
CRTC_EVENT_VSYNC_RISING = 0,
|
||||
CRTC_EVENT_VSYNC_FALLING
|
||||
};
|
||||
|
||||
struct crtc_trigger_info {
|
||||
bool enabled;
|
||||
struct dc_stream_state *event_source;
|
||||
enum crtc_event event;
|
||||
enum trigger_delay delay;
|
||||
};
|
||||
|
||||
struct dc_crtc_timing {
|
||||
|
||||
|
|
207
drivers/gpu/drm/amd/display/dc/dc_link.h
Normal file
207
drivers/gpu/drm/amd/display/dc/dc_link.h
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright 2012-14 Advanced Micro Devices, 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: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DC_LINK_H_
|
||||
#define DC_LINK_H_
|
||||
|
||||
#include "dc_types.h"
|
||||
#include "grph_object_defs.h"
|
||||
|
||||
struct dc_link_status {
|
||||
struct dpcd_caps *dpcd_caps;
|
||||
};
|
||||
|
||||
/* DP MST stream allocation (payload bandwidth number) */
|
||||
struct link_mst_stream_allocation {
|
||||
/* DIG front */
|
||||
const struct stream_encoder *stream_enc;
|
||||
/* associate DRM payload table with DC stream encoder */
|
||||
uint8_t vcp_id;
|
||||
/* number of slots required for the DP stream in transport packet */
|
||||
uint8_t slot_count;
|
||||
};
|
||||
|
||||
/* DP MST stream allocation table */
|
||||
struct link_mst_stream_allocation_table {
|
||||
/* number of DP video streams */
|
||||
int stream_count;
|
||||
/* array of stream allocations */
|
||||
struct link_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM];
|
||||
};
|
||||
|
||||
/*
|
||||
* A link contains one or more sinks and their connected status.
|
||||
* The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
|
||||
*/
|
||||
struct dc_link {
|
||||
struct dc_sink *remote_sinks[MAX_SINKS_PER_LINK];
|
||||
unsigned int sink_count;
|
||||
struct dc_sink *local_sink;
|
||||
unsigned int link_index;
|
||||
enum dc_connection_type type;
|
||||
enum signal_type connector_signal;
|
||||
enum dc_irq_source irq_source_hpd;
|
||||
enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse */
|
||||
/* caps is the same as reported_link_cap. link_traing use
|
||||
* reported_link_cap. Will clean up. TODO
|
||||
*/
|
||||
struct dc_link_settings reported_link_cap;
|
||||
struct dc_link_settings verified_link_cap;
|
||||
struct dc_link_settings cur_link_settings;
|
||||
struct dc_lane_settings cur_lane_setting;
|
||||
struct dc_link_settings preferred_link_setting;
|
||||
|
||||
uint8_t ddc_hw_inst;
|
||||
|
||||
uint8_t hpd_src;
|
||||
|
||||
uint8_t link_enc_hw_inst;
|
||||
|
||||
bool test_pattern_enabled;
|
||||
union compliance_test_state compliance_test_state;
|
||||
|
||||
void *priv;
|
||||
|
||||
struct ddc_service *ddc;
|
||||
|
||||
bool aux_mode;
|
||||
|
||||
/* Private to DC core */
|
||||
|
||||
const struct dc *dc;
|
||||
|
||||
struct dc_context *ctx;
|
||||
|
||||
struct link_encoder *link_enc;
|
||||
struct graphics_object_id link_id;
|
||||
union ddi_channel_mapping ddi_channel_mapping;
|
||||
struct connector_device_tag_info device_tag;
|
||||
struct dpcd_caps dpcd_caps;
|
||||
unsigned short chip_caps;
|
||||
unsigned int dpcd_sink_count;
|
||||
enum edp_revision edp_revision;
|
||||
bool psr_enabled;
|
||||
|
||||
/* MST record stream using this link */
|
||||
struct link_flags {
|
||||
bool dp_keep_receiver_powered;
|
||||
} wa_flags;
|
||||
struct link_mst_stream_allocation_table mst_stream_alloc_table;
|
||||
|
||||
struct dc_link_status link_status;
|
||||
|
||||
};
|
||||
|
||||
const struct dc_link_status *dc_link_get_status(const struct dc_link *dc_link);
|
||||
|
||||
/*
|
||||
* Return an enumerated dc_link. dc_link order is constant and determined at
|
||||
* boot time. They cannot be created or destroyed.
|
||||
* Use dc_get_caps() to get number of links.
|
||||
*/
|
||||
static inline struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index)
|
||||
{
|
||||
return dc->links[link_index];
|
||||
}
|
||||
|
||||
/* Set backlight level of an embedded panel (eDP, LVDS). */
|
||||
bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level,
|
||||
uint32_t frame_ramp, const struct dc_stream_state *stream);
|
||||
|
||||
bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable, bool wait);
|
||||
|
||||
bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state);
|
||||
|
||||
bool dc_link_setup_psr(struct dc_link *dc_link,
|
||||
const struct dc_stream_state *stream, struct psr_config *psr_config,
|
||||
struct psr_context *psr_context);
|
||||
|
||||
/* Request DC to detect if there is a Panel connected.
|
||||
* boot - If this call is during initial boot.
|
||||
* Return false for any type of detection failure or MST detection
|
||||
* true otherwise. True meaning further action is required (status update
|
||||
* and OS notification).
|
||||
*/
|
||||
enum dc_detect_reason {
|
||||
DETECT_REASON_BOOT,
|
||||
DETECT_REASON_HPD,
|
||||
DETECT_REASON_HPDRX,
|
||||
};
|
||||
|
||||
bool dc_link_detect(struct dc_link *dc_link, enum dc_detect_reason reason);
|
||||
|
||||
/* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
|
||||
* Return:
|
||||
* true - Downstream port status changed. DM should call DC to do the
|
||||
* detection.
|
||||
* false - no change in Downstream port status. No further action required
|
||||
* from DM. */
|
||||
bool dc_link_handle_hpd_rx_irq(struct dc_link *dc_link,
|
||||
union hpd_irq_data *hpd_irq_dpcd_data);
|
||||
|
||||
struct dc_sink_init_data;
|
||||
|
||||
struct dc_sink *dc_link_add_remote_sink(
|
||||
struct dc_link *dc_link,
|
||||
const uint8_t *edid,
|
||||
int len,
|
||||
struct dc_sink_init_data *init_data);
|
||||
|
||||
void dc_link_remove_remote_sink(
|
||||
struct dc_link *link,
|
||||
struct dc_sink *sink);
|
||||
|
||||
/* Used by diagnostics for virtual link at the moment */
|
||||
|
||||
void dc_link_dp_set_drive_settings(
|
||||
struct dc_link *link,
|
||||
struct link_training_settings *lt_settings);
|
||||
|
||||
enum link_training_result dc_link_dp_perform_link_training(
|
||||
struct dc_link *link,
|
||||
const struct dc_link_settings *link_setting,
|
||||
bool skip_video_pattern);
|
||||
|
||||
void dc_link_dp_enable_hpd(const struct dc_link *link);
|
||||
|
||||
void dc_link_dp_disable_hpd(const struct dc_link *link);
|
||||
|
||||
bool dc_link_dp_set_test_pattern(
|
||||
struct dc_link *link,
|
||||
enum dp_test_pattern test_pattern,
|
||||
const struct link_training_settings *p_link_settings,
|
||||
const unsigned char *p_custom_pattern,
|
||||
unsigned int cust_pattern_size);
|
||||
|
||||
/*
|
||||
* DPCD access interfaces
|
||||
*/
|
||||
|
||||
bool dc_submit_i2c(
|
||||
struct dc *dc,
|
||||
uint32_t link_index,
|
||||
struct i2c_command *cmd);
|
||||
|
||||
#endif /* DC_LINK_H_ */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue