wm_with_clock_ranges.num_wm_dmif_sets = ranges->num_reader_wm_sets;
        wm_with_clock_ranges.num_wm_mcif_sets = ranges->num_writer_wm_sets;
 
-       if (!pp_funcs || !pp_funcs->set_watermarks_for_clocks_ranges)
-               return;
-
        for (i = 0; i < wm_with_clock_ranges.num_wm_dmif_sets; i++) {
                if (ranges->reader_wm_sets[i].wm_inst > 3)
                        wm_dce_clocks[i].wm_set_id = WM_SET_A;
                                ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000;
        }
 
-       pp_funcs->set_watermarks_for_clocks_ranges(pp_handle, &wm_with_clock_ranges);
+       if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges)
+               pp_funcs->set_watermarks_for_clocks_ranges(pp_handle,
+                                                          &wm_with_clock_ranges);
+       else if (adev->smu.funcs &&
+                adev->smu.funcs->set_watermarks_for_clock_ranges)
+               smu_set_watermarks_for_clock_ranges(&adev->smu,
+                                                   &wm_with_clock_ranges);
 }
 
 void pp_rv_set_pme_wa_enable(struct pp_smu *pp)
 
        uint32_t default_power_limit;
 
        bool support_power_containment;
+       bool disable_watermark;
+
+#define WATERMARKS_EXIST       (1 << 0)
+#define WATERMARKS_LOADED      (1 << 1)
+       uint32_t watermarks_bitmap;
 };
 
 struct pptable_funcs {
        int (*get_current_shallow_sleep_clocks)(struct smu_context *smu,
                                                struct smu_clock_info *clocks);
        int (*notify_smu_enable_pwe)(struct smu_context *smu);
+       int (*set_watermarks_for_clock_ranges)(struct smu_context *smu,
+                                              struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges);
 };
 
 #define smu_init_microcode(smu) \
        ((smu)->funcs->get_current_shallow_sleep_clocks ? (smu)->funcs->get_current_shallow_sleep_clocks((smu), (clocks)) : 0)
 #define smu_notify_smu_enable_pwe(smu) \
        ((smu)->funcs->notify_smu_enable_pwe ? (smu)->funcs->notify_smu_enable_pwe((smu)) : 0)
+#define smu_set_watermarks_for_clock_ranges(smu, clock_ranges) \
+       ((smu)->funcs->set_watermarks_for_clock_ranges ? (smu)->funcs->set_watermarks_for_clock_ranges((smu), (clock_ranges)) : 0)
 
 
 extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
 
        return ret;
 }
 
+static int smu_v11_0_set_watermarks_table(struct smu_context *smu,
+                                         Watermarks_t *table, struct
+                                         dm_pp_wm_sets_with_clock_ranges_soc15
+                                         *clock_ranges)
+{
+       int i;
+
+       if (!table || !clock_ranges)
+               return -EINVAL;
+
+       if (clock_ranges->num_wm_dmif_sets > 4 ||
+           clock_ranges->num_wm_mcif_sets > 4)
+                return -EINVAL;
+
+        for (i = 0; i < clock_ranges->num_wm_dmif_sets; i++) {
+               table->WatermarkRow[1][i].MinClock =
+                       cpu_to_le16((uint16_t)
+                       (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz /
+                       1000));
+               table->WatermarkRow[1][i].MaxClock =
+                       cpu_to_le16((uint16_t)
+                       (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz /
+                       1000));
+               table->WatermarkRow[1][i].MinUclk =
+                       cpu_to_le16((uint16_t)
+                       (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz /
+                       1000));
+               table->WatermarkRow[1][i].MaxUclk =
+                       cpu_to_le16((uint16_t)
+                       (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz /
+                       1000));
+               table->WatermarkRow[1][i].WmSetting = (uint8_t)
+                               clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id;
+        }
+
+       for (i = 0; i < clock_ranges->num_wm_mcif_sets; i++) {
+               table->WatermarkRow[0][i].MinClock =
+                       cpu_to_le16((uint16_t)
+                       (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz /
+                       1000));
+               table->WatermarkRow[0][i].MaxClock =
+                       cpu_to_le16((uint16_t)
+                       (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz /
+                       1000));
+               table->WatermarkRow[0][i].MinUclk =
+                       cpu_to_le16((uint16_t)
+                       (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz /
+                       1000));
+               table->WatermarkRow[0][i].MaxUclk =
+                       cpu_to_le16((uint16_t)
+                       (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz /
+                       1000));
+               table->WatermarkRow[0][i].WmSetting = (uint8_t)
+                               clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
+        }
+
+       return 0;
+}
+
+static int
+smu_v11_0_set_watermarks_for_clock_ranges(struct smu_context *smu, struct
+                                         dm_pp_wm_sets_with_clock_ranges_soc15
+                                         *clock_ranges)
+{
+       int ret = 0;
+       struct smu_table *watermarks = &smu->smu_table.tables[TABLE_WATERMARKS];
+       Watermarks_t *table = watermarks->cpu_addr;
+
+       if (!smu->disable_watermark &&
+           smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT) &&
+           smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
+               smu_v11_0_set_watermarks_table(smu, table, clock_ranges);
+               smu->watermarks_bitmap |= WATERMARKS_EXIST;
+               smu->watermarks_bitmap &= ~WATERMARKS_LOADED;
+       }
+
+       return ret;
+}
+
 static const struct smu_funcs smu_v11_0_funcs = {
        .init_microcode = smu_v11_0_init_microcode,
        .load_microcode = smu_v11_0_load_microcode,
        .read_sensor = smu_v11_0_read_sensor,
        .set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
        .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
+       .set_watermarks_for_clock_ranges = smu_v11_0_set_watermarks_for_clock_ranges,
 };
 
 void smu_v11_0_set_smu_funcs(struct smu_context *smu)