diff --git a/drivers/amlogic/media_modules/common/firmware/firmware_cfg.h b/drivers/amlogic/media_modules/common/firmware/firmware_cfg.h index c98ceef675cb..720b99277038 100644 --- a/drivers/amlogic/media_modules/common/firmware/firmware_cfg.h +++ b/drivers/amlogic/media_modules/common/firmware/firmware_cfg.h @@ -16,27 +16,17 @@ */ /*all firmwares in one bin.*/ -{MESON_CPU_MAJOR_ID_GXBB, VIDEO_PACKAGE, "video_ucode.bin"}, -{MESON_CPU_MAJOR_ID_GXTVBB, VIDEO_PACKAGE, "video_ucode.bin"}, -{MESON_CPU_MAJOR_ID_GXL, VIDEO_PACKAGE, "video_ucode.bin"}, -{MESON_CPU_MAJOR_ID_GXM, VIDEO_PACKAGE, "video_ucode.bin"}, -{MESON_CPU_MAJOR_ID_TXL, VIDEO_PACKAGE, "video_ucode.bin"}, -{MESON_CPU_MAJOR_ID_TXLX, VIDEO_PACKAGE, "video_ucode.bin"}, -{MESON_CPU_MAJOR_ID_G12A, VIDEO_PACKAGE, "video_ucode.bin"}, +{VIDEO_MISC, VIDEO_PACKAGE, "video_ucode.bin"}, /* Note: if the addition of new package has the same name */ /* as the firmware in the video_ucode.bin, the firmware */ /* in the video_ucode.bin will be ignored yet, because the */ /* video_ucode.bin will always be processed in the end */ -{MESON_CPU_MAJOR_ID_GXM, VIDEO_PACKAGE, "h264_enc.bin"}, -{MESON_CPU_MAJOR_ID_GXL, VIDEO_PACKAGE, "h264_enc.bin"}, -{MESON_CPU_MAJOR_ID_TXLX, VIDEO_PACKAGE, "h264_enc.bin"}, -{MESON_CPU_MAJOR_ID_TXL, VIDEO_PACKAGE, "h264_enc.bin"}, -{MESON_CPU_MAJOR_ID_G12A, VIDEO_PACKAGE, "h264_enc.bin"}, +{VIDEO_ENCODE, VIDEO_FW_FILE, "h264_enc.bin"}, + /*firmware for a special format, to replace the format in the package.*/ -{MESON_CPU_MAJOR_ID_GXL, VIDEO_DEC_HEVC, "h265.bin"}, -{MESON_CPU_MAJOR_ID_GXL, VIDEO_DEC_H264, "h264.bin"}, -{MESON_CPU_MAJOR_ID_GXL, VIDEO_DEC_H264_MULTI, "h264_multi.bin"}, - +{VIDEO_DECODE, VIDEO_FW_FILE, "h265.bin"}, +{VIDEO_DECODE, VIDEO_FW_FILE, "h264.bin"}, +{VIDEO_DECODE, VIDEO_FW_FILE, "h264_multi.bin"}, diff --git a/drivers/amlogic/media_modules/common/firmware/firmware_drv.c b/drivers/amlogic/media_modules/common/firmware/firmware_drv.c index 6827bd897f31..3b65de085403 100644 --- a/drivers/amlogic/media_modules/common/firmware/firmware_drv.c +++ b/drivers/amlogic/media_modules/common/firmware/firmware_drv.c @@ -39,6 +39,9 @@ #include #include +/* major.minor.revision */ +#define PACK_VERS "v0.0.1" + #define CLASS_NAME "firmware_codec" #define DEV_NAME "firmware_vdec" #define DIR "video" @@ -56,28 +59,29 @@ static DEFINE_MUTEX(mutex); -static struct ucode_info_s ucode_info[] = { +static struct ucode_file_info_s ucode_info[] = { #include "firmware_cfg.h" }; -static const struct file_operations firmware_fops = { +static const struct file_operations fw_fops = { .owner = THIS_MODULE }; -struct firmware_mgr_s *g_mgr; -struct firmware_dev_s *g_dev; +struct fw_mgr_s *g_mgr; +struct fw_dev_s *g_dev; static u32 debug; +static u32 detail; -int get_firmware_data(enum firmware_type_e type, char *buf) +int get_firmware_data(unsigned int format, char *buf) { int data_len, ret = -1; - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; + struct fw_mgr_s *mgr = g_mgr; + struct fw_info_s *info; if (tee_enabled()) { - pr_info ("tee load firmware type= %d\n",(u32)type); - ret = tee_load_video_fw((u32)type, 0); + pr_info ("tee load firmware fomat = %d\n",(u32)format); + ret = tee_load_video_fw((u32)format, 0); if (ret == 0) ret = 1; else @@ -87,16 +91,16 @@ int get_firmware_data(enum firmware_type_e type, char *buf) mutex_lock(&mutex); - if (list_empty(&mgr->head)) { + if (list_empty(&mgr->fw_head)) { pr_info("the info list is empty.\n"); goto out; } - list_for_each_entry(info, &mgr->head, node) { - if (type != info->type) + list_for_each_entry(info, &mgr->fw_head, node) { + if (format != info->format) continue; - data_len = info->data->header.data_size; + data_len = info->data->head.data_size; memcpy(buf, info->data->data, data_len); ret = data_len; @@ -112,28 +116,28 @@ EXPORT_SYMBOL(get_firmware_data); int get_data_from_name(const char *name, char *buf) { int data_len, ret = -1; - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; - char *firmware_name = __getname(); + struct fw_mgr_s *mgr = g_mgr; + struct fw_info_s *info; + char *fw_name = __getname(); - if (IS_ERR_OR_NULL(firmware_name)) + if (IS_ERR_OR_NULL(fw_name)) return -ENOMEM; - strcat(firmware_name, name); - strcat(firmware_name, ".bin"); + strcat(fw_name, name); + strcat(fw_name, ".bin"); mutex_lock(&mutex); - if (list_empty(&mgr->head)) { + if (list_empty(&mgr->fw_head)) { pr_info("the info list is empty.\n"); goto out; } - list_for_each_entry(info, &mgr->head, node) { - if (strcmp(firmware_name, info->name)) + list_for_each_entry(info, &mgr->fw_head, node) { + if (strcmp(fw_name, info->name)) continue; - data_len = info->data->header.data_size; + data_len = info->data->head.data_size; memcpy(buf, info->data->data, data_len); ret = data_len; @@ -142,13 +146,13 @@ int get_data_from_name(const char *name, char *buf) out: mutex_unlock(&mutex); - __putname(firmware_name); + __putname(fw_name); return ret; } EXPORT_SYMBOL(get_data_from_name); -static int firmware_probe(char *buf) +static int fw_probe(char *buf) { int magic = 0; @@ -160,31 +164,31 @@ static int request_firmware_from_sys(const char *file_name, char *buf, int size) { int ret = -1; - const struct firmware *firmware; + const struct firmware *fw; int magic, offset = 0; - pr_info("Try load %s ...\n", file_name); + pr_info("Try to load %s ...\n", file_name); - ret = request_firmware(&firmware, file_name, g_dev->dev); + ret = request_firmware(&fw, file_name, g_dev->dev); if (ret < 0) { pr_info("Error : %d can't load the %s.\n", ret, file_name); goto err; } - if (firmware->size > size) { + if (fw->size > size) { pr_info("Not enough memory size for ucode.\n"); ret = -ENOMEM; goto release; } - magic = firmware_probe((char *)firmware->data); + magic = fw_probe((char *)fw->data); if (magic != PACK && magic != CODE) { - if (firmware->size < SEC_OFFSET) { + if (fw->size < SEC_OFFSET) { pr_info("This is an invalid firmware file.\n"); goto release; } - magic = firmware_probe((char *)firmware->data + SEC_OFFSET); + magic = fw_probe((char *)fw->data + SEC_OFFSET); if (magic != PACK) { pr_info("The firmware file is not packet.\n"); goto release; @@ -193,18 +197,18 @@ static int request_firmware_from_sys(const char *file_name, offset = SEC_OFFSET; } - memcpy(buf, (char *)firmware->data + offset, firmware->size - offset); + memcpy(buf, (char *)fw->data + offset, fw->size - offset); pr_info("load firmware size : %zd, Name : %s.\n", - firmware->size, file_name); - ret = firmware->size; + fw->size, file_name); + ret = fw->size; release: - release_firmware(firmware); + release_firmware(fw); err: return ret; } -int request_decoder_firmware_on_sys(enum vformat_e type, +int request_decoder_firmware_on_sys(enum vformat_e format, const char *file_name, char *buf, int size) { int ret; @@ -220,21 +224,21 @@ int request_decoder_firmware_on_sys(enum vformat_e type, return ret; } -int get_decoder_firmware_data(enum vformat_e type, +int get_decoder_firmware_data(enum vformat_e format, const char *file_name, char *buf, int size) { int ret; - ret = request_decoder_firmware_on_sys(type, file_name, buf, size); + ret = request_decoder_firmware_on_sys(format, file_name, buf, size); if (ret < 0) pr_info("get_decoder_firmware_data %s for format %d failed!\n", - file_name, type); + file_name, format); return ret; } EXPORT_SYMBOL(get_decoder_firmware_data); -static unsigned long firmware_mgr_lock(struct firmware_mgr_s *mgr) +static unsigned long fw_mgr_lock(struct fw_mgr_s *mgr) { unsigned long flags; @@ -242,98 +246,120 @@ static unsigned long firmware_mgr_lock(struct firmware_mgr_s *mgr) return flags; } -static void firmware_mgr_unlock(struct firmware_mgr_s *mgr, unsigned long flags) +static void fw_mgr_unlock(struct fw_mgr_s *mgr, unsigned long flags) { spin_unlock_irqrestore(&mgr->lock, flags); } -static void add_info(struct firmware_info_s *info) +static void fw_add_info(struct fw_info_s *info) { unsigned long flags; - struct firmware_mgr_s *mgr = g_mgr; + struct fw_mgr_s *mgr = g_mgr; - flags = firmware_mgr_lock(mgr); - list_add(&info->node, &mgr->head); - firmware_mgr_unlock(mgr, flags); + flags = fw_mgr_lock(mgr); + list_add(&info->node, &mgr->fw_head); + fw_mgr_unlock(mgr, flags); } -static void del_info(struct firmware_info_s *info) +static void fw_del_info(struct fw_info_s *info) { unsigned long flags; - struct firmware_mgr_s *mgr = g_mgr; + struct fw_mgr_s *mgr = g_mgr; - flags = firmware_mgr_lock(mgr); + flags = fw_mgr_lock(mgr); list_del(&info->node); - firmware_mgr_unlock(mgr, flags); + kfree(info); + fw_mgr_unlock(mgr, flags); } -static void walk_firmware_info(void) +static void fw_info_walk(void) { - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; + struct fw_mgr_s *mgr = g_mgr; + struct fw_info_s *info; - mutex_lock(&mutex); - - if (list_empty(&mgr->head)) { + if (list_empty(&mgr->fw_head)) { pr_info("the info list is empty.\n"); return; } - list_for_each_entry(info, &mgr->head, node) { + list_for_each_entry(info, &mgr->fw_head, node) { if (IS_ERR_OR_NULL(info->data)) continue; - pr_info("path : %s.\n", info->path); pr_info("name : %s.\n", info->name); - pr_info("version : %s.\n", - info->data->header.version); - pr_info("checksum : 0x%x.\n", - info->data->header.checksum); - pr_info("data size : %d.\n", - info->data->header.data_size); - pr_info("author : %s.\n", - info->data->header.author); - pr_info("date : %s.\n", - info->data->header.date); - pr_info("commit : %s.\n\n", - info->data->header.commit); + pr_info("ver : %s.\n", + info->data->head.version); + pr_info("crc : 0x%x.\n", + info->data->head.checksum); + pr_info("size : %d.\n", + info->data->head.data_size); + pr_info("maker: %s.\n", + info->data->head.maker); + pr_info("from : %s.\n", info->src_from); + pr_info("date : %s.\n\n", + info->data->head.date); + } +} + +static void fw_files_info_walk(void) +{ + struct fw_mgr_s *mgr = g_mgr; + struct fw_files_s *files; + + if (list_empty(&mgr->files_head)) { + pr_info("the file list is empty.\n"); + return; } - mutex_unlock(&mutex); + list_for_each_entry(files, &mgr->files_head, node) { + pr_info("type : %s.\n", !files->fw_type ? + "VIDEO_DECODE" : files->fw_type == 1 ? + "VIDEO_ENCODE" : "VIDEO_MISC"); + pr_info("from : %s.\n", !files->file_type ? + "VIDEO_PACKAGE" : "VIDEO_FW_FILE"); + pr_info("path : %s.\n", files->path); + pr_info("name : %s.\n\n", files->name); + } } static ssize_t info_show(struct class *class, struct class_attribute *attr, char *buf) { char *pbuf = buf; - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; + struct fw_mgr_s *mgr = g_mgr; + struct fw_info_s *info; mutex_lock(&mutex); - if (list_empty(&mgr->head)) { + if (list_empty(&mgr->fw_head)) { pbuf += sprintf(pbuf, "No firmware.\n"); goto out; } - list_for_each_entry(info, &mgr->head, node) { + list_for_each_entry(info, &mgr->fw_head, node) { if (IS_ERR_OR_NULL(info->data)) continue; - pr_info("%10s : %s\n", "from", info->src_from); - pr_info("%10s : %s\n", "name", info->name); - pr_info("%10s : %d\n", "size", - info->data->header.data_size); - pr_info("%10s : %s\n", "ver", - info->data->header.version); - pr_info("%10s : 0x%x\n", "sum", - info->data->header.checksum); - pr_info("%10s : %s\n", "commit", - info->data->header.commit); - pr_info("%10s : %s\n", "author", - info->data->header.author); - pr_info("%10s : %s\n\n", "date", - info->data->header.date); + if (detail) { + pr_info("%-5s: %s\n", "name", info->name); + pr_info("%-5s: %s\n", "ver", + info->data->head.version); + pr_info("%-5s: 0x%x\n", "sum", + info->data->head.checksum); + pr_info("%-5s: %d\n", "size", + info->data->head.data_size); + pr_info("%-5s: %s\n", "maker", + info->data->head.maker); + pr_info("%-5s: %s\n", "from", + info->src_from); + pr_info("%-5s: %s\n\n", "date", + info->data->head.date); + continue; + } + + pr_info("fmt: %-16s, crc: 0x%-8x, size: %-5d, file: %s\n", + info->data->head.format, info->data->head.checksum, + info->data->head.data_size, info->data->head.name); } out: mutex_unlock(&mutex); @@ -341,12 +367,12 @@ out: return pbuf - buf; } -static int set_firmware_info(void) +static int fw_info_fill(void) { int ret = 0, i, len; - struct firmware_info_s *info; + struct fw_mgr_s *mgr = g_mgr; + struct fw_files_s *files; int info_size = ARRAY_SIZE(ucode_info); - int cpu = get_cpu_type(); char *path = __getname(); const char *name; @@ -354,9 +380,6 @@ static int set_firmware_info(void) return -ENOMEM; for (i = 0; i < info_size; i++) { - if (cpu != ucode_info[i].cpu) - continue; - name = ucode_info[i].name; if (IS_ERR_OR_NULL(name)) break; @@ -366,70 +389,127 @@ static int set_firmware_info(void) if (len >= PATH_MAX) continue; - info = kzalloc(sizeof(struct firmware_info_s), GFP_KERNEL); - if (IS_ERR_OR_NULL(info)) { + files = kzalloc(sizeof(struct fw_files_s), GFP_KERNEL); + if (IS_ERR_OR_NULL(files)) { __putname(path); return -ENOMEM; } - strcpy(info->path, path); - strcpy(info->name, name); - strcpy(info->src_from, name); - info->type = ucode_info[i].type; - info->data = NULL; + files->file_type = ucode_info[i].file_type; + files->fw_type = ucode_info[i].fw_type; + strncpy(files->path, path, sizeof(files->path)); + strncpy(files->name, name, sizeof(files->name)); - add_info(info); + list_add(&files->node, &mgr->files_head); } __putname(path); + if (debug) + fw_files_info_walk(); + return ret; } -static int checksum(struct firmware_s *firmware) +static int fw_data_check_sum(struct firmware_s *fw) { unsigned int crc; - crc = crc32_le(~0U, firmware->data, firmware->header.data_size); + crc = crc32_le(~0U, fw->data, fw->head.data_size); - if (debug) - pr_info("firmware crc result : 0x%x\n", crc ^ ~0U); + /*pr_info("firmware crc result : 0x%x\n", crc ^ ~0U);*/ - return firmware->header.checksum != (crc ^ ~0U) ? 0 : 1; + return fw->head.checksum != (crc ^ ~0U) ? 0 : 1; } -static int check_repeat(struct firmware_s *data, enum firmware_type_e type) +static int fw_data_filter(struct firmware_s *fw, + struct fw_info_s *fw_info) { - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; + struct fw_mgr_s *mgr = g_mgr; + struct fw_info_s *info, *tmp; + int cpu = fw_get_cpu(fw->head.cpu); - if (list_empty(&mgr->head)) { - pr_info("the info list is empty.\n"); + if (mgr->cur_cpu < cpu) { + pr_info("the fw %s is not match.\n", fw_info->name); + kfree(fw_info); + kfree(fw); return -1; } - if (type == FIRMWARE_MAX) + /* the encode fw need to ignoring filtering rules. */ + if (fw_info->format == FIRMWARE_MAX) return 0; - list_for_each_entry(info, &mgr->head, node) { - if (info->type != type) + list_for_each_entry_safe(info, tmp, &mgr->fw_head, node) { + if (info->format != fw_info->format) continue; - if (IS_ERR_OR_NULL(info->data)) - info->data = data; + if (IS_ERR_OR_NULL(info->data)) { + fw_del_info(info); + return 0; + } - return 1; + /* high priority of VIDEO_FW_FILE */ + if (info->file_type == VIDEO_FW_FILE) { + pr_info("the %s need to priority proc.\n",info->name); + kfree(fw_info); + kfree(fw); + return 1; + } + + /* the cpu ver is lower and needs to be filtered */ + if (cpu < fw_get_cpu(info->data->head.cpu)) { + pr_info("the fw %s is not match.\n", + fw_info->name); + kfree(fw_info); + kfree(fw); + return 1; + } + + /* removes not match fw from info list */ + pr_info("the fw %s is not match.\n", info->name); + kfree(info->data); + fw_del_info(info); } return 0; } -static int firmware_parse_package(struct firmware_info_s *fw_info, +static int fw_check_pack_version(char *buf) +{ + struct package_s *pack = NULL; + int major, minor, rev, ver = 0; + + pack = (struct package_s *) buf; + sscanf(PACK_VERS, "v%x.%x.%x", &major, &minor, &rev); + ver = (major << 24 | minor << 16 | rev); + + pr_info("the package has %d fws totally.\n", pack->head.total); + + major = pack->head.version >> 24; + minor = (pack->head.version >> 16) & 0xf; + rev = pack->head.version & 0xff; + + if (ver < pack->head.version) { + pr_info("the pack ver v%d.%d.%d too higher to unsupport.\n", + major, minor, rev); + return -1; + } + + if (ver != pack->head.version) { + pr_info("the fw pack ver v%d.%d.%d is too lower.\n", major, minor, rev); + pr_info("it may work abnormally so need to be update in time.\n"); + } + + return 0; +} + +static int fw_package_parse(struct fw_files_s *files, char *buf, int size) { int ret = 0; struct package_info_s *pack_info; - struct firmware_info_s *info; + struct fw_info_s *info; struct firmware_s *data; char *pack_data; int info_len, len; @@ -444,15 +524,15 @@ static int firmware_parse_package(struct firmware_info_s *fw_info, info_len = sizeof(struct package_info_s); do { - if (!pack_info->header.length) + if (!pack_info->head.length) break; len = snprintf(path, PATH_MAX, "%s/%s", DIR, - pack_info->header.name); + pack_info->head.name); if (len >= PATH_MAX) continue; - info = kzalloc(sizeof(struct firmware_info_s), GFP_KERNEL); + info = kzalloc(sizeof(struct fw_info_s), GFP_KERNEL); if (IS_ERR_OR_NULL(info)) { ret = -ENOMEM; goto out; @@ -465,39 +545,34 @@ static int firmware_parse_package(struct firmware_info_s *fw_info, goto out; } - strcpy(info->path, path); - strcpy(info->name, pack_info->header.name); - strcpy(info->src_from, fw_info->src_from); - info->type = get_firmware_type(pack_info->header.format); + info->file_type = files->file_type; + strncpy(info->src_from, files->name, + sizeof(info->src_from)); + strncpy(info->name, pack_info->head.name, + sizeof(info->name)); + info->format = get_fw_format(pack_info->head.format); - len = pack_info->header.length; + len = pack_info->head.length; memcpy(data, pack_info->data, len); - pack_data += (pack_info->header.length + info_len); + pack_data += (pack_info->head.length + info_len); pack_info = (struct package_info_s *)pack_data; - ret = checksum(data); - if (!ret) { + if (!fw_data_check_sum(data)) { pr_info("check sum fail !\n"); kfree(data); kfree(info); goto out; } - ret = check_repeat(data, info->type); - if (ret < 0) { - kfree(data); - kfree(info); - goto out; - } - - if (ret) { - kfree(info); + if (fw_data_filter(data, info)) continue; - } + + if (debug) + pr_info("adds %s to the fw list.\n", info->name); info->data = data; - add_info(info); + fw_add_info(info); } while (try_cnt--); out: __putname(path); @@ -505,24 +580,35 @@ out: return ret; } -static int firmware_parse_code(struct firmware_info_s *info, +static int fw_code_parse(struct fw_files_s *files, char *buf, int size) { - if (!IS_ERR_OR_NULL(info->data)) - kfree(info->data); + struct fw_info_s *info; + + info = kzalloc(sizeof(struct fw_info_s), GFP_KERNEL); + if (IS_ERR_OR_NULL(info)) + return -ENOMEM; info->data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL); if (IS_ERR_OR_NULL(info->data)) return -ENOMEM; + info->file_type = files->file_type; + strncpy(info->src_from, files->name, + sizeof(info->src_from)); memcpy(info->data, buf, size); - if (!checksum(info->data)) { + if (!fw_data_check_sum(info->data)) { pr_info("check sum fail !\n"); kfree(info->data); return -1; } + if (debug) + pr_info("adds %s to the fw list.\n", info->name); + + fw_add_info(info); + return 0; } @@ -538,89 +624,141 @@ static int get_firmware_from_sys(const char *path, return len; } -static int set_firmware_data(void) +static int fw_data_binding(void) { int ret = 0, magic = 0; - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info, *temp; - char *buf = NULL; + struct fw_mgr_s *mgr = g_mgr; + struct fw_files_s *files, *tmp; + char *buf = vmalloc(BUFF_SIZE); int size; - if (list_empty(&mgr->head)) { - pr_info("the info list is empty.\n"); + if (list_empty(&mgr->files_head)) { + pr_info("the file list is empty.\n"); return 0; } - buf = vmalloc(BUFF_SIZE); if (IS_ERR_OR_NULL(buf)) return -ENOMEM; memset(buf, 0, BUFF_SIZE); - list_for_each_entry_safe(info, temp, &mgr->head, node) { - size = get_firmware_from_sys(info->path, buf, BUFF_SIZE); - magic = firmware_probe(buf); + list_for_each_entry_safe(files, tmp, &mgr->files_head, node) { + size = get_firmware_from_sys(files->path, buf, BUFF_SIZE); + magic = fw_probe(buf); - switch (magic) { - case PACK: - ret = firmware_parse_package(info, buf, size); + if (files->file_type == VIDEO_PACKAGE && magic == PACK) { + pr_info("start to parse fw package.\n"); - del_info(info); - kfree(info); - break; + if (!fw_check_pack_version(buf)) + ret = fw_package_parse(files, buf, size); + } else if (files->file_type == VIDEO_FW_FILE && magic == CODE) { + pr_info("start to parse fw code.\n"); - case CODE: - ret = firmware_parse_code(info, buf, size); - break; - - default: - del_info(info); - kfree(info); - pr_info("invaild type.\n"); + ret = fw_code_parse(files, buf, size); + } else { + list_del(&files->node); + kfree(files); + pr_info("invaild file type.\n"); } memset(buf, 0, BUFF_SIZE); } if (debug) - walk_firmware_info(); + fw_info_walk(); vfree(buf); return ret; } -static int firmware_pre_load(void) +static int fw_pre_load(void) { - int ret = -1; - - ret = set_firmware_info(); - if (ret < 0) { + if (fw_info_fill() < 0) { pr_info("Get path fail.\n"); - goto err; + return -1; } - ret = set_firmware_data(); - if (ret < 0) { + if (fw_data_binding() < 0) { pr_info("Set data fail.\n"); - goto err; + return -1; } -err: - return ret; + + return 0; } -static int firmware_mgr_init(void) +static int fw_mgr_init(void) { - g_mgr = kzalloc(sizeof(struct firmware_mgr_s), GFP_KERNEL); + g_mgr = kzalloc(sizeof(struct fw_mgr_s), GFP_KERNEL); if (IS_ERR_OR_NULL(g_mgr)) return -ENOMEM; - INIT_LIST_HEAD(&g_mgr->head); + g_mgr->cur_cpu = get_cpu_type(); + INIT_LIST_HEAD(&g_mgr->files_head); + INIT_LIST_HEAD(&g_mgr->fw_head); spin_lock_init(&g_mgr->lock); return 0; } +static void fw_ctx_clean(void) +{ + struct fw_mgr_s *mgr = g_mgr; + struct fw_files_s *files; + struct fw_info_s *info; + unsigned long flags; + + flags = fw_mgr_lock(mgr); + while (!list_empty(&mgr->files_head)) { + files = list_entry(mgr->files_head.next, + struct fw_files_s, node); + list_del(&files->node); + kfree(files); + } + + while (!list_empty(&mgr->fw_head)) { + info = list_entry(mgr->fw_head.next, + struct fw_info_s, node); + list_del(&info->node); + kfree(info->data); + kfree(info); + } + fw_mgr_unlock(mgr, flags); +} + +int video_fw_reload(int mode) +{ + int ret = 0; + struct fw_mgr_s *mgr = g_mgr; + + if (tee_enabled()) + return 0; + + mutex_lock(&mutex); + + if (mode & FW_LOAD_FORCE) { + fw_ctx_clean(); + + ret = fw_pre_load(); + if (ret < 0) + pr_err("The fw reload fail.\n"); + } else if (mode & FW_LOAD_TRY) { + if (!list_empty(&mgr->fw_head)) { + pr_info("The fw has been loaded.\n"); + goto out; + } + + ret = fw_pre_load(); + if (ret < 0) + pr_err("The fw try to reload fail.\n"); + } +out: + mutex_unlock(&mutex); + + return ret; +} +EXPORT_SYMBOL(video_fw_reload); + static ssize_t reload_show(struct class *class, struct class_attribute *attr, char *buf) { @@ -633,46 +771,6 @@ static ssize_t reload_show(struct class *class, return pbuf - buf; } -int firmware_reload(int mode) -{ - int ret = 0; - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info = NULL; - - if (tee_enabled()) - return 0; - - mutex_lock(&mutex); - - if (mode & FW_LOAD_FORCE) { - while (!list_empty(&mgr->head)) { - info = list_entry(mgr->head.next, - struct firmware_info_s, node); - list_del(&info->node); - kfree(info->data); - kfree(info); - } - - ret = firmware_pre_load(); - if (ret < 0) - pr_err("The fw reload fail.\n"); - } else if (mode & FW_LOAD_TRY) { - if (!list_empty(&mgr->head)) { - pr_info("The fw has been loaded.\n"); - goto out; - } - - ret = firmware_pre_load(); - if (ret < 0) - pr_err("The fw try to reload fail.\n"); - } -out: - mutex_unlock(&mutex); - - return ret; -} -EXPORT_SYMBOL(firmware_reload); - static ssize_t reload_store(struct class *class, struct class_attribute *attr, const char *buf, size_t size) @@ -684,29 +782,61 @@ static ssize_t reload_store(struct class *class, if (ret != 0) return -EINVAL; - ret = firmware_reload(val); + ret = video_fw_reload(val); if (ret < 0) pr_err("fw reload fail.\n"); return size; } -static struct class_attribute firmware_class_attrs[] = { +static ssize_t debug_show(struct class *cls, + struct class_attribute *attr, char *buf) +{ + return sprintf(buf, "%x\n", debug); +} + +static ssize_t debug_store(struct class *cls, + struct class_attribute *attr, const char *buf, size_t count) +{ + if (kstrtoint(buf, 0, &debug) < 0) + return -EINVAL; + + return count; +} + +static ssize_t detail_show(struct class *cls, + struct class_attribute *attr, char *buf) +{ + return sprintf(buf, "%x\n", detail); +} + +static ssize_t detail_store(struct class *cls, + struct class_attribute *attr, const char *buf, size_t count) +{ + if (kstrtoint(buf, 0, &detail) < 0) + return -EINVAL; + + return count; +} + +static struct class_attribute fw_class_attrs[] = { __ATTR_RO(info), __ATTR(reload, 0664, reload_show, reload_store), + __ATTR(debug, 0664, debug_show, debug_store), + __ATTR(detail, 0664, detail_show, detail_store), __ATTR_NULL }; -static struct class firmware_class = { +static struct class fw_class = { .name = CLASS_NAME, - .class_attrs = firmware_class_attrs, + .class_attrs = fw_class_attrs, }; -static int firmware_driver_init(void) +static int fw_driver_init(void) { int ret = -1; - g_dev = kzalloc(sizeof(struct firmware_dev_s), GFP_KERNEL); + g_dev = kzalloc(sizeof(struct fw_dev_s), GFP_KERNEL); if (IS_ERR_OR_NULL(g_dev)) return -ENOMEM; @@ -718,7 +848,7 @@ static int firmware_driver_init(void) goto err; } - cdev_init(&g_dev->cdev, &firmware_fops); + cdev_init(&g_dev->cdev, &fw_fops); g_dev->cdev.owner = THIS_MODULE; ret = cdev_add(&g_dev->cdev, g_dev->dev_no, 1); @@ -727,13 +857,13 @@ static int firmware_driver_init(void) goto err; } - ret = class_register(&firmware_class); + ret = class_register(&fw_class); if (ret < 0) { pr_info("Failed in creating class.\n"); goto err; } - g_dev->dev = device_create(&firmware_class, NULL, + g_dev->dev = device_create(&fw_class, NULL, g_dev->dev_no, NULL, DEV_NAME); if (IS_ERR_OR_NULL(g_dev->dev)) { pr_info("Create device failed.\n"); @@ -746,51 +876,33 @@ err: return ret; } -static void firmware_info_clean(void) +static void fw_driver_exit(void) { - struct firmware_mgr_s *mgr = g_mgr; - struct firmware_info_s *info; - unsigned long flags; - - flags = firmware_mgr_lock(mgr); - while (!list_empty(&mgr->head)) { - info = list_entry(mgr->head.next, - struct firmware_info_s, node); - list_del(&info->node); - kfree(info->data); - kfree(info); - } - firmware_mgr_unlock(mgr, flags); - + cdev_del(&g_dev->cdev); + device_destroy(&fw_class, g_dev->dev_no); + class_unregister(&fw_class); + unregister_chrdev_region(g_dev->dev_no, 1); + kfree(g_dev); kfree(g_mgr); } -static void firmware_driver_exit(void) -{ - cdev_del(&g_dev->cdev); - device_destroy(&firmware_class, g_dev->dev_no); - class_unregister(&firmware_class); - unregister_chrdev_region(g_dev->dev_no, 1); - kfree(g_dev); -} - -static int __init firmware_module_init(void) +static int __init fw_module_init(void) { int ret = -1; - ret = firmware_driver_init(); + ret = fw_driver_init(); if (ret) { pr_info("Error %d firmware driver init fail.\n", ret); goto err; } - ret = firmware_mgr_init(); + ret = fw_mgr_init(); if (ret) { pr_info("Error %d firmware mgr init fail.\n", ret); goto err; } - ret = firmware_pre_load(); + ret = fw_pre_load(); if (ret) { pr_info("Error %d firmware pre load fail.\n", ret); goto err; @@ -799,17 +911,15 @@ err: return ret; } -static void __exit firmware_module_exit(void) +static void __exit fw_module_exit(void) { - firmware_info_clean(); - firmware_driver_exit(); + fw_ctx_clean(); + fw_driver_exit(); pr_info("Firmware driver cleaned up.\n"); } -module_param(debug, uint, 0664); - -module_init(firmware_module_init); -module_exit(firmware_module_exit); +module_init(fw_module_init); +module_exit(fw_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Nanxin Qin "); diff --git a/drivers/amlogic/media_modules/common/firmware/firmware_priv.h b/drivers/amlogic/media_modules/common/firmware/firmware_priv.h index 4b03fd8e9b0a..811fdc6e0159 100644 --- a/drivers/amlogic/media_modules/common/firmware/firmware_priv.h +++ b/drivers/amlogic/media_modules/common/firmware/firmware_priv.h @@ -15,42 +15,52 @@ * */ -#ifndef __VIDEO_FIRMWARE_PRIV_HEADER_ -#define __VIDEO_FIRMWARE_PRIV_HEADER_ +#ifndef __VIDEO_FIRMWARE_PRIV_HEAD_ +#define __VIDEO_FIRMWARE_PRIV_HEAD_ #include #include #include #include #include "firmware_type.h" -struct firmware_mgr_s { - struct list_head head; +struct fw_mgr_s { + struct list_head fw_head; + struct list_head files_head; spinlock_t lock; + int cur_cpu; }; -struct firmware_info_s { +struct fw_files_s { struct list_head node; + int fw_type; + int file_type; char name[32]; char path[64]; - char src_from[32]; - enum firmware_type_e type; - struct firmware_s *data; }; -struct ucode_info_s { - int cpu; - enum firmware_type_e type; +struct ucode_file_info_s { + int fw_type; + int file_type; const char *name; }; -struct firmware_header_s { +struct fw_info_s { + struct list_head node; + char name[32]; + char src_from[32]; + int file_type; + unsigned int format; + struct firmware_s *data; +}; + +struct fw_head_s { int magic; int checksum; char name[32]; char cpu[16]; char format[32]; char version[32]; - char author[32]; + char maker[32]; char date[32]; char commit[16]; int data_size; @@ -60,28 +70,30 @@ struct firmware_header_s { struct firmware_s { union { - struct firmware_header_s header; + struct fw_head_s head; char buf[512]; }; char data[0]; }; -struct package_header_s { +struct package_head_s { int magic; int size; int checksum; + int total; + int version; char reserved[128]; }; struct package_s { union { - struct package_header_s header; + struct package_head_s head; char buf[256]; }; char data[0]; }; -struct info_header_s { +struct info_head_s { char name[32]; char format[32]; char cpu[32]; @@ -90,13 +102,13 @@ struct info_header_s { struct package_info_s { union { - struct info_header_s header; + struct info_head_s head; char buf[256]; }; char data[0]; }; -struct firmware_dev_s { +struct fw_dev_s { struct cdev cdev; struct device *dev; dev_t dev_no; diff --git a/drivers/amlogic/media_modules/common/firmware/firmware_type.c b/drivers/amlogic/media_modules/common/firmware/firmware_type.c index 5975c733c259..b2d9f17d6572 100644 --- a/drivers/amlogic/media_modules/common/firmware/firmware_type.c +++ b/drivers/amlogic/media_modules/common/firmware/firmware_type.c @@ -1,67 +1,92 @@ #include "firmware_type.h" +#include -static const struct type_name_s type_name[] = { - {VIDEO_DEC_MPEG12, "mpeg12"}, - {VIDEO_DEC_MPEG4_3, "divx311"}, - {VIDEO_DEC_MPEG4_4, "divx4x"}, - {VIDEO_DEC_MPEG4_5, "xvid"}, - {VIDEO_DEC_H263, "h263"}, - {VIDEO_DEC_MJPEG, "mjpeg"}, - {VIDEO_DEC_MJPEG_MULTI, "mjpeg_multi"}, - {VIDEO_DEC_REAL_V8, "real_v8"}, - {VIDEO_DEC_REAL_V9, "real_v9"}, - {VIDEO_DEC_VC1, "vc1"}, - {VIDEO_DEC_VC1_G12A, "vc1_g12a"}, - {VIDEO_DEC_AVS, "avs"}, - {VIDEO_DEC_AVS_GXM, "avs_gxm"}, - {VIDEO_DEC_AVS_NOCABAC, "avs_no_cabac"}, - {VIDEO_DEC_H264, "h264"}, - {VIDEO_DEC_H264_4k2K, "h264_4k2k"}, - {VIDEO_DEC_H264_4k2K_SINGLE, "h264_4k2k_single"}, - {VIDEO_DEC_H264_MVC, "h264_mvc"}, - {VIDEO_DEC_H264_MVC_GXM, "h264_mvc_gxm"}, - {VIDEO_DEC_H264_MULTI, "h264_multi"}, - {VIDEO_DEC_H264_MULTI_MMU, "h264_multi_mmu"}, - {VIDEO_DEC_H264_MULTI_GXM, "h264_multi_gxm"}, - {VIDEO_DEC_HEVC, "hevc"}, - {VIDEO_DEC_HEVC_MMU, "hevc_mmu"}, - {VIDEO_DEC_HEVC_G12A, "hevc_g12a"}, - {VIDEO_DEC_VP9, "vp9"}, - {VIDEO_DEC_VP9_MMU, "vp9_mmu"}, - {VIDEO_DEC_VP9_G12A, "vp9_g12a"}, - {VIDEO_DEC_AVS2, "avs2"}, - {VIDEO_DEC_AVS2_MMU, "avs2_mmu"}, - {VIDEO_ENC_H264, "h264_enc"}, - {VIDEO_ENC_JPEG, "jpeg_enc"}, - {FIRMWARE_MAX, "unknown"}, +static const struct format_name_s format_name[] = { + {VIDEO_DEC_MPEG12, "mpeg12"}, + {VIDEO_DEC_MPEG12_MULTI, "mpeg12_multi"}, + {VIDEO_DEC_MPEG4_3, "divx311"}, + {VIDEO_DEC_MPEG4_4, "divx4x"}, + {VIDEO_DEC_MPEG4_4_MULTI, "divx4x_multi"}, + {VIDEO_DEC_MPEG4_5, "xvid"}, + {VIDEO_DEC_MPEG4_5_MULTI, "xvid_multi"}, + {VIDEO_DEC_H263, "h263"}, + {VIDEO_DEC_H263_MULTI, "h263_multi"}, + {VIDEO_DEC_MJPEG, "mjpeg"}, + {VIDEO_DEC_MJPEG_MULTI, "mjpeg_multi"}, + {VIDEO_DEC_REAL_V8, "real_v8"}, + {VIDEO_DEC_REAL_V9, "real_v9"}, + {VIDEO_DEC_VC1, "vc1"}, + {VIDEO_DEC_VC1_G12A, "vc1_g12a"}, + {VIDEO_DEC_AVS, "avs"}, + {VIDEO_DEC_AVS_GXM, "avs_gxm"}, + {VIDEO_DEC_AVS_NOCABAC, "avs_no_cabac"}, + {VIDEO_DEC_H264, "h264"}, + {VIDEO_DEC_H264_4k2K, "h264_4k2k"}, + {VIDEO_DEC_H264_4k2K_SINGLE, "h264_4k2k_single"}, + {VIDEO_DEC_H264_MVC, "h264_mvc"}, + {VIDEO_DEC_H264_MVC_GXM, "h264_mvc_gxm"}, + {VIDEO_DEC_H264_MULTI, "h264_multi"}, + {VIDEO_DEC_H264_MULTI_MMU, "h264_multi_mmu"}, + {VIDEO_DEC_H264_MULTI_GXM, "h264_multi_gxm"}, + {VIDEO_DEC_HEVC, "hevc"}, + {VIDEO_DEC_HEVC_MMU, "hevc_mmu"}, + {VIDEO_DEC_HEVC_G12A, "hevc_g12a"}, + {VIDEO_DEC_VP9, "vp9"}, + {VIDEO_DEC_VP9_MMU, "vp9_mmu"}, + {VIDEO_DEC_VP9_G12A, "vp9_g12a"}, + {VIDEO_DEC_AVS2, "avs2"}, + {VIDEO_DEC_AVS2_MMU, "avs2_mmu"}, + {VIDEO_ENC_H264, "h264_enc"}, + {VIDEO_ENC_JPEG, "jpeg_enc"}, + {FIRMWARE_MAX, "unknown"}, }; +static const struct cpu_type_s cpu_type[] = { + {MESON_CPU_MAJOR_ID_GXL, "gxl"}, + {MESON_CPU_MAJOR_ID_GXM, "gxm"}, + {MESON_CPU_MAJOR_ID_G12A, "g12a"}, + {MESON_CPU_MAJOR_ID_G12B, "g12b"}, +}; -const char *get_firmware_type_name(enum firmware_type_e type) +const char *get_fw_format_name(unsigned int format) { const char *name = "unknown"; - int i, size = ARRAY_SIZE(type_name); + int i, size = ARRAY_SIZE(format_name); for (i = 0; i < size; i++) { - if (type == type_name[i].type) - name = type_name[i].name; + if (format == format_name[i].format) + name = format_name[i].name; } return name; } -EXPORT_SYMBOL(get_firmware_type_name); +EXPORT_SYMBOL(get_fw_format_name); -enum firmware_type_e get_firmware_type(const char *name) +unsigned int get_fw_format(const char *name) { - enum firmware_type_e type = FIRMWARE_MAX; - int i, size = ARRAY_SIZE(type_name); + unsigned int format = FIRMWARE_MAX; + int i, size = ARRAY_SIZE(format_name); for (i = 0; i < size; i++) { - if (!strcmp(name, type_name[i].name)) - type = type_name[i].type; + if (!strcmp(name, format_name[i].name)) + format = format_name[i].format; + } + + return format; +} +EXPORT_SYMBOL(get_fw_format); + +int fw_get_cpu(const char *name) +{ + int type = 0; + int i, size = ARRAY_SIZE(cpu_type); + + for (i = 0; i < size; i++) { + if (!strcmp(name, cpu_type[i].name)) + type = cpu_type[i].type; } return type; } -EXPORT_SYMBOL(get_firmware_type); +EXPORT_SYMBOL(fw_get_cpu); diff --git a/drivers/amlogic/media_modules/common/firmware/firmware_type.h b/drivers/amlogic/media_modules/common/firmware/firmware_type.h index 94c5a9a0f1fd..f51956bbf561 100644 --- a/drivers/amlogic/media_modules/common/firmware/firmware_type.h +++ b/drivers/amlogic/media_modules/common/firmware/firmware_type.h @@ -3,49 +3,74 @@ #include -enum firmware_type_e { - VIDEO_DEC_MPEG12, - VIDEO_DEC_MPEG4_3, - VIDEO_DEC_MPEG4_4, - VIDEO_DEC_MPEG4_5, - VIDEO_DEC_H263, - VIDEO_DEC_MJPEG, - VIDEO_DEC_MJPEG_MULTI, - VIDEO_DEC_REAL_V8, - VIDEO_DEC_REAL_V9, - VIDEO_DEC_VC1, - VIDEO_DEC_AVS, - VIDEO_DEC_H264, - VIDEO_DEC_H264_4k2K, - VIDEO_DEC_H264_4k2K_SINGLE, - VIDEO_DEC_H264_MVC, - VIDEO_DEC_H264_MULTI, - VIDEO_DEC_HEVC, - VIDEO_DEC_HEVC_MMU, - VIDEO_DEC_VP9, - VIDEO_DEC_VP9_MMU, - VIDEO_ENC_H264, - VIDEO_ENC_JPEG, - VIDEO_PACKAGE, - VIDEO_DEC_H264_MULTI_MMU, - VIDEO_DEC_HEVC_G12A, - VIDEO_DEC_VP9_G12A, - VIDEO_DEC_AVS2, - VIDEO_DEC_AVS2_MMU, - VIDEO_DEC_AVS_GXM, - VIDEO_DEC_AVS_NOCABAC, - VIDEO_DEC_H264_MULTI_GXM, - VIDEO_DEC_H264_MVC_GXM, - VIDEO_DEC_VC1_G12A, - FIRMWARE_MAX -}; +/* example: #define VIDEO_DEC_AV1 TAG('A', 'V', '1', '-')*/ +#define TAG(a, b, c, d)\ + ((a << 24) | (b << 16) | (c << 8) | d) -struct type_name_s { - enum firmware_type_e type; +/* fws define */ +#define VIDEO_DEC_MPEG12 (0) +#define VIDEO_DEC_MPEG4_3 (1) +#define VIDEO_DEC_MPEG4_4 (2) +#define VIDEO_DEC_MPEG4_5 (3) +#define VIDEO_DEC_H263 (4) +#define VIDEO_DEC_MJPEG (5) +#define VIDEO_DEC_MJPEG_MULTI (6) +#define VIDEO_DEC_REAL_V8 (7) +#define VIDEO_DEC_REAL_V9 (8) +#define VIDEO_DEC_VC1 (9) +#define VIDEO_DEC_AVS (10) +#define VIDEO_DEC_H264 (11) +#define VIDEO_DEC_H264_4k2K (12) +#define VIDEO_DEC_H264_4k2K_SINGLE (13) +#define VIDEO_DEC_H264_MVC (14) +#define VIDEO_DEC_H264_MULTI (15) +#define VIDEO_DEC_HEVC (16) +#define VIDEO_DEC_HEVC_MMU (17) +#define VIDEO_DEC_VP9 (18) +#define VIDEO_DEC_VP9_MMU (19) +#define VIDEO_ENC_H264 (20) +#define VIDEO_ENC_JPEG (21) +#define VIDEO_DEC_H264_MULTI_MMU (23) +#define VIDEO_DEC_HEVC_G12A (24) +#define VIDEO_DEC_VP9_G12A (25) +#define VIDEO_DEC_AVS2 (26) +#define VIDEO_DEC_AVS2_MMU (27) +#define VIDEO_DEC_AVS_GXM (28) +#define VIDEO_DEC_AVS_NOCABAC (29) +#define VIDEO_DEC_H264_MULTI_GXM (30) +#define VIDEO_DEC_H264_MVC_GXM (31) +#define VIDEO_DEC_VC1_G12A (32) +#define VIDEO_DEC_MPEG12_MULTI TAG('M', '1', '2', 'M') +#define VIDEO_DEC_MPEG4_4_MULTI TAG('M', '4', '4', 'M') +#define VIDEO_DEC_MPEG4_5_MULTI TAG('M', '4', '5', 'M') +#define VIDEO_DEC_H263_MULTI TAG('2', '6', '3', 'M') + +/* ... */ +#define FIRMWARE_MAX (UINT_MAX) + +#define VIDEO_PACKAGE (0) +#define VIDEO_FW_FILE (1) + +#define VIDEO_DECODE (0) +#define VIDEO_ENCODE (1) +#define VIDEO_MISC (2) + +#define OPTEE_VDEC_LEGENCY (0) +#define OPTEE_VDEC (1) +#define OPTEE_VDEC_HEVC (2) + +struct format_name_s { + unsigned int format; const char *name; }; -const char *get_firmware_type_name(enum firmware_type_e type); -enum firmware_type_e get_firmware_type(const char *name); +struct cpu_type_s { + int type; + const char *name; +}; + +const char *get_firmware_type_name(unsigned int format); +unsigned int get_fw_format(const char *name); +int fw_get_cpu(const char *name); #endif diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c b/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c index 8620fde2526f..f01bedd4a986 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/avs/avs.c @@ -1505,7 +1505,7 @@ static s32 vavs_init(void) vavs_local_init(); if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXM) - size = get_firmware_data(VIDEO_DEC_AVS_GXM, buf); + size = get_firmware_data(VIDEO_DEC_AVS, buf); else { if (firmware_sel == 1) size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, buf); @@ -1528,7 +1528,7 @@ static s32 vavs_init(void) pr_info("tee load ok\n"); if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXM) - size = amvdec_loadmc_ex(VFORMAT_AVS, "avs_gxm", buf); + size = amvdec_loadmc_ex(VFORMAT_AVS, NULL, buf); else if (firmware_sel == 1) size = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", buf); else diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c index 8a2b6b68675d..9ca073f99326 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264/vh264_mvc.c @@ -1425,12 +1425,7 @@ static s32 vh264mvc_init(void) if (tee_enabled()) { pr_info("the video fw from the teeload.\n"); - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXM) - ret = tee_load_video_fw((u32)VIDEO_DEC_H264_MVC_GXM, 0); - else - ret = tee_load_video_fw((u32)VIDEO_DEC_H264_MVC, 0); - + ret = tee_load_video_fw((u32)VIDEO_DEC_H264_MVC, 0); if (ret != 0) { amvdec_disable(); return -1; @@ -1448,11 +1443,7 @@ static s32 vh264mvc_init(void) WRITE_VREG(UCODE_START_ADDR, mc_dma_handle); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXM) - size = get_firmware_data(VIDEO_DEC_H264_MVC_GXM, buf); - else - size = get_firmware_data(VIDEO_DEC_H264_MVC, buf); - + size = get_firmware_data(VIDEO_DEC_H264_MVC, buf); if (size < 0) { pr_err("get firmware fail."); vfree(buf); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c index e9b936781ab3..23ab742a04e6 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c @@ -5063,11 +5063,7 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) if (IS_ERR_OR_NULL(fw)) return -ENOMEM; - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXM) - size = get_firmware_data(VIDEO_DEC_H264_MULTI_GXM, fw->data); - else - size = get_firmware_data(VIDEO_DEC_H264_MULTI, fw->data); - + size = get_firmware_data(VIDEO_DEC_H264_MULTI, fw->data); if (size < 0) { pr_err("get firmware fail.\n"); vfree(fw); @@ -6354,12 +6350,7 @@ static void run(struct vdec_s *vdec, unsigned long mask, start_process_time(hw); if (tee_enabled()) { - unsigned int fw_type = VIDEO_DEC_H264_MULTI; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXM) - fw_type = VIDEO_DEC_H264_MULTI_GXM; - - if (tee_load_video_fw(fw_type, 0) != 0) { + if (tee_load_video_fw(VIDEO_DEC_H264_MULTI, 0) != 0) { amvdec_enable_flag = false; amvdec_disable(); pr_err("id: %d, %s: Error amvdec_vdec_loadmc fail\n", diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c index 73f56dd6bf0a..4b20e0739a4a 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c @@ -8802,16 +8802,20 @@ static s32 vh265_init(struct hevc_state_s *hevc) size = 1; else #endif - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { - size = get_firmware_data(VIDEO_DEC_HEVC_G12A, fw->data); - hevc_print(hevc, 0, "vh265 g12a ucode loaded!\n"); - } else if (mmu_enable && (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)) { - size = get_firmware_data(VIDEO_DEC_HEVC_MMU, fw->data); - hevc_print(hevc, 0, "vh265 mmu ucode loaded!\n"); + + if (mmu_enable) { + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { + size = get_firmware_data(VIDEO_DEC_HEVC, fw->data); + hevc_print(hevc, 0, "vh265 ucode loaded!\n"); + } else { + size = get_firmware_data(VIDEO_DEC_HEVC_MMU, fw->data); + hevc_print(hevc, 0, "vh265 mmu ucode loaded!\n"); + } } else { size = get_firmware_data(VIDEO_DEC_HEVC, fw->data); hevc_print(hevc, 0, "vh265 ucode loaded!\n"); } + if (size < 0) { pr_err("get firmware fail.\n"); vfree(fw); @@ -8845,12 +8849,13 @@ static s32 vh265_init(struct hevc_state_s *hevc) if (size == 1) { pr_info ("tee load ok"); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) - ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC_G12A, 2); - else if (hevc->mmu_enable && - (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)) - ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC_MMU, 0); - else + + if (hevc->mmu_enable) { + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) + ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC, 0); + else + ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC_MMU, 0); + } else ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC, 0); } else ret = amhevc_loadmc_ex(VFORMAT_HEVC, NULL, fw->data); @@ -9618,7 +9623,7 @@ static void run(struct vdec_s *vdec, unsigned long mask, { struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; - int r, loadr; + int r, loadr = 0; unsigned char check_sum = 0; run_count[hevc->index]++; @@ -9682,14 +9687,14 @@ static void run(struct vdec_s *vdec, unsigned long mask, } } - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) - loadr = amhevc_vdec_loadmc_ex(vdec, - "vh265_mc_g12a", hevc->fw->data); - else if (hevc->mmu_enable && - (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)) - loadr = amhevc_vdec_loadmc_ex(vdec, - "vh265_mc_mmu", hevc->fw->data); - else + if (hevc->mmu_enable) { + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) + loadr = amhevc_vdec_loadmc_ex(vdec, + "vh265_mc", hevc->fw->data); + else + loadr = amhevc_vdec_loadmc_ex(vdec, + "vh265_mc_mmu", hevc->fw->data); + } else loadr = amhevc_vdec_loadmc_ex(vdec, "vh265_mc", hevc->fw->data); diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c b/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c index 0a0aa6365395..7289fece7d21 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/amvdec.c @@ -375,96 +375,85 @@ static s32 amvdec_loadmc(const u32 *p) s32 optee_load_fw(enum vformat_e type, const char *fw_name) { - s32 ret = 0; + s32 ret = -1; + unsigned int format = FIRMWARE_MAX; + unsigned int vdec = OPTEE_VDEC_LEGENCY; char *name = __getname(); sprintf(name, "%s", fw_name ? fw_name : "null"); switch ((u32)type) { case VFORMAT_VC1: - ret = tee_load_video_fw((u32)VIDEO_DEC_VC1, 0); + format = VIDEO_DEC_VC1; break; case VFORMAT_AVS: - if (!strcmp(name, "avs_gxm")) - ret = tee_load_video_fw((u32)VIDEO_DEC_AVS_GXM, 0); - else if (!strcmp(name, "avs_no_cabac")) - ret = tee_load_video_fw((u32)VIDEO_DEC_AVS_NOCABAC, 0); + if (!strcmp(name, "avs_no_cabac")) + format = VIDEO_DEC_AVS_NOCABAC; else - ret = tee_load_video_fw((u32)VIDEO_DEC_AVS, 0); + format = VIDEO_DEC_AVS; break; case VFORMAT_MPEG12: - ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG12, 0); + format = VIDEO_DEC_MPEG12; break; case VFORMAT_MJPEG: - ret = tee_load_video_fw((u32)VIDEO_DEC_MJPEG, 0); + format = VIDEO_DEC_MJPEG; break; case VFORMAT_VP9: - if (!strcmp(name, "vp9_mc_g12a")) - ret = tee_load_video_fw((u32)VIDEO_DEC_VP9_G12A, 2); + if (!strcmp(name, "vp9_mc")) + format = VIDEO_DEC_VP9; else - ret = tee_load_video_fw((u32)VIDEO_DEC_VP9_MMU, 0); + format = VIDEO_DEC_VP9_MMU; break; case VFORMAT_AVS2: - ret = tee_load_video_fw((u32)VIDEO_DEC_AVS2_MMU, 2); + format = VIDEO_DEC_AVS2_MMU; + vdec = OPTEE_VDEC_HEVC; break; case VFORMAT_HEVC: if (!strcmp(name, "vh265_mc")) - ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC, 0); - else if (!strcmp(name, "vh265_mc_mmu")) - ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC_MMU, 0); - else if (!strcmp(name, "vh265_mc_g12a")) - ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC_G12A, 2); + format = VIDEO_DEC_HEVC; + else + format = VIDEO_DEC_HEVC_MMU; break; case VFORMAT_REAL: if (!strcmp(name, "vreal_mc_8")) - ret = tee_load_video_fw((u32)VIDEO_DEC_REAL_V8, 0); + format = VIDEO_DEC_REAL_V8; else if (!strcmp(name, "vreal_mc_9")) - ret = tee_load_video_fw((u32)VIDEO_DEC_REAL_V9, 0); + format = VIDEO_DEC_REAL_V9; break; case VFORMAT_MPEG4: if (!strcmp(name, "vmpeg4_mc_311")) - ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_3, 0); + format = VIDEO_DEC_MPEG4_3; else if (!strcmp(name, "vmpeg4_mc_4")) - ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_4, 0); + format = VIDEO_DEC_MPEG4_4; else if (!strcmp(name, "vmpeg4_mc_5")) - ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_5, 0); + format = VIDEO_DEC_MPEG4_5; else if (!strcmp(name, "h263_mc")) - ret = tee_load_video_fw((u32)VIDEO_DEC_FORMAT_H263, 0); + format = VIDEO_DEC_FORMAT_H263; break; + default: if (!strcmp(name, "vh265_mc")) - ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC, 0); + format = VIDEO_DEC_HEVC; else if (!strcmp(name, "vh265_mc_mmu")) - ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC_MMU, 0); - else if (!strcmp(name, "vmpeg4_mc_311")) - ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_3, 0); - else if (!strcmp(name, "vmpeg4_mc_4")) - ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_4, 0); - else if (!strcmp(name, "vmpeg4_mc_5")) - ret = tee_load_video_fw((u32)VIDEO_DEC_MPEG4_5, 0); - else if (!strcmp(name, "h263_mc")) - ret = tee_load_video_fw((u32)VIDEO_DEC_FORMAT_H263, 0); - else if (!strcmp(name, "vreal_mc_8")) - ret = tee_load_video_fw((u32)VIDEO_DEC_REAL_V8, 0); - else if (!strcmp(name, "vreal_mc_9")) - ret = tee_load_video_fw((u32)VIDEO_DEC_REAL_V9, 0); + format = VIDEO_DEC_HEVC_MMU; else if (!strcmp(name, "vmmjpeg_mc")) - ret = tee_load_video_fw((u32)VIDEO_DEC_MJPEG_MULTI, 0); - else if (!strcmp(name, "vh265_mc_g12a")) - ret = tee_load_video_fw((u32)VIDEO_DEC_HEVC_G12A, 2); + format = VIDEO_DEC_MJPEG_MULTI; else pr_info("unknow dec format\n"); break; } + if (format < FIRMWARE_MAX) + ret = tee_load_video_fw(format, vdec); + __putname(name); return ret; diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/utils/firmware.h b/drivers/amlogic/media_modules/frame_provider/decoder/utils/firmware.h index a2fd138d5077..17f64e430b72 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/utils/firmware.h +++ b/drivers/amlogic/media_modules/frame_provider/decoder/utils/firmware.h @@ -15,7 +15,7 @@ struct firmware_s { extern int get_decoder_firmware_data(enum vformat_e type, const char *file_name, char *buf, int size); extern int get_data_from_name(const char *name, char *buf); -extern int get_firmware_data(enum firmware_type_e type, char *buf); -extern int firmware_reload(int mode); +extern int get_firmware_data(unsigned int foramt, char *buf); +extern int video_fw_reload(int mode); #endif diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c b/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c index 72e88495715a..49517eebf562 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/vc1/vvc1.c @@ -1056,20 +1056,12 @@ static s32 vvc1_init(void) } else pr_info("not supported VC1 format\n"); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) - fw_type = VIDEO_DEC_VC1_G12A; - - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A && tee_enabled()) { - ret = tee_load_video_fw((u32)fw_type, 1); - size = 1; - } else { - size = get_firmware_data(fw_type, buf); - if (size < 0) { - amvdec_disable(); - pr_err("get firmware fail."); - vfree(buf); - return -1; - } + size = get_firmware_data(fw_type, buf); + if (size < 0) { + amvdec_disable(); + pr_err("get firmware fail."); + vfree(buf); + return -1; } if (size == 1) diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c index 9a1e88f94988..66a12a92f227 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/vp9/vvp9.c @@ -8057,10 +8057,12 @@ static s32 vvp9_init(struct VP9Decoder_s *pbi) pr_debug ("laod\n"); } else #endif + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) - size = get_firmware_data(VIDEO_DEC_VP9_G12A, fw->data); + size = get_firmware_data(VIDEO_DEC_VP9, fw->data); else size = get_firmware_data(VIDEO_DEC_VP9_MMU, fw->data); + if (size < 0) { pr_err("get firmware fail.\n"); vfree(fw); @@ -8096,7 +8098,7 @@ static s32 vvp9_init(struct VP9Decoder_s *pbi) if (size == 1) { pr_info ("tee load ok\n"); if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) - ret = tee_load_video_fw((u32)VIDEO_DEC_VP9_G12A, 2); + ret = tee_load_video_fw((u32)VIDEO_DEC_VP9, 0); else ret = tee_load_video_fw((u32)VIDEO_DEC_VP9_MMU, 0); } else @@ -8824,8 +8826,7 @@ static void run_front(struct vdec_s *vdec) } if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) - ret = amhevc_loadmc_ex(VFORMAT_VP9, - "vp9_mc_g12a", pbi->fw->data); + ret = amhevc_loadmc_ex(VFORMAT_VP9, "vp9_mc", pbi->fw->data); else ret = amhevc_loadmc_ex(VFORMAT_VP9, NULL, pbi->fw->data); diff --git a/drivers/amlogic/media_modules/stream_input/amports/amstream.c b/drivers/amlogic/media_modules/stream_input/amports/amstream.c index 4614af242f61..91285e5e460e 100644 --- a/drivers/amlogic/media_modules/stream_input/amports/amstream.c +++ b/drivers/amlogic/media_modules/stream_input/amports/amstream.c @@ -885,7 +885,7 @@ static int amstream_port_init(struct port_priv_s *priv) } /* try to reload the fw.*/ - r = firmware_reload(FW_LOAD_TRY); + r = video_fw_reload(FW_LOAD_TRY); if (r) pr_err("the firmware reload fail.\n"); diff --git a/firmware/video/video_ucode.bin b/firmware/video/video_ucode.bin index 4f47fb851b5b..e5cfacd945b4 100644 Binary files a/firmware/video/video_ucode.bin and b/firmware/video/video_ucode.bin differ