Add support for MACO flag checking.
MACO mode only works if BACO is supported.
Signed-off-by: Ma Jun <Jun.Ma2@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
        /* PCIe replay counter */
        uint64_t (*get_pcie_replay_count)(struct amdgpu_device *adev);
        /* device supports BACO */
-       bool (*supports_baco)(struct amdgpu_device *adev);
+       int (*supports_baco)(struct amdgpu_device *adev);
        /* pre asic_init quirks */
        void (*pre_asic_init)(struct amdgpu_device *adev);
        /* enter/exit umd stable pstate */
 bool amdgpu_device_supports_px(struct drm_device *dev);
 bool amdgpu_device_supports_boco(struct drm_device *dev);
 bool amdgpu_device_supports_smart_shift(struct drm_device *dev);
-bool amdgpu_device_supports_baco(struct drm_device *dev);
+int amdgpu_device_supports_baco(struct drm_device *dev);
 bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev,
                                      struct amdgpu_device *peer_adev);
 int amdgpu_device_baco_enter(struct drm_device *dev);
 
  *
  * @dev: drm_device pointer
  *
- * Returns true if the device supporte BACO,
- * otherwise return false.
+ * Return:
+ * 1 if the device supporte BACO;
+ * 3 if the device support MACO (only works if BACO is supported)
+ * otherwise return 0.
  */
-bool amdgpu_device_supports_baco(struct drm_device *dev)
+int amdgpu_device_supports_baco(struct drm_device *dev)
 {
        struct amdgpu_device *adev = drm_to_adev(dev);
 
 
        return r;
 }
 
-static bool cik_asic_supports_baco(struct amdgpu_device *adev)
+static int cik_asic_supports_baco(struct amdgpu_device *adev)
 {
        switch (adev->asic_type) {
        case CHIP_BONAIRE:
        case CHIP_HAWAII:
                return amdgpu_dpm_is_baco_supported(adev);
        default:
-               return false;
+               return 0;
        }
 }
 
 
        return r;
 }
 
-static bool si_asic_supports_baco(struct amdgpu_device *adev)
+static int si_asic_supports_baco(struct amdgpu_device *adev)
 {
-       return false;
+       return 0;
 }
 
 static enum amd_reset_method
 
 static enum amd_reset_method
 soc15_asic_reset_method(struct amdgpu_device *adev)
 {
-       bool baco_reset = false;
+       int baco_reset = 0;
        bool connected_to_cpu = false;
        struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
 
                         */
                        if (ras && adev->ras_enabled &&
                            adev->pm.fw_version <= 0x283400)
-                               baco_reset = false;
+                               baco_reset = 0;
                } else {
                        baco_reset = amdgpu_dpm_is_baco_supported(adev);
                }
        }
 }
 
-static bool soc15_supports_baco(struct amdgpu_device *adev)
+static int soc15_supports_baco(struct amdgpu_device *adev)
 {
        switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
        case IP_VERSION(9, 0, 0):
                if (adev->asic_type == CHIP_VEGA20) {
                        if (adev->psp.sos.fw_version >= 0x80067)
                                return amdgpu_dpm_is_baco_supported(adev);
-                       return false;
+                       return 0;
                } else {
                        return amdgpu_dpm_is_baco_supported(adev);
                }
                break;
        default:
-               return false;
+               return 0;
        }
 }
 
 
        return r;
 }
 
-static bool vi_asic_supports_baco(struct amdgpu_device *adev)
+static int vi_asic_supports_baco(struct amdgpu_device *adev)
 {
        switch (adev->asic_type) {
        case CHIP_FIJI:
        case CHIP_TOPAZ:
                return amdgpu_dpm_is_baco_supported(adev);
        default:
-               return false;
+               return 0;
        }
 }
 
 static enum amd_reset_method
 vi_asic_reset_method(struct amdgpu_device *adev)
 {
-       bool baco_reset;
+       int baco_reset;
 
        if (amdgpu_reset_method == AMD_RESET_METHOD_LEGACY ||
            amdgpu_reset_method == AMD_RESET_METHOD_BACO)
                baco_reset = amdgpu_dpm_is_baco_supported(adev);
                break;
        default:
-               baco_reset = false;
+               baco_reset = 0;
                break;
        }
 
 
        int (*set_hard_min_dcefclk_by_freq)(void *handle, uint32_t clock);
        int (*set_hard_min_fclk_by_freq)(void *handle, uint32_t clock);
        int (*set_min_deep_sleep_dcefclk)(void *handle, uint32_t clock);
-       bool (*get_asic_baco_capability)(void *handle);
+       int (*get_asic_baco_capability)(void *handle);
        int (*get_asic_baco_state)(void *handle, int *state);
        int (*set_asic_baco_state)(void *handle, int state);
        int (*get_ppfeature_status)(void *handle, char *buf);
 
        return ret;
 }
 
-bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
+int amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
 {
        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
        void *pp_handle = adev->powerplay.pp_handle;
-       bool ret;
+       int ret;
 
        if (!pp_funcs || !pp_funcs->get_asic_baco_capability)
-               return false;
+               return 0;
        /* Don't use baco for reset in S3.
         * This is a workaround for some platforms
         * where entering BACO during suspend
         * devices.  Needs more investigation.
         */
        if (adev->in_s3)
-               return false;
+               return 0;
 
        mutex_lock(&adev->pm.mutex);
 
 
 int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev);
 int amdgpu_dpm_enable_gfx_features(struct amdgpu_device *adev);
 
-bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev);
+int amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev);
 
 bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev);
 int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev);
 
        return phm_set_active_display_count(hwmgr, count);
 }
 
-static bool pp_get_asic_baco_capability(void *handle)
+static int pp_get_asic_baco_capability(void *handle)
 {
        struct pp_hwmgr *hwmgr = handle;
 
 
 #include "smu/smu_7_1_2_d.h"
 #include "smu/smu_7_1_2_sh_mask.h"
 
-bool smu7_get_bamaco_support(struct pp_hwmgr *hwmgr)
+int smu7_get_bamaco_support(struct pp_hwmgr *hwmgr)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
        uint32_t reg;
        reg = RREG32(mmCC_BIF_BX_FUSESTRAP0);
 
        if (reg & CC_BIF_BX_FUSESTRAP0__STRAP_BIF_PX_CAPABLE_MASK)
-               return true;
+               return BACO_SUPPORT;
 
-       return false;
+       return 0;
 }
 
 int smu7_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state)
 
 #include "hwmgr.h"
 #include "common_baco.h"
 
-extern bool smu7_get_bamaco_support(struct pp_hwmgr *hwmgr);
+extern int smu7_get_bamaco_support(struct pp_hwmgr *hwmgr);
 extern int smu7_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state);
 extern int smu7_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
 
 
 #include "vega10_inc.h"
 #include "smu9_baco.h"
 
-bool smu9_get_bamaco_support(struct pp_hwmgr *hwmgr)
+int smu9_get_bamaco_support(struct pp_hwmgr *hwmgr)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
        uint32_t reg, data;
 
        if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_BACO))
-               return false;
+               return 0;
 
        WREG32(0x12074, 0xFFF0003B);
        data = RREG32(0x12075);
                reg = RREG32_SOC15(NBIF, 0, mmRCC_BIF_STRAP0);
 
                if (reg & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK)
-                       return true;
+                       return BACO_SUPPORT;
        }
 
-       return false;
+       return 0;
 }
 
 int smu9_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state)
 
 #include "hwmgr.h"
 #include "common_baco.h"
 
-extern bool smu9_get_bamaco_support(struct pp_hwmgr *hwmgr);
+extern int smu9_get_bamaco_support(struct pp_hwmgr *hwmgr);
 extern int smu9_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state);
 
 #endif
 
        {CMD_WRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIOS_SCRATCH_7), 0, 0, 0, 0},
 };
 
-bool vega20_get_bamaco_support(struct pp_hwmgr *hwmgr)
+int vega20_get_bamaco_support(struct pp_hwmgr *hwmgr)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
        uint32_t reg;
 
        if (!phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_BACO))
-               return false;
+               return 0;
 
        if (((RREG32(0x17569) & 0x20000000) >> 29) == 0x1) {
                reg = RREG32_SOC15(NBIF, 0, mmRCC_BIF_STRAP0);
 
                if (reg & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK)
-                       return true;
+                       return BACO_SUPPORT;
        }
 
-       return false;
+       return 0;
 }
 
 int vega20_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state)
 
 #include "hwmgr.h"
 #include "common_baco.h"
 
-extern bool vega20_get_bamaco_support(struct pp_hwmgr *hwmgr);
+extern int vega20_get_bamaco_support(struct pp_hwmgr *hwmgr);
 extern int vega20_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state);
 extern int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
 extern int vega20_baco_apply_vdci_flush_workaround(struct pp_hwmgr *hwmgr);
 
        int (*set_hard_min_fclk_by_freq)(struct pp_hwmgr *hwmgr, uint32_t clock);
        int (*set_hard_min_gfxclk_by_freq)(struct pp_hwmgr *hwmgr, uint32_t clock);
        int (*set_soft_max_gfxclk_by_freq)(struct pp_hwmgr *hwmgr, uint32_t clock);
-       bool (*get_bamaco_support)(struct pp_hwmgr *hwmgr);
+       int (*get_bamaco_support)(struct pp_hwmgr *hwmgr);
        int (*get_asic_baco_state)(struct pp_hwmgr *hwmgr, enum BACO_STATE *state);
        int (*set_asic_baco_state)(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
        int (*get_ppfeature_status)(struct pp_hwmgr *hwmgr, char *buf);
 
        smu->is_apu = false;
        smu->smu_baco.state = SMU_BACO_STATE_NONE;
        smu->smu_baco.platform_support = false;
+       smu->smu_baco.maco_support = false;
        smu->user_dpm_profile.fan_mode = -1;
 
        mutex_init(&smu->message_lock);
        return ret;
 }
 
