Skip to content

Commit 33c9ab5

Browse files
Shyam Sundar S Kjwrdegoede
authored andcommitted
platform/x86/amd/pmf: Notify OS power slider update
APMF fn8 can notify EC about the OS slider position change. Add this capability to the PMF driver so that it can call the APMF fn8 based on the changes in the Platform profile events. Co-developed-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Patil Rajesh Reddy <Patil.Reddy@amd.com> Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Link: https://lore.kernel.org/r/20230714144435.1239776-2-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
1 parent 839e90e commit 33c9ab5

File tree

4 files changed

+114
-6
lines changed

4 files changed

+114
-6
lines changed

drivers/platform/x86/amd/pmf/acpi.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,27 @@ int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev,
106106
data, sizeof(*data));
107107
}
108108

109+
int apmf_os_power_slider_update(struct amd_pmf_dev *pdev, u8 event)
110+
{
111+
struct os_power_slider args;
112+
struct acpi_buffer params;
113+
union acpi_object *info;
114+
int err = 0;
115+
116+
args.size = sizeof(args);
117+
args.slider_event = event;
118+
119+
params.length = sizeof(args);
120+
params.pointer = (void *)&args;
121+
122+
info = apmf_if_call(pdev, APMF_FUNC_OS_POWER_SLIDER_UPDATE, &params);
123+
if (!info)
124+
err = -EIO;
125+
126+
kfree(info);
127+
return err;
128+
}
129+
109130
static void apmf_sbios_heartbeat_notify(struct work_struct *work)
110131
{
111132
struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, heart_beat.work);

drivers/platform/x86/amd/pmf/core.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long
7272
return NOTIFY_DONE;
7373
}
7474

75-
amd_pmf_set_sps_power_limits(pmf);
75+
if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR))
76+
amd_pmf_set_sps_power_limits(pmf);
77+
78+
if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE))
79+
amd_pmf_power_slider_update_event(pmf);
7680

7781
return NOTIFY_OK;
7882
}
@@ -297,7 +301,8 @@ static void amd_pmf_init_features(struct amd_pmf_dev *dev)
297301
int ret;
298302

299303
/* Enable Static Slider */
300-
if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) {
304+
if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR) ||
305+
is_apmf_func_supported(dev, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) {
301306
amd_pmf_init_sps(dev);
302307
dev->pwr_src_notifier.notifier_call = amd_pmf_pwr_src_notify_call;
303308
power_supply_reg_notifier(&dev->pwr_src_notifier);

drivers/platform/x86/amd/pmf/pmf.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define APMF_FUNC_SBIOS_HEARTBEAT 4
2222
#define APMF_FUNC_AUTO_MODE 5
2323
#define APMF_FUNC_SET_FAN_IDX 7
24+
#define APMF_FUNC_OS_POWER_SLIDER_UPDATE 8
2425
#define APMF_FUNC_STATIC_SLIDER_GRANULAR 9
2526
#define APMF_FUNC_DYN_SLIDER_AC 11
2627
#define APMF_FUNC_DYN_SLIDER_DC 12
@@ -44,6 +45,14 @@
4445
#define GET_STT_LIMIT_APU 0x20
4546
#define GET_STT_LIMIT_HS2 0x21
4647

48+
/* OS slider update notification */
49+
#define DC_BEST_PERF 0
50+
#define DC_BETTER_PERF 1
51+
#define DC_BATTERY_SAVER 3
52+
#define AC_BEST_PERF 4
53+
#define AC_BETTER_PERF 5
54+
#define AC_BETTER_BATTERY 6
55+
4756
/* Fan Index for Auto Mode */
4857
#define FAN_INDEX_AUTO 0xFFFFFFFF
4958

@@ -193,6 +202,11 @@ struct amd_pmf_static_slider_granular {
193202
struct apmf_sps_prop_granular prop[POWER_SOURCE_MAX][POWER_MODE_MAX];
194203
};
195204

205+
struct os_power_slider {
206+
u16 size;
207+
u8 slider_event;
208+
} __packed;
209+
196210
struct fan_table_control {
197211
bool manual;
198212
unsigned long fan_id;
@@ -383,6 +397,7 @@ int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32
383397
int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev);
384398
int amd_pmf_get_power_source(void);
385399
int apmf_install_handler(struct amd_pmf_dev *pmf_dev);
400+
int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag);
386401

