diff --git a/drivers/power/meson.build b/drivers/power/meson.build
index 7d9034c7ac..0803e99027 100644
--- a/drivers/power/meson.build
+++ b/drivers/power/meson.build
@@ -3,6 +3,7 @@
 
 drivers = [
         'core',
+        'uncore',
 ]
 
 std_deps = ['power']
diff --git a/drivers/power/uncore/intel/meson.build b/drivers/power/uncore/intel/meson.build
new file mode 100644
index 0000000000..187ab15aec
--- /dev/null
+++ b/drivers/power/uncore/intel/meson.build
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2017 Intel Corporation
+# Copyright(c) 2024 AMD Limited
+
+sources = files('power_intel_uncore.c')
+
+headers = files('power_intel_uncore.h')
+
+deps += ['power']
diff --git a/lib/power/power_intel_uncore.c b/drivers/power/uncore/intel/power_intel_uncore.c
similarity index 95%
rename from lib/power/power_intel_uncore.c
rename to drivers/power/uncore/intel/power_intel_uncore.c
index 3ce8fccec2..3af4cc3bc7 100644
--- a/lib/power/power_intel_uncore.c
+++ b/drivers/power/uncore/intel/power_intel_uncore.c
@@ -476,3 +476,18 @@ power_intel_uncore_get_num_dies(unsigned int pkg)
 
 	return count;
 }
