diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp
index 602050729fd08649e2db8d07623a8a39e7a53a77..0c8e15030c377ac0797dbdc9d53694ee894cd9b8 100644
--- a/src/ipa/libipa/agc_mean_luminance.cpp
+++ b/src/ipa/libipa/agc_mean_luminance.cpp
@@ -461,6 +461,7 @@ int AgcMeanLuminance::parseTuningData(const YamlObject &tuningData)
  * \brief Set the ExposureModeHelper limits for this class
  * \param[in] minExposureTime Minimum exposure time to allow
  * \param[in] maxExposureTime Maximum ewposure time to allow
+ * \param[in] maxFrameDuration Maximum frame duration
  * \param[in] minGain Minimum gain to allow
  * \param[in] maxGain Maximum gain to allow
  * \param[in] constraints Additional constraints to apply
@@ -470,11 +471,13 @@ int AgcMeanLuminance::parseTuningData(const YamlObject &tuningData)
  */
 void AgcMeanLuminance::setLimits(utils::Duration minExposureTime,
 				 utils::Duration maxExposureTime,
+				 utils::Duration maxFrameDuration,
 				 double minGain, double maxGain,
 				 std::vector<AgcMeanLuminance::AgcConstraint> constraints)
 {
 	for (auto &[id, helper] : exposureModeHelpers_)
-		helper->setLimits(minExposureTime, maxExposureTime, minGain, maxGain);
+		helper->setLimits(minExposureTime, maxExposureTime, maxFrameDuration,
+				  minGain, maxGain);
 
 	additionalConstraints_ = std::move(constraints);
 }
diff --git a/src/ipa/libipa/agc_mean_luminance.h b/src/ipa/libipa/agc_mean_luminance.h
index c3c8ce1cdda9229eca400b730f2ee896e9a0af93..535f94502dc2649a5f4ba49a7040de12f9f74179 100644
--- a/src/ipa/libipa/agc_mean_luminance.h
+++ b/src/ipa/libipa/agc_mean_luminance.h
@@ -62,7 +62,8 @@ public:
 	}
 
 	void setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime,
-		       double minGain, double maxGain, std::vector<AgcConstraint> constraints);
+		       utils::Duration maxFrameDuration, double minGain, double maxGain,
+		       std::vector<AgcConstraint> constraints);
 
 	const std::map<int32_t, std::vector<AgcConstraint>> &constraintModes() const
 	{
diff --git a/src/ipa/libipa/exposure_mode_helper.cpp b/src/ipa/libipa/exposure_mode_helper.cpp
index 45f51f9088170c983bb0de2c18714627514c5641..fad13ff1521498244224a8a5f375738ee3fc9ff2 100644
--- a/src/ipa/libipa/exposure_mode_helper.cpp
+++ b/src/ipa/libipa/exposure_mode_helper.cpp
@@ -109,6 +109,27 @@ ExposureModeHelper::ExposureModeHelper(const Span<std::pair<utils::Duration, dou
 	}
 }
 
