From 991b79b76842a807dbb682c30b1dbdfdf2f059cc Mon Sep 17 00:00:00 2001
From: Jay Goyal <j-goyal@ti.com>
Date: Tue, 5 May 2026 12:10:40 +0530
Subject: [PATCH] Add SSC to MCU+SDK

Signed-off-by: Jay Goyal <j-goyal@ti.com>
---
 .../rm_pm_hal/BuildConfigurationAM62AX.mk     |   1 +
 .../rm_pm_hal/BuildConfigurations.mk          |   3 +
 .../fw_caps/soc/am62ax/soc_capabilities.h     |   4 +-
 .../include/lib/trace_protocol.h              |   2 +
 .../include/tisci/pm/tisci_pm_clock.h         | 124 ++++++++-
 .../rm_pm_hal_src/include/tisci/tisci_core.h  |   2 +
 .../include/tisci/tisci_protocol.h            |   2 +
 .../rm_pm_hal/rm_pm_hal_src/pm/Kconfig        |  13 +
 .../rm_pm_hal_src/pm/drivers/clock/clk.c      |  55 ++--
 .../pm/drivers/clock/clk_pll_16fft.c          | 255 ++++++++++++++++++
 .../rm_pm_hal_src/pm/drivers/clock/clock.c    | 149 +++++++++-
 .../pm/drivers/device/device_clk.c            | 191 ++++++++-----
 .../rm_pm_hal/rm_pm_hal_src/pm/include/clk.h  |  38 ++-
 .../rm_pm_hal_src/pm/include/device.h         |   1 -
 .../rm_pm_hal_src/pm/include/device_clk.h     |  55 ++--
 .../rm_pm_hal/rm_pm_hal_src/pm/pm.h           |  30 +++
 .../rm_pm_hal_src/pm/soc/am62ax/clocks.c      |   2 +-
 .../makefile.am62ax.r5f.ti-arm-clang          |   1 +
 .../sciclient_direct/sciclient_direct.c       |  13 +-
 .../makefile.am62ax.r5f.ti-arm-clang          |   1 +
 .../device_manager/sciserver/sciserver.c      |  12 +
 21 files changed, 812 insertions(+), 142 deletions(-)

diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/BuildConfigurationAM62AX.mk b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/BuildConfigurationAM62AX.mk
index 66f0c538..c5daacc2 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/BuildConfigurationAM62AX.mk
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/BuildConfigurationAM62AX.mk
@@ -15,6 +15,7 @@ CONFIG_PM=y
 CONFIG_PSC=y
 CONFIG_CLOCK=y
 CONFIG_CLK_PLL_16FFT=y
+CONFIG_PM_CLK_SSC=y
 CONFIG_LPM_CLK=y
 CONFIG_LPM_LIMIT_IR_TRACKING=y
 CONFIG_RM=y
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/BuildConfigurations.mk b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/BuildConfigurations.mk
index a8c6bd60..4bd9301b 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/BuildConfigurations.mk
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/BuildConfigurations.mk
@@ -35,6 +35,9 @@ endif
 ifeq ($(CONFIG_CLK_PLL_16FFT_FRACF_CALIBRATION),y)
 CFLAGS_LOCAL_COMMON += -DCONFIG_CLK_PLL_16FFT_FRACF_CALIBRATION
 endif
+ifeq ($(CONFIG_PM_CLK_SSC),y)
+CFLAGS_LOCAL_COMMON += -DCONFIG_PM_CLK_SSC
+endif
 ifeq ($(CONFIG_PSC_PD_MAX_COUNT_64),y)
 CFLAGS_LOCAL_COMMON += -DCONFIG_PSC_PD_MAX_COUNT_64
 endif
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/common/fw_caps/soc/am62ax/soc_capabilities.h b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/common/fw_caps/soc/am62ax/soc_capabilities.h
index 09c9883c..fed54909 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/common/fw_caps/soc/am62ax/soc_capabilities.h
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/common/fw_caps/soc/am62ax/soc_capabilities.h
@@ -37,7 +37,7 @@
 #include <config.h>
 #include <types/short_types.h>
 