+
+static struct rte_power_uncore_ops intel_uncore_ops = {
+	.init = power_intel_uncore_init,
+	.exit = power_intel_uncore_exit,
+	.get_avail_freqs = power_intel_uncore_freqs,
+	.get_num_pkgs = power_intel_uncore_get_num_pkgs,
+	.get_num_dies = power_intel_uncore_get_num_dies,
+	.get_num_freqs = power_intel_uncore_get_num_freqs,
+	.get_freq = power_get_intel_uncore_freq,
+	.set_freq = power_set_intel_uncore_freq,
+	.freq_max = power_intel_uncore_freq_max,
+	.freq_min = power_intel_uncore_freq_min,
+};
+
+RTE_POWER_REGISTER_UNCORE_OPS(intel_uncore_ops);
diff --git a/lib/power/power_intel_uncore.h b/drivers/power/uncore/intel/power_intel_uncore.h
similarity index 100%
rename from lib/power/power_intel_uncore.h
rename to drivers/power/uncore/intel/power_intel_uncore.h
diff --git a/drivers/power/uncore/meson.build b/drivers/power/uncore/meson.build
new file mode 100644
index 0000000000..005c0dc622
--- /dev/null
+++ b/drivers/power/uncore/meson.build
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2024 AMD Limited
+
+drivers = [
+        'intel',
+]
+
+std_deps = ['power']
diff --git a/lib/power/meson.build b/lib/power/meson.build
index 207d96d877..459e9b6e9b 100644
--- a/lib/power/meson.build
+++ b/lib/power/meson.build
@@ -13,7 +13,6 @@ if not is_linux
 endif
 sources = files(
         'power_common.c',
-        'power_intel_uncore.c',
         'rte_power.c',
         'rte_power_uncore.c',
         'rte_power_pmd_mgmt.c',
diff --git a/lib/power/rte_power_uncore.c b/lib/power/rte_power_uncore.c
index 48c75a5da0..8feb41736b 100644
--- a/lib/power/rte_power_uncore.c
+++ b/lib/power/rte_power_uncore.c
@@ -15,88 +15,68 @@
 enum rte_uncore_power_mgmt_env default_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET;
 
 static rte_spinlock_t global_env_cfg_lock = RTE_SPINLOCK_INITIALIZER;
+static struct rte_power_uncore_ops rte_power_uncore_ops[PM_ENV_MAX];
 
-static uint32_t
-power_get_dummy_uncore_freq(unsigned int pkg __rte_unused,
-	       unsigned int die __rte_unused)
-{
-	return 0;
-}
-
-static int
-power_set_dummy_uncore_freq(unsigned int pkg __rte_unused,
-	       unsigned int die __rte_unused, uint32_t index __rte_unused)
-{
-	return 0;
-}
-
-static int
-power_dummy_uncore_freq_max(unsigned int pkg __rte_unused,
-	       unsigned int die __rte_unused)
-{
-	return 0;
-}
 
-static int
-power_dummy_uncore_freq_min(unsigned int pkg __rte_unused,
-	       unsigned int die __rte_unused)
+/* register the ops struct in rte_power_uncore_ops, return 0 on success. */
+int
+rte_power_register_uncore_ops(const struct rte_power_uncore_ops *op)
 {
-	return 0;
-}
+	struct rte_power_uncore_ops *ops;
+
+	if ((op->env != RTE_UNCORE_PM_ENV_INTEL_UNCORE) &&
+		(op->env != RTE_UNCORE_PM_ENV_AMD_HSMP)) {
+		POWER_LOG(ERR,
+			"Unsupported uncore power management environment\n");
+			return -EINVAL;
+		return -EINVAL;
+	}
 
-static int
-power_dummy_uncore_freqs(unsigned int pkg __rte_unused, unsigned int die __rte_unused,
-		uint32_t *freqs __rte_unused, uint32_t num __rte_unused)
-{
-	return 0;
-}
+	if (op->status != 0) {
+		POWER_LOG(ERR,
+			"uncore Power management env[%d] ops registered already\n",
+			op->env);
+		return -EINVAL;
+	}
 
-static int
-power_dummy_uncore_get_num_freqs(unsigned int pkg __rte_unused,
-	       unsigned int die __rte_unused)
-{
-	return 0;
-}
+	if (!op->init || !op->exit || !op->get_num_pkgs || !op->get_num_dies ||
+		!op->get_num_freqs || !op->get_avail_freqs || !op->get_freq ||
+		!op->set_freq || !op->freq_max || !op->freq_min) {
+		POWER_LOG(ERR, "Missing callbacks while registering power ops\n");
+		return -EINVAL;
+	}
+	ops = &rte_power_uncore_ops[op->env];
+	ops->env = op->env;
+	ops->init = op->init;
+	ops->exit = op->exit;
+	ops->get_num_pkgs = op->get_num_pkgs;
+	ops->get_num_dies = op->get_num_dies;
+	ops->get_num_freqs = op->get_num_freqs;
+	ops->get_avail_freqs = op->get_avail_freqs;
+	ops->get_freq = op->get_freq;
+	ops->set_freq = op->set_freq;
+	ops->freq_max = op->freq_max;
+	ops->freq_min = op->freq_min;
+	ops->status = 1; /* registered */
 
-static unsigned int
-power_dummy_uncore_get_num_pkgs(void)
-{
 	return 0;
 }
 
-static unsigned int
-power_dummy_uncore_get_num_dies(unsigned int pkg __rte_unused)
+struct rte_power_uncore_ops *
+rte_power_get_uncore_ops(int ops_index)
 {
-	return 0;
-}
+	RTE_VERIFY((ops_index != RTE_UNCORE_PM_ENV_INTEL_UNCORE) &&
+			(ops_index != RTE_UNCORE_PM_ENV_AMD_HSMP));
+	RTE_VERIFY(rte_power_uncore_ops[ops_index].status != 0);
 
-/* function pointers */
-rte_power_get_uncore_freq_t rte_power_get_uncore_freq = power_get_dummy_uncore_freq;
-rte_power_set_uncore_freq_t rte_power_set_uncore_freq = power_set_dummy_uncore_freq;
-rte_power_uncore_freq_change_t rte_power_uncore_freq_max = power_dummy_uncore_freq_max;
-rte_power_uncore_freq_change_t rte_power_uncore_freq_min = power_dummy_uncore_freq_min;
-rte_power_uncore_freqs_t rte_power_uncore_freqs = power_dummy_uncore_freqs;
-rte_power_uncore_get_num_freqs_t rte_power_uncore_get_num_freqs = power_dummy_uncore_get_num_freqs;
-rte_power_uncore_get_num_pkgs_t rte_power_uncore_get_num_pkgs = power_dummy_uncore_get_num_pkgs;
-rte_power_uncore_get_num_dies_t rte_power_uncore_get_num_dies = power_dummy_uncore_get_num_dies;
-
-static void
-reset_power_uncore_function_ptrs(void)
-{
-	rte_power_get_uncore_freq = power_get_dummy_uncore_freq;
-	rte_power_set_uncore_freq = power_set_dummy_uncore_freq;
-	rte_power_uncore_freq_max = power_dummy_uncore_freq_max;
-	rte_power_uncore_freq_min = power_dummy_uncore_freq_min;
-	rte_power_uncore_freqs  = power_dummy_uncore_freqs;
-	rte_power_uncore_get_num_freqs = power_dummy_uncore_get_num_freqs;
-	rte_power_uncore_get_num_pkgs = power_dummy_uncore_get_num_pkgs;
-	rte_power_uncore_get_num_dies = power_dummy_uncore_get_num_dies;
+	return &rte_power_uncore_ops[ops_index];
 }
 
 int
 rte_power_set_uncore_env(enum rte_uncore_power_mgmt_env env)
 {
-	int ret;
+	int ret = 0;
+	struct rte_power_uncore_ops *ops;
 
 	rte_spinlock_lock(&global_env_cfg_lock);
 
@@ -113,24 +93,15 @@ rte_power_set_uncore_env(enum rte_uncore_power_mgmt_env env)
 		 */
 		env = RTE_UNCORE_PM_ENV_INTEL_UNCORE;
 
-	ret = 0;
-	if (env == RTE_UNCORE_PM_ENV_INTEL_UNCORE) {
-		rte_power_get_uncore_freq = power_get_intel_uncore_freq;
-		rte_power_set_uncore_freq = power_set_intel_uncore_freq;
-		rte_power_uncore_freq_min  = power_intel_uncore_freq_min;
-		rte_power_uncore_freq_max  = power_intel_uncore_freq_max;
-		rte_power_uncore_freqs = power_intel_uncore_freqs;
-		rte_power_uncore_get_num_freqs = power_intel_uncore_get_num_freqs;
-		rte_power_uncore_get_num_pkgs = power_intel_uncore_get_num_pkgs;
-		rte_power_uncore_get_num_dies = power_intel_uncore_get_num_dies;
-	} else {
+	}
+
+	ops = rte_power_get_uncore_ops(env);
+	if (ops->status == 0) {
 		POWER_LOG(ERR, "Invalid Power Management Environment(%d) set", env);
 		ret = -1;
-		goto out;
-	}
+	} else
+		default_uncore_env = env;
 
-	default_uncore_env = env;
-out:
 	rte_spinlock_unlock(&global_env_cfg_lock);
 	return ret;
 }
