diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index bb1558df5422..9a27696ff868 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -156,6 +156,15 @@ int Agc::init(IPAContext &context, const YamlObject &tuningData)
 				ControlValue(controls::AnalogueGainModeManual) } },
 			    ControlValue(controls::AnalogueGainModeAuto));
 	context.ctrlMap[&controls::ExposureValue] = ControlInfo(-8.0f, 8.0f, 0.0f);
+	/*
+	 * Insert the controlInfo for sync. Since FrameDurationLimits is only
+	 * set *after* the algorithms are initialized, we have no information
+	 * on it here. Use a sensible default here and update it later in
+	 * configure().
+	 * \todo Move FrameDurationLimits from the base IPA to AGC
+	 */
+	context.ctrlMap[&controls::SyncAdjustment] = controlInfo(120000);
+	/* Insert the controls for agc */
 	context.ctrlMap.merge(controls());
 
 	return 0;
@@ -202,7 +211,11 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
 		  context.configuration.sensor.minAnalogueGain,
 		  context.configuration.sensor.maxAnalogueGain);
 
+	context.ctrlMap[&controls::SyncAdjustment] =
+		controlInfo(frameDurationLimits.max().get<int64_t>());
+
 	resetFrameCount();
+	resetSync();
 
 	return 0;
 }
@@ -324,6 +337,10 @@ void Agc::queueRequest(IPAContext &context,
 	}
 	frameContext.agc.minFrameDuration = agc.minFrameDuration;
 	frameContext.agc.maxFrameDuration = agc.maxFrameDuration;
+
+	const auto &sync = controls.get(controls::SyncAdjustment);
+	if (sync)
+		setSync(*sync, frameContext.agc.minFrameDuration);
 }
 
 /**
@@ -413,6 +430,7 @@ void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext,
 	metadata.set(controls::AeExposureMode, frameContext.agc.exposureMode);
 	metadata.set(controls::AeConstraintMode, frameContext.agc.constraintMode);
 	metadata.set(controls::ExposureValue, frameContext.agc.exposureValue);
+	metadata.set(controls::SyncAdjustment, frameContext.agc.syncAdjustment.count());
 }
 
 /**
@@ -471,7 +489,9 @@ void Agc::processFrameDuration(IPAContext &context,
 	IPACameraSensorInfo &sensorInfo = context.sensorInfo;
 	utils::Duration lineDuration = context.configuration.sensor.lineDuration;
 
-	frameContext.agc.vblank = (frameDuration / lineDuration) - sensorInfo.outputSize.height;
+	utils::Duration sync = getSync();
+	frameContext.agc.vblank = ((frameDuration + sync) / lineDuration) - sensorInfo.outputSize.height;
+	frameContext.agc.syncAdjustment = sync;
 
 	/* Update frame duration accounting for line length quantization. */
 	frameContext.agc.frameDuration = (sensorInfo.outputSize.height + frameContext.agc.vblank) * lineDuration;
diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h
index 7867eed9c4e3..4441a519e857 100644
--- a/src/ipa/rkisp1/algorithms/agc.h
+++ b/src/ipa/rkisp1/algorithms/agc.h
@@ -15,6 +15,7 @@
 #include <libcamera/geometry.h>
 
 #include "libipa/agc_mean_luminance.h"
+#include "libipa/sync_helper.h"
 
 #include "algorithm.h"
 
@@ -22,7 +23,7 @@ namespace libcamera {
 
 namespace ipa::rkisp1::algorithms {
 
-class Agc : public Algorithm, public AgcMeanLuminance
+class Agc : public Algorithm, public AgcMeanLuminance, public SyncHelper
 {
 public:
 	Agc();
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index 7ccc7b501aff..c21ab77b2ba5 100644
--- a/src/ipa/rkisp1/ipa_context.h
+++ b/src/ipa/rkisp1/ipa_context.h
@@ -143,6 +143,7 @@ struct IPAFrameContext : public FrameContext {
 		bool updateMetering;
 		bool autoExposureModeChange;
 		bool autoGainModeChange;
+		utils::Duration syncAdjustment;
 	} agc;
 
 	struct {