-static bool smu_get_baco_capability(void *handle)
+static int smu_get_baco_capability(void *handle)
 {
        struct smu_context *smu = handle;
 
 
         * BACO: Bus Active, Chip Off
         * MACO: Memory Active, Chip Off
         */
-       bool (*get_bamaco_support)(struct smu_context *smu);
+       int (*get_bamaco_support)(struct smu_context *smu);
 
        /**
         * @baco_get_state: Get the current BACO state.
 
 int smu_v11_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
                struct pp_smu_nv_clock_table *max_clocks);
 
-bool smu_v11_0_get_bamaco_support(struct smu_context *smu);
+int smu_v11_0_get_bamaco_support(struct smu_context *smu);
 
 enum smu_baco_state smu_v11_0_baco_get_state(struct smu_context *smu);
 
 
 int smu_v13_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
                                               struct pp_smu_nv_clock_table *max_clocks);
 
-bool smu_v13_0_get_bamaco_support(struct smu_context *smu);
+int smu_v13_0_get_bamaco_support(struct smu_context *smu);
 
 int smu_v13_0_baco_enter(struct smu_context *smu);
 int smu_v13_0_baco_exit(struct smu_context *smu);
 
 int smu_v14_0_baco_set_armd3_sequence(struct smu_context *smu,
                                      enum smu_baco_seq baco_seq);
 
-bool smu_v14_0_get_bamaco_support(struct smu_context *smu);
+int smu_v14_0_get_bamaco_support(struct smu_context *smu);
 
 enum smu_baco_state smu_v14_0_baco_get_state(struct smu_context *smu);
 
 
        return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ArmD3, baco_seq, NULL);
 }
 
-bool smu_v11_0_get_bamaco_support(struct smu_context *smu)
+int smu_v11_0_get_bamaco_support(struct smu_context *smu)
 {
        struct smu_baco_context *smu_baco = &smu->smu_baco;
+       int bamaco_support = 0;
 
        if (amdgpu_sriov_vf(smu->adev) || !smu_baco->platform_support)
-               return false;
+               return 0;
+
+       if (smu_baco->maco_support)
+               bamaco_support |= MACO_SUPPORT;
 
        /* return true if ASIC is in BACO state already */
        if (smu_v11_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER)
-               return true;
+               return bamaco_support |= BACO_SUPPORT;
 
        /* Arcturus does not support this bit mask */
        if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) &&
           !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT))
-               return false;
+               return 0;
 
-       return true;
+       return (bamaco_support |= BACO_SUPPORT);
 }
 
 enum smu_baco_state smu_v11_0_baco_get_state(struct smu_context *smu)
 
        adev->unique_id = ((uint64_t)upper32 << 32) | lower32;
 }
 
-static bool aldebaran_get_bamaco_support(struct smu_context *smu)
+static int aldebaran_get_bamaco_support(struct smu_context *smu)
 {
        /* aldebaran is not support baco */
 
-       return false;
+       return 0;
 }
 
 static int aldebaran_set_df_cstate(struct smu_context *smu,
 
        return ret;
 }
 
-bool smu_v13_0_get_bamaco_support(struct smu_context *smu)
+int smu_v13_0_get_bamaco_support(struct smu_context *smu)
 {
        struct smu_baco_context *smu_baco = &smu->smu_baco;
+       int bamaco_support = 0;
 
        if (amdgpu_sriov_vf(smu->adev) || !smu_baco->platform_support)
-               return false;
+               return 0;
+
+       if (smu_baco->maco_support)
+               bamaco_support |= MACO_SUPPORT;
 
        /* return true if ASIC is in BACO state already */
        if (smu_v13_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER)
-               return true;
+               return bamaco_support |= BACO_SUPPORT;
 
        if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) &&
            !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT))
-               return false;
+               return 0;
 
-       return true;
+       return (bamaco_support |= BACO_SUPPORT);
 }
 
 int smu_v13_0_baco_enter(struct smu_context *smu)
 
        adev->unique_id = pptable->PublicSerialNumber_AID;
 }
 
-static bool smu_v13_0_6_get_bamaco_support(struct smu_context *smu)
+static int smu_v13_0_6_get_bamaco_support(struct smu_context *smu)
 {
        /* smu_13_0_6 does not support baco */
 
-       return false;
+       return 0;
 }
 
 static const char *const throttling_logging_label[] = {
 
        return 0;
 }
 
-bool smu_v14_0_get_bamaco_support(struct smu_context *smu)
+int smu_v14_0_get_bamaco_support(struct smu_context *smu)
 {
        struct smu_baco_context *smu_baco = &smu->smu_baco;
+       int bamaco_support = 0;
 
        if (amdgpu_sriov_vf(smu->adev) ||
            !smu_baco->platform_support)
-               return false;
+               return 0;
+
+       if (smu_baco->maco_support)
+               bamaco_support |= MACO_SUPPORT;
 
        /* return true if ASIC is in BACO state already */
        if (smu_v14_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER)
-               return true;
+               return (bamaco_support |= BACO_SUPPORT);
 
        if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) &&
            !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT))
-               return false;
+               return 0;
 
-       return true;
+       return (bamaco_support |= BACO_SUPPORT);
 }
 
 enum smu_baco_state smu_v14_0_baco_get_state(struct smu_context *smu)