Add CPU power management tools and dynamic frequency scaling

- Add cpu-power-control.sh: Script for managing CPU power limits and presets
- Add monitor-cpu-freq.sh: Real-time CPU frequency monitoring tool
- Add test-single-core-boost.sh: Tool for testing single-core boost frequencies
- Add BIOS-FIX.md: Documentation for BIOS configuration fix
- Update tlp.conf: Configure dynamic CPU frequency scaling (400MHz-4.2GHz on AC, 400MHz-2.2GHz on battery)
- Add Intel RAPL power limit controls for CPU power capping
- Enable dynamic frequency scaling with proper platform profiles
- Fix CPU frequency stuck at 1.6GHz issue (required BIOS SpeedStep disable)
- Configure balanced battery mode with 2.2GHz max for responsiveness
This commit is contained in:
rwiegand
2025-10-06 22:34:19 +02:00
parent ba8f37706f
commit b9e2c2a731
5 changed files with 648 additions and 12 deletions

163
docs/BIOS-FIX.md Normal file
View File

@@ -0,0 +1,163 @@
# BIOS Configuration Fix for CPU Frequency Scaling
## Problem Identified
The CPU was stuck at 1.6 GHz and unable to boost to 4.2 GHz despite all software configurations being correct.
## Root Cause
**Intel SpeedStep Technology** was enabled in BIOS with conflicting settings that prevented dynamic frequency scaling from working properly in Linux.
## Solution
### BIOS Settings Changed:
1. **Intel SpeedStep Technology**: `Disabled`
2. **Power Scheme for AC**: Changed from `Balanced` to `Maximum Performance`
### Location in BIOS:
- **Path**: Config → Power → Intel SpeedStep Technology
- **Original Setting**: [Disabled] or with Mode restrictions
- **New Setting**: Disabled (allows Linux kernel to fully control CPU frequencies)
## Results After BIOS Changes
### On AC Power:
-**Minimum Frequency**: 400 MHz (deep idle)
-**Maximum Frequency**: 4200 MHz (full turbo boost)
-**Dynamic Scaling**: Working perfectly
-**Power Consumption**: 6-8W idle, up to 25W+ under load
### On Battery:
-**Minimum Frequency**: 800 MHz (power saving idle)
-**Maximum Frequency**: 2200 MHz (responsive but battery friendly)
-**Dynamic Scaling**: Working with TLP configuration
-**Turbo Boost**: Enabled but capped at 2.2 GHz for better battery life
## Why This Works
When Intel SpeedStep Technology is **enabled** in BIOS:
- BIOS firmware tries to manage CPU frequencies
- This conflicts with Linux kernel's P-state driver
- Results in frequency locks and limited boost capability
When Intel SpeedStep Technology is **disabled** in BIOS:
- Linux kernel has full control via intel_pstate driver
- Dynamic frequency scaling works as intended
- All boost frequencies are accessible
- TLP can properly manage power states
## Current TLP Configuration
### AC Mode (Plugged In):
```bash
CPU_SCALING_MIN_FREQ_ON_AC=800000 # 800 MHz
CPU_SCALING_MAX_FREQ_ON_AC=4200000 # 4.2 GHz (full boost)
CPU_HWP_ON_AC=balance_performance # Responsive performance
CPU_MAX_PERF_ON_AC=100 # Allow 100% performance
CPU_BOOST_ON_AC=1 # Turbo boost enabled
PLATFORM_PROFILE_ON_AC=performance # Maximum performance
```
### Battery Mode (Unplugged):
```bash
CPU_SCALING_MIN_FREQ_ON_BAT=800000 # 800 MHz
CPU_SCALING_MAX_FREQ_ON_BAT=2200000 # 2.2 GHz (limited boost)
CPU_HWP_ON_BAT=balance_power # Power efficient
CPU_MAX_PERF_ON_BAT=52 # Limit to ~52% (2.2 GHz)
CPU_BOOST_ON_BAT=1 # Turbo enabled but limited
PLATFORM_PROFILE_ON_BAT=balanced # Balanced for battery
```
## Testing Your Configuration
### Check Current Frequency:
```bash
cat /proc/cpuinfo | grep "cpu MHz"
```
### Monitor Frequency Scaling:
```bash
sudo ./scripts/monitor-cpu-freq.sh
```
### Check Current Status:
```bash
./scripts/cpu-power-control.sh status
```
### Create CPU Load to Test Boost:
```bash
# Single-core intensive task
timeout 10s bash -c 'while true; do echo "scale=5000; 4*a(1)" | bc -l > /dev/null; done'
# Multi-core intensive task
yes > /dev/null &
yes > /dev/null &
yes > /dev/null &
yes > /dev/null &
# Kill with: killall yes
```
## Recommended BIOS Settings for Linux
For optimal CPU frequency scaling and power management on Linux:
### Power Management Settings:
-**Intel SpeedStep Technology**: `Disabled` (let Linux manage it)
-**Intel Turbo Boost**: `Enabled`
-**CPU Power Management**: `Enabled`
-**Power Scheme (AC)**: `Maximum Performance`
-**Power Scheme (Battery)**: `Battery Optimized` or `Balanced`
### Thermal Settings:
-**Adaptive Thermal Management**: `Enabled` (prevents overheating)
-**Fan Control**: `Auto` or `Automatic`
### Sleep/Idle Settings:
-**C-States**: `Enabled` (allows deep sleep for power saving)
-**Enhanced C-States**: `Enabled`
## Troubleshooting
### If CPU is still stuck at low frequency:
1. **Verify BIOS settings were saved**:
- Reboot and re-enter BIOS
- Check that SpeedStep is still disabled
2. **Check for conflicting power management**:
```bash
systemctl status power-profiles-daemon
# If running, it may conflict with TLP
```
3. **Restart TLP**:
```bash
sudo systemctl restart tlp
```
4. **Check platform profile**:
```bash
cat /sys/firmware/acpi/platform_profile
# Should be "performance" on AC, "balanced" on battery
```
5. **Verify turbo is enabled**:
```bash
cat /sys/devices/system/cpu/intel_pstate/no_turbo
# Should be 0 (turbo enabled)
```
## References
- TLP Documentation: https://linrunner.de/tlp/
- Intel P-state Driver: https://www.kernel.org/doc/html/latest/admin-guide/pm/intel_pstate.html
- ThinkPad BIOS Settings: https://support.lenovo.com/
## Summary
**Problem Solved**: Disabling Intel SpeedStep in BIOS allows Linux full control
**AC Mode**: Full dynamic range 400 MHz - 4.2 GHz
**Battery Mode**: Battery-friendly 800 MHz - 2.2 GHz with turbo boost
**Power Management**: TLP now working as intended