#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/firmware.h>
#include <linux/gcd.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/xlnx-vcu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-v4l2.h>
#include "allegro-mail.h"
#include "nal-h264.h"
#include "nal-hevc.h"
#define ALLEGRO_WIDTH_MIN …
#define ALLEGRO_WIDTH_DEFAULT …
#define ALLEGRO_WIDTH_MAX …
#define ALLEGRO_HEIGHT_MIN …
#define ALLEGRO_HEIGHT_DEFAULT …
#define ALLEGRO_HEIGHT_MAX …
#define ALLEGRO_FRAMERATE_DEFAULT …
#define ALLEGRO_GOP_SIZE_DEFAULT …
#define ALLEGRO_GOP_SIZE_MAX …
#define AL5_MCU_RESET …
#define AL5_MCU_RESET_SOFT …
#define AL5_MCU_RESET_REGS …
#define AL5_MCU_RESET_MODE …
#define AL5_MCU_RESET_MODE_SLEEP …
#define AL5_MCU_RESET_MODE_HALT …
#define AL5_MCU_STA …
#define AL5_MCU_STA_SLEEP …
#define AL5_MCU_WAKEUP …
#define AL5_ICACHE_ADDR_OFFSET_MSB …
#define AL5_ICACHE_ADDR_OFFSET_LSB …
#define AL5_DCACHE_ADDR_OFFSET_MSB …
#define AL5_DCACHE_ADDR_OFFSET_LSB …
#define AL5_MCU_INTERRUPT …
#define AL5_ITC_CPU_IRQ_MSK …
#define AL5_ITC_CPU_IRQ_CLR …
#define AL5_ITC_CPU_IRQ_STA …
#define AL5_ITC_CPU_IRQ_STA_TRIGGERED …
#define AXI_ADDR_OFFSET_IP …
#define MCU_CACHE_OFFSET …
#define ENCODER_STREAM_OFFSET …
#define SIZE_MACROBLOCK …
#define LOG2_MAX_FRAME_NUM …
#define LOG2_MAX_PIC_ORDER_CNT …
#define BETA_OFFSET_DIV_2 …
#define TC_OFFSET_DIV_2 …
#define V4L2_CID_USER_ALLEGRO_ENCODER_BUFFER …
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(…) …;
struct allegro_buffer { … };
struct allegro_dev;
struct allegro_channel;
struct allegro_mbox { … };
struct allegro_encoder_buffer { … };
struct allegro_dev { … };
static struct regmap_config allegro_regmap_config = …;
static struct regmap_config allegro_sram_config = …;
#define fh_to_channel(__fh) …
struct allegro_channel { … };
static inline int
allegro_channel_get_i_frame_qp(struct allegro_channel *channel)
{ … }
static inline int
allegro_channel_get_p_frame_qp(struct allegro_channel *channel)
{ … }
static inline int
allegro_channel_get_b_frame_qp(struct allegro_channel *channel)
{ … }
static inline int
allegro_channel_get_min_qp(struct allegro_channel *channel)
{ … }
static inline int
allegro_channel_get_max_qp(struct allegro_channel *channel)
{ … }
struct allegro_m2m_buffer { … };
#define to_allegro_m2m_buffer(__buf) …
struct fw_info { … };
static const struct fw_info supported_firmware[] = …;
static inline u32 to_mcu_addr(struct allegro_dev *dev, dma_addr_t phys)
{ … }
static inline u32 to_mcu_size(struct allegro_dev *dev, size_t size)
{ … }
static inline u32 to_codec_addr(struct allegro_dev *dev, dma_addr_t phys)
{ … }
static inline u64 ptr_to_u64(const void *ptr)
{ … }
static unsigned long allegro_next_user_id(struct allegro_dev *dev)
{ … }
static struct allegro_channel *
allegro_find_channel_by_user_id(struct allegro_dev *dev,
unsigned int user_id)
{ … }
static struct allegro_channel *
allegro_find_channel_by_channel_id(struct allegro_dev *dev,
unsigned int channel_id)
{ … }
static inline bool channel_exists(struct allegro_channel *channel)
{ … }
#define AL_ERROR …
#define AL_ERR_INIT_FAILED …
#define AL_ERR_NO_FRAME_DECODED …
#define AL_ERR_RESOLUTION_CHANGE …
#define AL_ERR_NO_MEMORY …
#define AL_ERR_STREAM_OVERFLOW …
#define AL_ERR_TOO_MANY_SLICES …
#define AL_ERR_BUF_NOT_READY …
#define AL_ERR_NO_CHANNEL_AVAILABLE …
#define AL_ERR_RESOURCE_UNAVAILABLE …
#define AL_ERR_NOT_ENOUGH_CORES …
#define AL_ERR_REQUEST_MALFORMED …
#define AL_ERR_CMD_NOT_ALLOWED …
#define AL_ERR_INVALID_CMD_VALUE …
static inline const char *allegro_err_to_string(unsigned int err)
{ … }
static unsigned int estimate_stream_size(unsigned int width,
unsigned int height)
{ … }
static enum v4l2_mpeg_video_h264_level
select_minimum_h264_level(unsigned int width, unsigned int height)
{ … }
static unsigned int h264_maximum_bitrate(enum v4l2_mpeg_video_h264_level level)
{ … }
static unsigned int h264_maximum_cpb_size(enum v4l2_mpeg_video_h264_level level)
{ … }
static enum v4l2_mpeg_video_hevc_level
select_minimum_hevc_level(unsigned int width, unsigned int height)
{ … }
static unsigned int hevc_maximum_bitrate(enum v4l2_mpeg_video_hevc_level level)
{ … }
static unsigned int hevc_maximum_cpb_size(enum v4l2_mpeg_video_hevc_level level)
{ … }
static const struct fw_info *
allegro_get_firmware_info(struct allegro_dev *dev,
const struct firmware *fw,
const struct firmware *fw_codec)
{ … }
static int allegro_alloc_buffer(struct allegro_dev *dev,
struct allegro_buffer *buffer, size_t size)
{ … }
static void allegro_free_buffer(struct allegro_dev *dev,
struct allegro_buffer *buffer)
{ … }
static void allegro_mcu_interrupt(struct allegro_dev *dev);
static void allegro_handle_message(struct allegro_dev *dev,
union mcu_msg_response *msg);
static struct allegro_mbox *allegro_mbox_init(struct allegro_dev *dev,
unsigned int base, size_t size)
{ … }
static int allegro_mbox_write(struct allegro_mbox *mbox,
const u32 *src, size_t size)
{ … }
static ssize_t allegro_mbox_read(struct allegro_mbox *mbox,
u32 *dst, size_t nbyte)
{ … }
static int allegro_mbox_send(struct allegro_mbox *mbox, void *msg)
{ … }
static void allegro_mbox_notify(struct allegro_mbox *mbox)
{ … }
static int allegro_encoder_buffer_init(struct allegro_dev *dev,
struct allegro_encoder_buffer *buffer)
{ … }
static void allegro_mcu_send_init(struct allegro_dev *dev,
dma_addr_t suballoc_dma, size_t suballoc_size)
{ … }
static u32 v4l2_pixelformat_to_mcu_format(u32 pixelformat)
{ … }
static u32 v4l2_colorspace_to_mcu_colorspace(enum v4l2_colorspace colorspace)
{ … }
static u8 v4l2_profile_to_mcu_profile(enum v4l2_mpeg_video_h264_profile profile)
{ … }
static u16 v4l2_level_to_mcu_level(enum v4l2_mpeg_video_h264_level level)
{ … }
static u8 hevc_profile_to_mcu_profile(enum v4l2_mpeg_video_hevc_profile profile)
{ … }
static u16 hevc_level_to_mcu_level(enum v4l2_mpeg_video_hevc_level level)
{ … }
static u8 hevc_tier_to_mcu_tier(enum v4l2_mpeg_video_hevc_tier tier)
{ … }
static u32
v4l2_bitrate_mode_to_mcu_mode(enum v4l2_mpeg_video_bitrate_mode mode)
{ … }
static u32 v4l2_cpb_size_to_mcu(unsigned int cpb_size, unsigned int bitrate)
{ … }
static s16 get_qp_delta(int minuend, int subtrahend)
{ … }
static u32 allegro_channel_get_entropy_mode(struct allegro_channel *channel)
{ … }
static int fill_create_channel_param(struct allegro_channel *channel,
struct create_channel_param *param)
{ … }
static int allegro_mcu_send_create_channel(struct allegro_dev *dev,
struct allegro_channel *channel)
{ … }
static int allegro_mcu_send_destroy_channel(struct allegro_dev *dev,
struct allegro_channel *channel)
{ … }
static int allegro_mcu_send_put_stream_buffer(struct allegro_dev *dev,
struct allegro_channel *channel,
dma_addr_t paddr,
unsigned long size,
u64 dst_handle)
{ … }
static int allegro_mcu_send_encode_frame(struct allegro_dev *dev,
struct allegro_channel *channel,
dma_addr_t src_y, dma_addr_t src_uv,
u64 src_handle)
{ … }
static int allegro_mcu_wait_for_init_timeout(struct allegro_dev *dev,
unsigned long timeout_ms)
{ … }
static int allegro_mcu_push_buffer_internal(struct allegro_channel *channel,
enum mcu_msg_type type)
{ … }
static int allegro_mcu_push_buffer_intermediate(struct allegro_channel *channel)
{ … }
static int allegro_mcu_push_buffer_reference(struct allegro_channel *channel)
{ … }
static int allocate_buffers_internal(struct allegro_channel *channel,
struct list_head *list,
size_t n, size_t size)
{ … }
static void destroy_buffers_internal(struct allegro_channel *channel,
struct list_head *list)
{ … }
static void destroy_reference_buffers(struct allegro_channel *channel)
{ … }
static void destroy_intermediate_buffers(struct allegro_channel *channel)
{ … }
static int allocate_intermediate_buffers(struct allegro_channel *channel,
size_t n, size_t size)
{ … }
static int allocate_reference_buffers(struct allegro_channel *channel,
size_t n, size_t size)
{ … }
static ssize_t allegro_h264_write_sps(struct allegro_channel *channel,
void *dest, size_t n)
{ … }
static ssize_t allegro_h264_write_pps(struct allegro_channel *channel,
void *dest, size_t n)
{ … }
static void allegro_channel_eos_event(struct allegro_channel *channel)
{ … }
static ssize_t allegro_hevc_write_vps(struct allegro_channel *channel,
void *dest, size_t n)
{ … }
static ssize_t allegro_hevc_write_sps(struct allegro_channel *channel,
void *dest, size_t n)
{ … }
static ssize_t allegro_hevc_write_pps(struct allegro_channel *channel,
struct mcu_msg_encode_frame_response *msg,
void *dest, size_t n)
{ … }
static u64 allegro_put_buffer(struct allegro_channel *channel,
struct list_head *list,
struct vb2_v4l2_buffer *buffer)
{ … }
static struct vb2_v4l2_buffer *
allegro_get_buffer(struct allegro_channel *channel,
struct list_head *list, u64 handle)
{ … }
static void allegro_channel_finish_frame(struct allegro_channel *channel,
struct mcu_msg_encode_frame_response *msg)
{ … }
static int allegro_handle_init(struct allegro_dev *dev,
struct mcu_msg_init_response *msg)
{ … }
static int
allegro_handle_create_channel(struct allegro_dev *dev,
struct mcu_msg_create_channel_response *msg)
{ … }
static int
allegro_handle_destroy_channel(struct allegro_dev *dev,
struct mcu_msg_destroy_channel_response *msg)
{ … }
static int
allegro_handle_encode_frame(struct allegro_dev *dev,
struct mcu_msg_encode_frame_response *msg)
{ … }
static void allegro_handle_message(struct allegro_dev *dev,
union mcu_msg_response *msg)
{ … }
static irqreturn_t allegro_hardirq(int irq, void *data)
{ … }
static irqreturn_t allegro_irq_thread(int irq, void *data)
{ … }
static void allegro_copy_firmware(struct allegro_dev *dev,
const u8 * const buf, size_t size)
{ … }
static void allegro_copy_fw_codec(struct allegro_dev *dev,
const u8 * const buf, size_t size)
{ … }
static void allegro_free_fw_codec(struct allegro_dev *dev)
{ … }
static int allegro_mcu_enable_interrupts(struct allegro_dev *dev)
{ … }
static int allegro_mcu_disable_interrupts(struct allegro_dev *dev)
{ … }
static int allegro_mcu_wait_for_sleep(struct allegro_dev *dev)
{ … }
static int allegro_mcu_start(struct allegro_dev *dev)
{ … }
static int allegro_mcu_reset(struct allegro_dev *dev)
{ … }
static void allegro_mcu_interrupt(struct allegro_dev *dev)
{ … }
static void allegro_destroy_channel(struct allegro_channel *channel)
{ … }
static int allegro_create_channel(struct allegro_channel *channel)
{ … }
static void allegro_channel_adjust(struct allegro_channel *channel)
{ … }
static void allegro_set_default_params(struct allegro_channel *channel)
{ … }
static int allegro_queue_setup(struct vb2_queue *vq,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[],
struct device *alloc_devs[])
{ … }
static int allegro_buf_prepare(struct vb2_buffer *vb)
{ … }
static void allegro_buf_queue(struct vb2_buffer *vb)
{ … }
static int allegro_start_streaming(struct vb2_queue *q, unsigned int count)
{ … }
static void allegro_stop_streaming(struct vb2_queue *q)
{ … }
static const struct vb2_ops allegro_queue_ops = …;
static int allegro_queue_init(void *priv,
struct vb2_queue *src_vq,
struct vb2_queue *dst_vq)
{ … }
static int allegro_clamp_qp(struct allegro_channel *channel,
struct v4l2_ctrl *ctrl)
{ … }
static int allegro_clamp_bitrate(struct allegro_channel *channel,
struct v4l2_ctrl *ctrl)
{ … }
static int allegro_try_ctrl(struct v4l2_ctrl *ctrl)
{ … }
static int allegro_s_ctrl(struct v4l2_ctrl *ctrl)
{ … }
static const struct v4l2_ctrl_ops allegro_ctrl_ops = …;
static const struct v4l2_ctrl_config allegro_encoder_buffer_ctrl_config = …;
static int allegro_open(struct file *file)
{ … }
static int allegro_release(struct file *file)
{ … }
static int allegro_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{ … }
static int allegro_enum_fmt_vid(struct file *file, void *fh,
struct v4l2_fmtdesc *f)
{ … }
static int allegro_g_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{ … }
static int allegro_try_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{ … }
static int allegro_s_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{ … }
static int allegro_g_fmt_vid_out(struct file *file, void *fh,
struct v4l2_format *f)
{ … }
static int allegro_try_fmt_vid_out(struct file *file, void *fh,
struct v4l2_format *f)
{ … }
static int allegro_s_fmt_vid_out(struct file *file, void *fh,
struct v4l2_format *f)
{ … }
static int allegro_channel_cmd_stop(struct allegro_channel *channel)
{ … }
static int allegro_channel_cmd_start(struct allegro_channel *channel)
{ … }
static int allegro_encoder_cmd(struct file *file, void *fh,
struct v4l2_encoder_cmd *cmd)
{ … }
static int allegro_enum_framesizes(struct file *file, void *fh,
struct v4l2_frmsizeenum *fsize)
{ … }
static int allegro_ioctl_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{ … }
static int allegro_g_parm(struct file *file, void *fh,
struct v4l2_streamparm *a)
{ … }
static int allegro_s_parm(struct file *file, void *fh,
struct v4l2_streamparm *a)
{ … }
static int allegro_subscribe_event(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub)
{ … }
static const struct v4l2_ioctl_ops allegro_ioctl_ops = …;
static const struct v4l2_file_operations allegro_fops = …;
static int allegro_register_device(struct allegro_dev *dev)
{ … }
static void allegro_device_run(void *priv)
{ … }
static const struct v4l2_m2m_ops allegro_m2m_ops = …;
static int allegro_mcu_hw_init(struct allegro_dev *dev,
const struct fw_info *info)
{ … }
static int allegro_mcu_hw_deinit(struct allegro_dev *dev)
{ … }
static void allegro_fw_callback(const struct firmware *fw, void *context)
{ … }
static int allegro_firmware_request_nowait(struct allegro_dev *dev)
{ … }
static int allegro_probe(struct platform_device *pdev)
{ … }
static void allegro_remove(struct platform_device *pdev)
{ … }
static int allegro_runtime_resume(struct device *device)
{ … }
static int allegro_runtime_suspend(struct device *device)
{ … }
static const struct of_device_id allegro_dt_ids[] = …;
MODULE_DEVICE_TABLE(of, allegro_dt_ids);
static const struct dev_pm_ops allegro_pm_ops = …;
static struct platform_driver allegro_driver = …;
module_platform_driver(…) …;
MODULE_LICENSE(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;