diff --git a/src/ipa/rkisp1/algorithms/denoise.h b/src/ipa/rkisp1/algorithms/denoise.h
index f40e5aa1..5fc78588 100644
--- a/src/ipa/rkisp1/algorithms/denoise.h
+++ b/src/ipa/rkisp1/algorithms/denoise.h
@@ -36,6 +36,7 @@ protected:
 			    const IPAFrameContext &frameContext) const;
 	template<typename LevelContainer>
 	int selectIsoBand(unsigned iso, const LevelContainer &levels) const;
+	virtual bool parseConfig(const YamlObject &tuningData) = 0;
 
 private:
 	bool manualMode_ = false; /**< Current manual/auto mode state */
diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp
index 9d1e6435..d1b89691 100644
--- a/src/ipa/rkisp1/algorithms/dpf.cpp
+++ b/src/ipa/rkisp1/algorithms/dpf.cpp
@@ -171,6 +171,48 @@ int Dpf::init([[maybe_unused]] IPAContext &context,
 	return 0;
 }
 
+bool Dpf::parseConfig(const YamlObject &tuningData)
+{
+	// Parse base config
+	if (!parseSingleConfig(tuningData, config_, strengthConfig_))
+		return false;
+
+	baseConfig_ = config_;
+	baseStrengthConfig_ = strengthConfig_;
+
+	/* Optional master enable flag (default true). If false, we parse but won't program. */
+	yamlHelper::optbool(tuningData, "enable", enableDpf_, true);
+
+	/* Optional developer mode flag (default true). If false, only basic manual controls available. */
+	bool devMode = true;
+	yamlHelper::optbool(tuningData, "devmode", devMode, true);
+	setDevMode(devMode);
+
+	// Parse ISO levels
+	if (tuningData.contains("IsoLevels")) {
+		useIsoLevels_ = true;
+		isoLevels_.clear();
+		for (const auto &entry : tuningData["IsoLevels"].asList()) {
+			std::optional<unsigned int> maxIsoOpt = entry["maxIso"].get<unsigned int>();
+			if (!maxIsoOpt) {
+				LOG(RkISP1Dpf, Error) << "IsoLevels entry missing maxIso";
+				continue;
+			}
+			IsoLevelConfig lvl{};
+			lvl.maxIso = *maxIsoOpt;
+			if (!parseSingleConfig(entry, lvl.dpf, lvl.strength))
+				continue;
+			isoLevels_.push_back(lvl);
+		}
+		std::sort(isoLevels_.begin(), isoLevels_.end(),
+			  [](const IsoLevelConfig &a, const IsoLevelConfig &b) {
+				  return a.maxIso < b.maxIso;
+			  });
+	}
+
+	return true;
+}
+
 bool Dpf::parseSingleConfig(const YamlObject &config,
 			    rkisp1_cif_isp_dpf_config &cfg,
 			    rkisp1_cif_isp_dpf_strength_config &strength)
diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h
index cfd6ef44..faeb6c27 100644
--- a/src/ipa/rkisp1/algorithms/dpf.h
+++ b/src/ipa/rkisp1/algorithms/dpf.h
@@ -32,8 +32,25 @@ public:
 		     RkISP1Params *params) override;
 
 private:
-	struct rkisp1_cif_isp_dpf_config config_;
-	struct rkisp1_cif_isp_dpf_strength_config strengthConfig_;
+	struct rkisp1_cif_isp_dpf_config config_ {
+	};
+	struct rkisp1_cif_isp_dpf_strength_config strengthConfig_ {
+	};
+	struct rkisp1_cif_isp_dpf_config baseConfig_ {
+	};
+	struct rkisp1_cif_isp_dpf_strength_config baseStrengthConfig_ {
+	};
+	struct IsoLevelConfig {
+		unsigned int maxIso; /* inclusive upper bound */
+		struct rkisp1_cif_isp_dpf_config dpf;
+		struct rkisp1_cif_isp_dpf_strength_config strength;
+	};
+
+	std::vector<IsoLevelConfig> isoLevels_;
+	bool useIsoLevels_ = false;
+	bool enableDpf_ = true; /* YAML master enable */
+
+	bool parseConfig(const YamlObject &tuningData) override;
 	bool parseSingleConfig(const YamlObject &config,
 			       rkisp1_cif_isp_dpf_config &cfg,
 			       rkisp1_cif_isp_dpf_strength_config &strength);