387402
/* SPS Layer */
388403
int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf);
@@ -393,6 +408,7 @@ void amd_pmf_deinit_sps(struct amd_pmf_dev *dev);
393408
int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev,
394409
struct apmf_static_slider_granular_output *output);
395410
bool is_pprof_balanced(struct amd_pmf_dev *pmf);
411+
int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev);
396412

397413

398414
int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx);

drivers/platform/x86/amd/pmf/sps.c

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,25 +174,91 @@ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf)
174174
return mode;
175175
}
176176

177+
int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev)
178+
{
179+
u8 mode, flag = 0;
180+
int src;
181+
182+
mode = amd_pmf_get_pprof_modes(dev);
183+
if (mode < 0)
184+
return mode;
185+
186+
src = amd_pmf_get_power_source();
187+
188+
if (src == POWER_SOURCE_AC) {
189+
switch (mode) {
190+
case POWER_MODE_PERFORMANCE:
191+
flag |= BIT(AC_BEST_PERF);
192+
break;
193+
case POWER_MODE_BALANCED_POWER:
194+
flag |= BIT(AC_BETTER_PERF);
195+
break;
196+
case POWER_MODE_POWER_SAVER:
197+
flag |= BIT(AC_BETTER_BATTERY);
198+
break;
199+
default:
200+
dev_err(dev->dev, "unsupported platform profile\n");
201+
return -EOPNOTSUPP;
202+
}
203+
204+
} else if (src == POWER_SOURCE_DC) {
205+
switch (mode) {
206+
case POWER_MODE_PERFORMANCE:
207+
flag |= BIT(DC_BEST_PERF);
208+
break;
209+
case POWER_MODE_BALANCED_POWER:
210+
flag |= BIT(DC_BETTER_PERF);
211+
break;
212+
case POWER_MODE_POWER_SAVER:
213+
flag |= BIT(DC_BATTERY_SAVER);
214+
break;
215+
default:
216+
dev_err(dev->dev, "unsupported platform profile\n");
217+
return -EOPNOTSUPP;
218+
}
219+
}
220+
221+
apmf_os_power_slider_update(dev, flag);
222+
223+
return 0;
224+
}
225+
177226
static int amd_pmf_profile_set(struct platform_profile_handler *pprof,
178227
enum platform_profile_option profile)
179228
{
180229
struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof);
230+
int ret = 0;
181231

182232
pmf->current_profile = profile;
183233

184-
return amd_pmf_set_sps_power_limits(pmf);
234+
/* Notify EC about the slider position change */
235+
if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) {
236+
ret = amd_pmf_power_slider_update_event(pmf);
237+
if (ret)
238+
return ret;
239+
}
240+
241+
if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR)) {
242+
ret = amd_pmf_set_sps_power_limits(pmf);
243+
if (ret)
244+
return ret;
245+
}
246+
247+
return 0;
185248
}
186249

187250
int amd_pmf_init_sps(struct amd_pmf_dev *dev)
188251
{
189252
int err;
190253

191254
dev->current_profile = PLATFORM_PROFILE_BALANCED;
192-
amd_pmf_load_defaults_sps(dev);
193255

194-
/* update SPS balanced power mode thermals */
195-
amd_pmf_set_sps_power_limits(dev);
256+
if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) {
257+
amd_pmf_load_defaults_sps(dev);
258+
259+
/* update SPS balanced power mode thermals */
260+
amd_pmf_set_sps_power_limits(dev);
261+
}
196262

197263
dev->pprof.profile_get = amd_pmf_profile_get;
198264
dev->pprof.profile_set = amd_pmf_profile_set;

0 commit comments

Comments
 (0)