}
 
-void clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id)
+unsigned int find_dcfclk_for_voltage(struct dpm_clocks *clock_table, unsigned int voltage)
 {
        int i;
 
+       for (i = 0; i < PP_SMU_NUM_DCFCLK_DPM_LEVELS; i++) {
+               if (clock_table->DcfClocks[i].Vol == voltage)
+                       return clock_table->DcfClocks[i].Freq;
+       }
+
+       ASSERT(0);
+       return 0;
+}
+
+void clk_mgr_helper_populate_bw_params(struct clk_bw_params *bw_params, struct dpm_clocks *clock_table, struct hw_asic_id *asic_id)
+{
+       int i, j = 0;
+
        ASSERT(PP_SMU_NUM_FCLK_DPM_LEVELS <= MAX_NUM_DPM_LVL);
 
-       for (i = 0; i < PP_SMU_NUM_FCLK_DPM_LEVELS; i++) {
-               if (clock_table->FClocks[i].Freq == 0)
+       /* Find lowest DPM, FCLK is filled in reverse order*/
+
+       for (i = PP_SMU_NUM_FCLK_DPM_LEVELS - 1; i >= 0; i--) {
+               if (clock_table->FClocks[i].Freq != 0) {
+                       j = i;
                        break;
+               }
+       }
 
-               bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i].Freq;
-               bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[i].Freq;
-               bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[i].Freq;
-               bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i].Freq;
-               bw_params->clk_table.entries[i].voltage = clock_table->FClocks[i].Vol;
+       for (i = 0; i < PP_SMU_NUM_FCLK_DPM_LEVELS; i++) {
+               if (j < 0) {
+                       /* Invalid entries */
+                       bw_params->clk_table.entries[i].fclk_mhz = 0;
+                       continue;
+               }
+               bw_params->clk_table.entries[i].fclk_mhz = clock_table->FClocks[j].Freq;
+               bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemClocks[j].Freq;
+               bw_params->clk_table.entries[i].voltage = clock_table->FClocks[j].Vol;
+               bw_params->clk_table.entries[i].dcfclk_mhz = find_dcfclk_for_voltage(clock_table, clock_table->FClocks[j].Vol);
+               j--;
        }
+
+
        bw_params->clk_table.num_entries = i;
 
        bw_params->vram_type = asic_id->vram_type;
        for (i = 0; i < WM_SET_COUNT; i++) {
                bw_params->wm_table.entries[i].wm_inst = i;
 
-               if (clock_table->FClocks[i].Freq == 0) {
+               if (i >= bw_params->clk_table.num_entries) {
                        bw_params->wm_table.entries[i].valid = false;
                        continue;
                }
 
 {
        struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL);
 
-       pp_smu->ctx.ver = PP_SMU_VER_RN;
+       if (!pp_smu)
+               return pp_smu;
 
-       pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table;
-       pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges;
+       if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) {
+               pp_smu->ctx.ver = PP_SMU_VER_RN;
+               pp_smu->rn_funcs.get_dpm_clock_table = dummy_get_dpm_clock_table;
+               pp_smu->rn_funcs.set_wm_ranges = dummy_set_wm_ranges;
+       } else {
+
+               dm_pp_get_funcs(ctx, pp_smu);
+
+               if (pp_smu->ctx.ver != PP_SMU_VER_RN)
+                       pp_smu = memset(pp_smu, 0, sizeof(struct pp_smu_funcs));
+       }
 
        return pp_smu;
 }