@@ -9,6 +9,22 @@
#define __UAPI_MALI_C55_CONFIG_H
#include <linux/types.h>
+#include <linux/v4l2-controls.h>
+
+#include <linux/media/v4l2-extensible-params.h>
+
+#define V4L2_CID_MALI_C55_CAPABILITIES (V4L2_CID_USER_MALI_C55_BASE + 0x0)
+#define MALI_C55_GPS_PONG (1U << 0)
+#define MALI_C55_GPS_WDR (1U << 1)
+#define MALI_C55_GPS_COMPRESSION (1U << 2)
+#define MALI_C55_GPS_TEMPER (1U << 3)
+#define MALI_C55_GPS_SINTER_LITE (1U << 4)
+#define MALI_C55_GPS_SINTER (1U << 5)
+#define MALI_C55_GPS_IRIDIX_LTM (1U << 6)
+#define MALI_C55_GPS_IRIDIX_GTM (1U << 7)
+#define MALI_C55_GPS_CNR (1U << 8)
+#define MALI_C55_GPS_FRSCALER (1U << 9)
+#define MALI_C55_GPS_DS_PIPE (1U << 10)
/*
* Frames are split into zones of almost equal width and height - a zone is a
@@ -228,65 +244,6 @@ enum mali_c55_param_block_type {
MALI_C55_PARAM_MESH_SHADING_SELECTION,
};
-#define MALI_C55_PARAM_BLOCK_FL_NONE 0
-#define MALI_C55_PARAM_BLOCK_FL_DISABLED BIT(0)
-
-/**
- * struct mali_c55_params_block_header - Mali-C55 parameter block header
- *
- * This structure represents the common part of all the ISP configuration
- * blocks. Each parameters block embeds an instance of this structure type
- * as its first member, followed by the block-specific configuration data. The
- * driver inspects this common header to discern the block type and its size and
- * properly handle the block content by casting it to the correct block-specific
- * type.
- *
- * The @type field is one of the values enumerated by
- * :c:type:`mali_c55_param_block_type` and specifies how the data should be
- * interpreted by the driver. The @size field specifies the size of the
- * parameters block and is used by the driver for validation purposes. The
- * @flags field holds a bitmask of per-block flags MALI_C55_PARAM_BLOCK_FL_*.
- *
- * If userspace wants to disable an ISP block the
- * MALI_C55_PARAM_BLOCK_FL_DISABLED bit should be set in the @flags field. In
- * that case userspace may optionally omit the remainder of the configuration
- * block, which will in any case be ignored by the driver. If a new
- * configuration of an ISP block has to be applied userspace shall fully
- * populate the ISP block and omit setting the MALI_C55_PARAM_BLOCK_FL_DISABLED
- * bit in the @flags field.
- *
- * Userspace is responsible for correctly populating the parameters block header
- * fields (@type, @flags and @size) and correctly populate the block-specific
- * parameters.
- *
- * For example:
- *
- * .. code-block:: c
- *
- * void populate_sensor_offs(struct mali_c55_params_block_header *block) {
- * block->type = MALI_C55_PARAM_BLOCK_SENSOR_OFFS;
- * block->enabled = MALI_C55_PARAM_BLOCK_FL_NONE;
- * block->size = sizeof(struct mali_c55_params_sensor_off_preshading);
- *
- * struct mali_c55_params_sensor_off_preshading *sensor_offs =
- * (struct mali_c55_params_sensor_off_preshading *)block;
- *
- * sensor_offs->chan00 = offset00;
- * sensor_offs->chan01 = offset01;
- * sensor_offs->chan10 = offset10;
- * sensor_offs->chan11 = offset11;
- * }
- *
- * @type: The parameters block type from :c:type:`mali_c55_param_block_type`
- * @flags: Bitmask of block flags
- * @size: Size (in bytes) of the parameters block
- */
-struct mali_c55_params_block_header {
- __u16 type;
- __u16 flags;
- __u32 size;
-} __attribute__((aligned(8)));
-
/**
* struct mali_c55_params_sensor_off_preshading - offset subtraction for each
* color channel
@@ -305,7 +262,7 @@ struct mali_c55_params_block_header {
* @chan11: Offset for color channel 11 (default: B)
*/
struct mali_c55_params_sensor_off_preshading {
- struct mali_c55_params_block_header header;
+ struct v4l2_params_block_header header;
__u32 chan00;
__u32 chan01;
__u32 chan10;
@@ -470,7 +427,7 @@ enum mali_c55_aexp_hist_plane_mode {
* This parameter is unused for the post-Iridix Histogram
*/
struct mali_c55_params_aexp_hist {
- struct mali_c55_params_block_header header;
+ struct v4l2_params_block_header header;
__u8 skip_x;
__u8 offset_x;
__u8 skip_y;
@@ -502,7 +459,7 @@ struct mali_c55_params_aexp_hist {
* @nodes_used_horiz
*/
struct mali_c55_params_aexp_weights {
- struct mali_c55_params_block_header header;
+ struct v4l2_params_block_header header;
__u8 nodes_used_horiz;
__u8 nodes_used_vert;
__u8 zone_weights[MALI_C55_MAX_ZONES];
@@ -520,7 +477,7 @@ struct mali_c55_params_aexp_weights {
* @gain: The digital gain value to apply, in Q5.8 format.
*/
struct mali_c55_params_digital_gain {
- struct mali_c55_params_block_header header;
+ struct v4l2_params_block_header header;
__u16 gain;
};
@@ -560,7 +517,7 @@ enum mali_c55_awb_stats_mode {
* @gain11: Multiplier for colour channel 11
*/
struct mali_c55_params_awb_gains {
- struct mali_c55_params_block_header header;
+ struct v4l2_params_block_header header;
__u16 gain00;
__u16 gain01;
__u16 gain10;
@@ -635,7 +592,7 @@ enum mali_c55_params_awb_tap_points {
* @cb_low: B/G ratio trim low (Q4.8 format)
*/
struct mali_c55_params_awb_config {
- struct mali_c55_params_block_header header;
+ struct v4l2_params_block_header header;
__u8 tap_point;
__u8 stats_mode;
__u16 white_level;
@@ -745,7 +702,7 @@ struct mali_c55_params_awb_config {
* @mesh: Mesh shading correction tables
*/
struct mali_c55_params_mesh_shading_config {
- struct mali_c55_params_block_header header;
+ struct v4l2_params_block_header header;
__u8 mesh_show;
__u8 mesh_scale;
__u8 mesh_page_r;
@@ -800,7 +757,7 @@ enum mali_c55_params_mesh_alpha_bank {
* @mesh_strength: Mesh strength in Q4.12 format [0..4096]
*/
struct mali_c55_params_mesh_shading_selection {
- struct mali_c55_params_block_header header;
+ struct v4l2_params_block_header header;
__u8 mesh_alpha_bank_r;
__u8 mesh_alpha_bank_g;
__u8 mesh_alpha_bank_b;
@@ -835,75 +792,4 @@ struct mali_c55_params_mesh_shading_selection {
sizeof(struct mali_c55_params_mesh_shading_config) + \
sizeof(struct mali_c55_params_mesh_shading_selection))
-/**
- * struct mali_c55_params_buffer - 3A configuration parameters
- *
- * This struct contains the configuration parameters of the Mali-C55 ISP
- * algorithms, serialized by userspace into a data buffer. Each configuration
- * parameter block is represented by a block-specific structure which contains a
- * :c:type:`mali_c55_params_block_header` entry as first member. Userspace
- * populates the @data buffer with configuration parameters for the blocks that
- * it intends to configure. As a consequence, the data buffer effective size
- * changes according to the number of ISP blocks that userspace intends to
- * configure.
- *
- * The parameters buffer is versioned by the @version field to allow modifying
- * and extending its definition. Userspace shall populate the @version field to
- * inform the driver about the version it intends to use. The driver will parse
- * and handle the @data buffer according to the data layout specific to the
- * indicated version and return an error if the desired version is not
- * supported.
- *
- * For each ISP block that userspace wants to configure, a block-specific
- * structure is appended to the @data buffer, one after the other without gaps
- * in between nor overlaps. Userspace shall populate the @total_size field with
- * the effective size, in bytes, of the @data buffer.
- *
- * The expected memory layout of the parameters buffer is::
- *
- * +-------------------- struct mali_c55_params_buffer ------------------+
- * | version = MALI_C55_PARAM_BUFFER_V1; |
- * | total_size = sizeof(struct mali_c55_params_sensor_off_preshading) |
- * | sizeof(struct mali_c55_params_aexp_hist); |
- * | +------------------------- data ---------------------------------+ |
- * | | +--------- struct mali_c55_params_sensor_off_preshading ------+ | |
- * | | | +-------- struct mali_c55_params_block_header header -----+ | | |
- * | | | | type = MALI_C55_PARAM_BLOCK_SENSOR_OFFS; | | | |
- * | | | | flags = MALI_C55_PARAM_BLOCK_FL_NONE; | | | |
- * | | | | size = | | | |
- * | | | | sizeof(struct mali_c55_params_sensor_off_preshading);| | | |
- * | | | +---------------------------------------------------------+ | | |
- * | | | chan00 = ...; | | |
- * | | | chan01 = ...; | | |
- * | | | chan10 = ...; | | |
- * | | | chan11 = ...; | | |
- * | | +------------ struct mali_c55_params_aexp_hist ---------------+ | |
- * | | | +-------- struct mali_c55_params_block_header header -----+ | | |
- * | | | | type = MALI_C55_PARAM_BLOCK_AEXP_HIST; | | | |
- * | | | | flags = MALI_C55_PARAM_BLOCK_FL_NONE; | | | |
- * | | | | size = sizeof(struct mali_c55_params_aexp_hist); | | | |
- * | | | +---------------------------------------------------------+ | | |
- * | | | skip_x = ...; | | |
- * | | | offset_x = ...; | | |
- * | | | skip_y = ...; | | |
- * | | | offset_y = ...; | | |
- * | | | scale_bottom = ...; | | |
- * | | | scale_top = ...; | | |
- * | | | plane_mode = ...; | | |
- * | | | tap_point = ...; | | |
- * | | +-------------------------------------------------------------+ | |
- * | +-----------------------------------------------------------------+ |
- * +---------------------------------------------------------------------+
- *
- * @version: The version from :c:type:`mali_c55_param_buffer_version`
- * @total_size: The Mali-C55 configuration data effective size, excluding this
- * header
- * @data: The Mali-C55 configuration blocks data
- */
-struct mali_c55_params_buffer {
- __u8 version;
- __u32 total_size;
- __u8 data[MALI_C55_PARAMS_MAX_SIZE];
-};
-
#endif /* __UAPI_MALI_C55_CONFIG_H */
@@ -252,7 +252,7 @@ size_t Agc::fillGainParamBlock(IPAContext &context, IPAFrameContext &frameContex
gain = activeState.agc.manual.ispGain;
block.header->type = MALI_C55_PARAM_BLOCK_DIGITAL_GAIN;
- block.header->flags = MALI_C55_PARAM_BLOCK_FL_NONE;
+ block.header->flags = 0;
block.header->size = sizeof(struct mali_c55_params_digital_gain);
block.digital_gain->gain = floatingToFixedPoint<5, 8, uint16_t, double>(gain);
@@ -265,7 +265,7 @@ size_t Agc::fillParamsBuffer(mali_c55_params_block block,
enum mali_c55_param_block_type type)
{
block.header->type = type;
- block.header->flags = MALI_C55_PARAM_BLOCK_FL_NONE;
+ block.header->flags = 0;
block.header->size = sizeof(struct mali_c55_params_aexp_hist);
/* Collect every 3rd pixel horizontally */
@@ -291,7 +291,7 @@ size_t Agc::fillWeightsArrayBuffer(mali_c55_params_block block,
enum mali_c55_param_block_type type)
{
block.header->type = type;
- block.header->flags = MALI_C55_PARAM_BLOCK_FL_NONE;
+ block.header->flags = 0;
block.header->size = sizeof(struct mali_c55_params_aexp_weights);
/* We use every zone - a 15x15 grid */
@@ -313,30 +313,30 @@ size_t Agc::fillWeightsArrayBuffer(mali_c55_params_block block,
}
void Agc::prepare(IPAContext &context, const uint32_t frame,
- IPAFrameContext &frameContext, mali_c55_params_buffer *params)
+ IPAFrameContext &frameContext, v4l2_params_buffer *params)
{
mali_c55_params_block block;
- block.data = ¶ms->data[params->total_size];
- params->total_size += fillGainParamBlock(context, frameContext, block);
+ block.data = ¶ms->data[params->data_size];
+ params->data_size += fillGainParamBlock(context, frameContext, block);
if (frame > 0)
return;
- block.data = ¶ms->data[params->total_size];
- params->total_size += fillParamsBuffer(block,
+ block.data = ¶ms->data[params->data_size];
+ params->data_size += fillParamsBuffer(block,
MALI_C55_PARAM_BLOCK_AEXP_HIST);
- block.data = ¶ms->data[params->total_size];
- params->total_size += fillWeightsArrayBuffer(block,
+ block.data = ¶ms->data[params->data_size];
+ params->data_size += fillWeightsArrayBuffer(block,
MALI_C55_PARAM_BLOCK_AEXP_HIST_WEIGHTS);
- block.data = ¶ms->data[params->total_size];
- params->total_size += fillParamsBuffer(block,
+ block.data = ¶ms->data[params->data_size];
+ params->data_size += fillParamsBuffer(block,
MALI_C55_PARAM_BLOCK_AEXP_IHIST);
- block.data = ¶ms->data[params->total_size];
- params->total_size += fillWeightsArrayBuffer(block,
+ block.data = ¶ms->data[params->data_size];
+ params->data_size += fillWeightsArrayBuffer(block,
MALI_C55_PARAM_BLOCK_AEXP_IHIST_WEIGHTS);
}
@@ -57,7 +57,7 @@ public:
const ControlList &controls) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- mali_c55_params_buffer *params) override;
+ v4l2_params_buffer *params) override;
void process(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
const mali_c55_stats_buffer *stats,
@@ -22,7 +22,7 @@ class Algorithm : public libcamera::ipa::Algorithm<Module>
};
union mali_c55_params_block {
- struct mali_c55_params_block_header *header;
+ struct v4l2_params_block_header *header;
struct mali_c55_params_sensor_off_preshading *sensor_offs;
struct mali_c55_params_aexp_hist *aexp_hist;
struct mali_c55_params_aexp_weights *aexp_weights;
@@ -47,7 +47,7 @@ size_t Awb::fillGainsParamBlock(mali_c55_params_block block, IPAContext &context
IPAFrameContext &frameContext)
{
block.header->type = MALI_C55_PARAM_BLOCK_AWB_GAINS;
- block.header->flags = MALI_C55_PARAM_BLOCK_FL_NONE;
+ block.header->flags = 0;
block.header->size = sizeof(struct mali_c55_params_awb_gains);
double rGain = context.activeState.awb.rGain;
@@ -77,7 +77,7 @@ size_t Awb::fillGainsParamBlock(mali_c55_params_block block, IPAContext &context
size_t Awb::fillConfigParamBlock(mali_c55_params_block block)
{
block.header->type = MALI_C55_PARAM_BLOCK_AWB_CONFIG;
- block.header->flags = MALI_C55_PARAM_BLOCK_FL_NONE;
+ block.header->flags = 0;
block.header->size = sizeof(struct mali_c55_params_awb_config);
/* Tap the stats after the purple fringe block */
@@ -126,18 +126,18 @@ size_t Awb::fillConfigParamBlock(mali_c55_params_block block)
}
void Awb::prepare(IPAContext &context, const uint32_t frame,
- IPAFrameContext &frameContext, mali_c55_params_buffer *params)
+ IPAFrameContext &frameContext, v4l2_params_buffer *params)
{
mali_c55_params_block block;
- block.data = ¶ms->data[params->total_size];
+ block.data = ¶ms->data[params->data_size];
- params->total_size += fillGainsParamBlock(block, context, frameContext);
+ params->data_size += fillGainsParamBlock(block, context, frameContext);
if (frame > 0)
return;
- block.data = ¶ms->data[params->total_size];
- params->total_size += fillConfigParamBlock(block);
+ block.data = ¶ms->data[params->data_size];
+ params->data_size += fillConfigParamBlock(block);
}
void Awb::process(IPAContext &context, const uint32_t frame,
@@ -22,7 +22,7 @@ public:
const IPACameraSensorInfo &configInfo) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- mali_c55_params_buffer *params) override;
+ v4l2_params_buffer *params) override;
void process(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
const mali_c55_stats_buffer *stats,
@@ -85,10 +85,10 @@ int BlackLevelCorrection::configure(IPAContext &context,
void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,
const uint32_t frame,
[[maybe_unused]] IPAFrameContext &frameContext,
- mali_c55_params_buffer *params)
+ v4l2_params_buffer *params)
{
mali_c55_params_block block;
- block.data = ¶ms->data[params->total_size];
+ block.data = ¶ms->data[params->data_size];
if (frame > 0)
return;
@@ -97,7 +97,7 @@ void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,
return;
block.header->type = MALI_C55_PARAM_BLOCK_SENSOR_OFFS;
- block.header->flags = MALI_C55_PARAM_BLOCK_FL_NONE;
+ block.header->flags = 0;
block.header->size = sizeof(mali_c55_params_sensor_off_preshading);
block.sensor_offs->chan00 = offset00;
@@ -105,7 +105,7 @@ void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,
block.sensor_offs->chan10 = offset10;
block.sensor_offs->chan11 = offset11;
- params->total_size += block.header->size;
+ params->data_size += block.header->size;
}
void BlackLevelCorrection::process([[maybe_unused]] IPAContext &context,
@@ -22,7 +22,7 @@ public:
const IPACameraSensorInfo &configInfo) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- mali_c55_params_buffer *params) override;
+ v4l2_params_buffer *params) override;
void process(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
const mali_c55_stats_buffer *stats,
@@ -111,7 +111,7 @@ int Lsc::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData
size_t Lsc::fillConfigParamsBlock(mali_c55_params_block block) const
{
block.header->type = MALI_C55_PARAM_MESH_SHADING_CONFIG;
- block.header->flags = MALI_C55_PARAM_BLOCK_FL_NONE;
+ block.header->flags = 0;
block.header->size = sizeof(struct mali_c55_params_mesh_shading_config);
block.shading_config->mesh_show = false;
@@ -131,7 +131,7 @@ size_t Lsc::fillSelectionParamsBlock(mali_c55_params_block block, uint8_t bank,
uint8_t alpha) const
{
block.header->type = MALI_C55_PARAM_MESH_SHADING_SELECTION;
- block.header->flags = MALI_C55_PARAM_BLOCK_FL_NONE;
+ block.header->flags = 0;
block.header->size = sizeof(struct mali_c55_params_mesh_shading_selection);
block.shading_selection->mesh_alpha_bank_r = bank;
@@ -170,7 +170,7 @@ std::tuple<uint8_t, uint8_t> Lsc::findBankAndAlpha(uint32_t ct) const
void Lsc::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,
[[maybe_unused]] IPAFrameContext &frameContext,
- mali_c55_params_buffer *params)
+ v4l2_params_buffer *params)
{
/*
* For each frame we assess the colour temperature of the **last** frame
@@ -194,9 +194,9 @@ void Lsc::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,
}
mali_c55_params_block block;
- block.data = ¶ms->data[params->total_size];
+ block.data = ¶ms->data[params->data_size];
- params->total_size += fillSelectionParamsBlock(block, bank, alpha);
+ params->data_size += fillSelectionParamsBlock(block, bank, alpha);
if (frame > 0)
return;
@@ -205,8 +205,8 @@ void Lsc::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,
* If this is the first frame, we need to load the parsed coefficient
* tables from tuning data to the ISP.
*/
- block.data = ¶ms->data[params->total_size];
- params->total_size += fillConfigParamsBlock(block);
+ block.data = ¶ms->data[params->data_size];
+ params->data_size += fillConfigParamsBlock(block);
}
REGISTER_IPA_ALGORITHM(Lsc, "Lsc")
@@ -23,7 +23,7 @@ public:
int init(IPAContext &context, const YamlObject &tuningData) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- mali_c55_params_buffer *params) override;
+ v4l2_params_buffer *params) override;
private:
static constexpr unsigned int kRedOffset = 0;
static constexpr unsigned int kGreenOffset = 1024;
@@ -331,22 +331,22 @@ void IPAMaliC55::queueRequest(const uint32_t request, const ControlList &control
void IPAMaliC55::fillParams(unsigned int request,
[[maybe_unused]] uint32_t bufferId)
{
- struct mali_c55_params_buffer *params;
+ struct v4l2_params_buffer *params;
IPAFrameContext &frameContext = context_.frameContexts.get(request);
- params = reinterpret_cast<mali_c55_params_buffer *>(
+ params = reinterpret_cast<v4l2_params_buffer *>(
buffers_.at(bufferId).planes()[0].data());
- memset(params, 0, sizeof(mali_c55_params_buffer));
+ memset(params, 0, sizeof(v4l2_params_buffer));
params->version = MALI_C55_PARAM_BUFFER_V1;
for (auto const &algo : algorithms()) {
algo->prepare(context_, request, frameContext, params);
- ASSERT(params->total_size <= MALI_C55_PARAMS_MAX_SIZE);
+ ASSERT(params->data_size <= MALI_C55_PARAMS_MAX_SIZE);
}
- size_t bytesused = offsetof(struct mali_c55_params_buffer, data) + params->total_size;
+ size_t bytesused = offsetof(struct v4l2_params_buffer, data) + params->data_size;
paramsComputed.emit(request, bytesused);
}
@@ -20,7 +20,7 @@ namespace libcamera {
namespace ipa::mali_c55 {
using Module = ipa::Module<IPAContext, IPAFrameContext, IPACameraSensorInfo,
- mali_c55_params_buffer, mali_c55_stats_buffer>;
+ v4l2_params_buffer, mali_c55_stats_buffer>;
} /* namespace ipa::mali_c55 */
Update Mali C55 header file with the v11 version of the patch series, based on v4l2 extensible parameters, sent to the linux-media mailing list at: https://lore.kernel.org/all/20250714-c55-v11-0-bc20e460e42a@ideasonboard.com/ Adjust the IPA module to use the new header file. Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> --- include/linux/mali-c55-config.h | 162 +++++--------------------------- src/ipa/mali-c55/algorithms/agc.cpp | 28 +++--- src/ipa/mali-c55/algorithms/agc.h | 2 +- src/ipa/mali-c55/algorithms/algorithm.h | 2 +- src/ipa/mali-c55/algorithms/awb.cpp | 14 +-- src/ipa/mali-c55/algorithms/awb.h | 2 +- src/ipa/mali-c55/algorithms/blc.cpp | 8 +- src/ipa/mali-c55/algorithms/blc.h | 2 +- src/ipa/mali-c55/algorithms/lsc.cpp | 14 +-- src/ipa/mali-c55/algorithms/lsc.h | 2 +- src/ipa/mali-c55/mali-c55.cpp | 10 +- src/ipa/mali-c55/module.h | 2 +- 12 files changed, 67 insertions(+), 181 deletions(-)