+void ExposureModeHelper::setMaxExposure(utils::Duration minExposureTime,
+					utils::Duration maxExposureTime,
+					utils::Duration maxFrameDuration)
+{
+	minExposureTime_ = minExposureTime;
+
+	/*
+	 * Compute the maximum shutter time.
+	 *
+	 * If maxExposureTime is equal to minExposureTime then we use them
+	 * to fix the exposure time.
+	 *
+	 * Otherwise, if the exposure can range between a min and max delegate
+	 * the maximum shutter time calculation to the sensor helper.
+	 */
+	maxExposureTime_ = minExposureTime != maxExposureTime
+			 ? sensorHelper_->maxShutterTime(maxFrameDuration,
+							 sensor_.lineDuration_)
+			 : minExposureTime;
+}
+
 /**
  * \brief Configure sensor details
  * \param[in] sensorConfig The sensor configuration
@@ -136,27 +157,15 @@ void ExposureModeHelper::configure(const SensorConfiguration &sensorConfig,
 	minGain_ = sensor_.minGain_;
 	maxGain_ = sensor_.maxGain_;
 
-	minExposureTime_ = sensor_.minExposureTime_;
-
-	/*
-	 * Compute the maximum shutter time.
-	 *
-	 * If maxExposureTime is equal to minExposureTime then we use them
-	 * to fix the exposure time.
-	 *
-	 * Otherwise, if the exposure can range between a min and max delegate
-	 * the maximum shutter time calculation to the sensor helper.
-	 */
-	maxExposureTime_ = minExposureTime_ != sensorConfig.maxExposureTime_
-			 ? sensorHelper_->maxShutterTime(sensorConfig.maxFrameDuration_,
-							 sensorConfig.lineDuration_)
-			 : minExposureTime_;
+	setMaxExposure(sensorConfig.minExposureTime_, sensorConfig.maxExposureTime_,
+		       sensorConfig.maxFrameDuration_);
 }
 
 /**
  * \brief Set the exposure time and gain limits
  * \param[in] minExposureTime The minimum exposure time supported
  * \param[in] maxExposureTime The maximum exposure time supported
+ * \param[in] maxFrameDuration The maximum frame duration
  * \param[in] minGain The minimum analogue gain supported
  * \param[in] maxGain The maximum analogue gain supported
  *
@@ -168,15 +177,19 @@ void ExposureModeHelper::configure(const SensorConfiguration &sensorConfig,
  * If the algorithm using the helpers needs to indicate that either exposure time
  * or analogue gain or both should be fixed it can do so by setting both the
  * minima and maxima to the same value.
+ *
+ * The exposure time limits are calculated using \a maxFrameDuration as the
+ * upper bound, the \a maxExposureTime paramter effectivelly only serves
+ * to indicate that the caller wants a fixed exposure value.
  */
 void ExposureModeHelper::setLimits(utils::Duration minExposureTime,
 				   utils::Duration maxExposureTime,
+				   utils::Duration maxFrameDuration,
 				   double minGain, double maxGain)
 {
-	minExposureTime_ = minExposureTime;
-	maxExposureTime_ = maxExposureTime;
 	minGain_ = minGain;
 	maxGain_ = maxGain;
+	setMaxExposure(minExposureTime, maxExposureTime, maxFrameDuration);
 }
 
 utils::Duration ExposureModeHelper::clampExposureTime(utils::Duration exposureTime,
diff --git a/src/ipa/libipa/exposure_mode_helper.h b/src/ipa/libipa/exposure_mode_helper.h
index e41c58767eee65dd27946336beb2bc182dd4ab58..36791c99face056835b0bb2d28b533380e8d9b95 100644
--- a/src/ipa/libipa/exposure_mode_helper.h
+++ b/src/ipa/libipa/exposure_mode_helper.h
@@ -41,12 +41,15 @@ public:
 	void configure(const SensorConfiguration &sensorConfig,
 		       const CameraSensorHelper *sensorHelper);
 	void setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime,
-		       double minGain, double maxGain);
+		       utils::Duration maxFrameDuration, double minGain, double maxGain);
 
 	std::tuple<utils::Duration, double, double, double>
 	splitExposure(utils::Duration exposure) const;
 
 private:
+	void setMaxExposure(utils::Duration minExposureTime,
+			    utils::Duration maxExposureTime,
+			    utils::Duration maxFrameDuration);
 	utils::Duration clampExposureTime(utils::Duration exposureTime,
 					  double *quantizationGain = nullptr) const;
 	double clampGain(double gain, double *quantizationGain = nullptr) const;
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index de2980485f2d3a8973f065981f8cdd520e3dfc47..db318a2c49f2fbd9b00222ec699a657eed131595 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -580,9 +580,7 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
 
 	if (frameContext.agc.autoExposureEnabled) {
 		minExposureTime = context.configuration.sensor.minExposureTime;
-		maxExposureTime = std::clamp(frameContext.agc.maxFrameDuration,
-					     context.configuration.sensor.minExposureTime,
-					     context.configuration.sensor.maxExposureTime);
+		maxExposureTime = context.configuration.sensor.maxExposureTime;
 	} else {
 		minExposureTime = context.configuration.sensor.lineDuration
 				* frameContext.agc.exposure;
@@ -601,8 +599,8 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
 	if (context.activeState.wdr.mode != controls::WdrOff)
 		additionalConstraints.push_back(context.activeState.wdr.constraint);
 
-	setLimits(minExposureTime, maxExposureTime, minAnalogueGain, maxAnalogueGain,
-		  std::move(additionalConstraints));
+	setLimits(minExposureTime, maxExposureTime, frameContext.agc.maxFrameDuration,
+		  minAnalogueGain, maxAnalogueGain, std::move(additionalConstraints));
 
 	/*
 	 * The Agc algorithm needs to know the effective exposure value that was
