diff --git a/src/ipa/rkisp1/algorithms/denoise.h b/src/ipa/rkisp1/algorithms/denoise.h
index c4b5b0af..e2bedc41 100644
--- a/src/ipa/rkisp1/algorithms/denoise.h
+++ b/src/ipa/rkisp1/algorithms/denoise.h
@@ -54,6 +54,12 @@ protected:
 
 	virtual void restoreAutoConfig(IPAContext &context, IPAFrameContext &frameContext) = 0;
 
+	virtual void prepareAutoMode(IPAContext &context, const uint32_t frame,
+				     IPAFrameContext &frameContext, RkISP1Params *params) = 0;
+
+	virtual void prepareManualMode(IPAContext &context, const uint32_t frame,
+				       IPAFrameContext &frameContext, RkISP1Params *params) = 0;
+
 private:
 	bool manualMode_ = false; /**< Current manual/auto mode state */
 	bool devMode_ = false; /**< Developer mode state for advanced controls */
diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp
index 75e083eb..c4597932 100644
--- a/src/ipa/rkisp1/algorithms/dpf.cpp
+++ b/src/ipa/rkisp1/algorithms/dpf.cpp
@@ -542,6 +542,11 @@ void Dpf::queueRequest(IPAContext &context,
 			frameContext.dpf.update = true;
 		}
 	}
+
+	LOG(RkISP1Dpf, Debug) << "queueRequest: denoise=" << frameContext.dpf.denoise
+			      << ", update=" << frameContext.dpf.update
+			      << (enableDpf_ ? "" : " (DPF disabled)")
+			      << (modeChanged ? " (mode change)" : "");
 }
 
 /**
@@ -550,42 +555,84 @@ void Dpf::queueRequest(IPAContext &context,
 void Dpf::prepare(IPAContext &context, const uint32_t frame,
 		  IPAFrameContext &frameContext, RkISP1Params *params)
 {
+	// check if master denoise toggle on
+	if (!frameContext.dpf.denoise) {
+		auto cfg = params->block<BlockType::Dpf>();
+		cfg.setEnabled(false);
+		auto str = params->block<BlockType::DpfStrength>();
+		str.setEnabled(false);
+		return;
+	}
+
+	if (isManualMode())
+		prepareManualMode(context, frame, frameContext, params);
+	else
+		prepareAutoMode(context, frame, frameContext, params);
+}
+
+void Dpf::prepareAutoMode(IPAContext &context, const uint32_t frame,
+			  IPAFrameContext &frameContext, RkISP1Params *params)
+{
+	unsigned iso = computeIso(context, frameContext);
+	bool baseIsoSkip = iso <= 100;
+
+	// Select different dpf config determined by iso Level
+	if (useIsoLevels_) {
+		int idx = DenoiseBaseAlgorithm::selectIsoBand(iso, isoLevels_);
+		if (idx >= 0 && idx != lastIsoIndex_) {
+			config_ = isoLevels_[idx].dpf;
+			strengthConfig_ = isoLevels_[idx].strength;
+			frameContext.dpf.update = true;
+			lastIsoIndex_ = idx;
+		}
+	}
+	// Disable dpf denoise due to high light
+	if (baseIsoSkip) {
+		auto cfg = params->block<BlockType::Dpf>();
+		cfg.setEnabled(false);
+		auto str = params->block<BlockType::DpfStrength>();
+		str.setEnabled(false);
+		return;
+	}
+
 	if (!frameContext.dpf.update && frame > 0)
 		return;
 
-	auto config = params->block<BlockType::Dpf>();
-	config.setEnabled(frameContext.dpf.denoise);
-
-	if (frameContext.dpf.denoise) {
-		*config = config_;
-
-		const auto &awb = context.configuration.awb;
-		const auto &lsc = context.configuration.lsc;
-
-		auto &mode = config->gain.mode;
-
-		/*
-		 * The DPF needs to take into account the total amount of
-		 * digital gain, which comes from the AWB and LSC modules. The
-		 * DPF hardware can be programmed with a digital gain value
-		 * manually, but can also use the gains supplied by the AWB and
-		 * LSC modules automatically when they are enabled. Use that
-		 * mode of operation as it simplifies control of the DPF.
-		 */
-		if (awb.enabled && lsc.enabled)
-			mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS;
-		else if (awb.enabled)
-			mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS;
-		else if (lsc.enabled)
-			mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS;
-		else
-			mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED;
-	}
-
-	if (frame == 0) {
-		auto strengthConfig = params->block<BlockType::DpfStrength>();
-		strengthConfig.setEnabled(true);
-		*strengthConfig = strengthConfig_;
+	auto cfgBlock = params->block<BlockType::Dpf>();
+	cfgBlock.setEnabled(true);
+	*cfgBlock = config_;
+
+	cfgBlock->gain.mode = config_.gain.mode;
+
+	if (frameContext.dpf.update) {
+		auto strBlock = params->block<BlockType::DpfStrength>();
+		strBlock.setEnabled(true);
+		*strBlock = strengthConfig_;
+		logConfigIfChanged(iso, lastIsoIndex_, false, frameContext);
+	}
+}
+
+void Dpf::prepareManualMode(IPAContext &context, const uint32_t frame,
+			    IPAFrameContext &frameContext, RkISP1Params *params)
+{
+	unsigned iso = computeIso(context, frameContext);
+
+	if (!frameContext.dpf.update && frame > 0)
+		return;
+
+	auto cfgBlock = params->block<BlockType::Dpf>();
+	cfgBlock.setEnabled(true);
+	*cfgBlock = config_;
+
+	cfgBlock->gain.mode = config_.gain.mode;
+
+	if (frame == 0 || frameContext.dpf.update) {
+		auto strBlock = params->block<BlockType::DpfStrength>();
+		strBlock.setEnabled(true);
+		*strBlock = strengthConfig_;
+		bool anyOverride = false;
+		applyOverridesTo(*cfgBlock, *strBlock, anyOverride);
+		logConfigIfChanged(iso, lastIsoIndex_, anyOverride, frameContext);
 	}
 }
 
diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h
index 8c34abcf..d84ba45f 100644
--- a/src/ipa/rkisp1/algorithms/dpf.h
+++ b/src/ipa/rkisp1/algorithms/dpf.h
@@ -105,6 +105,12 @@ private:
 	void applyOverridesTo(rkisp1_cif_isp_dpf_config &cfg, rkisp1_cif_isp_dpf_strength_config &str, bool &anyOverride);
 
 	void logConfigIfChanged(unsigned iso, int isoIndex, bool anyOverride, const IPAFrameContext &frameContext);
+
+	void prepareAutoMode(IPAContext &context, const uint32_t frame,
+			     IPAFrameContext &frameContext, RkISP1Params *params) override;
+
+	void prepareManualMode(IPAContext &context, const uint32_t frame,
+			       IPAFrameContext &frameContext, RkISP1Params *params) override;
 };
 
 } /* namespace ipa::rkisp1::algorithms */
