]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
drm/amdgpu/gmc: steal the appropriate amount of vram for fw hand-over (v3)
authorAlex Deucher <alexdeucher@gmail.com>
Thu, 7 Mar 2019 06:51:45 +0000 (08:51 +0200)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 1 Apr 2019 12:37:29 +0000 (14:37 +0200)
BugLink: https://launchpad.net/bugs/1818617
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
v3: squash in fix from Harry

Reviewed-and-Tested-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com> (v2)
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
(cherry picked from commit ebdef28ebbcf767d9fa687acb1d02d97d834c628)
Signed-off-by: Timo Aaltonen <timo.aaltonen@canonical.com>
Acked-by: Khalid Elmously <khalid.elmously@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c

index ad5bf86ee8a31911e1bf014b2f354f39a88fd337..8383529f429611fdce8604063edee2ddacc3622c 100644 (file)
@@ -1339,12 +1339,14 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
                return r;
        }
 
-       r = amdgpu_bo_create_kernel(adev, adev->mc.stolen_size, PAGE_SIZE,
-                                   AMDGPU_GEM_DOMAIN_VRAM,
-                                   &adev->stolen_vga_memory,
-                                   NULL, NULL);
-       if (r)
-               return r;
+       if (adev->mc.stolen_size) {
+               r = amdgpu_bo_create_kernel(adev, adev->mc.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->mc.real_vram_size / (1024 * 1024)));
 
index f4603a7c8ef32e193aa83f76d0380283ccc7cdc0..53c8c75545045caf0bd4d52efecd4674d6512b50 100644 (file)
@@ -809,6 +809,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->mc.real_vram_size - size) < (8 * 1024 * 1024))
+               return 0;
+       return size;
+}
+
 static int gmc_v6_0_sw_init(void *handle)
 {
        int r;
@@ -836,8 +855,6 @@ static int gmc_v6_0_sw_init(void *handle)
 
        adev->mc.mc_mask = 0xffffffffffULL;
 
-       adev->mc.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));
@@ -862,6 +879,8 @@ static int gmc_v6_0_sw_init(void *handle)
        if (r)
                return r;
 
+       adev->mc.stolen_size = gmc_v6_0_get_vbios_fb_size(adev);
+
        r = amdgpu_bo_init(adev);
        if (r)
                return r;
index b0528ca9207b9e93846992ee2b756e7c08ecc3d6..e257ae9f873fea81858e1cd80e59f6bef88e3e26 100644 (file)
@@ -944,6 +944,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->mc.real_vram_size - size) < (8 * 1024 * 1024))
+               return 0;
+       return size;
+}
+
 static int gmc_v7_0_sw_init(void *handle)
 {
        int r;
@@ -979,8 +998,6 @@ static int gmc_v7_0_sw_init(void *handle)
         */
        adev->mc.mc_mask = 0xffffffffffULL; /* 40 bit MC */
 
-       adev->mc.stolen_size = 256 * 1024;
-
        /* set DMA mask + need_dma32 flags.
         * PCIE - can handle 40-bits.
         * IGP - can handle 40-bits
@@ -1010,6 +1027,8 @@ static int gmc_v7_0_sw_init(void *handle)
        if (r)
                return r;
 
+       adev->mc.stolen_size = gmc_v7_0_get_vbios_fb_size(adev);
+
        /* Memory manager */
        r = amdgpu_bo_init(adev);
        if (r)
index f368cfe2f5851f7868a0f6b9aff95091b4e66490..dd30741964dbfb03a740e30b9dab3b0cf1cb28f8 100644 (file)
@@ -1034,6 +1034,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->mc.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)
@@ -1076,8 +1095,6 @@ static int gmc_v8_0_sw_init(void *handle)
         */
        adev->mc.mc_mask = 0xffffffffffULL; /* 40 bit MC */
 
-       adev->mc.stolen_size = 256 * 1024;
-
        /* set DMA mask + need_dma32 flags.
         * PCIE - can handle 40-bits.
         * IGP - can handle 40-bits
@@ -1107,6 +1124,8 @@ static int gmc_v8_0_sw_init(void *handle)
        if (r)
                return r;
 
+       adev->mc.stolen_size = gmc_v8_0_get_vbios_fb_size(adev);
+
        /* Memory manager */
        r = amdgpu_bo_init(adev);
        if (r)
index 9737408b56f5b7d611e4f22990c64bd9d4974c2c..8a9b7e6850339bd725092c8206426220c945235a 100644 (file)
 #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
 
@@ -546,6 +554,43 @@ 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)
+{
+#if 0
+       u32 d1vga_control = RREG32_SOC15(DCE, 0, mmD1VGA_CONTROL);
+#endif
+       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->mc.real_vram_size - size) < (8 * 1024 * 1024))
+               return 0;
+       return size;
+}
+
 static int gmc_v9_0_sw_init(void *handle)
 {
        int r;
@@ -610,12 +655,6 @@ static int gmc_v9_0_sw_init(void *handle)
         */
        adev->mc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */
 
-       /*
-        * It needs to reserve 8M stolen memory for vega10
-        * TODO: Figure out how to avoid that...
-        */
-       adev->mc.stolen_size = 8 * 1024 * 1024;
-
        /* set DMA mask + need_dma32 flags.
         * PCIE - can handle 44-bits.
         * IGP - can handle 44-bits
@@ -639,6 +678,8 @@ static int gmc_v9_0_sw_init(void *handle)
        if (r)
                return r;
 
+       adev->mc.stolen_size = gmc_v9_0_get_vbios_fb_size(adev);
+
        /* Memory manager */
        r = amdgpu_bo_init(adev);
        if (r)