diff --git a/ipu3.cpp b/ipu3.cpp
index 7589eecbb64c..8126e9d659df 100644
--- a/ipu3.cpp
+++ b/ipu3.cpp
@@ -44,13 +44,17 @@ public:
 	int start() override;
 	void stop() override {}
 
-	int configure(const IPAConfigInfo &configInfo) override;
+	int configure(const IPAConfigInfo &configInfo,
+		      ControlInfoMap *ipaControls) override;
 
 	void mapBuffers(const std::vector<IPABuffer> &buffers) override;
 	void unmapBuffers(const std::vector<unsigned int> &ids) override;
 	void processEvent(const IPU3Event &event) override;
 
 private:
+	void updateControls(const IPACameraSensorInfo &sensorInfo,
+			    const ControlInfoMap &sensorControls,
+			    ControlInfoMap *ipaControls);
 	void processControls(unsigned int frame, const ControlList &metadata);
 	void fillParams(unsigned int frame, ipu3_uapi_params *params);
 	void parseStatistics(unsigned int frame,
@@ -86,6 +90,68 @@ private:
 	BinaryData aiqd_;
 };
 
+/*
+ * Compute camera controls using the sensor information and the sensor
+ * v4l2 controls.
+ *
+ * Some of the camera controls are computed by the pipeline handler, some others
+ * by the IPA module which is in charge of handling, for example, the exposure
+ * time and the frame duration.
+ *
+ * This function computes:
+ * - controls::ExposureTime
+ * - controls::FrameDurationLimits
+ */
+void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo,
+			     const ControlInfoMap &sensorControls,
+			     ControlInfoMap *ipaControls)
+{
+	ControlInfoMap::Map controls{};
+
+	/*
+	 * Compute exposure time limits by using line length and pixel rate
+	 * converted to microseconds. Use the V4L2_CID_EXPOSURE control to get
+	 * exposure min, max and default and convert it from lines to
+	 * microseconds.
+	 */
+	double lineDuration = sensorInfo.lineLength / (sensorInfo.pixelRate / 1e6);
+	const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;
+	int32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;
+	int32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;
+	int32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;
+	controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,
+							defExposure);
+
+	/*
+	 * Compute the frame duration limits.
+	 *
+	 * The frame length is computed assuming a fixed line length combined
+	 * with the vertical frame sizes.
+	 */
+	const ControlInfo &v4l2HBlank = sensorControls.find(V4L2_CID_HBLANK)->second;
+	uint32_t hblank = v4l2HBlank.def().get<int32_t>();
+	uint32_t lineLength = sensorInfo.outputSize.width + hblank;
+
+	const ControlInfo &v4l2VBlank = sensorControls.find(V4L2_CID_VBLANK)->second;
+	std::array<uint32_t, 3> frameHeights{
+		v4l2VBlank.min().get<int32_t>() + sensorInfo.outputSize.height,
+		v4l2VBlank.max().get<int32_t>() + sensorInfo.outputSize.height,
+		v4l2VBlank.def().get<int32_t>() + sensorInfo.outputSize.height,
+	};
+
+	std::array<int64_t, 3> frameDurations;
+	for (unsigned int i = 0; i < frameHeights.size(); ++i) {
+		uint64_t frameSize = lineLength * frameHeights[i];
+		frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U);
+	}
+
+	controls[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0],
+							       frameDurations[1],
+							       frameDurations[2]);
+
+	*ipaControls = ControlInfoMap(std::move(controls), controls::controls);
+}
+
 int IPAIPU3::init(const IPASettings &settings,
 		  const IPACameraSensorInfo &sensorInfo,
 		  const ControlInfoMap &sensorControls,
@@ -141,53 +207,8 @@ int IPAIPU3::init(const IPASettings &settings,
 
 	aiqInputParams_.init();
 
-	/* Initialize Controls. */
-	ControlInfoMap::Map controls{};
-
-	/*
-	 * Compute exposure time limits.
-	 *
-	 * Initialize the control using the line length and pixel rate of the
-	 * current configuration converted to microseconds. Use the
-	 * V4L2_CID_EXPOSURE control to get exposure min, max and default and
-	 * convert it from lines to microseconds.
-	 */
-	double lineDuration = sensorInfo.lineLength / (sensorInfo.pixelRate / 1e6);
-	const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;
-	int32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;
-	int32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;
-	int32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;
-	controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,
-							defExposure);
-
-	/*
-	 * Compute the frame duration limits.
-	 *
-	 * The frame length is computed assuming a fixed line length combined
-	 * with the vertical frame sizes.
-	 */
-	const ControlInfo &v4l2HBlank = sensorControls.find(V4L2_CID_HBLANK)->second;
-	uint32_t hblank = v4l2HBlank.def().get<int32_t>();
-	uint32_t lineLength = sensorInfo.outputSize.width + hblank;
-
-	const ControlInfo &v4l2VBlank = sensorControls.find(V4L2_CID_VBLANK)->second;
-	std::array<uint32_t, 3> frameHeights{
-		v4l2VBlank.min().get<int32_t>() + sensorInfo.outputSize.height,
-		v4l2VBlank.max().get<int32_t>() + sensorInfo.outputSize.height,
-		v4l2VBlank.def().get<int32_t>() + sensorInfo.outputSize.height,
-	};
-
-	std::array<int64_t, 3> frameDurations;
-	for (unsigned int i = 0; i < frameHeights.size(); ++i) {
-		uint64_t frameSize = lineLength * frameHeights[i];
-		frameDurations[i] = frameSize / (sensorInfo.pixelRate / 1000000U);
-	}
-
-	controls[&controls::FrameDurationLimits] = ControlInfo(frameDurations[0],
-							       frameDurations[1],
-							       frameDurations[2]);
-
-	*ipaControls = ControlInfoMap(std::move(controls), controls::controls);
+	/* Initialize controls. */
+	updateControls(sensorInfo, sensorControls, ipaControls);
 
 	return 0;
 }
@@ -199,7 +220,8 @@ int IPAIPU3::start()
 	return 0;
 }
 
-int IPAIPU3::configure(const IPAConfigInfo &configInfo)
+int IPAIPU3::configure(const IPAConfigInfo &configInfo,
+		       ControlInfoMap *ipaControls)
 {
 	if (configInfo.sensorControls.empty()) {
 		LOG(IPAIPU3, Error) << "No sensor controls provided";
@@ -208,6 +230,10 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo)
 
 	sensorInfo_ = configInfo.sensorInfo;
 
+	/*
+	 * Compute the sensor V4L2 controls to be used by the algorithms and
+	 * to be set on the sensor.
+	 */
 	ctrls_ = configInfo.sensorControls;
 
 	const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE);
@@ -253,6 +279,9 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo)
 	/* Set AE/AWB defaults, this typically might not belong here */
 	aiqInputParams_.setAeAwbAfDefaults();
 
+	/* Upate the camera controls using the new sensor settings. */
+	updateControls(sensorInfo_, ctrls_, ipaControls);
+
 	return 0;
 }
 