-#define TISCI_MSG_FLAG_FW_CAP_MAX (0x08U)
+#define TISCI_MSG_FLAG_FW_CAP_MAX (0x0AU)
 const u64 soc_fw_caps[TISCI_MSG_FLAG_FW_CAP_MAX] = {
 	TISCI_MSG_FLAG_FW_CAP_GENERIC_CAP,
 	TISCI_MSG_FLAG_FW_CAP_LPM_DEEP_SLEEP,
@@ -47,6 +47,8 @@ const u64 soc_fw_caps[TISCI_MSG_FLAG_FW_CAP_MAX] = {
 	TISCI_MSG_FLAG_FW_CAP_LPM_IO_ONLY_PLUS_DDR,
 	TISCI_MSG_FLAG_FW_CAP_IO_ISOLATION,
 	TISCI_MSG_FLAG_FW_CAP_DM,
+	TISCI_MSG_FLAG_FW_CAP_LPM_ABORT,
+	TISCI_MSG_FLAG_FW_CAP_CLOCK_SSC,
 };
 
 #endif /* SOC_AM62AX_CAPABILITIES_H */
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/lib/trace_protocol.h b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/lib/trace_protocol.h
index ae002c1b..6ef992c3 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/lib/trace_protocol.h
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/lib/trace_protocol.h
@@ -328,6 +328,8 @@
 #define TRACE_PM_ACTION_INVALID_STATE                    0x7DU
 #define TRACE_PM_ACTION_BAD_DEVICE                       0x7EU
 #define TRACE_PM_ACTION_MSG_PARAM_LATENCY                0x18U
+#define TRACE_PM_ACTION_CLOCK_ENABLE_SSC                 0x19U
+#define TRACE_PM_ACTION_CLOCK_DISABLE_SSC                0x1AU
 
 #define TRACE_PM_VAL_CLOCK_VAL_SHIFT                     10U
 #define TRACE_PM_VAL_CLOCK_VAL_MASK                      0x0001FC00U
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/pm/tisci_pm_clock.h b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/pm/tisci_pm_clock.h
index 8b4d2e72..dcd5e0d4 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/pm/tisci_pm_clock.h
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/pm/tisci_pm_clock.h
@@ -64,10 +64,11 @@
 /** Indicate hardware state of the clock is that it is running. */
 #define TISCI_MSG_VALUE_CLOCK_HW_STATE_READY        1
 
-/** Allow this clock to be modified via spread spectrum clocking.
- *  \note: The SSC feature is currently not supported in System Firmware.
- */
-#define TISCI_MSG_FLAG_CLOCK_ALLOW_SSC                BIT(8)
+/** Indicate that the spread spectrum clocking as down spread */
+#define TISCI_MSG_VALUE_CLOCK_SSC_SPREAD_DOWN       3U
+
+/** Indicate that the spread spectrum clocking as center spread */
+#define TISCI_MSG_VALUE_CLOCK_SSC_SPREAD_CENTER     1U
 
 /**
  * Allow this clock's frequency to be changed while it is running
@@ -81,9 +82,7 @@
  */
 #define TISCI_MSG_FLAG_CLOCK_INPUT_TERM               BIT(10)
 
-/** Indicate that SSC is active for this clock.
- *  \note: The SSC feature is currently not supported in System Firmware.
- */
+/** Indicate that SSC is active for this clock. */
 #define TISCI_MSG_FLAG_CLOCK_SSC_ACTIVE               BIT(11)
 
 /**
@@ -93,8 +92,7 @@
  * the IP.
  *
  * Certain flags can be set in the message header for device clocks:
- * TISCI_MSG_FLAG_CLOCK_ALLOW_SSC, TISCI_MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
- * TISCI_MSG_FLAG_CLOCK_INPUT_TERM.
+ * TISCI_MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE, TISCI_MSG_FLAG_CLOCK_INPUT_TERM.
  *
  * \param hdr TISCI header
  *
@@ -544,4 +542,110 @@ struct tisci_msg_get_freq_resp {
 	u64			freq_hz;
 } __attribute__((__packed__));
 
-#endif /* TISCI_PM_TISCI_CLOCK_H */
+/**
+ * \brief Set the spread spectrum clocking for a clock.
+ *
+ * Set the SSC for a clock with desired modulation frequency, spread
+ * type and modulation depth, all within their allowable range. SSC can only
+ * be enabled on clocks that have SSC support in the hardware. This message
+ * will fail if SSC is not supported by the hardware.
+ *
+ * \param hdr TISCI header
+ *
+ * \param device
+ * The device ID that the clock is connected to.
+ *
+ * \param clk
+ * Each device has its own set of clock inputs. This indexes which clock
+ * input to modify.
+ *
+ * \param modfreq_hz
+ * The desired modulation frequency in Hz. The modulation period is the time
+ * required to cycle the clock nominal frequency from an initial value through
+ * all the different values along the modulation profile and back to the
+ * initial value. The modulation frequency is the inverse of the period. The
+ * minimum allowable frequency is 32 kHz and maximum is fREFCLK / 200. For
+ * example, if the fREFCLK is 25 MHz, the maximum allowable modulation
+ * frequency would be 125 kHz.
+ *
+ * \param mod_depth
+ * The target modulation depth in "permyriad". The modulation depth refers to
+ * the maximum variation in frequency as a percentage of the clock center
+ * frequency. The minimum modulation depth is 0.1% and the maximum is 3.1%.
+ * Modulation depth can be adjusted in 0.1% increments.
+ *
+ * \param spread_type
+ * The target spread type. Both center and down spread are supported.
+ *
+ * \param enable
+ * Enable or disable SSC.
+ */
+struct tisci_msg_set_clock_ssc_req {
+	struct tisci_header	hdr;
+	u32			device;
+	u32			clk;
+	u32			modfreq_hz;
+	u32			mod_depth;
+	u8			spread_type;
+	u8			enable;
+} __attribute__((__packed__));
+
+/**
+ * \brief Empty response for TISCI_MSG_SET_CLOCK_SSC
+ *
+ * Although this message is essentially empty and contains only a header
+ * a full data structure is created for consistency in implementation.
+ *
+ * \param hdr TISCI header to provide ACK/NAK flags to the host.
+ */
+struct tisci_msg_set_clock_ssc_resp {
+	struct tisci_header hdr;
+} __attribute__((__packed__));
+
+/**
+ * \brief Get the current SSC settings of a device's clock
+ *
+ * This message will only succeed if the clock is currently enabled, otherwise
+ * it returns nack.
+ *
+ * \param hdr TISCI header
+ *
+ * \param device
+ * The device ID that the clock is connected to.
+ *
+ * \param clk
+ * Each device has its own set of clock inputs. This indexes which clock
+ * input to query.
+ */
+struct tisci_msg_get_clock_ssc_req {
+	struct tisci_header	hdr;
+	u32			device;
+	u32			clk;
+} __attribute__((__packed__));
+
+/**
+ * \brief Result of get SSC request
+ *
+ * \param hdr TISCI header
+ *
+ * \param modfreq_hz
+ * The current modulation frequency in Hz.
+ *
+ * \param mod_depth
+ * The current modulation depth in "permyriad".
+ *
+ * \param spread_type
+ * The current spread type.
+ *
+ * \param enable
+ * The current enable state.
+ */
+struct tisci_msg_get_clock_ssc_resp {
+	struct tisci_header	hdr;
+	u32			modfreq_hz;
+	u32			mod_depth;
+	u8			spread_type;
+	u8			enable;
+} __attribute__((__packed__));
+
+#endif  /* TISCI_PM_TISCI_CLOCK_H */
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/tisci_core.h b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/tisci_core.h
index 630280a3..82f57571 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/tisci_core.h
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/tisci_core.h
@@ -51,6 +51,8 @@
 #define TISCI_MSG_FLAG_FW_CAP_LPM_IO_ONLY_PLUS_DDR      BIT(6)
 #define TISCI_MSG_FLAG_FW_CAP_IO_ISOLATION              BIT(7)
 #define TISCI_MSG_FLAG_FW_CAP_DM                        BIT(8)
+#define TISCI_MSG_FLAG_FW_CAP_LPM_ABORT                 BIT(9)
+#define TISCI_MSG_FLAG_FW_CAP_CLOCK_SSC                 BIT(10)
 
 /**
  * \brief Notification message to indicate the DMSC is available.
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/tisci_protocol.h b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/tisci_protocol.h
index 4a88fd4d..90da2a5b 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/tisci_protocol.h
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/tisci_protocol.h
@@ -128,6 +128,8 @@ struct tisci_sec_header {
 #define TISCI_MSG_SET_CLOCK_PARENT              (0x0102U)
 #define TISCI_MSG_GET_CLOCK_PARENT              (0x0103U)
 #define TISCI_MSG_GET_NUM_CLOCK_PARENTS         (0x0104U)
+#define TISCI_MSG_SET_CLOCK_SSC                 (0x010aU)
+#define TISCI_MSG_GET_CLOCK_SSC                 (0x010bU)
 #define TISCI_MSG_SET_FREQ                      (0x010cU)
 #define TISCI_MSG_QUERY_FREQ                    (0x010dU)
 #define TISCI_MSG_GET_FREQ                      (0x010eU)
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/Kconfig b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/Kconfig
index 8a305bd0..1b7c6d91 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/Kconfig
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/Kconfig
@@ -101,6 +101,19 @@ config CLK_PLL_16FFT_FRACF_CALIBRATION
 	help
 	 Enable support for 16fft pllfracf calibration
 
+config PM_CLK_SSC
+	bool "Enable support for Spread Spectrum Clocking (SSC)"
+	depends on CLK_PLL_16FFT
+	default n
+	default y if SOC_AM62
+	default y if SOC_AM62A
+	default y if SOC_AM62P
+	help
+	 Enable support for Spread Spectrum Clocking (SSC). SSC allows
+	 modulation of the clock frequency to reduce electromagnetic
+	 interference (EMI). This feature is only available on select
+	 SoCs with hardware SSC support in their PLL controllers.
+
 config CLK_PLL_DESKEW
 	bool "Enable support for 16fft deskew PLL"
 	depends on CLOCK
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clk.c b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clk.c
index b428f05c..f7e94d26 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clk.c
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clk.c
@@ -462,35 +462,46 @@ void clk_put(struct clk *clkp)
 	}
 }
 
-void clk_ssc_allow(struct clk *clkp)
+#ifdef CONFIG_PM_CLK_SSC
+u32 clk_set_ssc(struct clk *clkp, u32 modfreq_hz, u32 mod_depth, u8 spread_type, sbool enable)
 {
-	if (--clkp->ssc_block_count == 0U) {
-		const struct clk_parent *p;
-		p = clk_get_parent(clkp);
-		if (p != NULL) {
-			struct clk *clkp_parent;
-			clkp_parent = clk_lookup((clk_idx_t) p->clk);
-			if (clkp_parent != NULL) {
-				clk_ssc_allow(clkp_parent);
-			}
-		}
+	const struct clk_data *clk_data_p = clk_get_data(clkp);
+	u32 ret;
+
+	if ((clkp->flags & CLK_FLAG_INITIALIZED) == 0U) {
+		ret = 1U;       /* Fail: Clock not initialized */
+	} else if ((clk_data_p->flags & CLK_DATA_FLAG_ALLOW_SSC_CHANGE) == 0U) {
+		ret = 1U;       /* Fail: Hardware does not support SSC on this clock */
+	} else if (clk_data_p->drv->set_ssc == NULL) {
+		ret = 1U;       /* Fail: No driver support for SSC */
+	} else {
+		/* Success: Call hardware-specific driver to set SSC parameters */
+		ret = (clk_data_p->drv->set_ssc(clkp, modfreq_hz, mod_depth,
+						spread_type, enable) == 0) ? 0U : 1U;
 	}
+
+	return ret;
 }
 
