diff --git a/src/ipa/rkisp1/algorithms/algorithm.h b/src/ipa/rkisp1/algorithms/algorithm.h
index c3212cff76fe..9454c9a1fc06 100644
--- a/src/ipa/rkisp1/algorithms/algorithm.h
+++ b/src/ipa/rkisp1/algorithms/algorithm.h
@@ -15,7 +15,17 @@ namespace libcamera {
 
 namespace ipa::rkisp1 {
 
-using Algorithm = libcamera::ipa::Algorithm<Module>;
+class Algorithm : public libcamera::ipa::Algorithm<Module>
+{
+public:
+	Algorithm()
+		: disabled_(false), supportsRaw_(false)
+	{
+	}
+
+	bool disabled_;
+	bool supportsRaw_;
+};
 
 } /* namespace ipa::rkisp1 */
 
diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp
index 7a987497bd03..9bbf368432fa 100644
--- a/src/ipa/rkisp1/ipa_context.cpp
+++ b/src/ipa/rkisp1/ipa_context.cpp
@@ -89,6 +89,11 @@ namespace libcamera::ipa::rkisp1 {
  * \brief Sensor output resolution
  */
 
+/**
+ * \var IPASessionConfiguration::raw
+ * \brief Indicates if the camera is configured to capture raw frames
+ */
+
 /**
  * \struct IPAActiveState
  * \brief Active state for algorithms
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index bb60ab9eab72..3e47ac663c58 100644
--- a/src/ipa/rkisp1/ipa_context.h
+++ b/src/ipa/rkisp1/ipa_context.h
@@ -48,6 +48,8 @@ struct IPASessionConfiguration {
 	struct {
 		rkisp1_cif_isp_version revision;
 	} hw;
+
+	bool raw;
 };
 
 struct IPAActiveState {
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index fcb9dacccc3c..538e42cb6f7f 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -24,6 +24,7 @@
 #include <libcamera/ipa/rkisp1_ipa_interface.h>
 #include <libcamera/request.h>
 
+#include "libcamera/internal/formats.h"
 #include "libcamera/internal/mapped_framebuffer.h"
 #include "libcamera/internal/yaml_parser.h"
 
@@ -207,7 +208,7 @@ void IPARkISP1::stop()
  * before accessing them.
  */
 int IPARkISP1::configure([[maybe_unused]] const IPACameraSensorInfo &info,
-			 [[maybe_unused]] const std::map<uint32_t, IPAStream> &streamConfig,
+			 const std::map<uint32_t, IPAStream> &streamConfig,
 			 const std::map<uint32_t, ControlInfoMap> &entityControls)
 {
 	if (entityControls.empty())
@@ -264,7 +265,21 @@ int IPARkISP1::configure([[maybe_unused]] const IPACameraSensorInfo &info,
 	context_.configuration.sensor.minAnalogueGain = camHelper_->gain(minGain);
 	context_.configuration.sensor.maxAnalogueGain = camHelper_->gain(maxGain);
 
-	for (auto const &algo : algorithms()) {
+	context_.configuration.raw = std::any_of(streamConfig.begin(), streamConfig.end(),
+		[](auto &cfg) -> bool {
+			PixelFormat pixelFormat{ cfg.second.pixelFormat };
+			const PixelFormatInfo &format = PixelFormatInfo::info(pixelFormat);
+			return format.colourEncoding == PixelFormatInfo::ColourEncodingRAW;
+		});
+
+	for (auto const &a : algorithms()) {
+		Algorithm *algo = static_cast<Algorithm *>(a.get());
+
+		/* Disable algorithms that don't support raw formats. */
+		algo->disabled_ = context_.configuration.raw && !algo->supportsRaw_;
+		if (algo->disabled_)
+			continue;
+
 		int ret = algo->configure(context_, info);
 		if (ret)
 			return ret;
@@ -307,8 +322,12 @@ void IPARkISP1::queueRequest(const uint32_t frame, const ControlList &controls)
 {
 	IPAFrameContext &frameContext = context_.frameContexts.alloc(frame);
 
-	for (auto const &algo : algorithms())
+	for (auto const &a : algorithms()) {
+		Algorithm *algo = static_cast<Algorithm *>(a.get());
+		if (algo->disabled_)
+			continue;
 		algo->queueRequest(context_, frame, frameContext, controls);
+	}
 }
 
 void IPARkISP1::fillParamsBuffer(const uint32_t frame, const uint32_t bufferId)
@@ -333,9 +352,16 @@ void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId
 {
 	IPAFrameContext &frameContext = context_.frameContexts.get(frame);
 
-	const rkisp1_stat_buffer *stats =
-		reinterpret_cast<rkisp1_stat_buffer *>(
+	/*
+	 * In raw capture mode, the ISP is bypassed and no statistics buffer is
+	 * provided.
+	 */
+	const rkisp1_stat_buffer *stats;
+	if (!context_.configuration.raw)
+		stats = reinterpret_cast<rkisp1_stat_buffer *>(
 			mappedBuffers_.at(bufferId).planes()[0].data());
+	else
+		stats = nullptr;
 
 	frameContext.sensor.exposure =
 		sensorControls.get(V4L2_CID_EXPOSURE).get<int32_t>();
@@ -344,8 +370,12 @@ void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId
 
 	ControlList metadata(controls::controls);
 
-	for (auto const &algo : algorithms())
+	for (auto const &a : algorithms()) {
+		Algorithm *algo = static_cast<Algorithm *>(a.get());
+		if (algo->disabled_)
+			continue;
 		algo->process(context_, frame, frameContext, stats, metadata);
+	}
 
 	setControls(frame);
 
