[DNI,9/9] : rpi/pisp: Set format and bind ISP subdev
diff mbox series

Message ID 20250725-multicontext-v1-9-ea558291e101@ideasonboard.com
State New
Headers show
Series
  • libcamera: Support for multi-context operations
Related show

Commit Message

Jacopo Mondi July 25, 2025, 10:33 a.m. UTC
The in-review patch series that introduces multi-context support
in the Linux kernel also modifies the RaspberryPi BE driver to
expose the ISP subdevice to userspace.

In order to have this libcamera series tested with the kernel
series, set format on the ISP subdev to pass link validation and
also bind the ISP subdev to the media device context.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
 src/libcamera/pipeline/rpi/pisp/pisp.cpp | 49 +++++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp
index 49a97415c67f0c7c36b3c0b8bd597c278af16838..ea693da42e66cd4a2ea1770856fe3c4aa8f7d396 100644
--- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp
+++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp
@@ -780,6 +780,7 @@  public:
 
 	std::unique_ptr<V4L2Subdevice> csi2Subdev_;
 	std::unique_ptr<V4L2Subdevice> feSubdev_;
+	std::unique_ptr<V4L2Subdevice> ispSubdev_;
 
 	std::vector<FrameBuffer *> tdnBuffers_;
 	std::vector<FrameBuffer *> stitchBuffers_;
@@ -1136,8 +1137,14 @@  int PipelineHandlerPiSP::platformRegister(std::unique_ptr<RPi::CameraData> &came
 
 	data->csi2Subdev_ = std::make_unique<V4L2Subdevice>(cfe->getEntityByName("csi2"));
 	data->feSubdev_ = std::make_unique<V4L2Subdevice>(cfe->getEntityByName("pisp-fe"));
+	data->ispSubdev_ = std::make_unique<V4L2Subdevice>(isp->getEntityByName("pispbe"));
 	data->csi2Subdev_->open();
 	data->feSubdev_->open();
+	if (data->ispSubdev_->open()) {
+		/* Depends on an out-of-tree patch. */
+		LOG(RPI, Error) << "Make sure to have V4L2_SUBDEV_FL_HAS_DEVNODE in the pispbe driver";
+		return -EINVAL;
+	}
 
 	/*
 	 * Open all CFE and ISP streams. The exception is the embedded data
@@ -1177,6 +1184,7 @@  int PipelineHandlerPiSP::platformRegister(std::unique_ptr<RPi::CameraData> &came
 	data->bindDevice(data->isp_[Isp::TdnOutput].dev());
 	data->bindDevice(data->isp_[Isp::StitchInput].dev());
 	data->bindDevice(data->isp_[Isp::StitchOutput].dev());
+	data->bindDevice(data->ispSubdev_.get());
 
 	/* Write up all the IPA connections. */
 	data->ipa_->prepareIspComplete.connect(data, &PiSPCameraData::prepareIspComplete);
@@ -2188,6 +2196,10 @@  int PiSPCameraData::configureEntities(V4L2SubdeviceFormat sensorFormat,
 	constexpr unsigned int feVideo1SourcePad = 3;
 	constexpr unsigned int feStatsSourcePad = 4;
 
+	constexpr unsigned int ispInputPad = 0;
+	constexpr unsigned int ispOutput0Pad = 3;
+	constexpr unsigned int ispOutput1Pad = 4;
+
 	const MediaEntity *csi2 = csi2Subdev_->entity();
 	const MediaEntity *fe = feSubdev_->entity();
 
@@ -2253,8 +2265,43 @@  int PiSPCameraData::configureEntities(V4L2SubdeviceFormat sensorFormat,
 
 	feFormat.code = bayerToMbusCode(feOutputBayer);
 	ret = feSubdev_->setFormat(feVideo0SourcePad, &feFormat);
+	if (ret)
+		return ret;
 
-	return ret;
+	/* Apply format on the ISP subdev pad #0 (matches the input image size). */
+	V4L2DeviceFormat ispVdevFormat;
+	isp_[Isp::Input].dev()->getFormat(&ispVdevFormat);
+
+	V4L2SubdeviceFormat ispSubdevFormat;
+	ispSubdevFormat.code = MEDIA_BUS_FMT_FIXED;
+	ispSubdevFormat.size = ispVdevFormat.size;
+	ret = ispSubdev_->setFormat(ispInputPad, &ispSubdevFormat);
+	if (ret)
+		return ret;
+
+	/* Apply format on the ISP subdev pads connected to active inputs. */
+	pisp_be_global_config global;
+	be_->GetGlobal(global);
+	unsigned int beEnabled = global.rgb_enables;
+
+	if (beEnabled & PISP_BE_RGB_ENABLE_OUTPUT0) {
+		isp_[Isp::Output0].dev()->getFormat(&ispVdevFormat);
+
+		ispSubdevFormat.size = ispVdevFormat.size;
+		ret = ispSubdev_->setFormat(ispOutput0Pad, &ispSubdevFormat);
+		if (ret)
+			return ret;
+	}
+	if (beEnabled & PISP_BE_RGB_ENABLE_OUTPUT1) {
+		isp_[Isp::Output1].dev()->getFormat(&ispVdevFormat);
+
+		ispSubdevFormat.size = ispVdevFormat.size;
+		ret = ispSubdev_->setFormat(ispOutput1Pad, &ispSubdevFormat);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
 void PiSPCameraData::prepareCfe()