else if (type == CGS_UCODE_ID_SMU_SK)
                                        strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
                                break;
+                       case CHIP_POLARIS12:
+                               strcpy(fw_name, "amdgpu/polaris12_smc.bin");
+                               break;
                        default:
                                DRM_ERROR("SMC firmware not supported\n");
                                return -EINVAL;
 
        "STONEY",
        "POLARIS10",
        "POLARIS11",
+       "POLARIS12",
        "LAST",
 };
 
        case CHIP_FIJI:
        case CHIP_POLARIS11:
        case CHIP_POLARIS10:
+       case CHIP_POLARIS12:
        case CHIP_CARRIZO:
        case CHIP_STONEY:
                if (adev->asic_type == CHIP_CARRIZO || adev->asic_type == CHIP_STONEY)
 
 #define FIRMWARE_STONEY                "amdgpu/stoney_uvd.bin"
 #define FIRMWARE_POLARIS10     "amdgpu/polaris10_uvd.bin"
 #define FIRMWARE_POLARIS11     "amdgpu/polaris11_uvd.bin"
+#define FIRMWARE_POLARIS12     "amdgpu/polaris12_uvd.bin"
 
 /**
  * amdgpu_uvd_cs_ctx - Command submission parser context
 MODULE_FIRMWARE(FIRMWARE_STONEY);
 MODULE_FIRMWARE(FIRMWARE_POLARIS10);
 MODULE_FIRMWARE(FIRMWARE_POLARIS11);
+MODULE_FIRMWARE(FIRMWARE_POLARIS12);
 
 static void amdgpu_uvd_idle_work_handler(struct work_struct *work);
 
        case CHIP_POLARIS11:
                fw_name = FIRMWARE_POLARIS11;
                break;
+       case CHIP_POLARIS12:
+               fw_name = FIRMWARE_POLARIS12;
+               break;
        default:
                return -EINVAL;
        }
 
 #define FIRMWARE_STONEY                "amdgpu/stoney_vce.bin"
 #define FIRMWARE_POLARIS10     "amdgpu/polaris10_vce.bin"
 #define FIRMWARE_POLARIS11         "amdgpu/polaris11_vce.bin"
+#define FIRMWARE_POLARIS12         "amdgpu/polaris12_vce.bin"
 
 #ifdef CONFIG_DRM_AMDGPU_CIK
 MODULE_FIRMWARE(FIRMWARE_BONAIRE);
 MODULE_FIRMWARE(FIRMWARE_STONEY);
 MODULE_FIRMWARE(FIRMWARE_POLARIS10);
 MODULE_FIRMWARE(FIRMWARE_POLARIS11);
+MODULE_FIRMWARE(FIRMWARE_POLARIS12);
 
 static void amdgpu_vce_idle_work_handler(struct work_struct *work);
 
        case CHIP_POLARIS11:
                fw_name = FIRMWARE_POLARIS11;
                break;
+       case CHIP_POLARIS12:
+               fw_name = FIRMWARE_POLARIS12;
+               break;
 
        default:
                return -EINVAL;
 
                                                 (const u32)ARRAY_SIZE(stoney_golden_settings_a11));
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                amdgpu_program_register_sequence(adev,
                                                 polaris11_golden_settings_a11,
                                                 (const u32)ARRAY_SIZE(polaris11_golden_settings_a11));
                num_crtc = 6;
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                num_crtc = 5;
                break;
        default:
                adev->mode_info.audio.num_pins = 8;
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                adev->mode_info.audio.num_pins = 6;
                break;
        default:
        int pll;
 
        if ((adev->asic_type == CHIP_POLARIS10) ||
-           (adev->asic_type == CHIP_POLARIS11)) {
+           (adev->asic_type == CHIP_POLARIS11) ||
+           (adev->asic_type == CHIP_POLARIS12)) {
                struct amdgpu_encoder *amdgpu_encoder =
                        to_amdgpu_encoder(amdgpu_crtc->encoder);
                struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;
                return -EINVAL;
 
        if ((adev->asic_type == CHIP_POLARIS10) ||
-           (adev->asic_type == CHIP_POLARIS11)) {
+           (adev->asic_type == CHIP_POLARIS11) ||
+           (adev->asic_type == CHIP_POLARIS12)) {
                struct amdgpu_encoder *amdgpu_encoder =
                        to_amdgpu_encoder(amdgpu_crtc->encoder);
                int encoder_mode =
                adev->mode_info.num_dig = 6;
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                adev->mode_info.num_hpd = 5;
                adev->mode_info.num_dig = 5;
                break;
        amdgpu_atombios_crtc_powergate_init(adev);
        amdgpu_atombios_encoder_init_dig(adev);
        if ((adev->asic_type == CHIP_POLARIS10) ||
-           (adev->asic_type == CHIP_POLARIS11)) {
+           (adev->asic_type == CHIP_POLARIS11) ||
+           (adev->asic_type == CHIP_POLARIS12)) {
                amdgpu_atombios_crtc_set_dce_clock(adev, adev->clock.default_dispclk,
                                                   DCE_CLOCK_TYPE_DISPCLK, ATOM_GCK_DFS);
                amdgpu_atombios_crtc_set_dce_clock(adev, 0,
 
 MODULE_FIRMWARE("amdgpu/polaris10_mec2.bin");
 MODULE_FIRMWARE("amdgpu/polaris10_rlc.bin");
 
+MODULE_FIRMWARE("amdgpu/polaris12_ce.bin");
+MODULE_FIRMWARE("amdgpu/polaris12_pfp.bin");
+MODULE_FIRMWARE("amdgpu/polaris12_me.bin");
+MODULE_FIRMWARE("amdgpu/polaris12_mec.bin");
+MODULE_FIRMWARE("amdgpu/polaris12_mec2.bin");
+MODULE_FIRMWARE("amdgpu/polaris12_rlc.bin");
+
 static const struct amdgpu_gds_reg_offset amdgpu_gds_reg_offset[] =
 {
        {mmGDS_VMID0_BASE, mmGDS_VMID0_SIZE, mmGDS_GWS_VMID0, mmGDS_OA_VMID0},
                                                 (const u32)ARRAY_SIZE(tonga_golden_common_all));
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                amdgpu_program_register_sequence(adev,
                                                 golden_settings_polaris11_a11,
                                                 (const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
        case CHIP_POLARIS10:
                chip_name = "polaris10";
                break;
+       case CHIP_POLARIS12:
+               chip_name = "polaris12";
+               break;
        case CHIP_STONEY:
                chip_name = "stoney";
                break;
                gb_addr_config = TONGA_GB_ADDR_CONFIG_GOLDEN;
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                ret = amdgpu_atombios_get_gfx_info(adev);
                if (ret)
                        return ret;
 
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                modearray[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
                                PIPE_CONFIG(ADDR_SURF_P4_16x16) |
                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
                *rconf1 |= 0x0;
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                *rconf |= RB_MAP_PKR0(2) | RB_XSEL2(1) | SE_MAP(2) |
                          SE_XSEL(1) | SE_YSEL(1);
                *rconf1 |= 0x0;
                        cz_enable_cp_power_gating(adev, true);
                else
                        cz_enable_cp_power_gating(adev, false);
-       } else if (adev->asic_type == CHIP_POLARIS11) {
+       } else if ((adev->asic_type == CHIP_POLARIS11) ||
+                  (adev->asic_type == CHIP_POLARIS12)) {
                gfx_v8_0_init_csb(adev);
                gfx_v8_0_init_save_restore_list(adev);
                gfx_v8_0_enable_save_restore_machine(adev);
                 RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK);
        WREG32(mmRLC_CGCG_CGLS_CTRL, tmp);
        if (adev->asic_type == CHIP_POLARIS11 ||
-           adev->asic_type == CHIP_POLARIS10) {
+           adev->asic_type == CHIP_POLARIS10 ||
+           adev->asic_type == CHIP_POLARIS12) {
                tmp = RREG32(mmRLC_CGCG_CGLS_CTRL_3D);
                tmp &= ~0x3;
                WREG32(mmRLC_CGCG_CGLS_CTRL_3D, tmp);
                amdgpu_ring_write(ring, 0x0000002A);
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                amdgpu_ring_write(ring, 0x16000012);
                amdgpu_ring_write(ring, 0x00000000);
                break;
                            (adev->asic_type == CHIP_FIJI) ||
                            (adev->asic_type == CHIP_STONEY) ||
                            (adev->asic_type == CHIP_POLARIS11) ||
-                           (adev->asic_type == CHIP_POLARIS10)) {
+                           (adev->asic_type == CHIP_POLARIS10) ||
+                           (adev->asic_type == CHIP_POLARIS12)) {
                                WREG32(mmCP_MEC_DOORBELL_RANGE_LOWER,
                                       AMDGPU_DOORBELL_KIQ << 2);
                                WREG32(mmCP_MEC_DOORBELL_RANGE_UPPER,
                mqd->cp_hqd_persistent_state = tmp;
                if (adev->asic_type == CHIP_STONEY ||
                        adev->asic_type == CHIP_POLARIS11 ||
-                       adev->asic_type == CHIP_POLARIS10) {
+                       adev->asic_type == CHIP_POLARIS10 ||
+                       adev->asic_type == CHIP_POLARIS12) {
                        tmp = RREG32(mmCP_ME1_PIPE3_INT_CNTL);
                        tmp = REG_SET_FIELD(tmp, CP_ME1_PIPE3_INT_CNTL, GENERIC2_INT_ENABLE, 1);
                        WREG32(mmCP_ME1_PIPE3_INT_CNTL, tmp);
 static void gfx_v8_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev,
                                                       bool enable)
 {
-       if (adev->asic_type == CHIP_POLARIS11)
+       if ((adev->asic_type == CHIP_POLARIS11) ||
+           (adev->asic_type == CHIP_POLARIS12))
                /* Send msg to SMU via Powerplay */
                amdgpu_set_powergating_state(adev,
                                             AMD_IP_BLOCK_TYPE_SMC,
                        gfx_v8_0_enable_gfx_dynamic_mg_power_gating(adev, false);
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG) && enable)
                        gfx_v8_0_enable_gfx_static_mg_power_gating(adev, true);
                else
 
 MODULE_FIRMWARE("amdgpu/tonga_mc.bin");
 MODULE_FIRMWARE("amdgpu/polaris11_mc.bin");
 MODULE_FIRMWARE("amdgpu/polaris10_mc.bin");