-void clk_ssc_block(struct clk *clkp)
+u32 clk_get_ssc(struct clk *clkp, struct ssc_data *ssc_datap)
 {
-	if (0U == clkp->ssc_block_count++) {
-		const struct clk_parent *p;
-		p = clk_get_parent(clkp);
-		if (p != NULL) {
-			struct clk *clkp_parent;
-			clkp_parent = clk_lookup((clk_idx_t) p->clk);
-			if (clkp_parent != NULL) {
-				clk_ssc_block(clkp_parent);
-			}
-		}
+	const struct clk_data *clk_data_p = clk_get_data(clkp);
+	u32 ret = 0U;
+
+	if ((clkp->flags & CLK_FLAG_INITIALIZED) == 0U) {
+		ret = 1U;       /* Fail: Clock not initialized */
+	} else if ((clk_data_p->flags & CLK_DATA_FLAG_ALLOW_SSC_CHANGE) == 0U) {
+		ret = 1U;       /* Fail: Hardware does not support SSC on this clock */
+	} else if (clk_data_p->drv->get_ssc == NULL) {
+		ret = 1U;       /* Fail: No driver support for SSC */
+	} else {
+		/* Success: Call hardware-specific driver to get SSC parameters */
+		clk_data_p->drv->get_ssc(clkp, ssc_datap);
 	}
+
+	return ret;
 }
+#endif
 
 void clk_freq_change_allow(struct clk *clkp)
 {
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clk_pll_16fft.c b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clk_pll_16fft.c
index 84ae9637..b952ba10 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clk_pll_16fft.c
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clk_pll_16fft.c
@@ -45,6 +45,7 @@
 #include <lib/trace.h>
 #include <delay.h>
 #include <osal/osal_clock_user.h>
+#include <tisci/pm/tisci_pm_clock.h>
 
 #define PLL_16FFT_PID   (idx)                   ((0x1000UL * (idx)) + 0x00UL)
 #define PLL_16FFT_CFG(idx)                      ((0x1000UL * (idx)) + 0x08UL)
@@ -94,7 +95,22 @@
 #define PLL_16FFT_DIV_CTRL_REF_DIV_MASK         (0x3fUL << 0UL)
 
 #define PLL_16FFT_SS_CTRL(idx)                  ((0x1000UL * (idx)) + 0x40UL)
+#define PLL_16FFT_SS_CTRL_DOWNSPREAD_EN         BIT(4)
+#define PLL_16FFT_SS_CTRL_BYPASS_EN             BIT(31)
+
 #define PLL_16FFT_SS_SPREAD(idx)                ((0x1000UL * (idx)) + 0x44UL)
+#define PLL_16FFT_SS_SPREAD_SPREAD_SHIFT        0UL
+#define PLL_16FFT_SS_SPREAD_SPREAD_MASK         (0x1fUL << 0UL)
+#define PLL_16FFT_SS_SPREAD_MOD_DIV_SHIFT       16UL
+#define PLL_16FFT_SS_SPREAD_MOD_DIV_MASK        (0xfUL << 16UL)
+
+#define PLL_16FFT_SS_MOD_DEPTH_DIV              10U
+#define PLL_16FFT_SS_MOD_DEPTH_MIN              10U
+#define PLL_16FFT_SS_MOD_DEPTH_MAX              310U
+#define PLL_16FFT_SS_MOD_DIV_FACTOR             128U
+#define PLL_16FFT_SS_MOD_DIV_FACTOR_HALF        64U
+#define PLL_16FFT_SS_MOD_FREQ_MIN_HZ            32000U
+#define PLL_16FFT_SS_MOD_FREQ_MAX_DIV           200U
 
 #define PLL_16FFT_CAL_CTRL(idx)                 ((0x1000UL * (idx)) + 0x60UL)
 #define PLL_16FFT_CAL_CTRL_CAL_EN               BIT(31)
@@ -1350,12 +1366,251 @@ static s32 clk_pll_16fft_init(struct clk *clock_ptr)
 	return ret;
 }
 
+#ifdef CONFIG_PM_CLK_SSC
+static s32 clk_pll_16fft_internal_disable_ssc(const struct clk_data_pll_16fft *pll)
+{
+	u32 ss_ctrl;
+	s32 ret = SUCCESS;
+
+	/* Read the PLL's SS control register */
+	ss_ctrl = readl(pll->base + (u32) PLL_16FFT_SS_CTRL(pll->idx));
+
+	/* Set the SS BYPASS enable bit if it is not already set */
+	if ((ss_ctrl & PLL_16FFT_SS_CTRL_BYPASS_EN) == 0U) {
+		ss_ctrl |= PLL_16FFT_SS_CTRL_BYPASS_EN;
+		/* Write the PLL's SS control register */
+		ret = pm_writel_verified(ss_ctrl, pll->base + (u32) PLL_16FFT_SS_CTRL(pll->idx));
+		if (ret != SUCCESS) {
+			ret = -EFAIL;
+		}
+	}
+
+	return ret;
+}
+
+static s32 clk_pll_16fft_internal_enable_ssc(const struct clk_data_pll_16fft	*pll,
+					     u32				parent_freq_hz,
+					     u32				modfreq_hz,
+					     u32				mod_depth,
+					     u8					spread_type)
+{
+	u32 ctrl;
+	u32 ss_ctrl;
+	u32 ss_spread;
+	u32 mod_div;
+	u32 spread;
+	s32 ret = SUCCESS;
+	sbool lock = SFALSE;
+
+	/*
+	 * The PLL needs to be locked before SSC can be enabled.
+	 * Check if the PLL is locked. If not, return failure
+	 */
+	lock = clk_pll_16fft_check_lock(pll);
+	if (lock == SFALSE) {
+		ret = -EFAIL;
+	}
+
+	if (ret == SUCCESS) {
+		/* Read the PLL's control register */
+		ctrl = readl(pll->base + (u32) PLL_16FFT_CTRL(pll->idx));
+
+		/*
+		* The PLL needs to be in fractional mode, i.e DAC and DSM bits
+		* must be set before SSC can be enabled.
+		* Check if these bits are set. If not, return failure
+		*/
+		if ((ctrl & PLL_16FFT_CTRL_DAC_EN) == 0U) {
+			ret = -EFAIL;
+		}
+		if ((ctrl & PLL_16FFT_CTRL_DSM_EN) == 0U) {
+			ret = -EFAIL;
+		}
+	}
+
+	if (ret == SUCCESS) {
+		/* Read the PLL's SS control register */
+		ss_ctrl = readl(pll->base + (u32) PLL_16FFT_SS_CTRL(pll->idx));
+
+		/* Unset the SS BYPASS enable bit if it is not already unset */
+		if ((ss_ctrl & PLL_16FFT_SS_CTRL_BYPASS_EN) != 0U) {
+			ss_ctrl &= ~PLL_16FFT_SS_CTRL_BYPASS_EN;
+		}
+
+		/* Set the SS DOWNSPREAD enable bit if the spread_type is down or unset it if it is center */
+		if (spread_type == TISCI_MSG_VALUE_CLOCK_SSC_SPREAD_DOWN) {
+			ss_ctrl |= PLL_16FFT_SS_CTRL_DOWNSPREAD_EN;
+		} else if (spread_type == TISCI_MSG_VALUE_CLOCK_SSC_SPREAD_CENTER) {
+			ss_ctrl &= ~PLL_16FFT_SS_CTRL_DOWNSPREAD_EN;
+		} else {
+			ret = -EINVAL;
+		}
+
+		if (ret == SUCCESS) {
+			/* Write the PLL's SS spread register */
+			ret = pm_writel_verified(ss_ctrl, pll->base + (u32) PLL_16FFT_SS_CTRL(pll->idx));
+			if (ret != SUCCESS) {
+				ret = -EFAIL;
+			}
+		}
+	}
+
+	if (ret == SUCCESS) {
+		/* Read the PLL's SS spread register */
+		ss_spread = readl(pll->base + (u32) PLL_16FFT_SS_SPREAD(pll->idx));
+
+		/* if modfreq_hz is valid */
+		if ((modfreq_hz >= PLL_16FFT_SS_MOD_FREQ_MIN_HZ) &&
+		    (modfreq_hz <= (parent_freq_hz / PLL_16FFT_SS_MOD_FREQ_MAX_DIV))) {
+			/* Calculate the modulation frequency divider value */
+			mod_div = (parent_freq_hz +
+				   (PLL_16FFT_SS_MOD_DIV_FACTOR_HALF * modfreq_hz)) /
+				  (PLL_16FFT_SS_MOD_DIV_FACTOR * modfreq_hz);
+			ss_spread &= ~PLL_16FFT_SS_SPREAD_MOD_DIV_MASK;
+			ss_spread |= mod_div << PLL_16FFT_SS_SPREAD_MOD_DIV_SHIFT;
+		} else {
+			ret = -EINVAL;
+		}
+
+		/* if spread is valid */
+		if ((mod_depth >= PLL_16FFT_SS_MOD_DEPTH_MIN) &&
+		    (mod_depth <= PLL_16FFT_SS_MOD_DEPTH_MAX)) {
+			/* Calculate the spread modulation depth value */
+			spread = mod_depth / PLL_16FFT_SS_MOD_DEPTH_DIV;
+			ss_spread &= ~PLL_16FFT_SS_SPREAD_SPREAD_MASK;
+			ss_spread |= spread << PLL_16FFT_SS_SPREAD_SPREAD_SHIFT;
+		} else {
+			ret = -EINVAL;
+		}
+
+		if (ret == SUCCESS) {
+			/* Write the PLL's SS spread register */
+			ret = pm_writel_verified(ss_spread, pll->base + (u32) PLL_16FFT_SS_SPREAD(pll->idx));
+			if (ret != SUCCESS) {
+				ret = -EFAIL;
+			}
+		}
+	}
+
+	/* If enable failed, disable SSC to clean up */
+	if (ret != SUCCESS) {
+		s32 disable_ret;
+		disable_ret = clk_pll_16fft_internal_disable_ssc(pll);
+		/* Only overwrite ret if it's not a validation error */
+		if ((disable_ret != SUCCESS) && (ret != -EINVAL)) {
+			ret = disable_ret;
+		}
+	}
+
+	return ret;
+}
+
+static s32 clk_pll_16fft_set_ssc(struct clk	*clock_ptr,
+				 u32		modfreq_hz,
+				 u32		mod_depth,
+				 u8		spread_type,
+				 sbool		enable)
+{
+	const struct clk_data *clock_data;
+	const struct clk_data_pll *data_pll;
+	const struct clk_data_pll_16fft *pll;
+	u32 parent_freq_hz;
+	s32 ret;
+
+	clock_data = clk_get_data(clock_ptr);
+	data_pll = container_of(clock_data->data, const struct clk_data_pll,
+				data);
+	pll = container_of(data_pll, const struct clk_data_pll_16fft,
+			   data_pll);
+
+	if (enable) {
+		parent_freq_hz = clk_get_parent_freq(clock_ptr);
+		ret = clk_pll_16fft_internal_enable_ssc(pll, parent_freq_hz, modfreq_hz,
+							mod_depth, spread_type);
+	} else {
+		ret = clk_pll_16fft_internal_disable_ssc(pll);
+	}
+
+	return ret;
+}
+
+static void clk_pll_16fft_internal_get_ssc(const struct clk_data_pll_16fft	*pll,
+					   u32					parent_freq_hz,
+					   struct ssc_data			*ssc_datap)
+{
+	u32 ctrl;
+	u32 ss_ctrl;
+	u32 ss_spread;
+	u32 mod_div;
+	u32 spread;
+	u32 spread_type;
+
+	/* Read the PLL's control register */
+	ctrl = readl(pll->base + (u32) PLL_16FFT_CTRL(pll->idx));
+
+	/*
+	 * Check if the DAC and DSM enable bits are set.
+	 * If not, return SSC as disabled.
+	 */
+	if ((ctrl & PLL_16FFT_CTRL_DAC_EN) == 0U) {
+		ssc_datap->enable = 0U;
+	}
+	if ((ctrl & PLL_16FFT_CTRL_DSM_EN) == 0U) {
+		ssc_datap->enable = 0U;
+	}
+
+	/* Read the PLL's SS control register */
+	ss_ctrl = readl(pll->base + (u32) PLL_16FFT_SS_CTRL(pll->idx));
+
+	/* Check if the SS BYPASS enable bit is unset */
+	ssc_datap->enable = ((ss_ctrl & PLL_16FFT_SS_CTRL_BYPASS_EN) == 0U) ? 1U : 0U;
+
+	/* Get the spread type */
+	spread_type = ss_ctrl & PLL_16FFT_SS_CTRL_DOWNSPREAD_EN;
+	ssc_datap->spread_type = (spread_type == 0U) ? TISCI_MSG_VALUE_CLOCK_SSC_SPREAD_CENTER : TISCI_MSG_VALUE_CLOCK_SSC_SPREAD_DOWN;
+
+	/* Read the PLL's SS spread register */
+	ss_spread = readl(pll->base + (u32) PLL_16FFT_SS_SPREAD(pll->idx));
+
+	/* Get the modulation frequency */
+	mod_div = (ss_spread & PLL_16FFT_SS_SPREAD_MOD_DIV_MASK) >>
+		  PLL_16FFT_SS_SPREAD_MOD_DIV_SHIFT;
+	ssc_datap->modfreq_hz = (parent_freq_hz /
+				 (PLL_16FFT_SS_MOD_DIV_FACTOR * mod_div));
+
+	/* Get the modulation depth */
+	spread = ss_spread & PLL_16FFT_SS_SPREAD_SPREAD_MASK;
+	ssc_datap->mod_depth = spread * PLL_16FFT_SS_MOD_DEPTH_DIV;
+}
+
+static void clk_pll_16fft_get_ssc(struct clk *clock_ptr, struct ssc_data *ssc_datap)
+{
+	const struct clk_data *clock_data;
+	const struct clk_data_pll *data_pll;
+	const struct clk_data_pll_16fft *pll;
+	u32 parent_freq_hz;
+
+	clock_data = clk_get_data(clock_ptr);
+	data_pll = container_of(clock_data->data, const struct clk_data_pll,
+				data);
+	pll = container_of(data_pll, const struct clk_data_pll_16fft,
+			   data_pll);
+	parent_freq_hz = clk_get_parent_freq(clock_ptr);
+
+	clk_pll_16fft_internal_get_ssc(pll, parent_freq_hz, ssc_datap);
+}
+#endif
+
 const struct clk_drv clk_drv_pll_16fft = {
 	.init		= clk_pll_16fft_init,
 	.get_freq	= clk_pll_16fft_get_freq,
 	.set_freq	= clk_pll_16fft_set_freq,
 	.get_state	= clk_pll_16fft_get_state,
 	.set_state	= clk_pll_16fft_set_state,
+#ifdef CONFIG_PM_CLK_SSC
+	.set_ssc	= clk_pll_16fft_set_ssc,
+	.get_ssc	= clk_pll_16fft_get_ssc,
+#endif
 };
 
 /*
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clock.c b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clock.c
index 6c36c103..fc253a08 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clock.c
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/clock/clock.c
@@ -98,12 +98,6 @@ s32 set_clock_handler(u32 *msg_recv)
 	}
 
 	if (ret == SUCCESS) {
-		if ((flags & TISCI_MSG_FLAG_CLOCK_ALLOW_SSC) != 0UL) {
-			device_clk_set_ssc(dev, clkidx, STRUE);
-		} else {
-			device_clk_set_ssc(dev, clkidx, SFALSE);
-		}
-
 		if ((flags & TISCI_MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE) != 0UL) {
 			device_clk_set_freq_change(dev, clkidx, STRUE);
 		} else {
@@ -165,6 +159,9 @@ s32 get_clock_handler(u32 *msg_recv)
 	if (ret == SUCCESS) {
 		u8 prog;
 		u8 state;
+#ifdef CONFIG_PM_CLK_SSC
+		struct ssc_data current_ssc = { 0U };
+#endif
 
 		prog = (u8) (device_clk_get_sw_gated(dev, clkidx) ?
 			     TISCI_MSG_VALUE_CLOCK_SW_STATE_UNREQ :
@@ -174,14 +171,6 @@ s32 get_clock_handler(u32 *msg_recv)
 			      TISCI_MSG_VALUE_CLOCK_HW_STATE_READY :
 			      TISCI_MSG_VALUE_CLOCK_HW_STATE_NOT_READY);
 
-		if (device_clk_get_ssc(dev, clkidx)) {
-			resp->hdr.flags |= TISCI_MSG_FLAG_CLOCK_ALLOW_SSC;
-		}
-
-		if (device_clk_get_hw_ssc(dev, clkidx)) {
-			resp->hdr.flags |= TISCI_MSG_FLAG_CLOCK_SSC_ACTIVE;
-		}
-
 		if (device_clk_get_freq_change(dev, clkidx)) {
 			resp->hdr.flags |= TISCI_MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE;
 		}
@@ -190,6 +179,12 @@ s32 get_clock_handler(u32 *msg_recv)
 			resp->hdr.flags |= TISCI_MSG_FLAG_CLOCK_INPUT_TERM;
 		}
 
+#ifdef CONFIG_PM_CLK_SSC
+		if (device_clk_get_ssc(dev, clkidx, &current_ssc) && (current_ssc.enable != 0U)) {
+			resp->hdr.flags |= TISCI_MSG_FLAG_CLOCK_SSC_ACTIVE;
+		}
+#endif
+
 		resp->programmed_state  = prog;
 		resp->current_state     = state;
 	}
@@ -386,6 +381,11 @@ s32 set_freq_handler(u32 *msg_recv)
 	}
 
 	if (ret == SUCCESS) {
+#ifdef CONFIG_PM_CLK_SSC
+		struct ssc_data saved_ssc_data = { 0U };
+		sbool ssc_was_enabled = SFALSE;
+#endif
+
 		if (max_freq_hz > (u64) ULONG_MAX) {
 			max_freq_hz = ULONG_MAX;
 		}
@@ -394,10 +394,31 @@ s32 set_freq_handler(u32 *msg_recv)
 			target_freq_hz = ULONG_MAX;
 		}
 
+#ifdef CONFIG_PM_CLK_SSC
+		/* Save current SSC state if enabled */
+		if (device_clk_get_ssc(dev, clkidx, &saved_ssc_data) && (saved_ssc_data.enable != 0U)) {
+			ssc_was_enabled = STRUE;
+			/* Disable SSC before frequency change */
+			device_clk_set_ssc(dev, clkidx, saved_ssc_data.modfreq_hz,
+					   saved_ssc_data.mod_depth,
+					   saved_ssc_data.spread_type, SFALSE);
+		}
+#endif
+
+		/* Change the frequency */
 		if (!device_clk_set_freq(dev, clkidx, (u32) min_freq_hz,
 					 (u32) target_freq_hz, (u32) max_freq_hz)) {
 			ret = -EINVAL;
 		}
+
+#ifdef CONFIG_PM_CLK_SSC
+		/* Re-enable SSC if it was previously enabled */
+		if ((ret == SUCCESS) && ssc_was_enabled) {
+			device_clk_set_ssc(dev, clkidx, saved_ssc_data.modfreq_hz,
+					   saved_ssc_data.mod_depth,
+					   saved_ssc_data.spread_type, STRUE);
+		}
+#endif
 	}
 
 	mmr_lock_all();
