diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp
index af518d0b2c28..421f3d925a3f 100644
--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp
+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp
@@ -76,10 +76,7 @@ const std::map<libcamera::PixelFormat, unsigned int> maliC55FmtToCode = {
 	{ formats::NV21, MEDIA_BUS_FMT_YUV10_1X30 },
 
 	/* RAW formats, FR pipe only. */
-	{ formats::SGBRG16, MEDIA_BUS_FMT_SGBRG16_1X16 },
-	{ formats::SRGGB16, MEDIA_BUS_FMT_SRGGB16_1X16 },
-	{ formats::SBGGR16, MEDIA_BUS_FMT_SBGGR16_1X16 },
-	{ formats::SGRBG16, MEDIA_BUS_FMT_SGRBG16_1X16 },
+	{ formats::RAW16, MEDIA_BUS_FMT_RAW_16 },
 };
 
 constexpr Size kMaliC55MinInputSize = { 640, 480 };
@@ -191,13 +188,33 @@ public:
 		}, input_);
 	}
 
-	int pixfmtToMbusCode(const PixelFormat &pixFmt) const;
-	const PixelFormat &bestRawFormat() const;
+	ColorFilterArray bayerOrder(Transform t) const
+	{
+		return std::visit(utils::overloaded{
+			[&](const Tpg &tpg) -> ColorFilterArray {
+				V4L2Subdevice::Formats formats = tpg.sd_->formats(0);
+				for (const auto &[code, sizes] : formats) {
+					auto cfa = ColorFilterArray::fromMbusCode(code);
+					if (cfa)
+						return cfa.value();
+				}
+				return ColorFilterArray::MONO;
+			},
+			[&](const Inline &in) -> ColorFilterArray {
+				return in.sensor_->bayerOrder(t);
+			},
+			[&](const Memory &mem) -> ColorFilterArray {
+				return mem.cru_->sensor()->bayerOrder(t);
+			},
+		}, input_);
+	}
+
+	int bestMbusCode(ColorFilterArray cfa) const;
+	bool isSensorRaw() const;
 
 	void updateControls(const ControlInfoMap &ipaControls);
 
-	PixelFormat adjustRawFormat(const PixelFormat &pixFmt) const;
-	Size adjustRawSizes(const PixelFormat &pixFmt, const Size &rawSize) const;
+	Size adjustRawSizes(const Size &rawSize, unsigned int rawCode) const;
 
 	Stream frStream_;
 	Stream dsStream_;
@@ -305,21 +322,13 @@ void MaliC55CameraData::setSensorControls(const ControlList &sensorControls)
 }
 
 /*
- * The Mali C55 ISP can only produce 16-bit RAW output in bypass modes, but the
- * sensors connected to it might produce 8/10/12/16 bits. We simply search the
- * sensor's supported formats for the one with a matching bayer order and the
- * greatest bitdepth.
+ * The Mali C55 ISP can only accept as input RAW20 and can only produce as
+ * output RAW16. The sensors connected to it might produce 8/10/12/16 bits.
+ * We simply search the sensor's supported formats for the one with greatest
+ * bitdepth and matches the bayer color filter array order.
  */
