diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h
index 54d22278f6e41f31560a3f14ee15f1976df5b2b4..26c255ce8ccd19b09256d029a1d401aff47a3614 100644
--- a/Marlin/Conditionals_post.h
+++ b/Marlin/Conditionals_post.h
@@ -880,6 +880,23 @@
    */
   #define HAS_FANMUX PIN_EXISTS(FANMUX0)
 
+  /**
+   * MIN/MAX fan PWM scaling
+   */
+  #ifndef FAN_MIN_PWM
+    #define FAN_MIN_PWM 0
+  #endif
+  #ifndef FAN_MAX_PWM
+    #define FAN_MAX_PWM 255
+  #endif
+  #if FAN_MIN_PWM < 0 || FAN_MIN_PWM > 255
+    #error "FAN_MIN_PWM must be a value from 0 to 255."
+  #elif FAN_MAX_PWM < 0 || FAN_MAX_PWM > 255
+    #error "FAN_MAX_PWM must be a value from 0 to 255."
+  #elif FAN_MIN_PWM > FAN_MAX_PWM
+    #error "FAN_MIN_PWM must be less than or equal to FAN_MAX_PWM."
+  #endif
+
   /**
    * Bed Probe dependencies
    */
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 0decaf8871cbc270ddd4dd0ec706f8f405dc30c6..9cfbc8957cea46b806a77aadfb43c776591b0be1 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -208,10 +208,20 @@
 // before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu)
 //#define FAN_KICKSTART_TIME 100
 
-// This defines the minimal speed for the main fan, run in PWM mode
-// to enable uncomment and set minimal PWM speed for reliable running (1-255)
-// if fan speed is [1 - (FAN_MIN_PWM-1)] it is set to FAN_MIN_PWM
+/**
+ * PWM Fan Scaling
+ *
+ * Define the min/max speeds for PWM fans (as set with M106).
+ *
+ * With these options the M106 0-255 value range is scaled to a subset
+ * to ensure that the fan has enough power to spin, or to run lower
+ * current fans with higher current. (e.g., 5V/12V fans with 12V/24V)
+ * Value 0 always turns off the fan.
+ *
+ * Define one or both of these to override the default 0-255 range.
+ */
 //#define FAN_MIN_PWM 50
+//#define FAN_MAX_PWM 128
 
 // @section extruder
 
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index f504665f0d49fe9ce80cd3aea3d4e36d0ca00b76..4d4b92e9dc8543fd4511298d836a5298ea3dd402 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -1084,8 +1084,8 @@ void Planner::check_axes_activity() {
 
     #endif // FAN_KICKSTART_TIME > 0
 
-    #ifdef FAN_MIN_PWM
-      #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? ( FAN_MIN_PWM + (tail_fan_speed[f] * (255 - FAN_MIN_PWM)) / 255 ) : 0)
+    #if FAN_MIN_PWM != 0 || FAN_MAX_PWM != 255
+      #define CALC_FAN_SPEED(f) (tail_fan_speed[f] ? map(tail_fan_speed[f], 1, 255, FAN_MIN_PWM, FAN_MAX_PWM) : 0)
     #else
       #define CALC_FAN_SPEED(f) tail_fan_speed[f]
     #endif