[PATCH 1/2] drm/amdgpu/gmc: steal the appropriate amount of vram for fw hand-over (v2)

Alex Deucher alexdeucher at gmail.com
Fri Apr 6 20:17:35 UTC 2018


On Fri, Apr 6, 2018 at 4:06 PM, Andrey Grodzovsky
<Andrey.Grodzovsky at amd.com> wrote:
> On 04/06/2018 03:54 PM, Alex Deucher wrote:
>
>> Steal 9 MB for vga emulation and fb if vga is enabled, otherwise,
>> steal enough to cover the current display size as set by the vbios.
>>
>> If no memory is used (e.g., secondary or headless card), skip
>> stolen memory reserve.
>>
>> v2: skip reservation if vram is limited, address Christian's comments
>>
>> Reviewed-and-Tested-by: Andrey Grodzovsky <andrey.grodzovsky at amd.com> (v1)
>> Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 14 +++++----
>>   drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c   | 23 +++++++++++++--
>>   drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c   | 23 +++++++++++++--
>>   drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c   | 23 +++++++++++++--
>>   drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c   | 51
>> +++++++++++++++++++++++++++++----
>>   5 files changed, 116 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 205da3ff9cd0..46c69ad34461 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -1454,12 +1454,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>                 return r;
>>         }
>>   -     r = amdgpu_bo_create_kernel(adev, adev->gmc.stolen_size,
>> PAGE_SIZE,
>> -                                   AMDGPU_GEM_DOMAIN_VRAM,
>> -                                   &adev->stolen_vga_memory,
>> -                                   NULL, NULL);
>> -       if (r)
>> -               return r;
>> +       if (adev->gmc.stolen_size) {
>> +               r = amdgpu_bo_create_kernel(adev, adev->gmc.stolen_size,
>> PAGE_SIZE,
>> +                                           AMDGPU_GEM_DOMAIN_VRAM,
>> +                                           &adev->stolen_vga_memory,
>> +                                           NULL, NULL);
>> +               if (r)
>> +                       return r;
>> +       }
>>         DRM_INFO("amdgpu: %uM of VRAM memory ready\n",
>>                  (unsigned) (adev->gmc.real_vram_size / (1024 * 1024)));
>>   diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
>> b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
>> index 5617cf62c566..24e1ea36b454 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
>> @@ -825,6 +825,25 @@ static int gmc_v6_0_late_init(void *handle)
>>                 return 0;
>>   }
>>   +static unsigned gmc_v6_0_get_vbios_fb_size(struct amdgpu_device *adev)
>> +{
>> +       u32 d1vga_control = RREG32(mmD1VGA_CONTROL);
>> +       unsigned size;
>> +
>> +       if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL,
>> D1VGA_MODE_ENABLE)) {
>> +               size = 9 * 1024 * 1024; /* reserve 8MB for vga emulator
>> and 1 MB for FB */
>> +       } else {
>> +               u32 viewport = RREG32(mmVIEWPORT_SIZE);
>> +               size = (REG_GET_FIELD(viewport, VIEWPORT_SIZE,
>> VIEWPORT_HEIGHT) *
>> +                       REG_GET_FIELD(viewport, VIEWPORT_SIZE,
>> VIEWPORT_WIDTH) *
>> +                       4);
>> +       }
>> +       /* return 0 if the pre-OS buffer uses up most of vram */
>> +       if ((adev->gmc.real_vram_size - size) < (8 * 1024 * 1024))
>> +               return 0;
>
>
> This will not work unless gmc_v6_0_mc_init in gmc_v6_0_sw_init will be moved
> before gmc_v6_0_get_vbios_fb_size, real_vram_size
> is not initialized in this point. Same for other ASICs.

Yeah, I moved it down.  See below.

Alex

