[v2,14/16] pipeline: rkisp1: Query kernel for available params blocks
diff mbox series

Message ID 20250808141315.413839-15-stefan.klug@ideasonboard.com
State New
Headers show
Series
  • Implement WDR algorithm
Related show

Commit Message

Stefan Klug Aug. 8, 2025, 2:12 p.m. UTC
Query the params device for RKISP1_CID_SUPPORTED_PARAMS_BLOCKS and
inject the information into the IPA hardware context for use by the
algorithms.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
---
 include/libcamera/ipa/rkisp1.mojom       |  2 +-
 src/ipa/rkisp1/ipa_context.h             |  1 +
 src/ipa/rkisp1/rkisp1.cpp                | 20 +++++++++++-----
 src/libcamera/pipeline/rkisp1/rkisp1.cpp | 29 ++++++++++++++++++++----
 4 files changed, 41 insertions(+), 11 deletions(-)

Comments

Kieran Bingham Aug. 9, 2025, 5:34 p.m. UTC | #1
Quoting Stefan Klug (2025-08-08 15:12:52)
> Query the params device for RKISP1_CID_SUPPORTED_PARAMS_BLOCKS and
> inject the information into the IPA hardware context for use by the
> algorithms.
> 
> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> ---
>  include/libcamera/ipa/rkisp1.mojom       |  2 +-
>  src/ipa/rkisp1/ipa_context.h             |  1 +
>  src/ipa/rkisp1/rkisp1.cpp                | 20 +++++++++++-----
>  src/libcamera/pipeline/rkisp1/rkisp1.cpp | 29 ++++++++++++++++++++----
>  4 files changed, 41 insertions(+), 11 deletions(-)
> 
> diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom
> index 043ad27ea199..068e898848c4 100644
> --- a/include/libcamera/ipa/rkisp1.mojom
> +++ b/include/libcamera/ipa/rkisp1.mojom
> @@ -16,7 +16,7 @@ struct IPAConfigInfo {
>  
>  interface IPARkISP1Interface {
>         init(libcamera.IPASettings settings,
> -            uint32 hwRevision,
> +            uint32 hwRevision, uint32 supportedBlocks,
>              libcamera.IPACameraSensorInfo sensorInfo,
>              libcamera.ControlInfoMap sensorControls)
>                 => (int32 ret, libcamera.ControlInfoMap ipaControls);
> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
> index 362ab2fda5fe..60cfab228edf 100644
> --- a/src/ipa/rkisp1/ipa_context.h
> +++ b/src/ipa/rkisp1/ipa_context.h
> @@ -36,6 +36,7 @@ struct IPAHwSettings {
>         unsigned int numHistogramBins;
>         unsigned int numHistogramWeights;
>         unsigned int numGammaOutSamples;
> +       uint32_t supportedBlocks;
>         bool compand;
>  };
>  
> diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
> index cf66d5553dcd..9ba0f0e6eb9d 100644
> --- a/src/ipa/rkisp1/rkisp1.cpp
> +++ b/src/ipa/rkisp1/rkisp1.cpp
> @@ -52,6 +52,7 @@ public:
>         IPARkISP1();
>  
>         int init(const IPASettings &settings, unsigned int hwRevision,
> +                uint32_t supportedBlocks,
>                  const IPACameraSensorInfo &sensorInfo,
>                  const ControlInfoMap &sensorControls,
>                  ControlInfoMap *ipaControls) override;
> @@ -89,27 +90,30 @@ private:
>  
>  namespace {
>  
> -const IPAHwSettings ipaHwSettingsV10{
> +IPAHwSettings ipaHwSettingsV10{
>         RKISP1_CIF_ISP_AE_MEAN_MAX_V10,
>         RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10,
>         RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10,
>         RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10,
> +       0,
>         false,
>  };
>  
> -const IPAHwSettings ipaHwSettingsIMX8MP{
> +IPAHwSettings ipaHwSettingsIMX8MP{
>         RKISP1_CIF_ISP_AE_MEAN_MAX_V10,
>         RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10,
>         RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10,
>         RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10,
> +       0,
>         true,
>  };
>  
> -const IPAHwSettings ipaHwSettingsV12{
> +IPAHwSettings ipaHwSettingsV12{
>         RKISP1_CIF_ISP_AE_MEAN_MAX_V12,
>         RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12,
>         RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12,
>         RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12,
> +       0,
>         false,
>  };
>  
> @@ -132,20 +136,22 @@ std::string IPARkISP1::logPrefix() const
>  }
>  
>  int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
> +                   uint32_t supportedBlocks,
>                     const IPACameraSensorInfo &sensorInfo,
>                     const ControlInfoMap &sensorControls,
>                     ControlInfoMap *ipaControls)
>  {
> +       IPAHwSettings *hw = nullptr;
>         /* \todo Add support for other revisions */
>         switch (hwRevision) {
>         case RKISP1_V10:
> -               context_.hw = &ipaHwSettingsV10;
> +               hw = &ipaHwSettingsV10;
>                 break;
>         case RKISP1_V_IMX8MP:
> -               context_.hw = &ipaHwSettingsIMX8MP;
> +               hw = &ipaHwSettingsIMX8MP;
>                 break;
>         case RKISP1_V12:
> -               context_.hw = &ipaHwSettingsV12;
> +               hw = &ipaHwSettingsV12;
>                 break;
>         default:
>                 LOG(IPARkISP1, Error)
> @@ -153,6 +159,8 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
>                         << " is currently not supported";
>                 return -ENODEV;
>         }
> +       hw->supportedBlocks = supportedBlocks;
> +       context_.hw = hw;
>  
>         LOG(IPARkISP1, Debug) << "Hardware revision is " << hwRevision;
>  
> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> index 06785cb2fd57..435c618731a2 100644
> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> @@ -100,7 +100,7 @@ public:
>  
>         PipelineHandlerRkISP1 *pipe();
>         const PipelineHandlerRkISP1 *pipe() const;
> -       int loadIPA(unsigned int hwRevision);
> +       int loadIPA(unsigned int hwRevision, uint32_t supportedBlocks);
>  
>         Stream mainPathStream_;
>         Stream selfPathStream_;
> @@ -390,7 +390,7 @@ const PipelineHandlerRkISP1 *RkISP1CameraData::pipe() const
>         return static_cast<const PipelineHandlerRkISP1 *>(Camera::Private::pipe());
>  }
>  
> -int RkISP1CameraData::loadIPA(unsigned int hwRevision)
> +int RkISP1CameraData::loadIPA(unsigned int hwRevision, uint32_t supportedBlocks)
>  {
>         ipa_ = IPAManager::createIPA<ipa::rkisp1::IPAProxyRkISP1>(pipe(), 1, 1);
>         if (!ipa_)
> @@ -412,7 +412,8 @@ int RkISP1CameraData::loadIPA(unsigned int hwRevision)
>         }
>  
>         ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision,
> -                        sensorInfo, sensor_->controls(), &ipaControls_);
> +                        supportedBlocks, sensorInfo, sensor_->controls(),
> +                        &ipaControls_);
>         if (ret < 0) {
>                 LOG(RkISP1, Error) << "IPA initialization failure";
>                 return ret;
> @@ -1318,6 +1319,12 @@ int PipelineHandlerRkISP1::updateControls(RkISP1CameraData *data)
>         return 0;
>  }
>  
> +/*
> + * By default we assume all the blocks that were included in the first
> + * extensible parameters series are available. That is the lower 20bits.
> + */
> +const uint32_t kDefaultExtParamsBlocks = 0xfffff;
> +
>  int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
>  {
>         int ret;
> @@ -1355,7 +1362,21 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
>         isp_->frameStart.connect(data->delayedCtrls_.get(),
>                                  &DelayedControls::applyControls);
>  
> -       ret = data->loadIPA(media_->hwRevision());
> +       uint32_t supportedBlocks = kDefaultExtParamsBlocks;
> +
> +       auto &controls = param_->controls();
> +       if (controls.find(RKISP1_CID_SUPPORTED_PARAMS_BLOCKS) != controls.end()) {
> +               auto ctrl = param_->getControls({ RKISP1_CID_SUPPORTED_PARAMS_BLOCKS });
> +               supportedBlocks = static_cast<uint32_t>(
> +                       ctrl.get(RKISP1_CID_SUPPORTED_PARAMS_BLOCKS).get<int32_t>());
> +       } else {
> +               LOG(RkISP1, Error)
> +                       << "Failed to query supported params blocks. Falling back to defaults.";
> +       }
> +
> +       LOG(RkISP1, Error) << "Supported params blocks: " << supportedBlocks;

Perhaps just a LOG(, Debug) ?

Otherwise, it seems reasonable so with that:

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

> +
> +       ret = data->loadIPA(media_->hwRevision(), supportedBlocks);
>         if (ret)
>                 return ret;
>  
> -- 
> 2.48.1
>
Dan Scally Aug. 14, 2025, 12:21 p.m. UTC | #2
Hi Stefan

On 08/08/2025 15:12, Stefan Klug wrote:
> Query the params device for RKISP1_CID_SUPPORTED_PARAMS_BLOCKS and
> inject the information into the IPA hardware context for use by the
> algorithms.
> 
> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> ---

Couple of nitpicks, but:

Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>

>   include/libcamera/ipa/rkisp1.mojom       |  2 +-
>   src/ipa/rkisp1/ipa_context.h             |  1 +
>   src/ipa/rkisp1/rkisp1.cpp                | 20 +++++++++++-----
>   src/libcamera/pipeline/rkisp1/rkisp1.cpp | 29 ++++++++++++++++++++----
>   4 files changed, 41 insertions(+), 11 deletions(-)
> 
> diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom
> index 043ad27ea199..068e898848c4 100644
> --- a/include/libcamera/ipa/rkisp1.mojom
> +++ b/include/libcamera/ipa/rkisp1.mojom
> @@ -16,7 +16,7 @@ struct IPAConfigInfo {
>   
>   interface IPARkISP1Interface {
>   	init(libcamera.IPASettings settings,
> -	     uint32 hwRevision,
> +	     uint32 hwRevision, uint32 supportedBlocks,
>   	     libcamera.IPACameraSensorInfo sensorInfo,
>   	     libcamera.ControlInfoMap sensorControls)
>   		=> (int32 ret, libcamera.ControlInfoMap ipaControls);
> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
> index 362ab2fda5fe..60cfab228edf 100644
> --- a/src/ipa/rkisp1/ipa_context.h
> +++ b/src/ipa/rkisp1/ipa_context.h
> @@ -36,6 +36,7 @@ struct IPAHwSettings {
>   	unsigned int numHistogramBins;
>   	unsigned int numHistogramWeights;
>   	unsigned int numGammaOutSamples;
> +	uint32_t supportedBlocks;
>   	bool compand;
>   };
>   
> diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
> index cf66d5553dcd..9ba0f0e6eb9d 100644
> --- a/src/ipa/rkisp1/rkisp1.cpp
> +++ b/src/ipa/rkisp1/rkisp1.cpp
> @@ -52,6 +52,7 @@ public:
>   	IPARkISP1();
>   
>   	int init(const IPASettings &settings, unsigned int hwRevision,
> +		 uint32_t supportedBlocks,
>   		 const IPACameraSensorInfo &sensorInfo,
>   		 const ControlInfoMap &sensorControls,
>   		 ControlInfoMap *ipaControls) override;
> @@ -89,27 +90,30 @@ private:
>   
>   namespace {
>   
> -const IPAHwSettings ipaHwSettingsV10{
> +IPAHwSettings ipaHwSettingsV10{
>   	RKISP1_CIF_ISP_AE_MEAN_MAX_V10,
>   	RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10,
>   	RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10,
>   	RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10,
> +	0,
>   	false,
>   };
>   
> -const IPAHwSettings ipaHwSettingsIMX8MP{
> +IPAHwSettings ipaHwSettingsIMX8MP{
>   	RKISP1_CIF_ISP_AE_MEAN_MAX_V10,
>   	RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10,
>   	RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10,
>   	RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10,
> +	0,
>   	true,
>   };
>   
> -const IPAHwSettings ipaHwSettingsV12{
> +IPAHwSettings ipaHwSettingsV12{
>   	RKISP1_CIF_ISP_AE_MEAN_MAX_V12,
>   	RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12,
>   	RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12,
>   	RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12,
> +	0,
>   	false,
>   };
>   
> @@ -132,20 +136,22 @@ std::string IPARkISP1::logPrefix() const
>   }
>   
>   int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
> +		    uint32_t supportedBlocks,
>   		    const IPACameraSensorInfo &sensorInfo,
>   		    const ControlInfoMap &sensorControls,
>   		    ControlInfoMap *ipaControls)
>   {
> +	IPAHwSettings *hw = nullptr;
>   	/* \todo Add support for other revisions */
>   	switch (hwRevision) {
>   	case RKISP1_V10:
> -		context_.hw = &ipaHwSettingsV10;
> +		hw = &ipaHwSettingsV10;
>   		break;
>   	case RKISP1_V_IMX8MP:
> -		context_.hw = &ipaHwSettingsIMX8MP;
> +		hw = &ipaHwSettingsIMX8MP;
>   		break;
>   	case RKISP1_V12:
> -		context_.hw = &ipaHwSettingsV12;
> +		hw = &ipaHwSettingsV12;
>   		break;
>   	default:
>   		LOG(IPARkISP1, Error)
> @@ -153,6 +159,8 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
>   			<< " is currently not supported";
>   		return -ENODEV;
>   	}
> +	hw->supportedBlocks = supportedBlocks;
> +	context_.hw = hw;
>   
>   	LOG(IPARkISP1, Debug) << "Hardware revision is " << hwRevision;
>   
> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> index 06785cb2fd57..435c618731a2 100644
> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> @@ -100,7 +100,7 @@ public:
>   
>   	PipelineHandlerRkISP1 *pipe();
>   	const PipelineHandlerRkISP1 *pipe() const;
> -	int loadIPA(unsigned int hwRevision);
> +	int loadIPA(unsigned int hwRevision, uint32_t supportedBlocks);
>   
>   	Stream mainPathStream_;
>   	Stream selfPathStream_;
> @@ -390,7 +390,7 @@ const PipelineHandlerRkISP1 *RkISP1CameraData::pipe() const
>   	return static_cast<const PipelineHandlerRkISP1 *>(Camera::Private::pipe());
>   }
>   
> -int RkISP1CameraData::loadIPA(unsigned int hwRevision)
> +int RkISP1CameraData::loadIPA(unsigned int hwRevision, uint32_t supportedBlocks)
>   {
>   	ipa_ = IPAManager::createIPA<ipa::rkisp1::IPAProxyRkISP1>(pipe(), 1, 1);
>   	if (!ipa_)
> @@ -412,7 +412,8 @@ int RkISP1CameraData::loadIPA(unsigned int hwRevision)
>   	}
>   
>   	ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision,
> -			 sensorInfo, sensor_->controls(), &ipaControls_);
> +			 supportedBlocks, sensorInfo, sensor_->controls(),
> +			 &ipaControls_);
>   	if (ret < 0) {
>   		LOG(RkISP1, Error) << "IPA initialization failure";
>   		return ret;
> @@ -1318,6 +1319,12 @@ int PipelineHandlerRkISP1::updateControls(RkISP1CameraData *data)
>   	return 0;
>   }
>   
> +/*
> + * By default we assume all the blocks that were included in the first
> + * extensible parameters series are available. That is the lower 20bits.
> + */
> +const uint32_t kDefaultExtParamsBlocks = 0xfffff;
> +
>   int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
>   {
>   	int ret;
> @@ -1355,7 +1362,21 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
>   	isp_->frameStart.connect(data->delayedCtrls_.get(),
>   				 &DelayedControls::applyControls);
>   
> -	ret = data->loadIPA(media_->hwRevision());
> +	uint32_t supportedBlocks = kDefaultExtParamsBlocks;
> +
> +	auto &controls = param_->controls();
> +	if (controls.find(RKISP1_CID_SUPPORTED_PARAMS_BLOCKS) != controls.end()) {
> +		auto ctrl = param_->getControls({ RKISP1_CID_SUPPORTED_PARAMS_BLOCKS });
> +		supportedBlocks = static_cast<uint32_t>(
> +			ctrl.get(RKISP1_CID_SUPPORTED_PARAMS_BLOCKS).get<int32_t>());

getControls() has failure modes; maybe 
.get(<int32_t>)(kDefaultExtParamsBlocks)?

> +	} else {
> +		LOG(RkISP1, Error)
> +			<< "Failed to query supported params blocks. Falling back to defaults.";
> +	}
> +
> +	LOG(RkISP1, Error) << "Supported params blocks: " << supportedBlocks;

Probably meant to be a debug call

> +
> +	ret = data->loadIPA(media_->hwRevision(), supportedBlocks);
>   	if (ret)
>   		return ret;
>

Patch
diff mbox series

diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom
index 043ad27ea199..068e898848c4 100644
--- a/include/libcamera/ipa/rkisp1.mojom
+++ b/include/libcamera/ipa/rkisp1.mojom
@@ -16,7 +16,7 @@  struct IPAConfigInfo {
 
 interface IPARkISP1Interface {
 	init(libcamera.IPASettings settings,
-	     uint32 hwRevision,
+	     uint32 hwRevision, uint32 supportedBlocks,
 	     libcamera.IPACameraSensorInfo sensorInfo,
 	     libcamera.ControlInfoMap sensorControls)
 		=> (int32 ret, libcamera.ControlInfoMap ipaControls);
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index 362ab2fda5fe..60cfab228edf 100644
--- a/src/ipa/rkisp1/ipa_context.h
+++ b/src/ipa/rkisp1/ipa_context.h
@@ -36,6 +36,7 @@  struct IPAHwSettings {
 	unsigned int numHistogramBins;
 	unsigned int numHistogramWeights;
 	unsigned int numGammaOutSamples;
+	uint32_t supportedBlocks;
 	bool compand;
 };
 
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index cf66d5553dcd..9ba0f0e6eb9d 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -52,6 +52,7 @@  public:
 	IPARkISP1();
 
 	int init(const IPASettings &settings, unsigned int hwRevision,
+		 uint32_t supportedBlocks,
 		 const IPACameraSensorInfo &sensorInfo,
 		 const ControlInfoMap &sensorControls,
 		 ControlInfoMap *ipaControls) override;
@@ -89,27 +90,30 @@  private:
 
 namespace {
 
-const IPAHwSettings ipaHwSettingsV10{
+IPAHwSettings ipaHwSettingsV10{
 	RKISP1_CIF_ISP_AE_MEAN_MAX_V10,
 	RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10,
 	RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10,
 	RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10,
+	0,
 	false,
 };
 
-const IPAHwSettings ipaHwSettingsIMX8MP{
+IPAHwSettings ipaHwSettingsIMX8MP{
 	RKISP1_CIF_ISP_AE_MEAN_MAX_V10,
 	RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10,
 	RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10,
 	RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10,
+	0,
 	true,
 };
 
-const IPAHwSettings ipaHwSettingsV12{
+IPAHwSettings ipaHwSettingsV12{
 	RKISP1_CIF_ISP_AE_MEAN_MAX_V12,
 	RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12,
 	RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12,
 	RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12,
+	0,
 	false,
 };
 
@@ -132,20 +136,22 @@  std::string IPARkISP1::logPrefix() const
 }
 
 int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
+		    uint32_t supportedBlocks,
 		    const IPACameraSensorInfo &sensorInfo,
 		    const ControlInfoMap &sensorControls,
 		    ControlInfoMap *ipaControls)
 {
+	IPAHwSettings *hw = nullptr;
 	/* \todo Add support for other revisions */
 	switch (hwRevision) {
 	case RKISP1_V10:
-		context_.hw = &ipaHwSettingsV10;
+		hw = &ipaHwSettingsV10;
 		break;
 	case RKISP1_V_IMX8MP:
-		context_.hw = &ipaHwSettingsIMX8MP;
+		hw = &ipaHwSettingsIMX8MP;
 		break;
 	case RKISP1_V12:
-		context_.hw = &ipaHwSettingsV12;
+		hw = &ipaHwSettingsV12;
 		break;
 	default:
 		LOG(IPARkISP1, Error)
@@ -153,6 +159,8 @@  int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
 			<< " is currently not supported";
 		return -ENODEV;
 	}
+	hw->supportedBlocks = supportedBlocks;
+	context_.hw = hw;
 
 	LOG(IPARkISP1, Debug) << "Hardware revision is " << hwRevision;
 
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 06785cb2fd57..435c618731a2 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -100,7 +100,7 @@  public:
 
 	PipelineHandlerRkISP1 *pipe();
 	const PipelineHandlerRkISP1 *pipe() const;
-	int loadIPA(unsigned int hwRevision);
+	int loadIPA(unsigned int hwRevision, uint32_t supportedBlocks);
 
 	Stream mainPathStream_;
 	Stream selfPathStream_;
@@ -390,7 +390,7 @@  const PipelineHandlerRkISP1 *RkISP1CameraData::pipe() const
 	return static_cast<const PipelineHandlerRkISP1 *>(Camera::Private::pipe());
 }
 
-int RkISP1CameraData::loadIPA(unsigned int hwRevision)
+int RkISP1CameraData::loadIPA(unsigned int hwRevision, uint32_t supportedBlocks)
 {
 	ipa_ = IPAManager::createIPA<ipa::rkisp1::IPAProxyRkISP1>(pipe(), 1, 1);
 	if (!ipa_)
@@ -412,7 +412,8 @@  int RkISP1CameraData::loadIPA(unsigned int hwRevision)
 	}
 
 	ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision,
-			 sensorInfo, sensor_->controls(), &ipaControls_);
+			 supportedBlocks, sensorInfo, sensor_->controls(),
+			 &ipaControls_);
 	if (ret < 0) {
 		LOG(RkISP1, Error) << "IPA initialization failure";
 		return ret;
@@ -1318,6 +1319,12 @@  int PipelineHandlerRkISP1::updateControls(RkISP1CameraData *data)
 	return 0;
 }
 
+/*
+ * By default we assume all the blocks that were included in the first
+ * extensible parameters series are available. That is the lower 20bits.
+ */
+const uint32_t kDefaultExtParamsBlocks = 0xfffff;
+
 int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
 {
 	int ret;
@@ -1355,7 +1362,21 @@  int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
 	isp_->frameStart.connect(data->delayedCtrls_.get(),
 				 &DelayedControls::applyControls);
 
-	ret = data->loadIPA(media_->hwRevision());
+	uint32_t supportedBlocks = kDefaultExtParamsBlocks;
+
+	auto &controls = param_->controls();
+	if (controls.find(RKISP1_CID_SUPPORTED_PARAMS_BLOCKS) != controls.end()) {
+		auto ctrl = param_->getControls({ RKISP1_CID_SUPPORTED_PARAMS_BLOCKS });
+		supportedBlocks = static_cast<uint32_t>(
+			ctrl.get(RKISP1_CID_SUPPORTED_PARAMS_BLOCKS).get<int32_t>());
+	} else {
+		LOG(RkISP1, Error)
+			<< "Failed to query supported params blocks. Falling back to defaults.";
+	}
+
+	LOG(RkISP1, Error) << "Supported params blocks: " << supportedBlocks;
+
+	ret = data->loadIPA(media_->hwRevision(), supportedBlocks);
 	if (ret)
 		return ret;