-int MaliC55CameraData::pixfmtToMbusCode(const PixelFormat &pixFmt) const
+int MaliC55CameraData::bestMbusCode(ColorFilterArray cfa) const
 {
-	auto it = maliC55FmtToCode.find(pixFmt);
-	if (it == maliC55FmtToCode.end())
-		return -EINVAL;
-
-	BayerFormat bayerFormat = BayerFormat::fromMbusCode(it->second);
-	if (!bayerFormat.isValid())
-		return -EINVAL;
-
 	V4L2Subdevice::Formats formats = subdev()->formats(0);
 	unsigned int sensorMbusCode = 0;
 	unsigned int bitDepth = 0;
@@ -329,7 +338,12 @@ int MaliC55CameraData::pixfmtToMbusCode(const PixelFormat &pixFmt) const
 		if (!sdBayerFormat.isValid())
 			continue;
 
-		if (sdBayerFormat.cfa.order != bayerFormat.cfa.order)
+		/* The pipeline currently does not support generic codes */
+		if (MediaBusFormatInfo::info(code).genericRaw)
+			continue;
+
+		auto c = ColorFilterArray::fromMbusCode(code);
+		if (!c || c != cfa)
 			continue;
 
 		if (sdBayerFormat.bitDepth > bitDepth) {
@@ -344,38 +358,20 @@ int MaliC55CameraData::pixfmtToMbusCode(const PixelFormat &pixFmt) const
 	return sensorMbusCode;
 }
 
-/*
- * Find a RAW PixelFormat supported by both the ISP and the sensor.
- *
- * The situation is mildly complicated by the fact that we expect the sensor to
- * output something like RAW8/10/12/16, but the ISP can only accept as input
- * RAW20 and can only produce as output RAW16. The one constant in that is the
- * bayer order of the data, so we'll simply check that the sensor produces a
- * format with a bayer order that matches that of one of the formats we support,
- * and select that.
- */
-const PixelFormat &MaliC55CameraData::bestRawFormat() const
+bool MaliC55CameraData::isSensorRaw() const
 {
-	static const PixelFormat invalidPixFmt = {};
+	if (!std::holds_alternative<Tpg>(input_))
+		return this->sensor()->isRaw();
 
 	for (const auto &fmt : subdev()->formats(0)) {
 		BayerFormat sensorBayer = BayerFormat::fromMbusCode(fmt.first);
 
-		if (!sensorBayer.isValid())
-			continue;
-
-		for (const auto &[pixFmt, rawCode] : maliC55FmtToCode) {
-			if (!isFormatRaw(pixFmt))
-				continue;
-
-			BayerFormat bayer = BayerFormat::fromMbusCode(rawCode);
-			if (bayer.cfa.order == sensorBayer.cfa.order)
-				return pixFmt;
-		}
+		if (sensorBayer.isValid())
+			return true;
 	}
 
-	LOG(MaliC55, Error) << "Sensor doesn't provide a compatible format";
-	return invalidPixFmt;
+	LOG(MaliC55, Error) << "Sensor doesn't provide a raw bayer format";
+	return false;
 }
 
 void MaliC55CameraData::updateControls(const ControlInfoMap &ipaControls)
@@ -402,34 +398,13 @@ void MaliC55CameraData::updateControls(const ControlInfoMap &ipaControls)
 	controlInfo_ = ControlInfoMap(std::move(controls), controls::controls);
 }
 
-/*
- * Make sure the provided raw pixel format is supported and adjust it to
- * one of the supported ones if it's not.
- */
-PixelFormat MaliC55CameraData::adjustRawFormat(const PixelFormat &rawFmt) const
-{
-	/* Make sure the RAW mbus code is supported by the image source. */
-	int rawCode = pixfmtToMbusCode(rawFmt);
-	if (rawCode < 0)
-		return bestRawFormat();
-
-	const auto rawSizes = sizes(rawCode);
-	if (rawSizes.empty())
-		return bestRawFormat();
-
-	return rawFmt;
-}
-
-Size MaliC55CameraData::adjustRawSizes(const PixelFormat &rawFmt, const Size &size) const
+Size MaliC55CameraData::adjustRawSizes(const Size &size,
+				       unsigned int rawCode) const
 {
 	/* Expand the RAW size to the minimum ISP input size. */
 	Size rawSize = size.expandedTo(kMaliC55MinInputSize);
 
 	/* Check if the size is natively supported. */
-	int rawCode = pixfmtToMbusCode(rawFmt);
-	if (rawCode < 0)
-		return {};
-
 	const auto rawSizes = sizes(rawCode);
 	auto sizeIt = std::find(rawSizes.begin(), rawSizes.end(), rawSize);
 	if (sizeIt != rawSizes.end())
@@ -552,21 +527,28 @@ CameraConfiguration::Status MaliC55CameraConfiguration::validate()
 		rawConfig = &config;
 	}
 