+MODULE_FIRMWARE("amdgpu/polaris12_mc.bin");
 
 static const u32 golden_settings_tonga_a11[] =
 {
                                                 (const u32)ARRAY_SIZE(golden_settings_tonga_a11));
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                amdgpu_program_register_sequence(adev,
                                                 golden_settings_polaris11_a11,
                                                 (const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
        case CHIP_POLARIS10:
                chip_name = "polaris10";
                break;
+       case CHIP_POLARIS12:
+               chip_name = "polaris12";
+               break;
        case CHIP_FIJI:
        case CHIP_CARRIZO:
        case CHIP_STONEY:
 
 MODULE_FIRMWARE("amdgpu/polaris10_sdma1.bin");
 MODULE_FIRMWARE("amdgpu/polaris11_sdma.bin");
 MODULE_FIRMWARE("amdgpu/polaris11_sdma1.bin");
+MODULE_FIRMWARE("amdgpu/polaris12_sdma.bin");
+MODULE_FIRMWARE("amdgpu/polaris12_sdma1.bin");
 
 
 static const u32 sdma_offsets[SDMA_MAX_INSTANCE] =
                                                 (const u32)ARRAY_SIZE(golden_settings_tonga_a11));
                break;
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                amdgpu_program_register_sequence(adev,
                                                 golden_settings_polaris11_a11,
                                                 (const u32)ARRAY_SIZE(golden_settings_polaris11_a11));
        case CHIP_POLARIS10:
                chip_name = "polaris10";
                break;
+       case CHIP_POLARIS12:
+               chip_name = "polaris12";
+               break;
        case CHIP_CARRIZO:
                chip_name = "carrizo";
                break;
 
 {
        u32 tmp;
 
-       /* Fiji, Stoney, Polaris10, Polaris11 are single pipe */
+       /* Fiji, Stoney, Polaris10, Polaris11, Polaris12 are single pipe */
        if ((adev->asic_type == CHIP_FIJI) ||
            (adev->asic_type == CHIP_STONEY) ||
            (adev->asic_type == CHIP_POLARIS10) ||
-           (adev->asic_type == CHIP_POLARIS11))
+           (adev->asic_type == CHIP_POLARIS11) ||
+           (adev->asic_type == CHIP_POLARIS12))
                return AMDGPU_VCE_HARVEST_VCE1;
 
        /* Tonga and CZ are dual or single pipe */
 
 MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
 MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
 MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
+MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
 
 /*
  * Indirect registers accessor
                break;
        case CHIP_POLARIS11:
        case CHIP_POLARIS10:
+       case CHIP_POLARIS12:
        default:
                break;
        }
        case CHIP_TONGA:
        case CHIP_POLARIS11:
        case CHIP_POLARIS10:
+       case CHIP_POLARIS12:
        case CHIP_CARRIZO:
        case CHIP_STONEY:
                asic_register_table = cz_allowed_read_registers;
                adev->pg_flags = 0;
                adev->external_rev_id = adev->rev_id + 0x50;
                break;
+       case CHIP_POLARIS12:
+               adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG;
+               adev->pg_flags = 0;
+               adev->external_rev_id = adev->rev_id + 0x64;
+               break;
        case CHIP_CARRIZO:
                adev->cg_flags = AMD_CG_SUPPORT_UVD_MGCG |
                        AMD_CG_SUPPORT_GFX_MGCG |
        case CHIP_TONGA:
        case CHIP_POLARIS10:
        case CHIP_POLARIS11:
+       case CHIP_POLARIS12:
                vi_common_set_clockgating_state_by_smu(adev, state);
        default:
                break;
                break;
        case CHIP_POLARIS11:
        case CHIP_POLARIS10:
+       case CHIP_POLARIS12:
                amdgpu_ip_block_add(adev, &vi_common_ip_block);
                amdgpu_ip_block_add(adev, &gmc_v8_1_ip_block);
                amdgpu_ip_block_add(adev, &tonga_ih_ip_block);
 
        CHIP_STONEY,
        CHIP_POLARIS10,
        CHIP_POLARIS11,
+       CHIP_POLARIS12,
        CHIP_LAST,
 };