>
> Andrey
>
>> +       return size;
>> +}
>> +
>>   static int gmc_v6_0_sw_init(void *handle)
>>   {
>>         int r;
>> @@ -851,8 +870,6 @@ static int gmc_v6_0_sw_init(void *handle)
>>         adev->gmc.mc_mask = 0xffffffffffULL;
>>   -     adev->gmc.stolen_size = 256 * 1024;
>> -
>>         adev->need_dma32 = false;
>>         dma_bits = adev->need_dma32 ? 32 : 40;
>>         r = pci_set_dma_mask(adev->pdev, DMA_BIT_MASK(dma_bits));
>> @@ -878,6 +895,8 @@ static int gmc_v6_0_sw_init(void *handle)
>>         if (r)
>>                 return r;
>>   +     adev->gmc.stolen_size = gmc_v6_0_get_vbios_fb_size(adev);
>> +
>>         r = amdgpu_bo_init(adev);
>>         if (r)
>>                 return r;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
>> b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
>> index 80054f36e487..93861f9c7773 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
>> @@ -964,6 +964,25 @@ static int gmc_v7_0_late_init(void *handle)
>>                 return 0;
>>   }
>>   +static unsigned gmc_v7_0_get_vbios_fb_size(struct amdgpu_device *adev)
>> +{
>> +       u32 d1vga_control = RREG32(mmD1VGA_CONTROL);
>> +       unsigned size;
>> +
>> +       if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL,
>> D1VGA_MODE_ENABLE)) {
>> +               size = 9 * 1024 * 1024; /* reserve 8MB for vga emulator
>> and 1 MB for FB */
>> +       } else {
>> +               u32 viewport = RREG32(mmVIEWPORT_SIZE);
>> +               size = (REG_GET_FIELD(viewport, VIEWPORT_SIZE,
>> VIEWPORT_HEIGHT) *
>> +                       REG_GET_FIELD(viewport, VIEWPORT_SIZE,
>> VIEWPORT_WIDTH) *
>> +                       4);
>> +       }
>> +       /* return 0 if the pre-OS buffer uses up most of vram */
>> +       if ((adev->gmc.real_vram_size - size) < (8 * 1024 * 1024))
>> +               return 0;
>> +       return size;
>> +}
>> +
>>   static int gmc_v7_0_sw_init(void *handle)
>>   {
>>         int r;
>> @@ -998,8 +1017,6 @@ static int gmc_v7_0_sw_init(void *handle)
>>          */
>>         adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */
>>   -     adev->gmc.stolen_size = 256 * 1024;
>> -
>>         /* set DMA mask + need_dma32 flags.
>>          * PCIE - can handle 40-bits.
>>          * IGP - can handle 40-bits
>> @@ -1030,6 +1047,8 @@ static int gmc_v7_0_sw_init(void *handle)
>>         if (r)
>>                 return r;
>>   +     adev->gmc.stolen_size = gmc_v7_0_get_vbios_fb_size(adev);
>> +
>>         /* Memory manager */
>>         r = amdgpu_bo_init(adev);
>>         if (r)
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
>> b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
>> index d71d4cb68f9c..fbd8f56c70f3 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
>> @@ -1055,6 +1055,25 @@ static int gmc_v8_0_late_init(void *handle)
>>                 return 0;
>>   }
>>   +static unsigned gmc_v8_0_get_vbios_fb_size(struct amdgpu_device *adev)
>> +{
>> +       u32 d1vga_control = RREG32(mmD1VGA_CONTROL);
>> +       unsigned size;
>> +
>> +       if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL,
>> D1VGA_MODE_ENABLE)) {
>> +               size = 9 * 1024 * 1024; /* reserve 8MB for vga emulator
>> and 1 MB for FB */
>> +       } else {
>> +               u32 viewport = RREG32(mmVIEWPORT_SIZE);
>> +               size = (REG_GET_FIELD(viewport, VIEWPORT_SIZE,
>> VIEWPORT_HEIGHT) *
>> +                       REG_GET_FIELD(viewport, VIEWPORT_SIZE,
>> VIEWPORT_WIDTH) *
>> +                       4);
>> +       }
>> +       /* return 0 if the pre-OS buffer uses up most of vram */
>> +       if ((adev->gmc.real_vram_size - size) < (8 * 1024 * 1024))
>> +               return 0;
>> +       return size;
>> +}
>> +
>>   #define mmMC_SEQ_MISC0_FIJI 0xA71
>>     static int gmc_v8_0_sw_init(void *handle)
>> @@ -1096,8 +1115,6 @@ static int gmc_v8_0_sw_init(void *handle)
>>          */
>>         adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */
>>   -     adev->gmc.stolen_size = 256 * 1024;
>> -
>>         /* set DMA mask + need_dma32 flags.
>>          * PCIE - can handle 40-bits.
>>          * IGP - can handle 40-bits
>> @@ -1128,6 +1145,8 @@ static int gmc_v8_0_sw_init(void *handle)
>>         if (r)
>>                 return r;
>>   +     adev->gmc.stolen_size = gmc_v8_0_get_vbios_fb_size(adev);
>> +
>>         /* Memory manager */
>>         r = amdgpu_bo_init(adev);
>>         if (r)
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>> b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>> index 070946e1e4a7..fcc11a29c027 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
>> @@ -57,6 +57,14 @@
>>   #define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel_MASK
>> 0x00000700L
>>   #define DF_CS_AON0_DramBaseAddress0__DramBaseAddr_MASK
>> 0xFFFFF000L
>>   +/* add these here since we already include dce12 headers and these are
>> for DCN */
>> +#define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION
>> 0x055d
>> +#define mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION_BASE_IDX
>> 2
>> +#define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_WIDTH__SHIFT
>> 0x0
>> +#define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_HEIGHT__SHIFT
>> 0x10
>> +#define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_WIDTH_MASK
>> 0x00003FFFL
>> +#define HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION__PRI_VIEWPORT_HEIGHT_MASK
>> 0x3FFF0000L
>> +
>>   /* XXX Move this macro to VEGA10 header file, which is like vid.h for
>> VI.*/
>>   #define AMDGPU_NUM_OF_VMIDS                   8
>>   @@ -793,6 +801,41 @@ static int gmc_v9_0_gart_init(struct amdgpu_device
>> *adev)
>>         return amdgpu_gart_table_vram_alloc(adev);
>>   }
>>   +static unsigned gmc_v9_0_get_vbios_fb_size(struct amdgpu_device *adev)
>> +{
>> +       u32 d1vga_control = RREG32_SOC15(DCE, 0, mmD1VGA_CONTROL);
>> +       unsigned size;
>> +
>> +       if (REG_GET_FIELD(d1vga_control, D1VGA_CONTROL,
>> D1VGA_MODE_ENABLE)) {
>> +               size = 9 * 1024 * 1024; /* reserve 8MB for vga emulator
>> and 1 MB for FB */
>> +       } else {
>> +               u32 viewport;
>> +
>> +               switch (adev->asic_type) {
>> +               case CHIP_RAVEN:
>> +                       viewport = RREG32_SOC15(DCE, 0,
>> mmHUBP0_DCSURF_PRI_VIEWPORT_DIMENSION);
>> +                       size = (REG_GET_FIELD(viewport,
>> +
>> HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_HEIGHT) *
>> +                               REG_GET_FIELD(viewport,
>> +
>> HUBP0_DCSURF_PRI_VIEWPORT_DIMENSION, PRI_VIEWPORT_WIDTH) *
>> +                               4);
>> +                       break;
>> +               case CHIP_VEGA10:
>> +               case CHIP_VEGA12:
>> +               default:
>> +                       viewport = RREG32_SOC15(DCE, 0,
>> mmSCL0_VIEWPORT_SIZE);
>> +                       size = (REG_GET_FIELD(viewport,
>> SCL0_VIEWPORT_SIZE, VIEWPORT_HEIGHT) *
>> +                               REG_GET_FIELD(viewport,
>> SCL0_VIEWPORT_SIZE, VIEWPORT_WIDTH) *
>> +                               4);
>> +                       break;
>> +               }
>> +       }
>> +       /* return 0 if the pre-OS buffer uses up most of vram */
>> +       if ((adev->gmc.real_vram_size - size) < (8 * 1024 * 1024))
>> +               return 0;
>> +       return size;
>> +}
>> +
>>   static int gmc_v9_0_sw_init(void *handle)
>>   {
>>         int r;
>> @@ -844,12 +887,6 @@ static int gmc_v9_0_sw_init(void *handle)
>>          */
>>         adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */
>>   -     /*
>> -        * It needs to reserve 8M stolen memory for vega10
>> -        * TODO: Figure out how to avoid that...
>> -        */
>> -       adev->gmc.stolen_size = 8 * 1024 * 1024;
>> -
>>         /* set DMA mask + need_dma32 flags.
>>          * PCIE - can handle 44-bits.
>>          * IGP - can handle 44-bits
>> @@ -874,6 +911,8 @@ static int gmc_v9_0_sw_init(void *handle)
>>         if (r)
>>                 return r;
>>   +     adev->gmc.stolen_size = gmc_v9_0_get_vbios_fb_size(adev);
>> +
>>         /* Memory manager */
>>         r = amdgpu_bo_init(adev);
>>         if (r)
>
>


More information about the amd-gfx mailing list