@@ -156,6 +156,8 @@ struct amdgpu_gmc_funcs {
uint64_t addr, uint64_t *flags);
/* get the amount of memory used by the vbios for pre-OS console */
unsigned int (*get_vbios_fb_size)(struct amdgpu_device *adev);
+ /* get the DCC buffer alignment */
+ u64 (*get_dcc_alignment)(struct amdgpu_device *adev);
enum amdgpu_memory_partition (*query_mem_partition_mode)(
struct amdgpu_device *adev);
@@ -363,6 +365,7 @@ struct amdgpu_gmc {
(adev)->gmc.gmc_funcs->override_vm_pte_flags \
((adev), (vm), (addr), (pte_flags))
#define amdgpu_gmc_get_vbios_fb_size(adev) (adev)->gmc.gmc_funcs->get_vbios_fb_size((adev))
+#define amdgpu_gmc_get_dcc_alignment(adev) ((adev)->gmc.gmc_funcs->get_dcc_alignment((adev)))
/**
* amdgpu_gmc_vram_full_visible - Check if full VRAM is visible through the BAR
@@ -512,6 +512,16 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
vres->flags |= DRM_BUDDY_RANGE_ALLOCATION;
remaining_size = (u64)vres->base.size;
+ if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS &&
+ bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC) {
+ u64 adjust_size;
+
+ if (adev->gmc.gmc_funcs->get_dcc_alignment) {
+ adjust_size = amdgpu_gmc_get_dcc_alignment(adev);
+ remaining_size = roundup_pow_of_two(remaining_size + adjust_size);
+ vres->flags |= DRM_BUDDY_TRIM_DISABLE;
+ }
+ }
mutex_lock(&mgr->lock);
while (remaining_size) {
@@ -521,8 +531,12 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
min_block_size = mgr->default_page_size;
size = remaining_size;
- if ((size >= (u64)pages_per_block << PAGE_SHIFT) &&
- !(size & (((u64)pages_per_block << PAGE_SHIFT) - 1)))
+
+ if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS &&
+ bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC)
+ min_block_size = size;
+ else if ((size >= (u64)pages_per_block << PAGE_SHIFT) &&
+ !(size & (((u64)pages_per_block << PAGE_SHIFT) - 1)))
min_block_size = (u64)pages_per_block << PAGE_SHIFT;
BUG_ON(min_block_size < mm->chunk_size);
@@ -553,6 +567,24 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
}
mutex_unlock(&mgr->lock);
+ if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS &&
+ bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC) {
+ struct drm_buddy_block *dcc_block;
+ u64 dcc_start, alignment;
+
+ dcc_block = amdgpu_vram_mgr_first_block(&vres->blocks);
+ dcc_start = amdgpu_vram_mgr_block_start(dcc_block);
+
+ if (adev->gmc.gmc_funcs->get_dcc_alignment) {
+ alignment = amdgpu_gmc_get_dcc_alignment(adev);
+ /* Adjust the start address for DCC buffers only */
+ dcc_start = roundup(dcc_start, alignment);
+ drm_buddy_block_trim(mm, &dcc_start,
+ (u64)vres->base.size,
+ &vres->blocks);
+ }
+ }
+
vres->base.start = 0;
size = max_t(u64, amdgpu_vram_mgr_blocks_size(&vres->blocks),
vres->base.size);
@@ -542,6 +542,20 @@ static unsigned gmc_v12_0_get_vbios_fb_size(struct amdgpu_device *adev)
return 0;
}
+static u64 gmc_v12_0_get_dcc_alignment(struct amdgpu_device *adev)
+{
+ u64 max_tex_channel_caches, alignment;
+
+ max_tex_channel_caches = adev->gfx.config.max_texture_channel_caches;
+ if (is_power_of_2(max_tex_channel_caches))
+ alignment = (max_tex_channel_caches / SZ_4) * max_tex_channel_caches;
+ else
+ alignment = roundup_pow_of_two(max_tex_channel_caches) *
+ max_tex_channel_caches;
+
+ return (u64)alignment * SZ_1K;
+}
+
static const struct amdgpu_gmc_funcs gmc_v12_0_gmc_funcs = {
.flush_gpu_tlb = gmc_v12_0_flush_gpu_tlb,
.flush_gpu_tlb_pasid = gmc_v12_0_flush_gpu_tlb_pasid,
@@ -551,6 +565,7 @@ static const struct amdgpu_gmc_funcs gmc_v12_0_gmc_funcs = {
.get_vm_pde = gmc_v12_0_get_vm_pde,
.get_vm_pte = gmc_v12_0_get_vm_pte,
.get_vbios_fb_size = gmc_v12_0_get_vbios_fb_size,
+ .get_dcc_alignment = gmc_v12_0_get_dcc_alignment,
};
static void gmc_v12_0_set_gmc_funcs(struct amdgpu_device *adev)