+	/* Populate a valid sensor mbus code */
+	ColorFilterArray cfa = data_->bayerOrder(combinedTransform_);
+	int code = data_->bestMbusCode(cfa);
+	if (code < 0)
+		return Invalid;
+
+	sensorFormat_.code = code;
+
 	/*
 	 * The C55 can not upscale. Limit the configuration to the ISP
 	 * capabilities and the sensor resolution.
 	 */
 	Size maxSize = kMaliC55MaxSize.boundedTo(data_->resolution());
 	if (rawConfig) {
-		/*
-		 * \todo Take into account the Bayer components ordering once
-		 * we support rotations.
-		 */
-		PixelFormat rawFormat =
-			data_->adjustRawFormat(rawConfig->pixelFormat);
+		if (!rawConfig->bayerOrder ||
+		    rawConfig->bayerOrder.value() != cfa) {
+			rawConfig->bayerOrder = cfa;
+			status = Adjusted;
+		}
 
-		if (!rawFormat.isValid())
-			return Invalid;
+		/* C55 can only produce 16-bit raw output */
+		PixelFormat rawFormat = formats::RAW16;
 
 		if (rawFormat != rawConfig->pixelFormat) {
 			LOG(MaliC55, Debug)
@@ -576,7 +558,7 @@ CameraConfiguration::Status MaliC55CameraConfiguration::validate()
 		}
 
 		Size rawSize =
-			data_->adjustRawSizes(rawFormat, rawConfig->size);
+			data_->adjustRawSizes(rawConfig->size, sensorFormat_.code);
 		if (rawSize != rawConfig->size) {
 			LOG(MaliC55, Debug)
 				<< "RAW sizes adjusted to " << rawSize;
@@ -637,19 +619,15 @@ CameraConfiguration::Status MaliC55CameraConfiguration::validate()
 
 	/* If there's a RAW config, sensor configuration follows it. */
 	if (rawConfig) {
-		sensorFormat_.code = data_->pixfmtToMbusCode(rawConfig->pixelFormat);
 		sensorFormat_.size = rawConfig->size.expandedTo(minSensorSize);
 
 		return status;
 	}
 
 	/* If there's no RAW config, compute the sensor configuration here. */
-	PixelFormat rawFormat = data_->bestRawFormat();
-	if (!rawFormat.isValid())
+	if (!data_->isSensorRaw())
 		return Invalid;
 
-	sensorFormat_.code = data_->pixfmtToMbusCode(rawFormat);
-
 	uint16_t distance = std::numeric_limits<uint16_t>::max();
 	const auto sizes = data_->sizes(sensorFormat_.code);
 	Size bestSize;
@@ -799,6 +777,7 @@ PipelineHandlerMaliC55::generateConfiguration(Camera *camera,
 	std::unique_ptr<CameraConfiguration> config =
 		std::make_unique<MaliC55CameraConfiguration>(data);
 	bool frPipeAvailable = true;
+	ColorFilterArray cameraCfa = data->bayerOrder(Transform::Identity);
 
 	if (roles.empty())
 		return config;
@@ -838,12 +817,8 @@ PipelineHandlerMaliC55::generateConfiguration(Camera *camera,
 			break;
 
 		case StreamRole::Raw:
-			pixelFormat = data->bestRawFormat();
-			if (!pixelFormat.isValid()) {
-				LOG(MaliC55, Error)
-					<< "Camera does not support RAW formats";
+			if (!data->isSensorRaw())
 				return nullptr;
-			}
 
 			size = data->resolution();
 			break;
@@ -865,7 +840,7 @@ PipelineHandlerMaliC55::generateConfiguration(Camera *camera,
 
 			if (isRaw) {
 				/* Make sure the mbus code is supported. */
-				int rawCode = data->pixfmtToMbusCode(pixFmt);
+				int rawCode = data->bestMbusCode(cameraCfa);
 				if (rawCode < 0)
 					continue;
 
@@ -896,6 +871,9 @@ PipelineHandlerMaliC55::generateConfiguration(Camera *camera,
 		cfg.bufferCount = 4;
 		cfg.size = size;
 
+		if (role == StreamRole::Raw)
+			cfg.bayerOrder = cameraCfa;
+
 		config->addConfiguration(cfg);
 	}
 
@@ -1180,10 +1158,10 @@ int PipelineHandlerMaliC55::configure(Camera *camera,
 	 * affected by any flips that we've configured)
 	 */
 	const Transform &combinedTransform = maliConfig->combinedTransform();
-	ColorFilterArray::Order cfaOrder = data->sensor()->bayerOrder(combinedTransform);
+	ColorFilterArray cfa = data->bayerOrder(combinedTransform);
 
 	ControlInfoMap ipaControls;
-	ret = data->ipa_->configure(ipaConfig, utils::to_underlying(cfaOrder),
+	ret = data->ipa_->configure(ipaConfig, utils::to_underlying(cfa.order),
 				    &ipaControls);
 	if (ret) {
 		LOG(MaliC55, Error) << "Failed to configure IPA";
