History

media: allegro: add encoder buffer support

The encoder buffer serves as a cache for reference frames during the encoding process. The encoder buffer significantly reduces the bandwidth requirement for read accesses on the AXI ports of the VCU, but slightly reduces the quality of the encoded video. The encoder buffer must be configured as a whole during the firmware initialization and later explicitly enabled for every channel that shall use the encoder buffer. Prior to firmware version 2019.2, it was necessary to explicitly set the size of the encoder buffer for every channel. Since 2019.2 it is sufficient to enable the encoder buffer and leave the rest to the firmware. Therefore, only support the encoder buffer for firmware 2019.2 and later.

Michael Tretter committed 5 years ago

Commit 98f1cbf1 parent 83cc5fd3 files · +90 −22Browse files

Unified · Split

3 files
  1. drivers/media/platform/allegro-dvt/allegro-core.c +76 −7
  2. drivers/media/platform/allegro-dvt/allegro-mail.c +8 −11
  3. drivers/media/platform/allegro-dvt/allegro-mail.h +6 −4
drivers/media/platform/allegro-dvt/allegro-core.c+76−7
@@ -129,6 +129,13 @@ struct allegro_mbox { · 128 unmodified lines
129129 struct mutex lock;
130130 };
131131
132+struct allegro_encoder_buffer {
133+ unsigned int size;
134+ unsigned int color_depth;
135+ unsigned int num_cores;
136+ unsigned int clk_rate;
137+};
138+
132139 struct allegro_dev {
133140 struct v4l2_device v4l2_dev;
134141 struct video_device video_dev;
@@ -148,6 +155,8 @@ struct allegro_dev { · 13 unmodified lines
148155 const struct fw_info *fw_info;
149156 struct allegro_buffer firmware;
150157 struct allegro_buffer suballocator;
158+ bool has_encoder_buffer;
159+ struct allegro_encoder_buffer encoder_buffer;
151160
152161 struct completion init_complete;
153162 bool initialized;
@@ -930,6 +939,52 @@ out: · 776 unmodified lines
930939 kfree(msg);
931940 }
932941
942+static int allegro_encoder_buffer_init(struct allegro_dev *dev,
943+ struct allegro_encoder_buffer *buffer)
944+{
945+ int err;
946+ struct regmap *settings = dev->settings;
947+ unsigned int supports_10_bit;
948+ unsigned int memory_depth;
949+ unsigned int num_cores;
950+ unsigned int color_depth;
951+ unsigned long clk_rate;
952+
953+ /* We don't support the encoder buffer pre Firmware version 2019.2 */
954+ if (dev->fw_info->mailbox_version < MCU_MSG_VERSION_2019_2)
955+ return -ENODEV;
956+
957+ if (!settings)
958+ return -EINVAL;
959+
960+ err = regmap_read(settings, VCU_ENC_COLOR_DEPTH, &supports_10_bit);
961+ if (err < 0)
962+ return err;
963+ err = regmap_read(settings, VCU_MEMORY_DEPTH, &memory_depth);
964+ if (err < 0)
965+ return err;
966+ err = regmap_read(settings, VCU_NUM_CORE, &num_cores);
967+ if (err < 0)
968+ return err;
969+
970+ clk_rate = clk_get_rate(dev->clk_core);
971+ if (clk_rate == 0)
972+ return -EINVAL;
973+
974+ color_depth = supports_10_bit ? 10 : 8;
975+ /* The firmware expects the encoder buffer size in bits. */
976+ buffer->size = color_depth * 32 * memory_depth;
977+ buffer->color_depth = color_depth;
978+ buffer->num_cores = num_cores;
979+ buffer->clk_rate = clk_rate;
980+
981+ v4l2_dbg(1, debug, &dev->v4l2_dev,
982+ "using %d bits encoder buffer with %d-bit color depth\n",
983+ buffer->size, color_depth);
984+
985+ return 0;
986+}
987+
933988 static void allegro_mcu_send_init(struct allegro_dev *dev,
934989 dma_addr_t suballoc_dma, size_t suballoc_size)
935990 {
@@ -943,10 +998,17 @@ static void allegro_mcu_send_init(struct allegro_dev *dev, · 7 unmodified lines
943998 msg.suballoc_dma = to_mcu_addr(dev, suballoc_dma);
944999 msg.suballoc_size = to_mcu_size(dev, suballoc_size);
9451000
946− /* disable L2 cache */
947− msg.l2_cache[0] = -1;
948− msg.l2_cache[1] = -1;
949− msg.l2_cache[2] = -1;
1001+ if (dev->has_encoder_buffer) {
1002+ msg.encoder_buffer_size = dev->encoder_buffer.size;
1003+ msg.encoder_buffer_color_depth = dev->encoder_buffer.color_depth;
1004+ msg.num_cores = dev->encoder_buffer.num_cores;
1005+ msg.clk_rate = dev->encoder_buffer.clk_rate;
1006+ } else {
1007+ msg.encoder_buffer_size = -1;
1008+ msg.encoder_buffer_color_depth = -1;
1009+ msg.num_cores = -1;
1010+ msg.clk_rate = -1;
1011+ }
9501012
9511013 allegro_mbox_send(dev->mbox_command, &msg);
9521014 }
@@ -1193,9 +1255,8 @@ static int fill_create_channel_param(struct allegro_channel *channel, · 240 unmodified lines
11931255 param->max_transfo_depth_intra = channel->max_transfo_depth_intra;
11941256 param->max_transfo_depth_inter = channel->max_transfo_depth_inter;
11951257
1196− param->prefetch_auto = 0;
1197− param->prefetch_mem_offset = 0;
1198− param->prefetch_mem_size = 0;
1258+ param->encoder_buffer_enabled = channel->dev->has_encoder_buffer;
1259+ param->encoder_buffer_offset = 0;
11991260
12001261 param->rate_control_mode = channel->frame_rc_enable ?
12011262 v4l2_bitrate_mode_to_mcu_mode(bitrate_mode) : 0;
@@ -1320,6 +1381,7 @@ static int allegro_mcu_send_encode_frame(struct allegro_dev *dev, · 118 unmodified lines
13201381 u64 src_handle)
13211382 {
13221383 struct mcu_msg_encode_frame msg;
1384+ bool use_encoder_buffer = channel->dev->has_encoder_buffer;
13231385
13241386 memset(&msg, 0, sizeof(msg));
13251387
@@ -1328,6 +1390,8 @@ static int allegro_mcu_send_encode_frame(struct allegro_dev *dev, · 2 unmodified lines
13281390
13291391 msg.channel_id = channel->mcu_channel_id;
13301392 msg.encoding_options = AL_OPT_FORCE_LOAD;
1393+ if (use_encoder_buffer)
1394+ msg.encoding_options |= AL_OPT_USE_L2;
13311395 msg.pps_qp = 26; /* qp are relative to 26 */
13321396 msg.user_param = 0; /* copied to mcu_msg_encode_frame_response */
13331397 /* src_handle is copied to mcu_msg_encode_frame_response */
@@ -3522,6 +3586,11 @@ static int allegro_mcu_hw_init(struct allegro_dev *dev, · 2188 unmodified lines
35223586 return -EIO;
35233587 }
35243588
3589+ err = allegro_encoder_buffer_init(dev, &dev->encoder_buffer);
3590+ dev->has_encoder_buffer = (err == 0);
3591+ if (!dev->has_encoder_buffer)
3592+ v4l2_info(&dev->v4l2_dev, "encoder buffer not available\n");
3593+
35253594 allegro_mcu_enable_interrupts(dev);
35263595
35273596 /* The mcu sends INIT after reset. */
drivers/media/platform/allegro-dvt/allegro-mail.c+8−11
@@ -49,11 +49,11 @@ allegro_enc_init(u32 *dst, struct mcu_msg_init_request *msg) · 48 unmodified lines
4949 dst[i++] = msg->reserved0;
5050 dst[i++] = msg->suballoc_dma;
5151 dst[i++] = msg->suballoc_size;
52− dst[i++] = msg->l2_cache[0];
53− dst[i++] = msg->l2_cache[1];
54− dst[i++] = msg->l2_cache[2];
52+ dst[i++] = msg->encoder_buffer_size;
53+ dst[i++] = msg->encoder_buffer_color_depth;
54+ dst[i++] = msg->num_cores;
5555 if (version >= MCU_MSG_VERSION_2019_2) {
56− dst[i++] = -1;
56+ dst[i++] = msg->clk_rate;
5757 dst[i++] = 0;
5858 }
5959
@@ -146,13 +146,10 @@ allegro_encode_config_blob(u32 *dst, struct create_channel_param *param) · 86 unmodified lines
146146 FIELD_PREP(GENMASK(7, 0), param->tc_offset);
147147 dst[i++] = param->unknown11;
148148 dst[i++] = param->unknown12;
149− if (version >= MCU_MSG_VERSION_2019_2)
150− dst[i++] = param->num_slices;
151− else
152− dst[i++] = FIELD_PREP(GENMASK(31, 16), param->prefetch_auto) |
153− FIELD_PREP(GENMASK(15, 0), param->num_slices);
154− dst[i++] = param->prefetch_mem_offset;
155− dst[i++] = param->prefetch_mem_size;
149+ dst[i++] = param->num_slices;
150+ dst[i++] = param->encoder_buffer_offset;
151+ dst[i++] = param->encoder_buffer_enabled;
152+
156153 dst[i++] = FIELD_PREP(GENMASK(31, 16), param->clip_vrt_range) |
157154 FIELD_PREP(GENMASK(15, 0), param->clip_hrz_range);
158155 dst[i++] = FIELD_PREP(GENMASK(31, 16), param->me_range[1]) |
drivers/media/platform/allegro-dvt/allegro-mail.h+6−4
@@ -37,7 +37,10 @@ struct mcu_msg_init_request { · 36 unmodified lines
3737 u32 reserved0; /* maybe a unused channel id */
3838 u32 suballoc_dma;
3939 u32 suballoc_size;
40− s32 l2_cache[3];
40+ s32 encoder_buffer_size;
41+ s32 encoder_buffer_color_depth;
42+ s32 num_cores;
43+ s32 clk_rate;
4144 };
4245
4346 struct mcu_msg_init_response {
@@ -79,9 +82,8 @@ struct create_channel_param { · 35 unmodified lines
7982 u32 unknown11;
8083 u32 unknown12;
8184 u16 num_slices;
82− u16 prefetch_auto;
83− u32 prefetch_mem_offset;
84− u32 prefetch_mem_size;
85+ u32 encoder_buffer_offset;
86+ u32 encoder_buffer_enabled;
8587 u16 clip_hrz_range;
8688 u16 clip_vrt_range;
8789 u16 me_range[4];