diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp
index f5f98c59..e973abc2 100644
--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp
+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp
@@ -57,22 +57,6 @@ const std::map<libcamera::PixelFormat, unsigned int> maliC55FmtToCode = {
 	{ formats::NV21, MEDIA_BUS_FMT_YUV10_1X30 },
 
 	/* RAW formats, FR pipe only. */
-	{ formats::SGBRG8, MEDIA_BUS_FMT_SGBRG8_1X8 },
-	{ formats::SRGGB8, MEDIA_BUS_FMT_SRGGB8_1X8 },
-	{ formats::SBGGR8, MEDIA_BUS_FMT_SBGGR8_1X8 },
-	{ formats::SGRBG8, MEDIA_BUS_FMT_SGRBG8_1X8 },
-	{ formats::SGBRG10, MEDIA_BUS_FMT_SGBRG10_1X10 },
-	{ formats::SRGGB10, MEDIA_BUS_FMT_SRGGB10_1X10 },
-	{ formats::SBGGR10, MEDIA_BUS_FMT_SBGGR10_1X10 },
-	{ formats::SGRBG10, MEDIA_BUS_FMT_SGRBG10_1X10 },
-	{ formats::SGBRG12, MEDIA_BUS_FMT_SGBRG12_1X12 },
-	{ formats::SRGGB12, MEDIA_BUS_FMT_SRGGB12_1X12 },
-	{ formats::SBGGR12, MEDIA_BUS_FMT_SBGGR12_1X12 },
-	{ formats::SGRBG12, MEDIA_BUS_FMT_SGRBG12_1X12 },
-	{ formats::SGBRG14, MEDIA_BUS_FMT_SGBRG14_1X14 },
-	{ formats::SRGGB14, MEDIA_BUS_FMT_SRGGB14_1X14 },
-	{ formats::SBGGR14, MEDIA_BUS_FMT_SBGGR14_1X14 },
-	{ formats::SGRBG14, MEDIA_BUS_FMT_SGRBG14_1X14 },
 	{ formats::SGBRG16, MEDIA_BUS_FMT_SGBRG16_1X16 },
 	{ formats::SRGGB16, MEDIA_BUS_FMT_SRGGB16_1X16 },
 	{ formats::SBGGR16, MEDIA_BUS_FMT_SBGGR16_1X16 },
@@ -98,7 +82,8 @@ public:
 	const std::vector<Size> sizes(unsigned int mbusCode) const;
 	const Size resolution() const;
 
-	PixelFormat bestRawFormat() const;
+	int pixfmtToMbusCode(const PixelFormat &pixFmt) const;
+	const PixelFormat &bestRawFormat() const;
 
 	PixelFormat adjustRawFormat(const PixelFormat &pixFmt) const;
 	Size adjustRawSizes(const PixelFormat &pixFmt, const Size &rawSize) const;
@@ -207,33 +192,78 @@ const Size MaliC55CameraData::resolution() const
 	return tpgResolution_;
 }
 
-PixelFormat MaliC55CameraData::bestRawFormat() const
+/*
+ * 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.
+ */
+int MaliC55CameraData::pixfmtToMbusCode(const PixelFormat &pixFmt) 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 = sd_->formats(0);
+	unsigned int sensorMbusCode = 0;
 	unsigned int bitDepth = 0;
-	PixelFormat rawFormat;
 