@@ -517,3 +538,103 @@ s32 get_freq_handler(u32 *msg_recv)
 
 	return ret;
 }
+
+#ifdef CONFIG_PM_CLK_SSC
+s32 set_ssc_handler(u32 *msg_recv)
+{
+	struct tisci_msg_set_clock_ssc_req *req =
+		(struct tisci_msg_set_clock_ssc_req *) msg_recv;
+	struct tisci_msg_set_clock_ssc_resp *resp =
+		(struct tisci_msg_set_clock_ssc_resp *) msg_recv;
+	struct device *dev = NULL;
+	struct dev_clk *dev_clkp;
+	u32 id = req->device;
+	dev_clk_idx_t clkidx = (dev_clk_idx_t) req->clk;
+	u32 modfreq_hz = req->modfreq_hz;
+	u32 mod_depth = req->mod_depth;
+	u8 spread_type = req->spread_type;
+	sbool enable = (req->enable != 0U) ? STRUE : SFALSE;
+	s32 ret = SUCCESS;
+
+	mmr_unlock_all();
+
+	pm_trace(TRACE_PM_ACTION_MSG_RECEIVED, TISCI_MSG_SET_CLOCK_SSC);
+	pm_trace(TRACE_PM_ACTION_MSG_PARAM_DEV_CLK_ID,
+		 id | ((u32) clkidx << TRACE_PM_MSG_CLK_ID_SHIFT));
+	pm_trace(TRACE_PM_ACTION_MSG_PARAM_VAL, modfreq_hz);
+	pm_trace(TRACE_PM_ACTION_MSG_PARAM_VAL, mod_depth);
+	pm_trace(TRACE_PM_ACTION_MSG_PARAM_VAL, spread_type);
+	pm_trace(TRACE_PM_ACTION_MSG_PARAM_VAL, (enable == STRUE) ? 1U : 0U);
+
+	resp->hdr.flags = 0U;
+
+	ret = device_prepare_exclusive(req->hdr.host, id, NULL, &dev);
+	if (ret == SUCCESS) {
+		/* Check if "clk_idx" is available on the device */
+		dev_clkp = get_dev_clk(dev, clkidx);
+		if (dev_clkp == NULL) {
+			ret = -EFAIL;
+		}
+	}
+
+	if (ret == SUCCESS) {
+		/* Forward SSC request to device clock layer. */
+		if (!device_clk_set_ssc(dev, clkidx, modfreq_hz,
+					mod_depth, spread_type, enable)) {
+			ret = -EINVAL;
+		}
+	}
+
+	mmr_lock_all();
+
+	return ret;
+}
+
+s32 get_ssc_handler(u32 *msg_recv)
+{
+	struct tisci_msg_get_clock_ssc_req *req =
+		(struct tisci_msg_get_clock_ssc_req *) msg_recv;
+	struct tisci_msg_get_clock_ssc_resp *resp =
+		(struct tisci_msg_get_clock_ssc_resp *) msg_recv;
+	struct device *dev = NULL;
+	struct dev_clk *dev_clkp;
+	struct ssc_data data = { 0U };
+	u32 id = req->device;
+	dev_clk_idx_t clkidx = (dev_clk_idx_t) req->clk;
+	s32 ret = SUCCESS;
+
+	mmr_unlock_all();
+
+	pm_trace(TRACE_PM_ACTION_MSG_RECEIVED, TISCI_MSG_GET_CLOCK_SSC);
+	pm_trace(TRACE_PM_ACTION_MSG_PARAM_DEV_CLK_ID,
+		 id | ((u32) clkidx << TRACE_PM_MSG_CLK_ID_SHIFT));
+
+	resp->hdr.flags = 0U;
+
+	ret = device_prepare_nonexclusive(req->hdr.host, id, NULL, &dev);
+	if (ret == SUCCESS) {
+		/* Check if "clk_idx" is available on the device */
+		dev_clkp = get_dev_clk(dev, clkidx);
+		if (dev_clkp == NULL) {
+			ret = -EFAIL;
+		}
+	}
+
+	if (ret == SUCCESS) {
+		if (!device_clk_get_ssc(dev, clkidx, &data)) {
+			ret = -EINVAL;
+		}
+	}
+
+	if (ret == SUCCESS) {
+		resp->mod_depth = data.mod_depth;
+		resp->modfreq_hz = data.modfreq_hz;
+		resp->spread_type = data.spread_type;
+		resp->enable = data.enable;
+	}
+
+	mmr_lock_all();
+
+	return ret;
+}
+#endif
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/device/device_clk.c b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/device/device_clk.c
index 3f5f51af..b97b2819 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/device/device_clk.c
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/drivers/device/device_clk.c
@@ -113,10 +113,6 @@ sbool device_clk_set_gated(struct device *dev, dev_clk_idx_t clk_idx, sbool gate
 		if (is_enabled) {
 			clk_put(clkp);
 
-			if (0U == (dev_clkp->flags & DEV_CLK_FLAG_ALLOW_SSC)) {
-				clk_ssc_allow(clkp);
-			}
-
 			if (0U == (dev_clkp->flags &
 				   DEV_CLK_FLAG_ALLOW_FREQ_CHANGE)) {
 				clk_freq_change_allow(clkp);
@@ -126,10 +122,6 @@ sbool device_clk_set_gated(struct device *dev, dev_clk_idx_t clk_idx, sbool gate
 		dev_clkp->flags &= (u8) ~DEV_CLK_FLAG_DISABLE;
 		if (is_enabled) {
 			if (clk_get(clkp)) {
-				if (0U == (dev_clkp->flags & DEV_CLK_FLAG_ALLOW_SSC)) {
-					clk_ssc_block(clkp);
-				}
-
 				if (0U == (dev_clkp->flags &
 					   DEV_CLK_FLAG_ALLOW_FREQ_CHANGE)) {
 					clk_freq_change_block(clkp);
@@ -193,55 +185,7 @@ sbool device_clk_get_sw_gated(struct device *dev, dev_clk_idx_t clk_idx)
 	struct dev_clk *dev_clkp = get_dev_clk(dev, clk_idx);
 
 	return dev_clkp && (dev_clkp->flags & DEV_CLK_FLAG_DISABLE);
-}
-
-void device_clk_set_ssc(struct device *dev, dev_clk_idx_t clk_idx, sbool allow)
-{
-	struct dev_clk *dev_clkp = get_dev_clk(dev, clk_idx);
-	struct clk *clkp;
-	sbool is_allowed;
-
-	if (!dev_clkp) {
-		/* Nothing to do */
-	} else {
-		is_allowed = ((dev_clkp->flags & DEV_CLK_FLAG_ALLOW_SSC) > 0U) ? STRUE : SFALSE;
-		if (is_allowed == allow) {
-			/* Nothing to do */
-		} else {
-			dev_clkp->flags ^= DEV_CLK_FLAG_ALLOW_SSC;
-
-			if ((dev->flags & DEV_FLAG_ENABLED_MASK) == 0UL) {
-				/* Nothing to do */
-			} else {
-				if ((dev_clkp->flags & DEV_CLK_FLAG_DISABLE) != 0U) {
-					/* Nothing to do */
-				} else {
-					clkp = dev_get_clk(dev, clk_idx);
-
-					if (!clkp) {
-						/* fail */
-					} else if (allow) {
-						clk_ssc_allow(clkp);
-					} else {
-						clk_ssc_block(clkp);
-					}
-				}
-			}
-		}
-	}
-}
 
-sbool device_clk_get_ssc(struct device *dev, dev_clk_idx_t clk_idx)
-{
-	struct dev_clk *dev_clkp = get_dev_clk(dev, clk_idx);
-
-	return dev_clkp && (dev_clkp->flags & DEV_CLK_FLAG_ALLOW_SSC);
-}
-
-sbool device_clk_get_hw_ssc(struct device *dev __attribute__(
-				    (unused)), dev_clk_idx_t clk_idx __attribute__((unused)))
-{
-	return SFALSE;
 }
 
 void device_clk_set_freq_change(struct device *dev, dev_clk_idx_t clk_idx, sbool allow)
@@ -673,6 +617,132 @@ u32 device_clk_get_freq(struct device *dev, dev_clk_idx_t clk_idx)
 	return freq_hz;
 }
 
+#ifdef CONFIG_PM_CLK_SSC
+sbool device_clk_set_ssc(struct device *dev, dev_clk_idx_t clk_idx, u32 modfreq_hz, u32 mod_depth, u8 spread_type, sbool enable)
+{
+	const struct dev_clk_data *clock_data;
+	const struct clk_parent *parent_clk = NULL;
+	struct clk *parent = NULL;
+	sbool done = SFALSE;
+	sbool ssc_set = SFALSE;
+	sbool search_complete = SFALSE;
+	dev_clk_idx_t clk_idx_val = clk_idx;
+
+	/* Validate clock index on device */
+	if (!done) {
+		clock_data = get_dev_clk_data(dev, clk_idx_val);
+		if (clock_data == NULL) {
+			/* Invalid clock idx */
+			done = STRUE;
+		}
+	}
+
+	/* Get the clock structure */
+	if (!done) {
+		parent = dev_get_clk(dev, clk_idx_val);
+		if (parent == NULL) {
+			/* Parent not present */
+			done = STRUE;
+		}
+	}
+
+	/*
+	 * For PARENT, MUX or INPUT type clocks, walk up the clock tree to find
+	 * the actual PLL that supports SSC. Forward request to clk_set_ssc().
+	 */
+	if (!done) {
+		if ((clock_data->type == DEV_CLK_TABLE_TYPE_PARENT) ||
+		    (clock_data->type == DEV_CLK_TABLE_TYPE_MUX) ||
+		    (clock_data->type == DEV_CLK_TABLE_TYPE_INPUT)) {
+			while ((ssc_set != STRUE) && (search_complete != STRUE)) {
+				/* Walk up to find parent PLL with SSC capability */
+				parent_clk = clk_get_parent(parent);
+				if (parent_clk == NULL) {
+					search_complete = STRUE;
+				} else {
+					parent = clk_lookup(parent_clk->clk);
+					if (parent == NULL) {
+						search_complete = STRUE;
+					} else {
+						/* Call internal clock layer to set SSC on hardware */
+						ssc_set = (clk_set_ssc(parent, modfreq_hz, mod_depth,
+								       spread_type, enable) == 0U) ? STRUE : SFALSE;
+						if (ssc_set) {
+							if (enable) {
+								pm_trace(TRACE_PM_ACTION_CLOCK_ENABLE_SSC,
+									 clk_id(parent));
+							} else {
+								pm_trace(TRACE_PM_ACTION_CLOCK_DISABLE_SSC,
+									 clk_id(parent));
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return ssc_set;
+}
+
+sbool device_clk_get_ssc(struct device *dev, dev_clk_idx_t clk_idx, struct ssc_data *ssc_datap)
+{
+	const struct dev_clk_data *clock_data;
+	const struct clk_parent *parent_clk = NULL;
+	struct clk *parent = NULL;
+	sbool ssc_found = SFALSE;
+	sbool done = SFALSE;
+	sbool search_complete = SFALSE;
+	dev_clk_idx_t clk_idx_val = clk_idx;
+
+	/* Validate clock index on device */
+	if (!done) {
+		clock_data = get_dev_clk_data(dev, clk_idx_val);
+		if (clock_data == NULL) {
+			/* Invalid clock idx */
+			done = STRUE;
+		}
+	}
+
+	/* Get the clock structure */
+	if (!done) {
+		parent = dev_get_clk(dev, clk_idx_val);
+		if (parent == NULL) {
+			/* Parent not present */
+			done = STRUE;
+		}
+	}
+
+	/*
+	 * For PARENT, MUX or INPUT type clocks, walk up the clock tree to find
+	 * the actual PLL that supports SSC. Forward request to clk_get_ssc().
+	 */
+	if (!done) {
+		if ((clock_data->type == DEV_CLK_TABLE_TYPE_PARENT) ||
+		    (clock_data->type == DEV_CLK_TABLE_TYPE_MUX) ||
+		    (clock_data->type == DEV_CLK_TABLE_TYPE_INPUT)) {
+			while ((ssc_found != STRUE) && (search_complete != STRUE)) {
+				/* Walk up to find parent PLL with SSC capability */
+				parent_clk = clk_get_parent(parent);
+				if (parent_clk == NULL) {
+					search_complete = STRUE;
+				} else {
+					parent = clk_lookup(parent_clk->clk);
+					if (parent == NULL) {
+						search_complete = STRUE;
+					} else {
+						/* Call internal clock layer to get SSC configuration of hardware */
+						ssc_found = (clk_get_ssc(parent, ssc_datap) == 0U) ? STRUE : SFALSE;
+					}
+				}
+			}
+		}
+	}
+
+	return ssc_found;
+}
+#endif
+
 void device_clk_enable(struct device *dev, dev_clk_idx_t clk_idx)
 {
 	struct dev_clk *dev_clkp;
@@ -685,10 +755,6 @@ void device_clk_enable(struct device *dev, dev_clk_idx_t clk_idx)
 
 	if (clkp != NULL) {
 		if (clk_get(clkp)) {
-			if (0U == (dev_clkp->flags & DEV_CLK_FLAG_ALLOW_SSC)) {
-				clk_ssc_block(clkp);
-			}
-
 			if (0U == (dev_clkp->flags & DEV_CLK_FLAG_ALLOW_FREQ_CHANGE)) {
 				clk_freq_change_block(clkp);
 			}
@@ -709,10 +775,6 @@ void device_clk_disable(struct device *dev, dev_clk_idx_t clk_idx)
 	if (clkp != NULL) {
 		clk_put(clkp);
 
-		if (0U == (dev_clkp->flags & DEV_CLK_FLAG_ALLOW_SSC)) {
-			clk_ssc_allow(clkp);
-		}
-
 		if (0U == (dev_clkp->flags & DEV_CLK_FLAG_ALLOW_FREQ_CHANGE)) {
 			clk_freq_change_allow(clkp);
 		}
@@ -732,7 +794,6 @@ void device_clk_init(struct device *dev, dev_clk_idx_t clk_idx)
 	if ((dev_clk_datap != NULL) && (dev_clkp != NULL)) {
 		if (dev_clk_datap->type == DEV_CLK_TABLE_TYPE_PARENT) {
 			dev_clkp->flags |= DEV_CLK_FLAG_DISABLE |
-					   DEV_CLK_FLAG_ALLOW_SSC |
 					   DEV_CLK_FLAG_ALLOW_FREQ_CHANGE;
 		}
 	}
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/clk.h b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/clk.h
index c62f3a17..282a7231 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/clk.h
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/clk.h
@@ -70,6 +70,7 @@
 #define CLK_DATA_FLAG_ALLOW_FREQ_CHANGE         BIT(1)
 #define CLK_DATA_FLAG_NO_HW_REINIT              BIT(2)
 #define CLK_DATA_FLAG_BLOCK_FREQ_CHANGE         BIT(3)
+#define CLK_DATA_FLAG_ALLOW_SSC_CHANGE          BIT(4)
 
 #define CLK_FLAG_PWR_UP_EN                      ((u8) BIT(0))
 #define CLK_FLAG_PLL_BYPASS_FREQ                ((u8) BIT(1)) /* For PLLs */
@@ -87,6 +88,13 @@
 
 #define CLK_ID_NONE ((clk_idx_t) (0xFFFFFFFFU))
 
+struct ssc_data {
+	u32	modfreq_hz;
+	u32	mod_depth;
+	u8	spread_type;
+	u8	enable;
+};
+
 struct clk_range {
 	u32	min_hz;
 	u32	max_hz;
@@ -100,7 +108,6 @@ struct clk_default {
 
 struct clk {
 	u8	ref_count;
-	u8	ssc_block_count;
 	u8	freq_change_block_count;
 	u8	flags;
 };
@@ -205,6 +212,31 @@ struct clk_drv {
 	 */
 	s32 (*resume_restore)(struct clk *clkp);
 #endif
+
+#ifdef CONFIG_PM_CLK_SSC
+	/**
+	 * \brief Set the SSC state of a clock.
+	 *
+	 * \param clk The clock to modify
+	 * \param modfreq_hz The modulation frequency in Hz
+	 * \param mod_depth The modulation depth in "permyriad"
+	 * \param spread_type The spread type
+	 * \param enable True to enable, SFALSE to disable
+	 *
+	 * \return STRUE if the action succeeded
+	 */
+	s32 (*set_ssc)(struct clk *clkp, u32 modfreq_hz, u32 mod_depth, u8 spread_type, sbool enable);
+
+	/**
+	 * \brief Get the SSC state of a clock.
+	 *
+	 * \param clk The clock to query
+	 * \param ssc_datap The ssc data structure to populate
+	 *
+	 * \return STRUE if the clock has SSC enabled
+	 */
+	void (*get_ssc)(struct clk *clkp, struct ssc_data *ssc_datap);
+#endif
 };
 
 struct clk_data_reg {
@@ -332,8 +364,8 @@ u32 clk_get_state(struct clk *clkp);
 sbool clk_set_state(struct clk *clkp, sbool enable);
 sbool clk_get(struct clk *clkp);
 void clk_put(struct clk *clkp);
-void clk_ssc_allow(struct clk *clkp);
-void clk_ssc_block(struct clk *clkp);
+u32 clk_set_ssc(struct clk *clkp, u32 modfreq_hz, u32 mod_depth, u8 spread_type, sbool enable);
+u32 clk_get_ssc(struct clk *clkp, struct ssc_data *ssc_datap);
 void clk_freq_change_allow(struct clk *clkp);
 void clk_freq_change_block(struct clk *clkp);
 
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/device.h b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/device.h
index 4143a037..bf7c7d77 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/device.h
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/device.h
@@ -58,7 +58,6 @@
  * clock.
  */
 #define DEV_CLK_FLAG_DISABLE            BIT(0)
-#define DEV_CLK_FLAG_ALLOW_SSC          BIT(1)
 #define DEV_CLK_FLAG_ALLOW_FREQ_CHANGE  BIT(2)
 #define DEV_CLK_FLAG_INPUT_TERM         BIT(3)
 
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/device_clk.h b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/device_clk.h
index 19d2f9de..112138cc 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/device_clk.h
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/include/device_clk.h
@@ -84,6 +84,8 @@
 
 struct device;
 
+struct ssc_data;
+
 /**
  * \brief Const clock device data
  *
@@ -280,11 +282,10 @@ sbool device_clk_get_hw_ready(struct device *dev, dev_clk_idx_t clk_idx);
 sbool device_clk_get_sw_gated(struct device *dev, dev_clk_idx_t clk_idx);
 
 /**
- * \brief Allow or block SSC (Spread Spectrum Clocking)
+ * \brief Set the SSC for a device's clock
  *
- * This allows or blocks SSC operation for this clock while it is running.
- * If all clocks downsteam from a PLL are either disabled and/or allow SSC,
- * SSC will be enabled for that PLL.
+ * This locates the correct clock and calls the internal clock API
+ * set function. Configures the SSC on the PLL.
  *
  * \param dev
  * The device ID that the clock is connected to.
@@ -292,31 +293,34 @@ sbool device_clk_get_sw_gated(struct device *dev, dev_clk_idx_t clk_idx);
  * \param clk_idx
  * The index of the clock on this device.
  *
- * \param allow
- * True to allow SSC, SFALSE to block SSC while the clock is enabled.
- */
-void device_clk_set_ssc(struct device *dev, dev_clk_idx_t clk_idx, sbool allow);
-
-/**
- * \brief Get the current state of the SSC flag for this device clock.
+ * \param mod_freq_hz
+ * The desired modulation frequency in Hz. The modulation period is the time
+ * required to cycle the clock nominal frequency from an initial value through
+ * all the different values along the modulation profile and back to the
+ * initial value. The modulation frequency is the inverse of the period. The
+ * minimum allowable frequency is 32 kHz and maximum is fREFCLK / 200. For
+ * example, if the fREFCLK is 25 MHz, the maximum allowable modulation
+ * frequency would be 125 kHz.
  *
- * \param dev
- * The device ID that the clock is connected to.
+ * \param mod_depth
+ * The target modulation depth in "permyriad". The modulation depth refers to
+ * the maximum variation in frequency as a percentage of the clock center
+ * frequency. The minimum modulation depth is 0.1% and the maximum is 3.1%.
+ * Modulation depth can be adjusted in 0.1% increments.
  *
- * \param clk_idx
- * The index of the clock on this device.
+ * \param spread_type
+ * The target spread type. Both center and down spread are supported.
+ *
+ * \param enable
+ * Enable or Disable SSC
  *
  * \return
- * True if SSC is allowed for this clock, SFALSE if SSC is blocked.
+ * True if the new SSC configuration was accepted, SFALSE otherwise.
  */
-sbool device_clk_get_ssc(struct device *dev, dev_clk_idx_t clk_idx);
+sbool device_clk_set_ssc(struct device *dev, dev_clk_idx_t clk_idx, u32 modfreq_hz, u32 mod_depth, u8 spread_type, sbool enable);
 
 /**
- * \brief Get the current SSC state of this clock.
- *
- * Although the device clock can allow SSC, SSC is not actually enabled unless
- * it is allowed by all other users of the PLL. This call can be used to
- * determine if SSC has actually been activated.
+ * \brief Get the current SSC configuration of a device clock.
  *
  * \param dev
  * The device ID that the clock is connected to.
@@ -324,10 +328,13 @@ sbool device_clk_get_ssc(struct device *dev, dev_clk_idx_t clk_idx);
  * \param clk_idx
  * The index of the clock on this device.
  *
+ * \param ssc_data
+ * The current SSC configuration of the clock.
+ *
  * \return
- * True if SSC is active.
+ * True if the SSC configuration was found, SFALSE otherwise.
  */
-sbool device_clk_get_hw_ssc(struct device *dev, dev_clk_idx_t clk_idx);
+sbool device_clk_get_ssc(struct device *dev, dev_clk_idx_t clk_idx, struct ssc_data *ssc_datap);
 
 /**
  * \brief Allow or block frequency changes.
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/pm.h b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/pm.h
index e6379c8d..47042349 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/pm.h
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/pm.h
@@ -119,6 +119,26 @@ s32 query_freq_handler(u32 *msg_recv);
  */
 s32 get_freq_handler(u32 *msg_recv);
 
+/**
+ *  \brief  Set clock SSC Handler PM Function.
+ *
+ *  \param  msg_recv Pointer to the recieved and returned message. Same buffer
+ *                   used.
+ *  \return ret      SUCCESS if the API executed successfully.
+ *                   EFAIL   if the API failed to execute.
+ */
+s32 set_ssc_handler(u32 *msg_recv);
+
+/**
+ *  \brief  Get clock SSC Handler PM Function.
+ *
+ *  \param  msg_recv Pointer to the recieved and returned message. Same buffer
+ *                   used.
+ *  \return ret      SUCCESS if the API executed successfully.
+ *                   EFAIL   if the API failed to execute.
+ */
+s32 get_ssc_handler(u32 *msg_recv);
+
 /**
  *  \brief  Set Device State Handler PM Function.
  *
@@ -139,6 +159,16 @@ s32 set_device_handler(u32 *msg_recv);
  */
 s32 get_device_handler(u32 *msg_recv);
 
+/**
+ *  \brief  Get Multiple Device States Handler PM Function.
+ *
+ *  \param  msg_recv Pointer to the recieved and returned message. Same buffer
+ *                   used.
+ *  \return ret      SUCCESS if the API executed successfully.
+ *                   EFAIL   if the API failed to execute.
+ */
+s32 get_device_multiple_handler(u32 *msg_recv);
+
 /**
  *  \brief  Set Device Resets Handler PM Function.
  *
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/soc/am62ax/clocks.c b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/soc/am62ax/clocks.c
index 086b1f05..91ded4e1 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/soc/am62ax/clocks.c
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/rm_pm_hal/rm_pm_hal_src/pm/soc/am62ax/clocks.c
@@ -3722,7 +3722,7 @@ const struct clk_data soc_clock_data[260] = {
 		.drv		= &clk_drv_pll_16fft,
 		.freq_idx	= AM62AX_FREQ_VALUE_PLLFRACF2_SSMOD_16FFT_MAIN_17,
 		.data		= &clk_data_pllfracf2_ssmod_16fft_main_17.data_pll.data,
-		.flags		= 0,
+		.flags		= CLK_DATA_FLAG_ALLOW_SSC_CHANGE,
 	},
 	[CLK_AM62AX_PLLFRACF2_SSMOD_16FFT_MAIN_2_FOUTVCOP_CLK] =				{
 		.parent		=								{
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciclient_direct/makefile.am62ax.r5f.ti-arm-clang b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciclient_direct/makefile.am62ax.r5f.ti-arm-clang
index 38381610..8777321b 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciclient_direct/makefile.am62ax.r5f.ti-arm-clang
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciclient_direct/makefile.am62ax.r5f.ti-arm-clang
@@ -61,6 +61,7 @@ DEFINES_common := \
     -DCONFIG_CLOCK \
     -DCONFIG_CLK_PLL_16FFT \
     -DCONFIG_CLK_PLL_16FFT_FRACF_CALIBRATION \
+    -DCONFIG_PM_CLK_SSC \
     -DCONFIG_DM_BUILD \
     -DCONFIG_RM \
     -DCONFIG_RM_IRQ \
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciclient_direct/sciclient_direct.c b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciclient_direct/sciclient_direct.c
index 2b200e7a..13ef46d9 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciclient_direct/sciclient_direct.c
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciclient_direct/sciclient_direct.c
@@ -45,7 +45,8 @@
 #include <string.h>
 //#include <ti/osal/osal.h>
 #include<kernel/dpl/CacheP.h>
-#include <drivers/sciclient/include/tisci/tisci_protocol.h>
+#include <drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/tisci_protocol.h>
+#include <drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/pm/tisci_pm_clock.h>
 #include <boardcfg/boardcfg.h>
 #include <startup.h>
 #include <pm.h>
@@ -280,6 +281,10 @@ int32_t Sciclient_service (const Sciclient_ReqPrm_t *pReqPrm,
             case TISCI_MSG_SET_CLOCK_PARENT:
             case TISCI_MSG_GET_CLOCK_PARENT:
             case TISCI_MSG_GET_NUM_CLOCK_PARENTS:
+#ifdef CONFIG_PM_CLK_SSC
+            case TISCI_MSG_SET_CLOCK_SSC:
+            case TISCI_MSG_GET_CLOCK_SSC:
+#endif
             case TISCI_MSG_SET_FREQ:
             case TISCI_MSG_QUERY_FREQ:
             case TISCI_MSG_GET_FREQ:
@@ -714,6 +719,12 @@ int32_t Sciclient_ProcessPmMessage(const uint32_t reqFlags, void *tx_msg)
             ret = get_clock_parent_handler((uint32_t*)tx_msg); break;
         case TISCI_MSG_GET_NUM_CLOCK_PARENTS   :
             ret = get_num_clock_parents_handler((uint32_t*)tx_msg); break;
+#ifdef CONFIG_PM_CLK_SSC
+        case TISCI_MSG_SET_CLOCK_SSC           :
+            ret = set_ssc_handler((uint32_t*)tx_msg); break;
+        case TISCI_MSG_GET_CLOCK_SSC           :
+            ret = get_ssc_handler((uint32_t*)tx_msg); break;
+#endif
         case TISCI_MSG_SET_FREQ                :
             ret = set_freq_handler((uint32_t*)tx_msg); break;
         case TISCI_MSG_QUERY_FREQ              :
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciserver/makefile.am62ax.r5f.ti-arm-clang b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciserver/makefile.am62ax.r5f.ti-arm-clang
index 1c477d82..20f8dadd 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciserver/makefile.am62ax.r5f.ti-arm-clang
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciserver/makefile.am62ax.r5f.ti-arm-clang
@@ -49,6 +49,7 @@ DEFINES_common := \
     -DBUILD_DM_R5 \
     -DBUILD_MCU1_0 \
     -DBUILD_MCU \
+    -DCONFIG_PM_CLK_SSC \
     -DCONFIG_LPM_DM \
     -DCONFIG_OSAL_MINIMAL_QUEUES \
     -DMAKEFILE_BUILD \
diff --git a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciserver/sciserver.c b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciserver/sciserver.c
index f97f1529..56d2300b 100644
--- a/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciserver/sciserver.c
+++ b/mcu_plus_sdk_am62ax_11_01_00_16/source/drivers/device_manager/sciserver/sciserver.c
@@ -44,6 +44,8 @@
 #include <drivers/hw_include/csl_types.h>
 #include <drivers/hw_include/hw_types.h>
 #include <drivers/sciclient/csl_sec_proxy.h>
+#include <drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/tisci_protocol.h>
+#include <drivers/device_manager/rm_pm_hal/rm_pm_hal_src/include/tisci/pm/tisci_pm_clock.h>
 #include <drivers/device_manager/sciserver.h>
 #include <sciserver_secproxyConfigData.h>
 #include <sciserver_secproxyTransfer.h>
@@ -564,6 +566,16 @@ static int32_t Sciserver_UserProcessMsg(uint32_t *msg_recv,
             reqMsgSize = sizeof(struct tisci_msg_get_freq_req);
             respMsgSize = sizeof(struct tisci_msg_get_freq_resp);
             break;
+#ifdef CONFIG_PM_CLK_SSC
+        case TISCI_MSG_SET_CLOCK_SSC:
+            reqMsgSize = sizeof(struct tisci_msg_set_clock_ssc_req);
+            respMsgSize = sizeof(struct tisci_msg_set_clock_ssc_resp);
+            break;
+        case TISCI_MSG_GET_CLOCK_SSC:
+            reqMsgSize = sizeof(struct tisci_msg_get_clock_ssc_req);
+            respMsgSize = sizeof(struct tisci_msg_get_clock_ssc_resp);
+            break;
+#endif
         case TISCI_MSG_SET_DEVICE:
             reqMsgSize = sizeof(struct tisci_msg_set_device_req);
             respMsgSize = sizeof(struct tisci_msg_set_device_resp);
-- 
2.54.0

