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.grodzov...@amd.com> (v1)
Signed-off-by: Alex Deucher <alexander.deuc...@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.

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)

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to