diff options
author | Michael Tretter <m.tretter@pengutronix.de> | 2020-12-02 14:30:37 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+huawei@kernel.org> | 2021-01-04 13:19:40 +0100 |
commit | d74d4e2359ec7985831192f9b5ee22ed5e55b81c (patch) | |
tree | 78edc9494750ab2f1496b212db37cbd34cd41435 /drivers/staging/media/allegro-dvt/allegro-mail.c | |
parent | ce814ad4bb52bfc7c0472e6da0aa742ab88f4361 (diff) | |
download | linux-d74d4e2359ec7985831192f9b5ee22ed5e55b81c.tar.bz2 |
media: allegro: move driver out of staging
The stateful encoder API was finalized. Nothing is blocking the driver
from being moved out of staging.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/staging/media/allegro-dvt/allegro-mail.c')
-rw-r--r-- | drivers/staging/media/allegro-dvt/allegro-mail.c | 543 |
1 files changed, 0 insertions, 543 deletions
diff --git a/drivers/staging/media/allegro-dvt/allegro-mail.c b/drivers/staging/media/allegro-dvt/allegro-mail.c deleted file mode 100644 index 9286d2162377..000000000000 --- a/drivers/staging/media/allegro-dvt/allegro-mail.c +++ /dev/null @@ -1,543 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2019 Pengutronix, Michael Tretter <kernel@pengutronix.de> - * - * Helper functions for handling messages that are send via mailbox to the - * Allegro VCU firmware. - */ - -#include <linux/bitfield.h> -#include <linux/export.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/videodev2.h> - -#include "allegro-mail.h" - -const char *msg_type_name(enum mcu_msg_type type) -{ - static char buf[9]; - - switch (type) { - case MCU_MSG_TYPE_INIT: - return "INIT"; - case MCU_MSG_TYPE_CREATE_CHANNEL: - return "CREATE_CHANNEL"; - case MCU_MSG_TYPE_DESTROY_CHANNEL: - return "DESTROY_CHANNEL"; - case MCU_MSG_TYPE_ENCODE_FRAME: - return "ENCODE_FRAME"; - case MCU_MSG_TYPE_PUT_STREAM_BUFFER: - return "PUT_STREAM_BUFFER"; - case MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE: - return "PUSH_BUFFER_INTERMEDIATE"; - case MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE: - return "PUSH_BUFFER_REFERENCE"; - default: - snprintf(buf, sizeof(buf), "(0x%04x)", type); - return buf; - } -} -EXPORT_SYMBOL(msg_type_name); - -static ssize_t -allegro_enc_init(u32 *dst, struct mcu_msg_init_request *msg) -{ - unsigned int i = 0; - enum mcu_msg_version version = msg->header.version; - - dst[i++] = msg->reserved0; - dst[i++] = msg->suballoc_dma; - dst[i++] = msg->suballoc_size; - dst[i++] = msg->l2_cache[0]; - dst[i++] = msg->l2_cache[1]; - dst[i++] = msg->l2_cache[2]; - if (version >= MCU_MSG_VERSION_2019_2) { - dst[i++] = -1; - dst[i++] = 0; - } - - return i * sizeof(*dst); -} - -static inline u32 settings_get_mcu_codec(struct create_channel_param *param) -{ - enum mcu_msg_version version = param->version; - u32 pixelformat = param->codec; - - if (version < MCU_MSG_VERSION_2019_2) { - switch (pixelformat) { - case V4L2_PIX_FMT_H264: - default: - return 1; - } - } else { - switch (pixelformat) { - case V4L2_PIX_FMT_H264: - default: - return 0; - } - } -} - -ssize_t -allegro_encode_config_blob(u32 *dst, struct create_channel_param *param) -{ - enum mcu_msg_version version = param->version; - unsigned int i = 0; - unsigned int j = 0; - u32 val; - unsigned int codec = settings_get_mcu_codec(param); - - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = param->layer_id; - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->height) | - FIELD_PREP(GENMASK(15, 0), param->width); - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = param->videomode; - dst[i++] = param->format; - if (version < MCU_MSG_VERSION_2019_2) - dst[i++] = param->colorspace; - dst[i++] = param->src_mode; - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = param->src_bit_depth; - dst[i++] = FIELD_PREP(GENMASK(31, 24), codec) | - FIELD_PREP(GENMASK(23, 8), param->constraint_set_flags) | - FIELD_PREP(GENMASK(7, 0), param->profile); - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->tier) | - FIELD_PREP(GENMASK(15, 0), param->level); - - val = 0; - val |= param->temporal_mvp_enable ? BIT(20) : 0; - val |= FIELD_PREP(GENMASK(7, 4), param->log2_max_frame_num) | - FIELD_PREP(GENMASK(3, 0), param->log2_max_poc); - dst[i++] = val; - - val = 0; - val |= param->dbf_ovr_en ? BIT(2) : 0; - dst[i++] = val; - - if (version >= MCU_MSG_VERSION_2019_2) { - val = 0; - val |= param->custom_lda ? BIT(2) : 0; - val |= param->rdo_cost_mode ? BIT(20) : 0; - dst[i++] = val; - - val = 0; - val |= param->lf ? BIT(2) : 0; - val |= param->lf_x_tile ? BIT(3) : 0; - val |= param->lf_x_slice ? BIT(4) : 0; - dst[i++] = val; - } else { - val = 0; - dst[i++] = val; - } - - dst[i++] = FIELD_PREP(GENMASK(15, 8), param->beta_offset) | - FIELD_PREP(GENMASK(7, 0), param->tc_offset); - dst[i++] = param->unknown11; - dst[i++] = param->unknown12; - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = param->num_slices; - else - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->prefetch_auto) | - FIELD_PREP(GENMASK(15, 0), param->num_slices); - dst[i++] = param->prefetch_mem_offset; - dst[i++] = param->prefetch_mem_size; - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->clip_vrt_range) | - FIELD_PREP(GENMASK(15, 0), param->clip_hrz_range); - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->me_range[1]) | - FIELD_PREP(GENMASK(15, 0), param->me_range[0]); - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->me_range[3]) | - FIELD_PREP(GENMASK(15, 0), param->me_range[2]); - dst[i++] = FIELD_PREP(GENMASK(31, 24), param->min_tu_size) | - FIELD_PREP(GENMASK(23, 16), param->max_tu_size) | - FIELD_PREP(GENMASK(15, 8), param->min_cu_size) | - FIELD_PREP(GENMASK(8, 0), param->max_cu_size); - dst[i++] = FIELD_PREP(GENMASK(15, 8), param->max_transfo_depth_intra) | - FIELD_PREP(GENMASK(7, 0), param->max_transfo_depth_inter); - dst[i++] = param->entropy_mode; - dst[i++] = param->wp_mode; - - dst[i++] = param->rate_control_mode; - dst[i++] = param->initial_rem_delay; - dst[i++] = param->cpb_size; - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->clk_ratio) | - FIELD_PREP(GENMASK(15, 0), param->framerate); - dst[i++] = param->target_bitrate; - dst[i++] = param->max_bitrate; - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->min_qp) | - FIELD_PREP(GENMASK(15, 0), param->initial_qp); - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->ip_delta) | - FIELD_PREP(GENMASK(15, 0), param->max_qp); - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->golden_ref) | - FIELD_PREP(GENMASK(15, 0), param->pb_delta); - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->golden_ref_frequency) | - FIELD_PREP(GENMASK(15, 0), param->golden_delta); - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = param->rate_control_option; - else - dst[i++] = 0; - - if (version >= MCU_MSG_VERSION_2019_2) { - dst[i++] = param->num_pixel; - dst[i++] = FIELD_PREP(GENMASK(31, 16), param->max_pixel_value) | - FIELD_PREP(GENMASK(15, 0), param->max_psnr); - for (j = 0; j < 3; j++) - dst[i++] = param->maxpicturesize[j]; - } - - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = param->gop_ctrl_mode; - else - dst[i++] = 0; - - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = FIELD_PREP(GENMASK(31, 24), param->freq_golden_ref) | - FIELD_PREP(GENMASK(23, 16), param->num_b) | - FIELD_PREP(GENMASK(15, 0), param->gop_length); - dst[i++] = param->freq_idr; - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = param->enable_lt; - dst[i++] = param->freq_lt; - dst[i++] = param->gdr_mode; - if (version < MCU_MSG_VERSION_2019_2) - dst[i++] = FIELD_PREP(GENMASK(31, 24), param->freq_golden_ref) | - FIELD_PREP(GENMASK(23, 16), param->num_b) | - FIELD_PREP(GENMASK(15, 0), param->gop_length); - - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = param->tmpdqp; - - dst[i++] = param->subframe_latency; - dst[i++] = param->lda_control_mode; - if (version < MCU_MSG_VERSION_2019_2) - dst[i++] = param->unknown41; - - if (version >= MCU_MSG_VERSION_2019_2) { - for (j = 0; j < 6; j++) - dst[i++] = param->lda_factors[j]; - dst[i++] = param->max_num_merge_cand; - } - - return i * sizeof(*dst); -} - -static ssize_t -allegro_enc_create_channel(u32 *dst, struct mcu_msg_create_channel *msg) -{ - enum mcu_msg_version version = msg->header.version; - unsigned int i = 0; - - dst[i++] = msg->user_id; - - if (version >= MCU_MSG_VERSION_2019_2) { - dst[i++] = msg->blob_mcu_addr; - } else { - memcpy(&dst[i], msg->blob, msg->blob_size); - i += msg->blob_size / sizeof(*dst); - } - - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = msg->ep1_addr; - - return i * sizeof(*dst); -} - -ssize_t allegro_decode_config_blob(struct create_channel_param *param, - struct mcu_msg_create_channel_response *msg, - u32 *src) -{ - enum mcu_msg_version version = msg->header.version; - - if (version >= MCU_MSG_VERSION_2019_2) { - param->num_ref_idx_l0 = FIELD_GET(GENMASK(7, 4), src[9]); - param->num_ref_idx_l1 = FIELD_GET(GENMASK(11, 8), src[9]); - } else { - param->num_ref_idx_l0 = msg->num_ref_idx_l0; - param->num_ref_idx_l1 = msg->num_ref_idx_l1; - } - - return 0; -} - -static ssize_t -allegro_enc_destroy_channel(u32 *dst, struct mcu_msg_destroy_channel *msg) -{ - unsigned int i = 0; - - dst[i++] = msg->channel_id; - - return i * sizeof(*dst); -} - -static ssize_t -allegro_enc_push_buffers(u32 *dst, struct mcu_msg_push_buffers_internal *msg) -{ - unsigned int i = 0; - struct mcu_msg_push_buffers_internal_buffer *buffer; - unsigned int num_buffers = msg->num_buffers; - unsigned int j; - - dst[i++] = msg->channel_id; - - for (j = 0; j < num_buffers; j++) { - buffer = &msg->buffer[j]; - dst[i++] = buffer->dma_addr; - dst[i++] = buffer->mcu_addr; - dst[i++] = buffer->size; - } - - return i * sizeof(*dst); -} - -static ssize_t -allegro_enc_put_stream_buffer(u32 *dst, - struct mcu_msg_put_stream_buffer *msg) -{ - unsigned int i = 0; - - dst[i++] = msg->channel_id; - dst[i++] = msg->dma_addr; - dst[i++] = msg->mcu_addr; - dst[i++] = msg->size; - dst[i++] = msg->offset; - dst[i++] = lower_32_bits(msg->stream_id); - dst[i++] = upper_32_bits(msg->stream_id); - - return i * sizeof(*dst); -} - -static ssize_t -allegro_enc_encode_frame(u32 *dst, struct mcu_msg_encode_frame *msg) -{ - enum mcu_msg_version version = msg->header.version; - unsigned int i = 0; - - dst[i++] = msg->channel_id; - - dst[i++] = msg->reserved; - dst[i++] = msg->encoding_options; - dst[i++] = FIELD_PREP(GENMASK(31, 16), msg->padding) | - FIELD_PREP(GENMASK(15, 0), msg->pps_qp); - - if (version >= MCU_MSG_VERSION_2019_2) { - dst[i++] = 0; - dst[i++] = 0; - dst[i++] = 0; - dst[i++] = 0; - } - - dst[i++] = lower_32_bits(msg->user_param); - dst[i++] = upper_32_bits(msg->user_param); - dst[i++] = lower_32_bits(msg->src_handle); - dst[i++] = upper_32_bits(msg->src_handle); - dst[i++] = msg->request_options; - dst[i++] = msg->src_y; - dst[i++] = msg->src_uv; - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = msg->is_10_bit; - dst[i++] = msg->stride; - if (version >= MCU_MSG_VERSION_2019_2) - dst[i++] = msg->format; - dst[i++] = msg->ep2; - dst[i++] = lower_32_bits(msg->ep2_v); - dst[i++] = upper_32_bits(msg->ep2_v); - - return i * sizeof(*dst); -} - -static ssize_t -allegro_dec_init(struct mcu_msg_init_response *msg, u32 *src) -{ - unsigned int i = 0; - - msg->reserved0 = src[i++]; - - return i * sizeof(*src); -} - -static ssize_t -allegro_dec_create_channel(struct mcu_msg_create_channel_response *msg, - u32 *src) -{ - enum mcu_msg_version version = msg->header.version; - unsigned int i = 0; - - msg->channel_id = src[i++]; - msg->user_id = src[i++]; - /* - * Version >= MCU_MSG_VERSION_2019_2 is handled in - * allegro_decode_config_blob(). - */ - if (version < MCU_MSG_VERSION_2019_2) { - msg->options = src[i++]; - msg->num_core = src[i++]; - msg->num_ref_idx_l0 = FIELD_GET(GENMASK(7, 4), src[i]); - msg->num_ref_idx_l1 = FIELD_GET(GENMASK(11, 8), src[i++]); - } - msg->int_buffers_count = src[i++]; - msg->int_buffers_size = src[i++]; - msg->rec_buffers_count = src[i++]; - msg->rec_buffers_size = src[i++]; - msg->reserved = src[i++]; - msg->error_code = src[i++]; - - return i * sizeof(*src); -} - -static ssize_t -allegro_dec_destroy_channel(struct mcu_msg_destroy_channel_response *msg, - u32 *src) -{ - unsigned int i = 0; - - msg->channel_id = src[i++]; - - return i * sizeof(*src); -} - -static ssize_t -allegro_dec_encode_frame(struct mcu_msg_encode_frame_response *msg, u32 *src) -{ - enum mcu_msg_version version = msg->header.version; - unsigned int i = 0; - unsigned int j; - - msg->channel_id = src[i++]; - - msg->stream_id = src[i++]; - msg->stream_id |= (((u64)src[i++]) << 32); - msg->user_param = src[i++]; - msg->user_param |= (((u64)src[i++]) << 32); - msg->src_handle = src[i++]; - msg->src_handle |= (((u64)src[i++]) << 32); - msg->skip = FIELD_GET(GENMASK(31, 16), src[i]); - msg->is_ref = FIELD_GET(GENMASK(15, 0), src[i++]); - msg->initial_removal_delay = src[i++]; - msg->dpb_output_delay = src[i++]; - msg->size = src[i++]; - msg->frame_tag_size = src[i++]; - msg->stuffing = src[i++]; - msg->filler = src[i++]; - msg->num_column = FIELD_GET(GENMASK(31, 16), src[i]); - msg->num_row = FIELD_GET(GENMASK(15, 0), src[i++]); - msg->num_ref_idx_l1 = FIELD_GET(GENMASK(31, 24), src[i]); - msg->num_ref_idx_l0 = FIELD_GET(GENMASK(23, 16), src[i]); - msg->qp = FIELD_GET(GENMASK(15, 0), src[i++]); - msg->partition_table_offset = src[i++]; - msg->partition_table_size = src[i++]; - msg->sum_complex = src[i++]; - for (j = 0; j < 4; j++) - msg->tile_width[j] = src[i++]; - for (j = 0; j < 22; j++) - msg->tile_height[j] = src[i++]; - msg->error_code = src[i++]; - msg->slice_type = src[i++]; - msg->pic_struct = src[i++]; - msg->reserved = FIELD_GET(GENMASK(31, 24), src[i]); - msg->is_last_slice = FIELD_GET(GENMASK(23, 16), src[i]); - msg->is_first_slice = FIELD_GET(GENMASK(15, 8), src[i]); - msg->is_idr = FIELD_GET(GENMASK(7, 0), src[i++]); - - msg->reserved1 = FIELD_GET(GENMASK(31, 16), src[i]); - msg->pps_qp = FIELD_GET(GENMASK(15, 0), src[i++]); - - msg->reserved2 = src[i++]; - if (version >= MCU_MSG_VERSION_2019_2) { - msg->reserved3 = src[i++]; - msg->reserved4 = src[i++]; - msg->reserved5 = src[i++]; - msg->reserved6 = src[i++]; - } - - return i * sizeof(*src); -} - -/** - * allegro_encode_mail() - Encode allegro messages to firmware format - * @dst: Pointer to the memory that will be filled with data - * @msg: The allegro message that will be encoded - */ -ssize_t allegro_encode_mail(u32 *dst, void *msg) -{ - const struct mcu_msg_header *header = msg; - ssize_t size; - - if (!msg || !dst) - return -EINVAL; - - switch (header->type) { - case MCU_MSG_TYPE_INIT: - size = allegro_enc_init(&dst[1], msg); - break; - case MCU_MSG_TYPE_CREATE_CHANNEL: - size = allegro_enc_create_channel(&dst[1], msg); - break; - case MCU_MSG_TYPE_DESTROY_CHANNEL: - size = allegro_enc_destroy_channel(&dst[1], msg); - break; - case MCU_MSG_TYPE_ENCODE_FRAME: - size = allegro_enc_encode_frame(&dst[1], msg); - break; - case MCU_MSG_TYPE_PUT_STREAM_BUFFER: - size = allegro_enc_put_stream_buffer(&dst[1], msg); - break; - case MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE: - case MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE: - size = allegro_enc_push_buffers(&dst[1], msg); - break; - default: - return -EINVAL; - } - - /* - * The encoded messages might have different length depending on - * the firmware version or certain fields. Therefore, we have to - * set the body length after encoding the message. - */ - dst[0] = FIELD_PREP(GENMASK(31, 16), header->type) | - FIELD_PREP(GENMASK(15, 0), size); - - return size + sizeof(*dst); -} - -/** - * allegro_decode_mail() - Parse allegro messages from the firmware. - * @msg: The mcu_msg_response that will be filled with parsed values. - * @src: Pointer to the memory that will be parsed - * - * The message format in the mailbox depends on the firmware. Parse the - * different formats into a uniform message format that can be used without - * taking care of the firmware version. - */ -int allegro_decode_mail(void *msg, u32 *src) -{ - struct mcu_msg_header *header; - - if (!src || !msg) - return -EINVAL; - - header = msg; - header->type = FIELD_GET(GENMASK(31, 16), src[0]); - - src++; - switch (header->type) { - case MCU_MSG_TYPE_INIT: - allegro_dec_init(msg, src); - break; - case MCU_MSG_TYPE_CREATE_CHANNEL: - allegro_dec_create_channel(msg, src); - break; - case MCU_MSG_TYPE_DESTROY_CHANNEL: - allegro_dec_destroy_channel(msg, src); - break; - case MCU_MSG_TYPE_ENCODE_FRAME: - allegro_dec_encode_frame(msg, src); - break; - default: - return -EINVAL; - } - - return 0; -} |