-	/*
-	 * Iterate over all the supported PixelFormat and find the one
-	 * supported by the camera with the largest bitdepth.
-	 */
-	for (const auto &maliFormat : maliC55FmtToCode) {
-		PixelFormat pixFmt = maliFormat.first;
-		if (!isFormatRaw(pixFmt))
+	for (const auto &[code, sizes] : formats) {
+		BayerFormat sdBayerFormat = BayerFormat::fromMbusCode(code);
+		if (!sdBayerFormat.isValid())
 			continue;
 
-		unsigned int rawCode = maliFormat.second;
-		const auto rawSizes = sizes(rawCode);
-		if (rawSizes.empty())
+		if (sdBayerFormat.order != bayerFormat.order)
+			continue;
+
+		if (sdBayerFormat.bitDepth > bitDepth) {
+			bitDepth = sdBayerFormat.bitDepth;
+			sensorMbusCode = code;
+		}
+	}
+
+	if (!sensorMbusCode)
+		return -EINVAL;
+
+	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
+{
+	static const PixelFormat invalidPixFmt = {};
+
+	for (const auto &fmt : sd_->formats(0)) {
+		BayerFormat sensorBayer = BayerFormat::fromMbusCode(fmt.first);
+
+		if (!sensorBayer.isValid())
 			continue;
 
-		BayerFormat bayer = BayerFormat::fromMbusCode(rawCode);
-		if (bayer.bitDepth > bitDepth) {
-			bitDepth = bayer.bitDepth;
-			rawFormat = pixFmt;
+		for (const auto &[pixFmt, rawCode] : maliC55FmtToCode) {
+			if (!isFormatRaw(pixFmt))
+				continue;
+
+			BayerFormat bayer = BayerFormat::fromMbusCode(rawCode);
+			if (bayer.order == sensorBayer.order)
+				return pixFmt;
 		}
 	}
 
-	return rawFormat;
+	LOG(MaliC55, Error) << "Sensor doesn't provide a compatible format";
+	return invalidPixFmt;
 }
 
 /*
@@ -242,13 +272,11 @@ PixelFormat MaliC55CameraData::bestRawFormat() const
  */
 PixelFormat MaliC55CameraData::adjustRawFormat(const PixelFormat &rawFmt) const
 {
-	/* Make sure the provided raw format is supported by the pipeline. */
-	auto it = maliC55FmtToCode.find(rawFmt);
-	if (it == maliC55FmtToCode.end())
+	/* Make sure the RAW mbus code is supported by the image source. */
+	int rawCode = pixfmtToMbusCode(rawFmt);
+	if (rawCode < 0)
 		return bestRawFormat();
 
-	/* Now make sure the RAW mbus code is supported by the image source. */
-	unsigned int rawCode = it->second;
 	const auto rawSizes = sizes(rawCode);
 	if (rawSizes.empty())
 		return bestRawFormat();
@@ -258,16 +286,14 @@ PixelFormat MaliC55CameraData::adjustRawFormat(const PixelFormat &rawFmt) const
 
 Size MaliC55CameraData::adjustRawSizes(const PixelFormat &rawFmt, const Size &size) const
 {
-	/* Just make sure the format is supported. */
-	auto it = maliC55FmtToCode.find(rawFmt);
-	if (it == maliC55FmtToCode.end())
-		return {};
-
 	/* Expand the RAW size to the minimum ISP input size. */
 	Size rawSize = size.expandedTo(kMaliC55MinInputSize);
 
 	/* Check if the size is natively supported. */
-	unsigned int rawCode = it->second;
+	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())
@@ -348,6 +374,10 @@ CameraConfiguration::Status MaliC55CameraConfiguration::validate()
 		 */
 		PixelFormat rawFormat =
 			data_->adjustRawFormat(rawConfig->pixelFormat);
+
+		if (!rawFormat.isValid())
+			return Invalid;
+
 		if (rawFormat != rawConfig->pixelFormat) {
 			LOG(MaliC55, Debug)
 				<< "RAW format adjusted to " << rawFormat;
@@ -417,8 +447,7 @@ CameraConfiguration::Status MaliC55CameraConfiguration::validate()
 
 	/* If there's a RAW config, sensor configuration follows it. */
 	if (rawConfig) {
-		const auto it = maliC55FmtToCode.find(rawConfig->pixelFormat);
-		sensorFormat_.code = it->second;
+		sensorFormat_.code = data_->pixfmtToMbusCode(rawConfig->pixelFormat);
 		sensorFormat_.size = rawConfig->size.expandedTo(minSensorSize);
 
 		return status;
@@ -426,11 +455,13 @@ CameraConfiguration::Status MaliC55CameraConfiguration::validate()
 
 	/* If there's no RAW config, compute the sensor configuration here. */
 	PixelFormat rawFormat = data_->bestRawFormat();
-	const auto it = maliC55FmtToCode.find(rawFormat);
-	sensorFormat_.code = it->second;
+	if (!rawFormat.isValid())
+		return Invalid;
+
+	sensorFormat_.code = data_->pixfmtToMbusCode(rawFormat);
 
 	uint16_t distance = std::numeric_limits<uint16_t>::max();
-	const auto sizes = data_->sizes(it->second);
+	const auto sizes = data_->sizes(sensorFormat_.code);
 	Size bestSize;
 	for (const auto &size : sizes) {
 		if (minSensorSize.width > size.width ||
@@ -613,7 +644,10 @@ PipelineHandlerMaliC55::generateConfiguration(Camera *camera,
 
 			if (isRaw) {
 				/* Make sure the mbus code is supported. */
-				unsigned int rawCode = maliFormat.second;
+				int rawCode = data->pixfmtToMbusCode(pixFmt);
+				if (rawCode < 0)
+					continue;
+
 				const auto sizes = data->sizes(rawCode);
 				if (sizes.empty())
 					continue;
