Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: chips-media: wave5: support Wave515 decoder

Add initial support for the Wave515 multi-decoder IP. For now it is only
able to decode HEVC Main/Main10 profile videos into YUV420.

This was tested on FPGA prototype, so wave5_dt_ids[] was not expanded.
Users of the real hardware with Wave515 IP will have to
* provide firmware specific to their SoC
* add struct wave5_match_data like this:

static const struct wave5_match_data platform_name_wave515_data = {
.flags = WAVE5_IS_DEC,
.fw_name = "cnm/wave515_platform_name_fw.bin",
.sram_size = (71 * 1024),
};

* add item to wave5_dt_ids[] like this:

{
.compatible = "vendor,soc-wave515",
.data = &platform_name_wave515_data,
},

* describe new compatible in
Documentation/devicetree/bindings/media/cnm,wave521c.yaml

Signed-off-by: Ivan Bornyakov <brnkv.i1@gmail.com>
Signed-off-by: Sebastian Fricke <sebastian.fricke@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>

authored by

Ivan Bornyakov and committed by
Hans Verkuil
6aa08291 a83d4a68

+278 -77
+7 -1
drivers/media/platform/chips-media/wave5/wave5-helper.c
··· 29 29 { 30 30 int i; 31 31 32 - if (list_is_singular(&inst->list)) 32 + /* 33 + * For Wave515 SRAM memory is allocated at 34 + * wave5_vpu_dec_register_device() and freed at 35 + * wave5_vpu_dec_unregister_device(). 36 + */ 37 + if (list_is_singular(&inst->list) && 38 + inst->dev->product_code != WAVE515_CODE) 33 39 wave5_vdi_free_sram(inst->dev); 34 40 35 41 for (i = 0; i < inst->fbc_buf_count; i++)
+215 -67
drivers/media/platform/chips-media/wave5/wave5-hw.c
··· 18 18 #define QUEUE_REPORT_MASK 0xffff 19 19 20 20 /* Encoder support fields */ 21 - #define FEATURE_HEVC10BIT_ENC BIT(3) 22 - #define FEATURE_AVC10BIT_ENC BIT(11) 23 - #define FEATURE_AVC_ENCODER BIT(1) 24 - #define FEATURE_HEVC_ENCODER BIT(0) 21 + #define W521_FEATURE_HEVC10BIT_ENC BIT(3) 22 + #define W521_FEATURE_AVC10BIT_ENC BIT(11) 23 + #define W521_FEATURE_AVC_ENCODER BIT(1) 24 + #define W521_FEATURE_HEVC_ENCODER BIT(0) 25 25 26 26 /* Decoder support fields */ 27 - #define FEATURE_AVC_DECODER BIT(3) 28 - #define FEATURE_HEVC_DECODER BIT(2) 27 + #define W521_FEATURE_AVC_DECODER BIT(3) 28 + #define W521_FEATURE_HEVC_DECODER BIT(2) 29 + #define W515_FEATURE_HEVC10BIT_DEC BIT(1) 30 + #define W515_FEATURE_HEVC_DECODER BIT(0) 29 31 30 - #define FEATURE_BACKBONE BIT(16) 31 - #define FEATURE_VCORE_BACKBONE BIT(22) 32 - #define FEATURE_VCPU_BACKBONE BIT(28) 32 + #define W521_FEATURE_BACKBONE BIT(16) 33 + #define W521_FEATURE_VCORE_BACKBONE BIT(22) 34 + #define W521_FEATURE_VCPU_BACKBONE BIT(28) 33 35 34 36 #define REMAP_CTRL_MAX_SIZE_BITS ((W5_REMAP_MAX_SIZE >> 12) & 0x1ff) 35 37 #define REMAP_CTRL_REGISTER_VALUE(index) ( \ ··· 157 155 { 158 156 u32 gdi_status_check_value = 0x3f; 159 157 158 + if (vpu_dev->product_code == WAVE515_CODE) 159 + gdi_status_check_value = 0x0738; 160 160 if (vpu_dev->product_code == WAVE521C_CODE || 161 161 vpu_dev->product_code == WAVE521_CODE || 162 162 vpu_dev->product_code == WAVE521E1_CODE) ··· 190 186 u32 val = vpu_read_reg(vpu_dev, W5_PRODUCT_NUMBER); 191 187 192 188 switch (val) { 189 + case WAVE515_CODE: 190 + return PRODUCT_ID_515; 193 191 case WAVE521C_CODE: 194 192 return PRODUCT_ID_521; 195 193 case WAVE521_CODE: ··· 355 349 hw_config_def1 = vpu_read_reg(vpu_dev, W5_RET_STD_DEF1); 356 350 hw_config_feature = vpu_read_reg(vpu_dev, W5_RET_CONF_FEATURE); 357 351 358 - p_attr->support_hevc10bit_enc = FIELD_GET(FEATURE_HEVC10BIT_ENC, hw_config_feature); 359 - p_attr->support_avc10bit_enc = FIELD_GET(FEATURE_AVC10BIT_ENC, hw_config_feature); 352 + if (vpu_dev->product_code == WAVE515_CODE) { 353 + p_attr->support_hevc10bit_dec = FIELD_GET(W515_FEATURE_HEVC10BIT_DEC, 354 + hw_config_feature); 355 + p_attr->support_decoders = FIELD_GET(W515_FEATURE_HEVC_DECODER, 356 + hw_config_def1) << STD_HEVC; 357 + } else { 358 + p_attr->support_hevc10bit_enc = FIELD_GET(W521_FEATURE_HEVC10BIT_ENC, 359 + hw_config_feature); 360 + p_attr->support_avc10bit_enc = FIELD_GET(W521_FEATURE_AVC10BIT_ENC, 361 + hw_config_feature); 360 362 361 - p_attr->support_decoders = FIELD_GET(FEATURE_AVC_DECODER, hw_config_def1) << STD_AVC; 362 - p_attr->support_decoders |= FIELD_GET(FEATURE_HEVC_DECODER, hw_config_def1) << STD_HEVC; 363 - p_attr->support_encoders = FIELD_GET(FEATURE_AVC_ENCODER, hw_config_def1) << STD_AVC; 364 - p_attr->support_encoders |= FIELD_GET(FEATURE_HEVC_ENCODER, hw_config_def1) << STD_HEVC; 363 + p_attr->support_decoders = FIELD_GET(W521_FEATURE_AVC_DECODER, 364 + hw_config_def1) << STD_AVC; 365 + p_attr->support_decoders |= FIELD_GET(W521_FEATURE_HEVC_DECODER, 366 + hw_config_def1) << STD_HEVC; 367 + p_attr->support_encoders = FIELD_GET(W521_FEATURE_AVC_ENCODER, 368 + hw_config_def1) << STD_AVC; 369 + p_attr->support_encoders |= FIELD_GET(W521_FEATURE_HEVC_ENCODER, 370 + hw_config_def1) << STD_HEVC; 365 371 366 - p_attr->support_backbone = FIELD_GET(FEATURE_BACKBONE, hw_config_def0); 367 - p_attr->support_vcpu_backbone = FIELD_GET(FEATURE_VCPU_BACKBONE, hw_config_def0); 368 - p_attr->support_vcore_backbone = FIELD_GET(FEATURE_VCORE_BACKBONE, hw_config_def0); 372 + p_attr->support_backbone = FIELD_GET(W521_FEATURE_BACKBONE, 373 + hw_config_def0); 374 + p_attr->support_vcpu_backbone = FIELD_GET(W521_FEATURE_VCPU_BACKBONE, 375 + hw_config_def0); 376 + p_attr->support_vcore_backbone = FIELD_GET(W521_FEATURE_VCORE_BACKBONE, 377 + hw_config_def0); 378 + } 369 379 370 380 setup_wave5_interrupts(vpu_dev); 371 381 ··· 425 403 common_vb = &vpu_dev->common_mem; 426 404 427 405 code_base = common_vb->daddr; 406 + 407 + if (vpu_dev->product_code == WAVE515_CODE) 408 + code_size = WAVE515_MAX_CODE_BUF_SIZE; 409 + else 410 + code_size = WAVE521_MAX_CODE_BUF_SIZE; 411 + 428 412 /* ALIGN TO 4KB */ 429 - code_size = (WAVE5_MAX_CODE_BUF_SIZE & ~0xfff); 413 + code_size &= ~0xfff; 430 414 if (code_size < size * 2) 431 415 return -EINVAL; 432 416 433 - temp_base = common_vb->daddr + WAVE5_TEMPBUF_OFFSET; 417 + temp_base = code_base + code_size; 434 418 temp_size = WAVE5_TEMPBUF_SIZE; 435 419 436 420 ret = wave5_vdi_write_memory(vpu_dev, common_vb, 0, fw, size); ··· 464 436 465 437 /* These register must be reset explicitly */ 466 438 vpu_write_reg(vpu_dev, W5_HW_OPTION, 0); 467 - wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0); 468 - wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); 469 - vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); 439 + 440 + if (vpu_dev->product_code != WAVE515_CODE) { 441 + wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0); 442 + wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); 443 + vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); 444 + } 470 445 471 446 reg_val = vpu_read_reg(vpu_dev, W5_VPU_RET_VPU_CONFIG0); 472 - if (FIELD_GET(FEATURE_BACKBONE, reg_val)) { 447 + if (FIELD_GET(W521_FEATURE_BACKBONE, reg_val)) { 473 448 reg_val = ((WAVE5_PROC_AXI_ID << 28) | 474 449 (WAVE5_PRP_AXI_ID << 24) | 475 450 (WAVE5_FBD_Y_AXI_ID << 20) | ··· 482 451 (WAVE5_PRI_AXI_ID << 4) | 483 452 WAVE5_SEC_AXI_ID); 484 453 wave5_fio_writel(vpu_dev, W5_BACKBONE_PROG_AXI_ID, reg_val); 454 + } 455 + 456 + if (vpu_dev->product_code == WAVE515_CODE) { 457 + dma_addr_t task_buf_base; 458 + 459 + vpu_write_reg(vpu_dev, W5_CMD_INIT_NUM_TASK_BUF, WAVE515_COMMAND_QUEUE_DEPTH); 460 + vpu_write_reg(vpu_dev, W5_CMD_INIT_TASK_BUF_SIZE, WAVE515_ONE_TASKBUF_SIZE); 461 + 462 + for (i = 0; i < WAVE515_COMMAND_QUEUE_DEPTH; i++) { 463 + task_buf_base = temp_base + temp_size + 464 + (i * WAVE515_ONE_TASKBUF_SIZE); 465 + vpu_write_reg(vpu_dev, 466 + W5_CMD_INIT_ADDR_TASK_BUF0 + (i * 4), 467 + task_buf_base); 468 + } 469 + 470 + vpu_write_reg(vpu_dev, W515_CMD_ADDR_SEC_AXI, vpu_dev->sram_buf.daddr); 471 + vpu_write_reg(vpu_dev, W515_CMD_SEC_AXI_SIZE, vpu_dev->sram_buf.size); 485 472 } 486 473 487 474 vpu_write_reg(vpu_dev, W5_VPU_BUSY_STATUS, 1); ··· 542 493 return -EINVAL; 543 494 } 544 495 545 - p_dec_info->vb_work.size = WAVE521DEC_WORKBUF_SIZE; 496 + if (vpu_dev->product == PRODUCT_ID_515) 497 + p_dec_info->vb_work.size = WAVE515DEC_WORKBUF_SIZE; 498 + else 499 + p_dec_info->vb_work.size = WAVE521DEC_WORKBUF_SIZE; 500 + 546 501 ret = wave5_vdi_allocate_dma_memory(inst->dev, &p_dec_info->vb_work); 547 502 if (ret) 548 503 return ret; 549 504 550 - vpu_write_reg(inst->dev, W5_CMD_DEC_VCORE_INFO, 1); 505 + if (inst->dev->product_code != WAVE515_CODE) 506 + vpu_write_reg(inst->dev, W5_CMD_DEC_VCORE_INFO, 1); 551 507 552 508 wave5_vdi_clear_memory(inst->dev, &p_dec_info->vb_work); 553 509 554 510 vpu_write_reg(inst->dev, W5_ADDR_WORK_BASE, p_dec_info->vb_work.daddr); 555 511 vpu_write_reg(inst->dev, W5_WORK_SIZE, p_dec_info->vb_work.size); 556 512 557 - vpu_write_reg(inst->dev, W5_CMD_ADDR_SEC_AXI, vpu_dev->sram_buf.daddr); 558 - vpu_write_reg(inst->dev, W5_CMD_SEC_AXI_SIZE, vpu_dev->sram_buf.size); 513 + if (inst->dev->product_code != WAVE515_CODE) { 514 + vpu_write_reg(inst->dev, W5_CMD_ADDR_SEC_AXI, vpu_dev->sram_buf.daddr); 515 + vpu_write_reg(inst->dev, W5_CMD_SEC_AXI_SIZE, vpu_dev->sram_buf.size); 516 + } 559 517 560 518 vpu_write_reg(inst->dev, W5_CMD_DEC_BS_START_ADDR, p_dec_info->stream_buf_start_addr); 561 519 vpu_write_reg(inst->dev, W5_CMD_DEC_BS_SIZE, p_dec_info->stream_buf_size); 562 520 563 521 /* NOTE: SDMA reads MSB first */ 564 522 vpu_write_reg(inst->dev, W5_CMD_BS_PARAM, BITSTREAM_ENDIANNESS_BIG_ENDIAN); 565 - /* This register must be reset explicitly */ 566 - vpu_write_reg(inst->dev, W5_CMD_EXT_ADDR, 0); 567 - vpu_write_reg(inst->dev, W5_CMD_NUM_CQ_DEPTH_M1, (COMMAND_QUEUE_DEPTH - 1)); 523 + 524 + if (inst->dev->product_code != WAVE515_CODE) { 525 + /* This register must be reset explicitly */ 526 + vpu_write_reg(inst->dev, W5_CMD_EXT_ADDR, 0); 527 + vpu_write_reg(inst->dev, W5_CMD_NUM_CQ_DEPTH_M1, 528 + WAVE521_COMMAND_QUEUE_DEPTH - 1); 529 + } 568 530 569 531 ret = send_firmware_command(inst, W5_CREATE_INSTANCE, true, NULL, NULL); 570 532 if (ret) { ··· 626 566 int wave5_vpu_dec_init_seq(struct vpu_instance *inst) 627 567 { 628 568 struct dec_info *p_dec_info = &inst->codec_info->dec_info; 629 - u32 cmd_option = INIT_SEQ_NORMAL; 569 + u32 bs_option, cmd_option = INIT_SEQ_NORMAL; 630 570 u32 reg_val, fail_res; 631 571 int ret; 632 572 ··· 636 576 vpu_write_reg(inst->dev, W5_BS_RD_PTR, p_dec_info->stream_rd_ptr); 637 577 vpu_write_reg(inst->dev, W5_BS_WR_PTR, p_dec_info->stream_wr_ptr); 638 578 639 - vpu_write_reg(inst->dev, W5_BS_OPTION, get_bitstream_options(p_dec_info)); 579 + bs_option = get_bitstream_options(p_dec_info); 580 + 581 + /* Without RD_PTR_VALID_FLAG Wave515 ignores RD_PTR value */ 582 + if (inst->dev->product_code == WAVE515_CODE) 583 + bs_option |= BSOPTION_RD_PTR_VALID_FLAG; 584 + 585 + vpu_write_reg(inst->dev, W5_BS_OPTION, bs_option); 640 586 641 587 vpu_write_reg(inst->dev, W5_COMMAND_OPTION, cmd_option); 642 588 vpu_write_reg(inst->dev, W5_CMD_DEC_USER_MASK, p_dec_info->user_data_enable); ··· 708 642 info->profile = FIELD_GET(SEQ_PARAM_PROFILE_MASK, reg_val); 709 643 } 710 644 711 - info->vlc_buf_size = vpu_read_reg(inst->dev, W5_RET_VLC_BUF_SIZE); 712 - info->param_buf_size = vpu_read_reg(inst->dev, W5_RET_PARAM_BUF_SIZE); 713 - p_dec_info->vlc_buf_size = info->vlc_buf_size; 714 - p_dec_info->param_buf_size = info->param_buf_size; 645 + if (inst->dev->product_code != WAVE515_CODE) { 646 + info->vlc_buf_size = vpu_read_reg(inst->dev, W5_RET_VLC_BUF_SIZE); 647 + info->param_buf_size = vpu_read_reg(inst->dev, W5_RET_PARAM_BUF_SIZE); 648 + p_dec_info->vlc_buf_size = info->vlc_buf_size; 649 + p_dec_info->param_buf_size = info->param_buf_size; 650 + } 715 651 } 716 652 717 653 int wave5_vpu_dec_get_seq_info(struct vpu_instance *inst, struct dec_initial_info *info) ··· 815 747 816 748 pic_size = (init_info->pic_width << 16) | (init_info->pic_height); 817 749 818 - vb_buf.size = (p_dec_info->vlc_buf_size * VLC_BUF_NUM) + 819 - (p_dec_info->param_buf_size * COMMAND_QUEUE_DEPTH); 820 - vb_buf.daddr = 0; 750 + if (inst->dev->product_code != WAVE515_CODE) { 751 + vb_buf.size = (p_dec_info->vlc_buf_size * VLC_BUF_NUM) + 752 + (p_dec_info->param_buf_size * WAVE521_COMMAND_QUEUE_DEPTH); 753 + vb_buf.daddr = 0; 821 754 822 - if (vb_buf.size != p_dec_info->vb_task.size) { 823 - wave5_vdi_free_dma_memory(inst->dev, &p_dec_info->vb_task); 824 - ret = wave5_vdi_allocate_dma_memory(inst->dev, &vb_buf); 825 - if (ret) 826 - goto free_fbc_c_tbl_buffers; 755 + if (vb_buf.size != p_dec_info->vb_task.size) { 756 + wave5_vdi_free_dma_memory(inst->dev, 757 + &p_dec_info->vb_task); 758 + ret = wave5_vdi_allocate_dma_memory(inst->dev, 759 + &vb_buf); 760 + if (ret) 761 + goto free_fbc_c_tbl_buffers; 827 762 828 - p_dec_info->vb_task = vb_buf; 763 + p_dec_info->vb_task = vb_buf; 764 + } 765 + 766 + vpu_write_reg(inst->dev, W5_CMD_SET_FB_ADDR_TASK_BUF, 767 + p_dec_info->vb_task.daddr); 768 + vpu_write_reg(inst->dev, W5_CMD_SET_FB_TASK_BUF_SIZE, 769 + vb_buf.size); 829 770 } 830 - 831 - vpu_write_reg(inst->dev, W5_CMD_SET_FB_ADDR_TASK_BUF, 832 - p_dec_info->vb_task.daddr); 833 - vpu_write_reg(inst->dev, W5_CMD_SET_FB_TASK_BUF_SIZE, vb_buf.size); 834 771 } else { 835 772 pic_size = (init_info->pic_width << 16) | (init_info->pic_height); 836 773 ··· 918 845 919 846 static u32 wave5_vpu_dec_validate_sec_axi(struct vpu_instance *inst) 920 847 { 848 + u32 bitdepth = inst->codec_info->dec_info.initial_info.luma_bitdepth; 921 849 struct dec_info *p_dec_info = &inst->codec_info->dec_info; 922 850 u32 bit_size = 0, ip_size = 0, lf_size = 0, ret = 0; 923 851 u32 sram_size = inst->dev->sram_size; 852 + u32 width = inst->src_fmt.width; 924 853 925 854 if (!sram_size) 926 855 return 0; 927 856 928 857 /* 929 - * TODO: calculate bit_size, ip_size, lf_size from inst->src_fmt.width 930 - * and inst->codec_info->dec_info.initial_info.luma_bitdepth 858 + * TODO: calculate bit_size, ip_size, lf_size from width and bitdepth 859 + * for Wave521. 931 860 */ 861 + if (inst->dev->product_code == WAVE515_CODE) { 862 + bit_size = DIV_ROUND_UP(width, 16) * 5 * 8; 863 + ip_size = ALIGN(width, 16) * 2 * bitdepth / 8; 864 + lf_size = ALIGN(width, 16) * 10 * bitdepth / 8; 865 + } 932 866 933 867 if (p_dec_info->sec_axi_info.use_bit_enable && sram_size >= bit_size) { 934 868 ret |= BIT(0); ··· 1113 1033 common_vb = &vpu_dev->common_mem; 1114 1034 1115 1035 code_base = common_vb->daddr; 1036 + 1037 + if (vpu_dev->product_code == WAVE515_CODE) 1038 + code_size = WAVE515_MAX_CODE_BUF_SIZE; 1039 + else 1040 + code_size = WAVE521_MAX_CODE_BUF_SIZE; 1041 + 1116 1042 /* ALIGN TO 4KB */ 1117 - code_size = (WAVE5_MAX_CODE_BUF_SIZE & ~0xfff); 1043 + code_size &= ~0xfff; 1118 1044 if (code_size < size * 2) 1119 1045 return -EINVAL; 1120 - temp_base = common_vb->daddr + WAVE5_TEMPBUF_OFFSET; 1046 + 1047 + temp_base = code_base + code_size; 1121 1048 temp_size = WAVE5_TEMPBUF_SIZE; 1122 1049 1123 1050 old_code_base = vpu_read_reg(vpu_dev, W5_VPU_REMAP_PADDR); ··· 1158 1071 1159 1072 /* These register must be reset explicitly */ 1160 1073 vpu_write_reg(vpu_dev, W5_HW_OPTION, 0); 1161 - wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0); 1162 - wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); 1163 - vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); 1074 + 1075 + if (vpu_dev->product_code != WAVE515_CODE) { 1076 + wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0); 1077 + wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); 1078 + vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); 1079 + } 1164 1080 1165 1081 reg_val = vpu_read_reg(vpu_dev, W5_VPU_RET_VPU_CONFIG0); 1166 - if (FIELD_GET(FEATURE_BACKBONE, reg_val)) { 1082 + if (FIELD_GET(W521_FEATURE_BACKBONE, reg_val)) { 1167 1083 reg_val = ((WAVE5_PROC_AXI_ID << 28) | 1168 1084 (WAVE5_PRP_AXI_ID << 24) | 1169 1085 (WAVE5_FBD_Y_AXI_ID << 20) | ··· 1176 1086 (WAVE5_PRI_AXI_ID << 4) | 1177 1087 WAVE5_SEC_AXI_ID); 1178 1088 wave5_fio_writel(vpu_dev, W5_BACKBONE_PROG_AXI_ID, reg_val); 1089 + } 1090 + 1091 + if (vpu_dev->product_code == WAVE515_CODE) { 1092 + dma_addr_t task_buf_base; 1093 + u32 i; 1094 + 1095 + vpu_write_reg(vpu_dev, W5_CMD_INIT_NUM_TASK_BUF, 1096 + WAVE515_COMMAND_QUEUE_DEPTH); 1097 + vpu_write_reg(vpu_dev, W5_CMD_INIT_TASK_BUF_SIZE, 1098 + WAVE515_ONE_TASKBUF_SIZE); 1099 + 1100 + for (i = 0; i < WAVE515_COMMAND_QUEUE_DEPTH; i++) { 1101 + task_buf_base = temp_base + temp_size + 1102 + (i * WAVE515_ONE_TASKBUF_SIZE); 1103 + vpu_write_reg(vpu_dev, 1104 + W5_CMD_INIT_ADDR_TASK_BUF0 + (i * 4), 1105 + task_buf_base); 1106 + } 1107 + 1108 + vpu_write_reg(vpu_dev, W515_CMD_ADDR_SEC_AXI, 1109 + vpu_dev->sram_buf.daddr); 1110 + vpu_write_reg(vpu_dev, W515_CMD_SEC_AXI_SIZE, 1111 + vpu_dev->sram_buf.size); 1179 1112 } 1180 1113 1181 1114 vpu_write_reg(vpu_dev, W5_VPU_BUSY_STATUS, 1); ··· 1224 1111 { 1225 1112 u32 reg_val; 1226 1113 struct vpu_buf *common_vb; 1227 - dma_addr_t code_base; 1228 - u32 code_size, reason_code; 1114 + dma_addr_t code_base, temp_base; 1115 + u32 code_size, temp_size, reason_code; 1229 1116 struct vpu_device *vpu_dev = dev_get_drvdata(dev); 1230 1117 int ret; 1231 1118 ··· 1255 1142 common_vb = &vpu_dev->common_mem; 1256 1143 1257 1144 code_base = common_vb->daddr; 1145 + 1146 + if (vpu_dev->product_code == WAVE515_CODE) 1147 + code_size = WAVE515_MAX_CODE_BUF_SIZE; 1148 + else 1149 + code_size = WAVE521_MAX_CODE_BUF_SIZE; 1150 + 1258 1151 /* ALIGN TO 4KB */ 1259 - code_size = (WAVE5_MAX_CODE_BUF_SIZE & ~0xfff); 1152 + code_size &= ~0xfff; 1260 1153 if (code_size < size * 2) { 1261 1154 dev_err(dev, "size too small\n"); 1262 1155 return -EINVAL; 1263 1156 } 1157 + 1158 + temp_base = code_base + code_size; 1159 + temp_size = WAVE5_TEMPBUF_SIZE; 1264 1160 1265 1161 /* Power on without DEBUG mode */ 1266 1162 vpu_write_reg(vpu_dev, W5_PO_CONF, 0); ··· 1283 1161 1284 1162 /* These register must be reset explicitly */ 1285 1163 vpu_write_reg(vpu_dev, W5_HW_OPTION, 0); 1286 - wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0); 1287 - wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); 1288 - vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); 1164 + 1165 + if (vpu_dev->product_code != WAVE515_CODE) { 1166 + wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0); 1167 + wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); 1168 + vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); 1169 + } 1289 1170 1290 1171 setup_wave5_interrupts(vpu_dev); 1291 1172 1292 1173 reg_val = vpu_read_reg(vpu_dev, W5_VPU_RET_VPU_CONFIG0); 1293 - if (FIELD_GET(FEATURE_BACKBONE, reg_val)) { 1174 + if (FIELD_GET(W521_FEATURE_BACKBONE, reg_val)) { 1294 1175 reg_val = ((WAVE5_PROC_AXI_ID << 28) | 1295 1176 (WAVE5_PRP_AXI_ID << 24) | 1296 1177 (WAVE5_FBD_Y_AXI_ID << 20) | ··· 1303 1178 (WAVE5_PRI_AXI_ID << 4) | 1304 1179 WAVE5_SEC_AXI_ID); 1305 1180 wave5_fio_writel(vpu_dev, W5_BACKBONE_PROG_AXI_ID, reg_val); 1181 + } 1182 + 1183 + if (vpu_dev->product_code == WAVE515_CODE) { 1184 + dma_addr_t task_buf_base; 1185 + u32 i; 1186 + 1187 + vpu_write_reg(vpu_dev, W5_CMD_INIT_NUM_TASK_BUF, 1188 + WAVE515_COMMAND_QUEUE_DEPTH); 1189 + vpu_write_reg(vpu_dev, W5_CMD_INIT_TASK_BUF_SIZE, 1190 + WAVE515_ONE_TASKBUF_SIZE); 1191 + 1192 + for (i = 0; i < WAVE515_COMMAND_QUEUE_DEPTH; i++) { 1193 + task_buf_base = temp_base + temp_size + 1194 + (i * WAVE515_ONE_TASKBUF_SIZE); 1195 + vpu_write_reg(vpu_dev, 1196 + W5_CMD_INIT_ADDR_TASK_BUF0 + (i * 4), 1197 + task_buf_base); 1198 + } 1199 + 1200 + vpu_write_reg(vpu_dev, W515_CMD_ADDR_SEC_AXI, 1201 + vpu_dev->sram_buf.daddr); 1202 + vpu_write_reg(vpu_dev, W515_CMD_SEC_AXI_SIZE, 1203 + vpu_dev->sram_buf.size); 1306 1204 } 1307 1205 1308 1206 vpu_write_reg(vpu_dev, W5_VPU_BUSY_STATUS, 1); ··· 1572 1424 reg_val = (open_param->line_buf_int_en << 6) | BITSTREAM_ENDIANNESS_BIG_ENDIAN; 1573 1425 vpu_write_reg(inst->dev, W5_CMD_BS_PARAM, reg_val); 1574 1426 vpu_write_reg(inst->dev, W5_CMD_EXT_ADDR, 0); 1575 - vpu_write_reg(inst->dev, W5_CMD_NUM_CQ_DEPTH_M1, (COMMAND_QUEUE_DEPTH - 1)); 1427 + vpu_write_reg(inst->dev, W5_CMD_NUM_CQ_DEPTH_M1, WAVE521_COMMAND_QUEUE_DEPTH - 1); 1576 1428 1577 1429 /* This register must be reset explicitly */ 1578 1430 vpu_write_reg(inst->dev, W5_CMD_ENC_SRC_OPTIONS, 0); ··· 2026 1878 p_enc_info->vb_sub_sam_buf = vb_sub_sam_buf; 2027 1879 2028 1880 vb_task.size = (p_enc_info->vlc_buf_size * VLC_BUF_NUM) + 2029 - (p_enc_info->param_buf_size * COMMAND_QUEUE_DEPTH); 1881 + (p_enc_info->param_buf_size * WAVE521_COMMAND_QUEUE_DEPTH); 2030 1882 vb_task.daddr = 0; 2031 1883 if (p_enc_info->vb_task.size == 0) { 2032 1884 ret = wave5_vdi_allocate_dma_memory(vpu_dev, &vb_task);
+5
drivers/media/platform/chips-media/wave5/wave5-regdefine.h
··· 205 205 #define W5_ADDR_TEMP_BASE (W5_REG_BASE + 0x011C) 206 206 #define W5_TEMP_SIZE (W5_REG_BASE + 0x0120) 207 207 #define W5_HW_OPTION (W5_REG_BASE + 0x012C) 208 + #define W5_CMD_INIT_NUM_TASK_BUF (W5_REG_BASE + 0x0134) 209 + #define W5_CMD_INIT_ADDR_TASK_BUF0 (W5_REG_BASE + 0x0138) 210 + #define W5_CMD_INIT_TASK_BUF_SIZE (W5_REG_BASE + 0x0178) 208 211 #define W5_SEC_AXI_PARAM (W5_REG_BASE + 0x0180) 209 212 210 213 /************************************************************************/ ··· 219 216 #define W5_CMD_DEC_BS_SIZE (W5_REG_BASE + 0x0120) 220 217 #define W5_CMD_BS_PARAM (W5_REG_BASE + 0x0124) 221 218 #define W5_CMD_ADDR_SEC_AXI (W5_REG_BASE + 0x0130) 219 + #define W515_CMD_ADDR_SEC_AXI (W5_REG_BASE + 0x0124) 222 220 #define W5_CMD_SEC_AXI_SIZE (W5_REG_BASE + 0x0134) 221 + #define W515_CMD_SEC_AXI_SIZE (W5_REG_BASE + 0x0128) 223 222 #define W5_CMD_EXT_ADDR (W5_REG_BASE + 0x0138) 224 223 #define W5_CMD_NUM_CQ_DEPTH_M1 (W5_REG_BASE + 0x013C) 225 224 #define W5_CMD_ERR_CONCEAL (W5_REG_BASE + 0x0140)
+5 -1
drivers/media/platform/chips-media/wave5/wave5-vdi.c
··· 18 18 if (!vpu_dev->common_mem.vaddr) { 19 19 int ret; 20 20 21 - vpu_dev->common_mem.size = SIZE_COMMON; 21 + if (vpu_dev->product_code == WAVE515_CODE) 22 + vpu_dev->common_mem.size = WAVE515_SIZE_COMMON; 23 + else 24 + vpu_dev->common_mem.size = WAVE521_SIZE_COMMON; 25 + 22 26 ret = wave5_vdi_allocate_dma_memory(vpu_dev, &vpu_dev->common_mem); 23 27 if (ret) { 24 28 dev_err(dev, "unable to allocate common buffer\n");
+20 -1
drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
··· 1868 1868 goto cleanup_inst; 1869 1869 } 1870 1870 1871 - wave5_vdi_allocate_sram(inst->dev); 1871 + /* 1872 + * For Wave515 SRAM memory was already allocated 1873 + * at wave5_vpu_dec_register_device() 1874 + */ 1875 + if (inst->dev->product_code != WAVE515_CODE) 1876 + wave5_vdi_allocate_sram(inst->dev); 1872 1877 1873 1878 ret = mutex_lock_interruptible(&dev->dev_lock); 1874 1879 if (ret) ··· 1913 1908 struct video_device *vdev_dec; 1914 1909 int ret; 1915 1910 1911 + /* 1912 + * Secondary AXI setup for Wave515 is done by INIT_VPU command, 1913 + * i.e. wave5_vpu_init(), that's why we allocate SRAM memory early. 1914 + */ 1915 + if (dev->product_code == WAVE515_CODE) 1916 + wave5_vdi_allocate_sram(dev); 1917 + 1916 1918 vdev_dec = devm_kzalloc(dev->v4l2_dev.dev, sizeof(*vdev_dec), GFP_KERNEL); 1917 1919 if (!vdev_dec) 1918 1920 return -ENOMEM; ··· 1953 1941 1954 1942 void wave5_vpu_dec_unregister_device(struct vpu_device *dev) 1955 1943 { 1944 + /* 1945 + * Here is a freeing pair for Wave515 SRAM memory allocation 1946 + * happened at wave5_vpu_dec_register_device(). 1947 + */ 1948 + if (dev->product_code == WAVE515_CODE) 1949 + wave5_vdi_free_sram(dev); 1950 + 1956 1951 video_unregister_device(dev->video_dev_dec); 1957 1952 if (dev->v4l2_m2m_dec_dev) 1958 1953 v4l2_m2m_release(dev->v4l2_m2m_dec_dev);
+1 -1
drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
··· 1247 1247 __func__, initial_info.min_frame_buffer_count, 1248 1248 initial_info.min_src_frame_count); 1249 1249 inst->min_src_buf_count = initial_info.min_src_frame_count + 1250 - COMMAND_QUEUE_DEPTH; 1250 + WAVE521_COMMAND_QUEUE_DEPTH; 1251 1251 1252 1252 ctrl = v4l2_ctrl_find(&inst->v4l2_ctrl_hdl, 1253 1253 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT);
+7 -1
drivers/media/platform/chips-media/wave5/wave5-vpu.c
··· 63 63 64 64 if (irq_reason & BIT(INT_WAVE5_INIT_SEQ) || 65 65 irq_reason & BIT(INT_WAVE5_ENC_SET_PARAM)) { 66 - if (seq_done & BIT(inst->id)) { 66 + if (dev->product_code == WAVE515_CODE && 67 + (cmd_done & BIT(inst->id))) { 68 + cmd_done &= ~BIT(inst->id); 69 + wave5_vdi_write_register(dev, W5_RET_QUEUE_CMD_DONE_INST, 70 + cmd_done); 71 + complete(&inst->irq_done); 72 + } else if (seq_done & BIT(inst->id)) { 67 73 seq_done &= ~BIT(inst->id); 68 74 wave5_vdi_write_register(dev, W5_RET_SEQ_DONE_INSTANCE_INFO, 69 75 seq_done);
+1
drivers/media/platform/chips-media/wave5/wave5-vpuapi.h
··· 18 18 #include "wave5-vdi.h" 19 19 20 20 enum product_id { 21 + PRODUCT_ID_515, 21 22 PRODUCT_ID_521, 22 23 PRODUCT_ID_511, 23 24 PRODUCT_ID_517,
+11 -5
drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h
··· 8 8 #ifndef _VPU_CONFIG_H_ 9 9 #define _VPU_CONFIG_H_ 10 10 11 + #define WAVE515_CODE 0x5150 11 12 #define WAVE517_CODE 0x5170 12 13 #define WAVE537_CODE 0x5370 13 14 #define WAVE511_CODE 0x5110 ··· 22 21 ((c) == WAVE517_CODE || (c) == WAVE537_CODE || \ 23 22 (c) == WAVE511_CODE || (c) == WAVE521_CODE || \ 24 23 (c) == WAVE521E1_CODE || (c) == WAVE521C_CODE || \ 25 - (c) == WAVE521C_DUAL_CODE); \ 24 + (c) == WAVE521C_DUAL_CODE) || (c) == WAVE515_CODE; \ 26 25 }) 27 26 28 27 #define WAVE517_WORKBUF_SIZE (2 * 1024 * 1024) 29 28 #define WAVE521ENC_WORKBUF_SIZE (128 * 1024) //HEVC 128K, AVC 40K 30 29 #define WAVE521DEC_WORKBUF_SIZE (1784 * 1024) 30 + #define WAVE515DEC_WORKBUF_SIZE (2 * 1024 * 1024) 31 31 32 32 #define MAX_NUM_INSTANCE 32 33 33 ··· 51 49 /************************************************************************/ 52 50 #define VLC_BUF_NUM (2) 53 51 54 - #define COMMAND_QUEUE_DEPTH (2) 52 + #define WAVE521_COMMAND_QUEUE_DEPTH (2) 53 + #define WAVE515_COMMAND_QUEUE_DEPTH (4) 55 54 56 55 #define W5_REMAP_INDEX0 0 57 56 #define W5_REMAP_INDEX1 1 58 57 #define W5_REMAP_MAX_SIZE (1024 * 1024) 59 58 60 - #define WAVE5_MAX_CODE_BUF_SIZE (2 * 1024 * 1024) 61 - #define WAVE5_TEMPBUF_OFFSET WAVE5_MAX_CODE_BUF_SIZE 59 + #define WAVE521_MAX_CODE_BUF_SIZE (2 * 1024 * 1024) 60 + #define WAVE515_MAX_CODE_BUF_SIZE (1024 * 1024) 62 61 #define WAVE5_TEMPBUF_SIZE (1024 * 1024) 63 62 64 - #define SIZE_COMMON (WAVE5_MAX_CODE_BUF_SIZE + WAVE5_TEMPBUF_SIZE) 63 + #define WAVE521_SIZE_COMMON (WAVE521_MAX_CODE_BUF_SIZE + WAVE5_TEMPBUF_SIZE) 64 + #define WAVE515_ONE_TASKBUF_SIZE (8 * 1024 * 1024) 65 + #define WAVE515_SIZE_COMMON (WAVE515_MAX_CODE_BUF_SIZE + WAVE5_TEMPBUF_SIZE + \ 66 + WAVE515_COMMAND_QUEUE_DEPTH * WAVE515_ONE_TASKBUF_SIZE) 65 67 66 68 //=====4. VPU REPORT MEMORY ======================// 67 69
+6
drivers/media/platform/chips-media/wave5/wave5.h
··· 22 22 */ 23 23 #define BSOPTION_ENABLE_EXPLICIT_END BIT(0) 24 24 #define BSOPTION_HIGHLIGHT_STREAM_END BIT(1) 25 + /* 26 + * When RD_PTR_VALID_FLAG is 0 Wave515 ignores RD_PTR value and starts to 27 + * decode from the access unit end position of the last decoded picture in 28 + * bitstream buffer. 29 + */ 30 + #define BSOPTION_RD_PTR_VALID_FLAG BIT(31) 25 31 26 32 /* 27 33 * Currently the driver only supports hardware with little endian but for source