@@ -140,7 +111,6 @@ rte_power_unset_uncore_env(void)
 {
 	rte_spinlock_lock(&global_env_cfg_lock);
 	default_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET;
-	reset_power_uncore_function_ptrs();
 	rte_spinlock_unlock(&global_env_cfg_lock);
 }
 
@@ -154,18 +124,18 @@ int
 rte_power_uncore_init(unsigned int pkg, unsigned int die)
 {
 	int ret = -1;
+	struct rte_power_uncore_ops *ops;
 
-	switch (default_uncore_env) {
-	case RTE_UNCORE_PM_ENV_INTEL_UNCORE:
-		return power_intel_uncore_init(pkg, die);
-	default:
-		POWER_LOG(INFO, "Uncore Env isn't set yet!");
-		break;
+	if ((default_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) &&
+		(default_uncore_env != RTE_UNCORE_PM_ENV_AUTO_DETECT)) {
+		ops = rte_power_get_uncore_ops(default_uncore_env);
+		return ops->init(pkg, die);
 	}
 
 	/* Auto detect Environment */
 	POWER_LOG(INFO, "Attempting to initialise Intel Uncore power mgmt...");
-	ret = power_intel_uncore_init(pkg, die);
+	ops = rte_power_get_uncore_ops(RTE_UNCORE_PM_ENV_INTEL_UNCORE);
+	ret = ops->init(pkg, die);
 	if (ret == 0) {
 		rte_power_set_uncore_env(RTE_UNCORE_PM_ENV_INTEL_UNCORE);
 		goto out;
@@ -183,12 +153,13 @@ rte_power_uncore_init(unsigned int pkg, unsigned int die)
 int
 rte_power_uncore_exit(unsigned int pkg, unsigned int die)
 {
-	switch (default_uncore_env) {
-	case RTE_UNCORE_PM_ENV_INTEL_UNCORE:
-		return power_intel_uncore_exit(pkg, die);
-	default:
-		POWER_LOG(ERR, "Uncore Env has not been set, unable to exit gracefully");
-		break;
+	struct rte_power_uncore_ops *ops;
+
+	if (default_uncore_env == RTE_UNCORE_PM_ENV_NOT_SET) {
+		POWER_LOG(ERR,
+			"Uncore Env has not been set, unable to exit gracefully");
+		return -1;
 	}
-	return -1;
+	ops = rte_power_get_uncore_ops(default_uncore_env);
+	return ops->exit(pkg, die);
 }
diff --git a/lib/power/rte_power_uncore.h b/lib/power/rte_power_uncore.h
index 99859042dd..fe14a1bbe5 100644
--- a/lib/power/rte_power_uncore.h
+++ b/lib/power/rte_power_uncore.h
@@ -58,6 +58,81 @@ void rte_power_unset_uncore_env(void);
 __rte_experimental
 enum rte_uncore_power_mgmt_env rte_power_get_uncore_env(void);
 
+/**
+ * Function pointers for generic frequency change functions.
+ *
+ * @param pkg
+ *  Package number.
+ *  Each physical CPU in a system is referred to as a package.
+ * @param die
+ *  Die number.
+ *  Each package can have several dies connected together via the uncore mesh.
+ *
+ * @return
+ *  - 1 on success with frequency changed.
+ *  - 0 on success without frequency changed.
+ *  - Negative on error.
+ */
+typedef int (*rte_power_uncore_init_t)(unsigned int pkg, unsigned int die);
+typedef int (*rte_power_uncore_exit_t)(unsigned int pkg, unsigned int die);
+
+typedef uint32_t (*rte_power_get_uncore_freq_t)(unsigned int pkg, unsigned int die);
+typedef int (*rte_power_set_uncore_freq_t)(unsigned int pkg, unsigned int die, uint32_t index);
+typedef int (*rte_power_uncore_get_num_freqs_t)(unsigned int pkg, unsigned int die);
+typedef int (*rte_power_uncore_freqs_t)(unsigned int pkg, unsigned int die,
+					uint32_t *freqs, uint32_t num);
+typedef int (*rte_power_uncore_freq_change_t)(unsigned int pkg, unsigned int die);
+typedef unsigned int (*rte_power_uncore_get_num_pkgs_t)(void);
+typedef unsigned int (*rte_power_uncore_get_num_dies_t)(unsigned int pkg);
+
+/** Structure defining uncore power operations structure */
+struct rte_power_uncore_ops {
+	uint8_t status;                         /**< ops register status. */
+	enum rte_uncore_power_mgmt_env env;          /**< power mgmt env. */
+	rte_power_uncore_init_t init;    /**< Initialize power management. */
+	rte_power_uncore_exit_t exit;    /**< Exit power management. */
+	rte_power_uncore_get_num_pkgs_t get_num_pkgs;
+	rte_power_uncore_get_num_dies_t get_num_dies;
+	rte_power_uncore_get_num_freqs_t get_num_freqs; /**< Number of available frequencies. */
+	rte_power_uncore_freqs_t get_avail_freqs; /**< Get the available frequencies. */
+	rte_power_get_uncore_freq_t get_freq; /**< Get frequency index. */
+	rte_power_set_uncore_freq_t set_freq; /**< Set frequency index. */
+	rte_power_uncore_freq_change_t freq_max;  /**< Scale up frequency to highest. */
+	rte_power_uncore_freq_change_t freq_min;  /**< Scale up frequency to lowest. */
+} __rte_cache_aligned;
+
+
+/**
+ * Register power uncore frequency operations.
+ * @param ops
+ *   Pointer to an ops structure to register.
+ * @return
+ *   - >=0: Success; return the index of the ops struct in the table.
+ *   - -EINVAL - error while registering ops struct.
+ */
+__rte_internal
+int rte_power_register_uncore_ops(const struct rte_power_uncore_ops *ops);
+
+/**
+ * Macro to statically register the ops of an uncore driver.
+ */
+#define RTE_POWER_REGISTER_UNCORE_OPS(ops)		\
+	(RTE_INIT(power_hdlr_init_uncore_##ops)         \
+	{                                               \
+		rte_power_register_uncore_ops(&ops);    \
+	})
+
+/**
+ * @internal Get the power uncore ops struct from its index.
+ *
+ * @param ops_index
+ *   The index of the ops struct in the ops struct table.
+ * @return
+ *   The pointer to the ops struct in the table if registered.
+ */
+struct rte_power_uncore_ops *
+rte_power_get_uncore_ops(int ops_index);
+
 /**
  * Initialize uncore frequency management for specific die on a package.
  * It will get the available frequencies and prepare to set new die frequencies.
@@ -116,9 +191,14 @@ rte_power_uncore_exit(unsigned int pkg, unsigned int die);
  *  The current index of available frequencies.
  *  If error, it will return 'RTE_POWER_INVALID_FREQ_INDEX = (~0)'.
  */
-typedef uint32_t (*rte_power_get_uncore_freq_t)(unsigned int pkg, unsigned int die);
+static inline uint32_t
+rte_power_get_uncore_freq(unsigned int pkg, unsigned int die)
+{
+	struct rte_power_uncore_ops *ops;
 
-extern rte_power_get_uncore_freq_t rte_power_get_uncore_freq;
+	ops = rte_power_get_uncore_ops(rte_power_get_uncore_env());
+	return ops->get_freq(pkg, die);
+}
 
 /**
  * Set minimum and maximum uncore frequency for specified die on a package
@@ -141,9 +221,15 @@ extern rte_power_get_uncore_freq_t rte_power_get_uncore_freq;
  *  - 0 on success without frequency changed.
  *  - Negative on error.
  */
-typedef int (*rte_power_set_uncore_freq_t)(unsigned int pkg, unsigned int die, uint32_t index);
+static inline uint32_t
+rte_power_set_uncore_freq(unsigned int pkg, unsigned int die, uint32_t index)
+{
+	struct rte_power_uncore_ops *ops;
+
+	ops = rte_power_get_uncore_ops(rte_power_get_uncore_env());
+	return ops->set_freq(pkg, die, index);
+}
 
-extern rte_power_set_uncore_freq_t rte_power_set_uncore_freq;
 
 /**
  * Function pointer definition for generic frequency change functions.
@@ -169,7 +255,14 @@ typedef int (*rte_power_uncore_freq_change_t)(unsigned int pkg, unsigned int die
  *
  * This function should NOT be called in the fast path.
  */
-extern rte_power_uncore_freq_change_t rte_power_uncore_freq_max;
+static inline uint32_t
+rte_power_uncore_freq_max(unsigned int pkg, unsigned int die)
+{
+	struct rte_power_uncore_ops *ops;
+
+	ops = rte_power_get_uncore_ops(rte_power_get_uncore_env());
+	return ops->freq_max(pkg, die);
+}
 
 /**
  * Set minimum and maximum uncore frequency for specified die on a package
@@ -178,7 +271,14 @@ extern rte_power_uncore_freq_change_t rte_power_uncore_freq_max;
  *
  * This function should NOT be called in the fast path.
  */
-extern rte_power_uncore_freq_change_t rte_power_uncore_freq_min;
+static inline uint32_t
+rte_power_uncore_freq_min(unsigned int pkg, unsigned int die)
+{
+	struct rte_power_uncore_ops *ops;
+
+	ops = rte_power_get_uncore_ops(rte_power_get_uncore_env());
+	return ops->freq_min(pkg, die);
+}
 
 /**
  * Return the list of available frequencies in the index array.
@@ -200,10 +300,15 @@ extern rte_power_uncore_freq_change_t rte_power_uncore_freq_min;
  *  - The number of available index's in frequency array.
  *  - Negative on error.
  */
-typedef int (*rte_power_uncore_freqs_t)(unsigned int pkg, unsigned int die,
-		uint32_t *freqs, uint32_t num);
+static inline uint32_t
+rte_power_uncore_freqs(unsigned int pkg, unsigned int die,
+		uint32_t *freqs, uint32_t num)
+{
+	struct rte_power_uncore_ops *ops;
 
-extern rte_power_uncore_freqs_t rte_power_uncore_freqs;
+	ops = rte_power_get_uncore_ops(rte_power_get_uncore_env());
+	return ops->get_avail_freqs(pkg, die, freqs, num);
+}
 
 /**
  * Return the list length of available frequencies in the index array.
@@ -221,9 +326,14 @@ extern rte_power_uncore_freqs_t rte_power_uncore_freqs;
  *  - The number of available index's in frequency array.
  *  - Negative on error.
  */
-typedef int (*rte_power_uncore_get_num_freqs_t)(unsigned int pkg, unsigned int die);
+static inline int
+rte_power_uncore_get_num_freqs(unsigned int pkg, unsigned int die)
+{
+	struct rte_power_uncore_ops *ops;
 
-extern rte_power_uncore_get_num_freqs_t rte_power_uncore_get_num_freqs;
+	ops = rte_power_get_uncore_ops(rte_power_get_uncore_env());
+	return ops->get_num_freqs(pkg, die);
+}
 
 /**
  * Return the number of packages (CPUs) on a system
@@ -235,9 +345,14 @@ extern rte_power_uncore_get_num_freqs_t rte_power_uncore_get_num_freqs;
  *  - Zero on error.
  *  - Number of package on system on success.
  */
-typedef unsigned int (*rte_power_uncore_get_num_pkgs_t)(void);
+static inline unsigned int
+rte_power_uncore_get_num_pkgs(void)
+{
+	struct rte_power_uncore_ops *ops;
 
-extern rte_power_uncore_get_num_pkgs_t rte_power_uncore_get_num_pkgs;
+	ops = rte_power_get_uncore_ops(rte_power_get_uncore_env());
+	return ops->get_num_pkgs(void);
+}
 
 /**
  * Return the number of dies for pakckages (CPUs) specified
@@ -253,9 +368,14 @@ extern rte_power_uncore_get_num_pkgs_t rte_power_uncore_get_num_pkgs;
  *  - Zero on error.
  *  - Number of dies for package on sucecss.
  */
-typedef unsigned int (*rte_power_uncore_get_num_dies_t)(unsigned int pkg);
+static inline unsigned int
+rte_power_uncore_get_num_dies(unsigned int pkg)
+{
+	struct rte_power_uncore_ops *ops;
 
-extern rte_power_uncore_get_num_dies_t rte_power_uncore_get_num_dies;
+	ops = rte_power_get_uncore_ops(rte_power_get_uncore_env());
+	return ops->get_num_dies(pkg);
+}
 
 #ifdef __cplusplus
 }
diff --git a/lib/power/version.map b/lib/power/version.map
index 2f89645ec2..d8a6f9436c 100644
--- a/lib/power/version.map
+++ b/lib/power/version.map
@@ -57,6 +57,7 @@ INTERNAL {
        global:
 
        rte_power_register_ops;
+       rte_power_register_uncore_ops;
        cpufreq_check_scaling_driver;
        power_set_governor;
        open_core_sysfs_file;
