/* SPDX-License-Identifier: GPL-2.0 */ /* * ARM Mali-C55 ISP Driver - Common definitions * * Copyright (C) 2025 Ideas on Board Oy */ #ifndef _MALI_C55_COMMON_H #define _MALI_C55_COMMON_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MALI_C55_DRIVER_NAME "mali-c55" /* min and max values for the image sizes */ #define MALI_C55_MIN_WIDTH 640U #define MALI_C55_MIN_HEIGHT 480U #define MALI_C55_MAX_WIDTH 8192U #define MALI_C55_MAX_HEIGHT 8192U #define MALI_C55_DEFAULT_WIDTH 1920U #define MALI_C55_DEFAULT_HEIGHT 1080U #define MALI_C55_DEFAULT_MEDIA_BUS_FMT MEDIA_BUS_FMT_RGB121212_1X36 #define MALI_C55_NUM_CLKS 3 #define MALI_C55_NUM_RESETS 3 struct device; struct mali_c55; struct mali_c55_cap_dev; struct media_pipeline; struct mali_c55_params_buffer; struct platform_device; struct resource; enum mali_c55_isp_pads { MALI_C55_ISP_PAD_SINK_VIDEO, MALI_C55_ISP_PAD_SOURCE_VIDEO, MALI_C55_ISP_PAD_SOURCE_BYPASS, MALI_C55_ISP_PAD_SOURCE_STATS, MALI_C55_ISP_PAD_SINK_PARAMS, MALI_C55_ISP_NUM_PADS, }; struct mali_c55_tpg { struct mali_c55 *mali_c55; struct v4l2_subdev sd; struct media_pad pad; struct mali_c55_tpg_ctrls { struct v4l2_ctrl_handler handler; struct v4l2_ctrl *vblank; } ctrls; }; struct mali_c55_isp { struct mali_c55 *mali_c55; struct v4l2_subdev sd; struct media_pad pads[MALI_C55_ISP_NUM_PADS]; struct v4l2_ctrl_handler handler; struct media_pad *remote_src; /* Mutex to guard vb2 start/stop streaming */ struct mutex capture_lock; unsigned int frame_sequence; }; enum mali_c55_resizer_ids { MALI_C55_RSZ_FR, MALI_C55_RSZ_DS, MALI_C55_NUM_RSZS, }; enum mali_c55_rsz_pads { MALI_C55_RSZ_SINK_PAD, MALI_C55_RSZ_SOURCE_PAD, MALI_C55_RSZ_SINK_BYPASS_PAD, MALI_C55_RSZ_NUM_PADS }; struct mali_c55_resizer { struct mali_c55 *mali_c55; struct mali_c55_cap_dev *cap_dev; enum mali_c55_resizer_ids id; struct v4l2_subdev sd; struct media_pad pads[MALI_C55_RSZ_NUM_PADS]; unsigned int num_routes; }; enum mali_c55_cap_devs { MALI_C55_CAP_DEV_FR, MALI_C55_CAP_DEV_DS, MALI_C55_NUM_CAP_DEVS }; struct mali_c55_format_info { u32 fourcc; /* * The output formats can be produced by a couple of different media bus * formats, depending on how the ISP is configured. */ unsigned int mbus_codes[2]; bool is_raw; struct { u32 base_mode; u32 uv_plane; } registers; }; struct mali_c55_isp_format_info { u32 code; u32 shifted_code; bool bypass; u32 order; }; enum mali_c55_planes { MALI_C55_PLANE_Y, MALI_C55_PLANE_UV, MALI_C55_NUM_PLANES }; struct mali_c55_buffer { struct vb2_v4l2_buffer vb; unsigned int planes_pending; struct list_head queue; dma_addr_t addrs[MALI_C55_NUM_PLANES]; }; struct mali_c55_cap_dev { struct mali_c55 *mali_c55; struct mali_c55_resizer *rsz; struct video_device vdev; struct media_pad pad; struct vb2_queue queue; /* Mutex to provide to vb2 */ struct mutex lock; unsigned int reg_offset; struct { const struct mali_c55_format_info *info; struct v4l2_pix_format_mplane format; } format; struct { /* Spinlock to guard buffer queue */ spinlock_t lock; /* Spinlock to guard the queue of buffers being processed */ spinlock_t processing_lock; struct list_head input; struct list_head processing; } buffers; }; struct mali_c55_stats_buf { struct vb2_v4l2_buffer vb; unsigned int segments_remaining; struct list_head queue; bool failed; }; struct mali_c55_params_buf { struct vb2_v4l2_buffer vb; struct list_head queue; struct v4l2_isp_params_buffer *config; }; struct mali_c55_stats { struct mali_c55 *mali_c55; struct video_device vdev; struct vb2_queue queue; struct media_pad pad; /* Mutex to provide to vb2 */ struct mutex lock; struct { /* Spinlock to guard buffer queue */ spinlock_t lock; struct list_head queue; } buffers; }; struct mali_c55_params { struct mali_c55 *mali_c55; struct video_device vdev; struct vb2_queue queue; struct media_pad pad; /* Mutex to provide to vb2 */ struct mutex lock; struct { /* Spinlock to guard buffer queue */ spinlock_t lock; struct list_head queue; } buffers; }; enum mali_c55_config_spaces { MALI_C55_CONFIG_PONG, MALI_C55_CONFIG_PING, }; /** * struct mali_c55_context - Fields relating to a single camera context * * @mali_c55: Pointer to the main struct mali_c55 * @registers: A pointer to some allocated memory holding register * values to be written to the hardware at frame interrupt * @base: Base address of the config space in the hardware * @lock: A spinlock to protect against writes to @registers whilst that * space is being copied to the hardware * @list: A list head to facilitate a context queue */ struct mali_c55_context { struct mali_c55 *mali_c55; u32 *registers; phys_addr_t base; /* Spinlock to prevent simultaneous access of register space */ spinlock_t lock; struct list_head list; }; struct mali_c55 { struct device *dev; void __iomem *base; struct clk_bulk_data clks[MALI_C55_NUM_CLKS]; struct reset_control_bulk_data resets[MALI_C55_NUM_RESETS]; int irqnum; u16 capabilities; bool inline_mode; struct media_device media_dev; struct v4l2_device v4l2_dev; struct v4l2_async_notifier notifier; struct media_pipeline pipe; struct mali_c55_tpg tpg; struct mali_c55_isp isp; struct mali_c55_resizer resizers[MALI_C55_NUM_RSZS]; struct mali_c55_cap_dev cap_devs[MALI_C55_NUM_CAP_DEVS]; struct mali_c55_params params; struct mali_c55_stats stats; struct mali_c55_context context; u32 next_config; }; void mali_c55_write(struct mali_c55 *mali_c55, unsigned int addr, u32 val); void mali_c55_cap_dev_write(struct mali_c55_cap_dev *cap_dev, unsigned int addr, u32 val); void mali_c55_update_bits(struct mali_c55 *mali_c55, unsigned int addr, u32 mask, u32 val); u32 mali_c55_read(struct mali_c55 *mali_c55, unsigned int addr); void mali_c55_ctx_write(struct mali_c55 *mali_c55, unsigned int addr, u32 val); u32 mali_c55_ctx_read(struct mali_c55 *mali_c55, unsigned int addr); void mali_c55_ctx_update_bits(struct mali_c55 *mali_c55, unsigned int addr, u32 mask, u32 val); int mali_c55_config_write(struct mali_c55_context *ctx, enum mali_c55_config_spaces cfg_space, bool force_synchronous); int mali_c55_register_isp(struct mali_c55 *mali_c55); int mali_c55_register_tpg(struct mali_c55 *mali_c55); void mali_c55_unregister_tpg(struct mali_c55 *mali_c55); void mali_c55_unregister_isp(struct mali_c55 *mali_c55); int mali_c55_register_resizers(struct mali_c55 *mali_c55); void mali_c55_unregister_resizers(struct mali_c55 *mali_c55); int mali_c55_register_capture_devs(struct mali_c55 *mali_c55); void mali_c55_unregister_capture_devs(struct mali_c55 *mali_c55); int mali_c55_register_stats(struct mali_c55 *mali_c55); void mali_c55_unregister_stats(struct mali_c55 *mali_c55); int mali_c55_register_params(struct mali_c55 *mali_c55); void mali_c55_unregister_params(struct mali_c55 *mali_c55); struct mali_c55_context *mali_c55_get_active_context(struct mali_c55 *mali_c55); void mali_c55_set_plane_done(struct mali_c55_cap_dev *cap_dev, enum mali_c55_planes plane); void mali_c55_set_next_buffer(struct mali_c55_cap_dev *cap_dev); void mali_c55_isp_queue_event_sof(struct mali_c55 *mali_c55); bool mali_c55_format_is_raw(unsigned int mbus_code); const struct mali_c55_isp_format_info * mali_c55_isp_fmt_next(const struct mali_c55_isp_format_info *fmt); const struct mali_c55_isp_format_info * mali_c55_isp_get_mbus_config_by_code(u32 code); const struct mali_c55_isp_format_info * mali_c55_isp_get_mbus_config_by_shifted_code(u32 code); const struct mali_c55_isp_format_info * mali_c55_isp_get_mbus_config_by_index(u32 index); bool mali_c55_pipeline_ready(struct mali_c55 *mali_c55); void mali_c55_stats_fill_buffer(struct mali_c55 *mali_c55, enum mali_c55_config_spaces cfg_space); void mali_c55_params_write_config(struct mali_c55 *mali_c55); #endif /* _MALI_C55_COMMON_H */