u16 infra_gfx_maxfreq; /* in MHz */
        u16 skin_temp; /* in centi-Celsius */
        u16 device_state;
+       u16 curtemp; /* in centi-Celsius */
+       u16 filter_alpha_value;
+       u16 avg_gfx_clkfrequency;
+       u16 avg_fclk_frequency;
+       u16 avg_gfx_activity;
+       u16 avg_socclk_frequency;
+       u16 avg_vclk_frequency;
+       u16 avg_vcn_activity;
+       u16 avg_dram_reads;
+       u16 avg_dram_writes;
+       u16 avg_socket_power;
+       u16 avg_core_power[2];
+       u16 avg_core_c0residency[16];
+       u16 spare1;
+       u32 metrics_counter;
 } __packed;
 
 enum amd_stt_skin_temp {
 int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev);
 void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev);
 int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev);
+
+/* Smart PC - TA interfaces */
+void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in);
 #endif /* PMF_H */
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD Platform Management Framework Driver - Smart PC Capabilities
+ *
+ * Copyright (c) 2023, Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+ *          Patil Rajesh Reddy <Patil.Reddy@amd.com>
+ */
+
+#include <acpi/button.h>
+#include <linux/power_supply.h>
+#include <linux/units.h>
+#include "pmf.h"
+
+static void amd_pmf_get_smu_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
+{
+       u16 max, avg = 0;
+       int i;
+
+       memset(dev->buf, 0, sizeof(dev->m_table));
+       amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, 0, 7, NULL);
+       memcpy(&dev->m_table, dev->buf, sizeof(dev->m_table));
+
+       in->ev_info.socket_power = dev->m_table.apu_power + dev->m_table.dgpu_power;
+       in->ev_info.skin_temperature = dev->m_table.skin_temp;
+
+       /* Get the avg and max C0 residency of all the cores */
+       max = dev->m_table.avg_core_c0residency[0];
+       for (i = 0; i < ARRAY_SIZE(dev->m_table.avg_core_c0residency); i++) {
+               avg += dev->m_table.avg_core_c0residency[i];
+               if (dev->m_table.avg_core_c0residency[i] > max)
+                       max = dev->m_table.avg_core_c0residency[i];
+       }
+
+       avg = DIV_ROUND_CLOSEST(avg, ARRAY_SIZE(dev->m_table.avg_core_c0residency));
+       in->ev_info.avg_c0residency = avg;
+       in->ev_info.max_c0residency = max;
+       in->ev_info.gfx_busy = dev->m_table.avg_gfx_activity;
+}
+
+static const char * const pmf_battery_supply_name[] = {
+       "BATT",
+       "BAT0",
+};
+
+static int amd_pmf_get_battery_prop(enum power_supply_property prop)
+{
+       union power_supply_propval value;
+       struct power_supply *psy;
+       int i, ret;
+
+       for (i = 0; i < ARRAY_SIZE(pmf_battery_supply_name); i++) {
+               psy = power_supply_get_by_name(pmf_battery_supply_name[i]);
+               if (!psy)
+                       continue;
+
+               ret = power_supply_get_property(psy, prop, &value);
+               if (ret) {
+                       power_supply_put(psy);
+                       return ret;
+               }
+       }
+
+       return value.intval;
+}
+
+static int amd_pmf_get_battery_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
+{
+       int val;
+
+       val = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_PRESENT);
+       if (val < 0)
+               return val;
+       if (val != 1)
+               return -ENODEV;
+
+       in->ev_info.bat_percentage = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_CAPACITY);
+       /* all values in mWh metrics */
+       in->ev_info.bat_design = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN) /
+               MILLIWATT_PER_WATT;
+       in->ev_info.full_charge_capacity = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_ENERGY_FULL) /
+               MILLIWATT_PER_WATT;
+       in->ev_info.drain_rate = amd_pmf_get_battery_prop(POWER_SUPPLY_PROP_POWER_NOW) /
+               MILLIWATT_PER_WATT;
+
+       return 0;
+}
+
+static int amd_pmf_get_slider_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
+{
+       int val;
+
+       switch (dev->current_profile) {
+       case PLATFORM_PROFILE_PERFORMANCE:
+               val = TA_BEST_PERFORMANCE;
+               break;
+       case PLATFORM_PROFILE_BALANCED:
+               val = TA_BETTER_PERFORMANCE;
+               break;
+       case PLATFORM_PROFILE_LOW_POWER:
+               val = TA_BEST_BATTERY;
+               break;
+       default:
+               dev_err(dev->dev, "Unknown Platform Profile.\n");
+               return -EOPNOTSUPP;
+       }
+       in->ev_info.power_slider = val;
+
+       return 0;
+}
+
+void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
+{
+       /* TA side lid open is 1 and close is 0, hence the ! here */
+       in->ev_info.lid_state = !acpi_lid_open();
+       in->ev_info.power_source = amd_pmf_get_power_source();
+       amd_pmf_get_smu_info(dev, in);
+       amd_pmf_get_battery_info(dev, in);
+       amd_pmf_get_slider_info(dev, in);
+}
 
 {
        struct ta_pmf_shared_memory *ta_sm = NULL;
        struct ta_pmf_enact_result *out = NULL;
+       struct ta_pmf_enact_table *in = NULL;
        struct tee_param param[MAX_TEE_PARAM];
        struct tee_ioctl_invoke_arg arg;
        int ret = 0;
        memset(dev->shbuf, 0, dev->policy_sz);
        ta_sm = dev->shbuf;
        out = &ta_sm->pmf_output.policy_apply_table;
+       in = &ta_sm->pmf_input.enact_table;
 
        memset(ta_sm, 0, sizeof(*ta_sm));
        ta_sm->command_id = TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES;
        ta_sm->if_version = PMF_TA_IF_VERSION_MAJOR;
 
+       amd_pmf_populate_ta_inputs(dev, in);
        amd_pmf_prepare_args(dev, TA_PMF_COMMAND_POLICY_BUILDER_ENACT_POLICIES, &arg, param);
 
        ret = tee_client_invoke_func(dev->tee_ctx, &arg, param);