aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0944-drm-amd-amdgpu-add-power-gating-initialization-suppo.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0944-drm-amd-amdgpu-add-power-gating-initialization-suppo.patch')
-rw-r--r--common/recipes-kernel/linux/files/0944-drm-amd-amdgpu-add-power-gating-initialization-suppo.patch461
1 files changed, 0 insertions, 461 deletions
diff --git a/common/recipes-kernel/linux/files/0944-drm-amd-amdgpu-add-power-gating-initialization-suppo.patch b/common/recipes-kernel/linux/files/0944-drm-amd-amdgpu-add-power-gating-initialization-suppo.patch
deleted file mode 100644
index af31e77a..00000000
--- a/common/recipes-kernel/linux/files/0944-drm-amd-amdgpu-add-power-gating-initialization-suppo.patch
+++ /dev/null
@@ -1,461 +0,0 @@
-From 6530781feecc3ea8bdb603b0978abaabea82cb4a Mon Sep 17 00:00:00 2001
-From: Eric Huang <JinHuiEric.Huang@amd.com>
-Date: Thu, 14 Apr 2016 17:26:07 -0400
-Subject: [PATCH 0944/1110] drm/amd/amdgpu: add power gating initialization
- support for GFX8.0
-
-Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com>
-Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
----
- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 14 ++
- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 353 +++++++++++++++++++++++++++++++++-
- 2 files changed, 364 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
-index 1b22de0..a8c59be 100644
---- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
-+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
-@@ -1082,6 +1082,20 @@ struct amdgpu_rlc {
- /* safe mode for updating CG/PG state */
- bool in_safe_mode;
- const struct amdgpu_rlc_funcs *funcs;
-+
-+ /* for firmware data */
-+ u32 save_and_restore_offset;
-+ u32 clear_state_descriptor_offset;
-+ u32 avail_scratch_ram_locations;
-+ u32 reg_restore_list_size;
-+ u32 reg_list_format_start;
-+ u32 reg_list_format_separate_start;
-+ u32 starting_offsets_start;
-+ u32 reg_list_format_size_bytes;
-+ u32 reg_list_size_bytes;
-+
-+ u32 *register_list_format;
-+ u32 *register_restore;
- };
-
- struct amdgpu_mec {
-diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
-index 17391b8..3fdce2d 100644
---- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
-+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
-@@ -86,6 +86,8 @@ enum {
- BPM_REG_FGCG_MAX
- };
-
-+#define RLC_FormatDirectRegListLength 14
-+
- MODULE_FIRMWARE("amdgpu/carrizo_ce.bin");
- MODULE_FIRMWARE("amdgpu/carrizo_pfp.bin");
- MODULE_FIRMWARE("amdgpu/carrizo_me.bin");
-@@ -633,6 +635,7 @@ static void gfx_v8_0_set_ring_funcs(struct amdgpu_device *adev);
- static void gfx_v8_0_set_irq_funcs(struct amdgpu_device *adev);
- static void gfx_v8_0_set_gds_init(struct amdgpu_device *adev);
- static void gfx_v8_0_set_rlc_funcs(struct amdgpu_device *adev);
-+static u32 gfx_v8_0_get_csb_size(struct amdgpu_device *adev);
-
- static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev)
- {
-@@ -838,6 +841,8 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev)
- struct amdgpu_firmware_info *info = NULL;
- const struct common_firmware_header *header = NULL;
- const struct gfx_firmware_header_v1_0 *cp_hdr;
-+ const struct rlc_firmware_header_v2_0 *rlc_hdr;
-+ unsigned int *tmp = NULL, i;
-
- DRM_DEBUG("\n");
-
-@@ -905,9 +910,49 @@ static int gfx_v8_0_init_microcode(struct amdgpu_device *adev)
- if (err)
- goto out;
- err = amdgpu_ucode_validate(adev->gfx.rlc_fw);
-- cp_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.rlc_fw->data;
-- adev->gfx.rlc_fw_version = le32_to_cpu(cp_hdr->header.ucode_version);
-- adev->gfx.rlc_feature_version = le32_to_cpu(cp_hdr->ucode_feature_version);
-+ rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
-+ adev->gfx.rlc_fw_version = le32_to_cpu(rlc_hdr->header.ucode_version);
-+ adev->gfx.rlc_feature_version = le32_to_cpu(rlc_hdr->ucode_feature_version);
-+
-+ adev->gfx.rlc.save_and_restore_offset =
-+ le32_to_cpu(rlc_hdr->save_and_restore_offset);
-+ adev->gfx.rlc.clear_state_descriptor_offset =
-+ le32_to_cpu(rlc_hdr->clear_state_descriptor_offset);
-+ adev->gfx.rlc.avail_scratch_ram_locations =
-+ le32_to_cpu(rlc_hdr->avail_scratch_ram_locations);
-+ adev->gfx.rlc.reg_restore_list_size =
-+ le32_to_cpu(rlc_hdr->reg_restore_list_size);
-+ adev->gfx.rlc.reg_list_format_start =
-+ le32_to_cpu(rlc_hdr->reg_list_format_start);
-+ adev->gfx.rlc.reg_list_format_separate_start =
-+ le32_to_cpu(rlc_hdr->reg_list_format_separate_start);
-+ adev->gfx.rlc.starting_offsets_start =
-+ le32_to_cpu(rlc_hdr->starting_offsets_start);
-+ adev->gfx.rlc.reg_list_format_size_bytes =
-+ le32_to_cpu(rlc_hdr->reg_list_format_size_bytes);
-+ adev->gfx.rlc.reg_list_size_bytes =
-+ le32_to_cpu(rlc_hdr->reg_list_size_bytes);
-+
-+ adev->gfx.rlc.register_list_format =
-+ kmalloc(adev->gfx.rlc.reg_list_format_size_bytes +
-+ adev->gfx.rlc.reg_list_size_bytes, GFP_KERNEL);
-+
-+ if (!adev->gfx.rlc.register_list_format) {
-+ err = -ENOMEM;
-+ goto out;
-+ }
-+
-+ tmp = (unsigned int *)((uint64_t)rlc_hdr +
-+ le32_to_cpu(rlc_hdr->reg_list_format_array_offset_bytes));
-+ for (i = 0 ; i < (rlc_hdr->reg_list_format_size_bytes >> 2); i++)
-+ adev->gfx.rlc.register_list_format[i] = le32_to_cpu(tmp[i]);
-+
-+ adev->gfx.rlc.register_restore = adev->gfx.rlc.register_list_format + i;
-+
-+ tmp = (unsigned int *)((uint64_t)rlc_hdr +
-+ le32_to_cpu(rlc_hdr->reg_list_array_offset_bytes));
-+ for (i = 0 ; i < (rlc_hdr->reg_list_size_bytes >> 2); i++)
-+ adev->gfx.rlc.register_restore[i] = le32_to_cpu(tmp[i]);
-
- snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mec.bin", chip_name);
- err = request_firmware(&adev->gfx.mec_fw, fw_name, adev->dev);
-@@ -1008,6 +1053,148 @@ out:
- return err;
- }
-
-+static void gfx_v8_0_get_csb_buffer(struct amdgpu_device *adev,
-+ volatile u32 *buffer)
-+{
-+ u32 count = 0, i;
-+ const struct cs_section_def *sect = NULL;
-+ const struct cs_extent_def *ext = NULL;
-+
-+ if (adev->gfx.rlc.cs_data == NULL)
-+ return;
-+ if (buffer == NULL)
-+ return;
-+
-+ buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
-+ buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
-+
-+ buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1));
-+ buffer[count++] = cpu_to_le32(0x80000000);
-+ buffer[count++] = cpu_to_le32(0x80000000);
-+
-+ for (sect = adev->gfx.rlc.cs_data; sect->section != NULL; ++sect) {
-+ for (ext = sect->section; ext->extent != NULL; ++ext) {
-+ if (sect->id == SECT_CONTEXT) {
-+ buffer[count++] =
-+ cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count));
-+ buffer[count++] = cpu_to_le32(ext->reg_index -
-+ PACKET3_SET_CONTEXT_REG_START);
-+ for (i = 0; i < ext->reg_count; i++)
-+ buffer[count++] = cpu_to_le32(ext->extent[i]);
-+ } else {
-+ return;
-+ }
-+ }
-+ }
-+
-+ buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 2));
-+ buffer[count++] = cpu_to_le32(mmPA_SC_RASTER_CONFIG -
-+ PACKET3_SET_CONTEXT_REG_START);
-+ switch (adev->asic_type) {
-+ case CHIP_TONGA:
-+ buffer[count++] = cpu_to_le32(0x16000012);
-+ buffer[count++] = cpu_to_le32(0x0000002A);
-+ break;
-+ case CHIP_FIJI:
-+ buffer[count++] = cpu_to_le32(0x3a00161a);
-+ buffer[count++] = cpu_to_le32(0x0000002e);
-+ break;
-+ case CHIP_TOPAZ:
-+ case CHIP_CARRIZO:
-+ buffer[count++] = cpu_to_le32(0x00000002);
-+ buffer[count++] = cpu_to_le32(0x00000000);
-+ break;
-+ case CHIP_STONEY:
-+ buffer[count++] = cpu_to_le32(0x00000000);
-+ buffer[count++] = cpu_to_le32(0x00000000);
-+ break;
-+ default:
-+ buffer[count++] = cpu_to_le32(0x00000000);
-+ buffer[count++] = cpu_to_le32(0x00000000);
-+ break;
-+ }
-+
-+ buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
-+ buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE);
-+
-+ buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0));
-+ buffer[count++] = cpu_to_le32(0);
-+}
-+
-+static void gfx_v8_0_rlc_fini(struct amdgpu_device *adev)
-+{
-+ int r;
-+
-+ /* clear state block */
-+ if (adev->gfx.rlc.clear_state_obj) {
-+ r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
-+ if (unlikely(r != 0))
-+ dev_warn(adev->dev, "(%d) reserve RLC c bo failed\n", r);
-+ amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj);
-+ amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-+
-+ amdgpu_bo_unref(&adev->gfx.rlc.clear_state_obj);
-+ adev->gfx.rlc.clear_state_obj = NULL;
-+ }
-+}
-+
-+static int gfx_v8_0_rlc_init(struct amdgpu_device *adev)
-+{
-+ volatile u32 *dst_ptr;
-+ u32 dws;
-+ const struct cs_section_def *cs_data;
-+ int r;
-+
-+ adev->gfx.rlc.cs_data = vi_cs_data;
-+
-+ cs_data = adev->gfx.rlc.cs_data;
-+
-+ if (cs_data) {
-+ /* clear state block */
-+ adev->gfx.rlc.clear_state_size = dws = gfx_v8_0_get_csb_size(adev);
-+
-+ if (adev->gfx.rlc.clear_state_obj == NULL) {
-+ r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true,
-+ AMDGPU_GEM_DOMAIN_VRAM,
-+ AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
-+ NULL, NULL,
-+ &adev->gfx.rlc.clear_state_obj);
-+ if (r) {
-+ dev_warn(adev->dev, "(%d) create RLC c bo failed\n", r);
-+ gfx_v8_0_rlc_fini(adev);
-+ return r;
-+ }
-+ }
-+ r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false);
-+ if (unlikely(r != 0)) {
-+ gfx_v8_0_rlc_fini(adev);
-+ return r;
-+ }
-+ r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, AMDGPU_GEM_DOMAIN_VRAM,
-+ &adev->gfx.rlc.clear_state_gpu_addr);
-+ if (r) {
-+ amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-+ dev_warn(adev->dev, "(%d) pin RLC c bo failed\n", r);
-+ gfx_v8_0_rlc_fini(adev);
-+ return r;
-+ }
-+
-+ r = amdgpu_bo_kmap(adev->gfx.rlc.clear_state_obj, (void **)&adev->gfx.rlc.cs_ptr);
-+ if (r) {
-+ dev_warn(adev->dev, "(%d) map RLC c bo failed\n", r);
-+ gfx_v8_0_rlc_fini(adev);
-+ return r;
-+ }
-+ /* set up the cs buffer */
-+ dst_ptr = adev->gfx.rlc.cs_ptr;
-+ gfx_v8_0_get_csb_buffer(adev, dst_ptr);
-+ amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj);
-+ amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj);
-+ }
-+
-+ return 0;
-+}
-+
- static void gfx_v8_0_mec_fini(struct amdgpu_device *adev)
- {
- int r;
-@@ -1681,6 +1868,12 @@ static int gfx_v8_0_sw_init(void *handle)
- return r;
- }
-
-+ r = gfx_v8_0_rlc_init(adev);
-+ if (r) {
-+ DRM_ERROR("Failed to init rlc BOs!\n");
-+ return r;
-+ }
-+
- r = gfx_v8_0_mec_init(adev);
- if (r) {
- DRM_ERROR("Failed to init MEC BOs!\n");
-@@ -1780,6 +1973,10 @@ static int gfx_v8_0_sw_fini(void *handle)
-
- gfx_v8_0_mec_fini(adev);
-
-+ gfx_v8_0_rlc_fini(adev);
-+
-+ kfree(adev->gfx.rlc.register_list_format);
-+
- return 0;
- }
-
-@@ -3322,6 +3519,154 @@ static void gfx_v8_0_enable_gui_idle_interrupt(struct amdgpu_device *adev,
- WREG32(mmCP_INT_CNTL_RING0, tmp);
- }
-
-+static void gfx_v8_0_init_csb(struct amdgpu_device *adev)
-+{
-+ /* csib */
-+ WREG32(mmRLC_CSIB_ADDR_HI,
-+ adev->gfx.rlc.clear_state_gpu_addr >> 32);
-+ WREG32(mmRLC_CSIB_ADDR_LO,
-+ adev->gfx.rlc.clear_state_gpu_addr & 0xfffffffc);
-+ WREG32(mmRLC_CSIB_LENGTH,
-+ adev->gfx.rlc.clear_state_size);
-+}
-+
-+static void gfx_v8_0_parse_ind_reg_list(int *register_list_format,
-+ int ind_offset,
-+ int list_size,
-+ int *unique_indices,
-+ int *indices_count,
-+ int max_indices,
-+ int *ind_start_offsets,
-+ int *offset_count,
-+ int max_offset)
-+{
-+ int indices;
-+ bool new_entry = true;
-+
-+ for (; ind_offset < list_size; ind_offset++) {
-+
-+ if (new_entry) {
-+ new_entry = false;
-+ ind_start_offsets[*offset_count] = ind_offset;
-+ *offset_count = *offset_count + 1;
-+ BUG_ON(*offset_count >= max_offset);
-+ }
-+
-+ if (register_list_format[ind_offset] == 0xFFFFFFFF) {
-+ new_entry = true;
-+ continue;
-+ }
-+
-+ ind_offset += 2;
-+
-+ /* look for the matching indice */
-+ for (indices = 0;
-+ indices < *indices_count;
-+ indices++) {
-+ if (unique_indices[indices] ==
-+ register_list_format[ind_offset])
-+ break;
-+ }
-+
-+ if (indices >= *indices_count) {
-+ unique_indices[*indices_count] =
-+ register_list_format[ind_offset];
-+ indices = *indices_count;
-+ *indices_count = *indices_count + 1;
-+ BUG_ON(*indices_count >= max_indices);
-+ }
-+
-+ register_list_format[ind_offset] = indices;
-+ }
-+}
-+
-+static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev)
-+{
-+ int i, temp, data;
-+ int unique_indices[] = {0, 0, 0, 0, 0, 0, 0, 0};
-+ int indices_count = 0;
-+ int indirect_start_offsets[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-+ int offset_count = 0;
-+
-+ int list_size;
-+ unsigned int *register_list_format =
-+ kmalloc(adev->gfx.rlc.reg_list_format_size_bytes, GFP_KERNEL);
-+ if (register_list_format == NULL)
-+ return -ENOMEM;
-+ memcpy(register_list_format, adev->gfx.rlc.register_list_format,
-+ adev->gfx.rlc.reg_list_format_size_bytes);
-+
-+ gfx_v8_0_parse_ind_reg_list(register_list_format,
-+ RLC_FormatDirectRegListLength,
-+ adev->gfx.rlc.reg_list_format_size_bytes >> 2,
-+ unique_indices,
-+ &indices_count,
-+ sizeof(unique_indices) / sizeof(int),
-+ indirect_start_offsets,
-+ &offset_count,
-+ sizeof(indirect_start_offsets)/sizeof(int));
-+
-+ /* save and restore list */
-+ temp = RREG32(mmRLC_SRM_CNTL);
-+ temp |= RLC_SRM_CNTL__AUTO_INCR_ADDR_MASK;
-+ WREG32(mmRLC_SRM_CNTL, temp);
-+
-+ WREG32(mmRLC_SRM_ARAM_ADDR, 0);
-+ for (i = 0; i < adev->gfx.rlc.reg_list_size_bytes >> 2; i++)
-+ WREG32(mmRLC_SRM_ARAM_DATA, adev->gfx.rlc.register_restore[i]);
-+
-+ /* indirect list */
-+ WREG32(mmRLC_GPM_SCRATCH_ADDR, adev->gfx.rlc.reg_list_format_start);
-+ for (i = 0; i < adev->gfx.rlc.reg_list_format_size_bytes >> 2; i++)
-+ WREG32(mmRLC_GPM_SCRATCH_DATA, register_list_format[i]);
-+
-+ list_size = adev->gfx.rlc.reg_list_size_bytes >> 2;
-+ list_size = list_size >> 1;
-+ WREG32(mmRLC_GPM_SCRATCH_ADDR, adev->gfx.rlc.reg_restore_list_size);
-+ WREG32(mmRLC_GPM_SCRATCH_DATA, list_size);
-+
-+ /* starting offsets starts */
-+ WREG32(mmRLC_GPM_SCRATCH_ADDR,
-+ adev->gfx.rlc.starting_offsets_start);
-+ for (i = 0; i < sizeof(indirect_start_offsets)/sizeof(int); i++)
-+ WREG32(mmRLC_GPM_SCRATCH_DATA,
-+ indirect_start_offsets[i]);
-+
-+ /* unique indices */
-+ temp = mmRLC_SRM_INDEX_CNTL_ADDR_0;
-+ data = mmRLC_SRM_INDEX_CNTL_DATA_0;
-+ for (i = 0; i < sizeof(unique_indices) / sizeof(int); i++) {
-+ amdgpu_mm_wreg(adev, temp + i, unique_indices[i] & 0x3FFFF, false);
-+ amdgpu_mm_wreg(adev, data + i, unique_indices[i] >> 20, false);
-+ }
-+ kfree(register_list_format);
-+
-+ return 0;
-+}
-+
-+static void gfx_v8_0_enable_save_restore_machine(struct amdgpu_device *adev)
-+{
-+ uint32_t data;
-+
-+ data = RREG32(mmRLC_SRM_CNTL);
-+ data |= RLC_SRM_CNTL__SRM_ENABLE_MASK;
-+ WREG32(mmRLC_SRM_CNTL, data);
-+}
-+
-+static void gfx_v8_0_init_pg(struct amdgpu_device *adev)
-+{
-+ if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG |
-+ AMD_PG_SUPPORT_GFX_SMG |
-+ AMD_PG_SUPPORT_GFX_DMG |
-+ AMD_PG_SUPPORT_CP |
-+ AMD_PG_SUPPORT_GDS |
-+ AMD_PG_SUPPORT_RLC_SMU_HS)) {
-+ gfx_v8_0_init_csb(adev);
-+ gfx_v8_0_init_save_restore_list(adev);
-+ gfx_v8_0_enable_save_restore_machine(adev);
-+ }
-+}
-+
- void gfx_v8_0_rlc_stop(struct amdgpu_device *adev)
- {
- u32 tmp = RREG32(mmRLC_CNTL);
-@@ -3401,6 +3746,8 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)
-
- gfx_v8_0_rlc_reset(adev);
-
-+ gfx_v8_0_init_pg(adev);
-+
- if (!adev->pp_enabled) {
- if (!adev->firmware.smu_load) {
- /* legacy rlc firmware loading */
---
-2.7.4
-