1 /*
2 * drivers/amlogic/media/common/firmware/firmware.c
3 *
4 * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 */
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/types.h>
20 #include <linux/fs.h>
21 #include <linux/init.h>
22 #include <linux/device.h>
23 #include <linux/vmalloc.h>
24 #include <linux/mm.h>
25 #include <linux/slab.h>
26
27 #include <linux/amlogic/media/utils/vformat.h>
28 #include <linux/amlogic/cpu_version.h>
29 #include "../../stream_input/amports/amports_priv.h"
30 #include "../../frame_provider/decoder/utils/vdec.h"
31 #include "firmware_priv.h"
32 #include "../chips/chips.h"
33 #include <linux/string.h>
34 #include <linux/amlogic/media/utils/log.h>
35 #include <linux/firmware.h>
36 #ifdef CONFIG_AMLOGIC_TEE
37 #include <linux/amlogic/tee.h>
38 #endif
39 #include <linux/amlogic/major.h>
40 #include <linux/cdev.h>
41 #include <linux/crc32.h>
42 #include "../chips/decoder_cpu_ver_info.h"
43
44 /* major.minor */
45 #define PACK_VERS "v0.2"
46
47 #define CLASS_NAME "firmware_codec"
48 #define DEV_NAME "firmware_vdec"
49 #define DIR "video"
50 #define FRIMWARE_SIZE (64 * 1024) /*64k*/
51 #define BUFF_SIZE (1024 * 1024 * 2)
52
53 #define FW_LOAD_FORCE (0x1)
54 #define FW_LOAD_TRY (0X2)
55
56 /*the first 256 bytes are signature data*/
57 #define SEC_OFFSET (256)
58
59 #define TRY_PARSE_MAX (256)
60
61 #define PACK ('P' << 24 | 'A' << 16 | 'C' << 8 | 'K')
62 #define CODE ('C' << 24 | 'O' << 16 | 'D' << 8 | 'E')
63
64 #ifndef FIRMWARE_MAJOR
65 #define FIRMWARE_MAJOR AMSTREAM_MAJOR
66 #endif
67
68 static DEFINE_MUTEX(mutex);
69
70 static struct ucode_file_info_s ucode_info[] = {
71 #include "firmware_cfg.h"
72 };
73
74 static const struct file_operations fw_fops = {
75 .owner = THIS_MODULE
76 };
77
78 struct fw_mgr_s *g_mgr;
79 struct fw_dev_s *g_dev;
80
81 static u32 debug;
82 static u32 detail;
83
84 #ifndef CONFIG_AMLOGIC_TEE
tee_enabled(void)85 static inline bool tee_enabled(void)
86 {
87 return false;
88 }
89 #endif
90
get_firmware_data(unsigned int format,char * buf)91 int get_firmware_data(unsigned int format, char *buf)
92 {
93 int data_len, ret = -1;
94 struct fw_mgr_s *mgr = g_mgr;
95 struct fw_info_s *info;
96
97 pr_info("[%s], the fw (%s) will be loaded.\n",
98 tee_enabled() ? "TEE" : "LOCAL",
99 get_fw_format_name(format));
100
101 if (tee_enabled())
102 return 0;
103
104 mutex_lock(&mutex);
105
106 if (list_empty(&mgr->fw_head)) {
107 pr_info("the info list is empty.\n");
108 goto out;
109 }
110
111 list_for_each_entry(info, &mgr->fw_head, node) {
112 if (format != info->format)
113 continue;
114
115 data_len = info->data->head.data_size;
116 memcpy(buf, info->data->data, data_len);
117 ret = data_len;
118
119 break;
120 }
121 out:
122 mutex_unlock(&mutex);
123
124 return ret;
125 }
126 EXPORT_SYMBOL(get_firmware_data);
127
get_data_from_name(const char * name,char * buf)128 int get_data_from_name(const char *name, char *buf)
129 {
130 int data_len, ret = -1;
131 struct fw_mgr_s *mgr = g_mgr;
132 struct fw_info_s *info;
133 char *fw_name = __getname();
134 int len;
135
136 if (fw_name == NULL)
137 return -ENOMEM;
138
139 len = snprintf(fw_name, PATH_MAX, "%s.bin", name);
140 if (len >= PATH_MAX) {
141 __putname(fw_name);
142 return -ENAMETOOLONG;
143 }
144
145 mutex_lock(&mutex);
146
147 if (list_empty(&mgr->fw_head)) {
148 pr_info("the info list is empty.\n");
149 goto out;
150 }
151
152 list_for_each_entry(info, &mgr->fw_head, node) {
153 if (strcmp(fw_name, info->name))
154 continue;
155
156 data_len = info->data->head.data_size;
157 memcpy(buf, info->data->data, data_len);
158 ret = data_len;
159
160 break;
161 }
162 out:
163 mutex_unlock(&mutex);
164
165 __putname(fw_name);
166
167 return ret;
168 }
169 EXPORT_SYMBOL(get_data_from_name);
170
fw_probe(char * buf)171 static int fw_probe(char *buf)
172 {
173 int magic = 0;
174
175 memcpy(&magic, buf, sizeof(int));
176 return magic;
177 }
178
request_firmware_from_sys(const char * file_name,char * buf,int size)179 static int request_firmware_from_sys(const char *file_name,
180 char *buf, int size)
181 {
182 int ret = -1;
183 const struct firmware *fw;
184 int magic, offset = 0;
185
186 pr_info("Try to load %s ...\n", file_name);
187
188 ret = request_firmware(&fw, file_name, g_dev->dev);
189 if (ret < 0) {
190 pr_info("Error : %d can't load the %s.\n", ret, file_name);
191 goto err;
192 }
193
194 if (fw->size > size) {
195 pr_info("Not enough memory size for ucode.\n");
196 ret = -ENOMEM;
197 goto release;
198 }
199
200 magic = fw_probe((char *)fw->data);
201 if (magic != PACK && magic != CODE) {
202 if (fw->size < SEC_OFFSET) {
203 pr_info("This is an invalid firmware file.\n");
204 goto release;
205 }
206
207 magic = fw_probe((char *)fw->data + SEC_OFFSET);
208 if (magic != PACK) {
209 pr_info("The firmware file is not packet.\n");
210 goto release;
211 }
212
213 offset = SEC_OFFSET;
214 }
215
216 memcpy(buf, (char *)fw->data + offset, fw->size - offset);
217
218 pr_info("load firmware size : %zd, Name : %s.\n",
219 fw->size, file_name);
220 ret = fw->size;
221 release:
222 release_firmware(fw);
223 err:
224 return ret;
225 }
226
request_decoder_firmware_on_sys(enum vformat_e format,const char * file_name,char * buf,int size)227 int request_decoder_firmware_on_sys(enum vformat_e format,
228 const char *file_name, char *buf, int size)
229 {
230 int ret;
231
232 ret = get_data_from_name(file_name, buf);
233 if (ret < 0)
234 pr_info("Get firmware fail.\n");
235
236 if (ret > size) {
237 pr_info("Not enough memory.\n");
238 return -ENOMEM;
239 }
240
241 return ret;
242 }
get_decoder_firmware_data(enum vformat_e format,const char * file_name,char * buf,int size)243 int get_decoder_firmware_data(enum vformat_e format,
244 const char *file_name, char *buf, int size)
245 {
246 int ret;
247
248 ret = request_decoder_firmware_on_sys(format, file_name, buf, size);
249 if (ret < 0)
250 pr_info("get_decoder_firmware_data %s for format %d failed!\n",
251 file_name, format);
252
253 return ret;
254 }
255 EXPORT_SYMBOL(get_decoder_firmware_data);
256
fw_mgr_lock(struct fw_mgr_s * mgr)257 static unsigned long fw_mgr_lock(struct fw_mgr_s *mgr)
258 {
259 unsigned long flags;
260
261 spin_lock_irqsave(&mgr->lock, flags);
262 return flags;
263 }
264
fw_mgr_unlock(struct fw_mgr_s * mgr,unsigned long flags)265 static void fw_mgr_unlock(struct fw_mgr_s *mgr, unsigned long flags)
266 {
267 spin_unlock_irqrestore(&mgr->lock, flags);
268 }
269
fw_add_info(struct fw_info_s * info)270 static void fw_add_info(struct fw_info_s *info)
271 {
272 unsigned long flags;
273 struct fw_mgr_s *mgr = g_mgr;
274
275 flags = fw_mgr_lock(mgr);
276 list_add(&info->node, &mgr->fw_head);
277 fw_mgr_unlock(mgr, flags);
278 }
279
fw_del_info(struct fw_info_s * info)280 static void fw_del_info(struct fw_info_s *info)
281 {
282 unsigned long flags;
283 struct fw_mgr_s *mgr = g_mgr;
284
285 flags = fw_mgr_lock(mgr);
286 list_del(&info->node);
287 kfree(info);
288 fw_mgr_unlock(mgr, flags);
289 }
290
fw_info_walk(void)291 static void fw_info_walk(void)
292 {
293 struct fw_mgr_s *mgr = g_mgr;
294 struct fw_info_s *info;
295
296 if (list_empty(&mgr->fw_head)) {
297 pr_info("the info list is empty.\n");
298 return;
299 }
300
301 list_for_each_entry(info, &mgr->fw_head, node) {
302 if (IS_ERR_OR_NULL(info->data))
303 continue;
304
305 pr_info("name : %s.\n", info->name);
306 pr_info("ver : %s.\n",
307 info->data->head.version);
308 pr_info("crc : 0x%x.\n",
309 info->data->head.checksum);
310 pr_info("size : %d.\n",
311 info->data->head.data_size);
312 pr_info("maker: %s.\n",
313 info->data->head.maker);
314 pr_info("from : %s.\n", info->src_from);
315 pr_info("date : %s.\n",
316 info->data->head.date);
317 if (info->data->head.duplicate)
318 pr_info("NOTE : Dup from %s.\n",
319 info->data->head.dup_from);
320 pr_info("\n");
321 }
322 }
323
fw_files_info_walk(void)324 static void fw_files_info_walk(void)
325 {
326 struct fw_mgr_s *mgr = g_mgr;
327 struct fw_files_s *files;
328
329 if (list_empty(&mgr->files_head)) {
330 pr_info("the file list is empty.\n");
331 return;
332 }
333
334 list_for_each_entry(files, &mgr->files_head, node) {
335 pr_info("type : %s.\n", !files->fw_type ?
336 "VIDEO_DECODE" : files->fw_type == 1 ?
337 "VIDEO_ENCODE" : "VIDEO_MISC");
338 pr_info("from : %s.\n", !files->file_type ?
339 "VIDEO_PACKAGE" : "VIDEO_FW_FILE");
340 pr_info("path : %s.\n", files->path);
341 pr_info("name : %s.\n\n", files->name);
342 }
343 }
344
info_show(struct class * class,struct class_attribute * attr,char * buf)345 static ssize_t info_show(struct class *class,
346 struct class_attribute *attr, char *buf)
347 {
348 char *pbuf = buf;
349 struct fw_mgr_s *mgr = g_mgr;
350 struct fw_info_s *info;
351 unsigned int secs = 0;
352 struct tm tm;
353
354 mutex_lock(&mutex);
355
356 if (list_empty(&mgr->fw_head)) {
357 pbuf += sprintf(pbuf, "No firmware.\n");
358 goto out;
359 }
360
361 /* shows version of driver. */
362 pr_info("The driver version is %s\n", PACK_VERS);
363
364 list_for_each_entry(info, &mgr->fw_head, node) {
365 if (IS_ERR_OR_NULL(info->data))
366 continue;
367
368 if (detail) {
369 pr_info("%-5s: %s\n", "name", info->name);
370 pr_info("%-5s: %s\n", "ver",
371 info->data->head.version);
372 pr_info("%-5s: 0x%x\n", "sum",
373 info->data->head.checksum);
374 pr_info("%-5s: %d\n", "size",
375 info->data->head.data_size);
376 pr_info("%-5s: %s\n", "maker",
377 info->data->head.maker);
378 pr_info("%-5s: %s\n", "from",
379 info->src_from);
380 pr_info("%-5s: %s\n\n", "date",
381 info->data->head.date);
382 continue;
383 }
384
385 secs = info->data->head.time
386 - sys_tz.tz_minuteswest * 60;
387 time64_to_tm(secs, 0, &tm);
388
389 pr_info("%s %-16s, %02d:%02d:%02d %d/%d/%ld, %s %-8s, %s %-8s, %s %s\n",
390 "fmt:", info->data->head.format,
391 tm.tm_hour, tm.tm_min, tm.tm_sec,
392 tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900,
393 "cmtid:", info->data->head.commit,
394 "chgid:", info->data->head.change_id,
395 "mk:", info->data->head.maker);
396 }
397 out:
398 mutex_unlock(&mutex);
399
400 return pbuf - buf;
401 }
402
info_store(struct class * cls,struct class_attribute * attr,const char * buf,size_t count)403 static ssize_t info_store(struct class *cls,
404 struct class_attribute *attr, const char *buf, size_t count)
405 {
406 if (kstrtoint(buf, 0, &detail) < 0)
407 return -EINVAL;
408
409 return count;
410 }
411
fw_info_fill(void)412 static int fw_info_fill(void)
413 {
414 int ret = 0, i, len;
415 struct fw_mgr_s *mgr = g_mgr;
416 struct fw_files_s *files;
417 int info_size = ARRAY_SIZE(ucode_info);
418 char *path = __getname();
419 const char *name;
420
421 if (path == NULL)
422 return -ENOMEM;
423
424 for (i = 0; i < info_size; i++) {
425 name = ucode_info[i].name;
426 if (IS_ERR_OR_NULL(name))
427 break;
428
429 len = snprintf(path, PATH_MAX, "%s/%s", DIR,
430 ucode_info[i].name);
431 if (len >= PATH_MAX)
432 continue;
433
434 files = kzalloc(sizeof(struct fw_files_s), GFP_KERNEL);
435 if (files == NULL) {
436 __putname(path);
437 return -ENOMEM;
438 }
439
440 files->file_type = ucode_info[i].file_type;
441 files->fw_type = ucode_info[i].fw_type;
442 strncpy(files->path, path, sizeof(files->path));
443 files->path[sizeof(files->path) - 1] = '\0';
444 strncpy(files->name, name, sizeof(files->name));
445 files->name[sizeof(files->name) - 1] = '\0';
446
447 list_add(&files->node, &mgr->files_head);
448 }
449
450 __putname(path);
451
452 if (debug)
453 fw_files_info_walk();
454
455 return ret;
456 }
457
fw_data_check_sum(struct firmware_s * fw)458 static int fw_data_check_sum(struct firmware_s *fw)
459 {
460 unsigned int crc;
461
462 crc = crc32_le(~0U, fw->data, fw->head.data_size);
463
464 /*pr_info("firmware crc result : 0x%x\n", crc ^ ~0U);*/
465
466 return fw->head.checksum != (crc ^ ~0U) ? 0 : 1;
467 }
468
fw_data_filter(struct firmware_s * fw,struct fw_info_s * fw_info)469 static int fw_data_filter(struct firmware_s *fw,
470 struct fw_info_s *fw_info)
471 {
472 struct fw_mgr_s *mgr = g_mgr;
473 struct fw_info_s *info, *tmp;
474 int cpu = fw_get_cpu(fw->head.cpu);
475
476 if (mgr->cur_cpu < cpu) {
477 kfree(fw_info);
478 kfree(fw);
479 return -1;
480 }
481
482 /* the encode fw need to ignoring filtering rules. */
483 if (fw_info->format == FIRMWARE_MAX)
484 return 0;
485
486 list_for_each_entry_safe(info, tmp, &mgr->fw_head, node) {
487 if (info->format != fw_info->format)
488 continue;
489
490 if (IS_ERR_OR_NULL(info->data)) {
491 fw_del_info(info);
492 return 0;
493 }
494
495 /* high priority of VIDEO_FW_FILE */
496 if (info->file_type == VIDEO_FW_FILE) {
497 pr_info("the %s need to priority proc.\n",info->name);
498 kfree(fw_info);
499 kfree(fw);
500 return 1;
501 }
502
503 /* the cpu ver is lower and needs to be filtered */
504 if (cpu < fw_get_cpu(info->data->head.cpu)) {
505 if (debug)
506 pr_info("keep the newer fw (%s) and ignore the older fw (%s).\n",
507 info->name, fw_info->name);
508 kfree(fw_info);
509 kfree(fw);
510 return 1;
511 }
512
513 /* removes not match fw from info list */
514 if (debug)
515 pr_info("drop the old fw (%s) will be load the newer fw (%s).\n",
516 info->name, fw_info->name);
517 kfree(info->data);
518 fw_del_info(info);
519 }
520
521 return 0;
522 }
523
fw_replace_dup_data(char * buf)524 static int fw_replace_dup_data(char *buf)
525 {
526 int ret = 0;
527 struct fw_mgr_s *mgr = g_mgr;
528 struct package_s *pkg =
529 (struct package_s *) buf;
530 struct package_info_s *pinfo =
531 (struct package_info_s *) pkg->data;
532 struct fw_info_s *info = NULL;
533 char *pdata = pkg->data;
534 int try_cnt = TRY_PARSE_MAX;
535
536 do {
537 if (!pinfo->head.length)
538 break;
539 list_for_each_entry(info, &mgr->fw_head, node) {
540 struct firmware_s *comp = NULL;
541 struct firmware_s *data = NULL;
542 int len = 0;
543
544 comp = (struct firmware_s *)pinfo->data;
545 if (comp->head.duplicate)
546 break;
547
548 if (!info->data->head.duplicate ||
549 comp->head.checksum !=
550 info->data->head.checksum)
551 continue;
552
553 len = pinfo->head.length;
554 data = kzalloc(len, GFP_KERNEL);
555 if (data == NULL) {
556 ret = -ENOMEM;
557 goto out;
558 }
559
560 memcpy(data, pinfo->data, len);
561
562 /* update header information. */
563 memcpy(data, info->data, sizeof(*data));
564
565 /* if replaced success need to update real size. */
566 data->head.data_size = comp->head.data_size;
567
568 kfree(info->data);
569 info->data = data;
570 }
571 pdata += (pinfo->head.length + sizeof(*pinfo));
572 pinfo = (struct package_info_s *)pdata;
573 } while (try_cnt--);
574 out:
575 return ret;
576 }
577
fw_check_pack_version(char * buf)578 static int fw_check_pack_version(char *buf)
579 {
580 struct package_s *pack = NULL;
581 int major, minor, major_fw, minor_fw;
582 int ret;
583
584 pack = (struct package_s *) buf;
585 ret = sscanf(PACK_VERS, "v%x.%x", &major, &minor);
586 if (ret != 2)
587 return -1;
588
589 major_fw = (pack->head.version >> 16) & 0xff;
590 minor_fw = pack->head.version & 0xff;
591
592 if (major < major_fw) {
593 pr_info("the pack ver v%d.%d too higher to unsupport.\n",
594 major_fw, minor_fw);
595 return -1;
596 }
597
598 if (minor < minor_fw) {
599 pr_info("The fw driver version (v%d.%d) is lower than the pkg version (v%d.%d).\n",
600 major, minor, major_fw, minor_fw);
601 pr_info("The driver version is too low that may affect the work please update asap.\n");
602 }
603
604 if (debug) {
605 pr_info("The package has %d fws totally.\n", pack->head.total);
606 pr_info("The driver ver is v%d.%d\n", major, minor);
607 pr_info("The firmware ver is v%d.%d\n", major_fw, minor_fw);
608 }
609
610 return 0;
611 }
612
fw_package_parse(struct fw_files_s * files,char * buf,int size)613 static int fw_package_parse(struct fw_files_s *files,
614 char *buf, int size)
615 {
616 int ret = 0;
617 struct package_info_s *pack_info;
618 struct fw_info_s *info;
619 struct firmware_s *data;
620 char *pack_data;
621 int info_len, len;
622 int try_cnt = TRY_PARSE_MAX;
623 char *path = __getname();
624
625 if (path == NULL)
626 return -ENOMEM;
627
628 pack_data = ((struct package_s *)buf)->data;
629 pack_info = (struct package_info_s *)pack_data;
630 info_len = sizeof(struct package_info_s);
631
632 do {
633 if (!pack_info->head.length)
634 break;
635
636 len = snprintf(path, PATH_MAX, "%s/%s", DIR,
637 pack_info->head.name);
638 if (len >= PATH_MAX)
639 continue;
640
641 info = kzalloc(sizeof(struct fw_info_s), GFP_KERNEL);
642 if (info == NULL) {
643 ret = -ENOMEM;
644 goto out;
645 }
646
647 data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL);
648 if (data == NULL) {
649 kfree(info);
650 ret = -ENOMEM;
651 goto out;
652 }
653
654 info->file_type = files->file_type;
655 strncpy(info->src_from, files->name,
656 sizeof(info->src_from));
657 info->src_from[sizeof(info->src_from) - 1] = '\0';
658 strncpy(info->name, pack_info->head.name,
659 sizeof(info->name));
660 info->name[sizeof(info->name) - 1] = '\0';
661 info->format = get_fw_format(pack_info->head.format);
662
663 len = pack_info->head.length;
664 memcpy(data, pack_info->data, len);
665
666 pack_data += (pack_info->head.length + info_len);
667 pack_info = (struct package_info_s *)pack_data;
668
669 if (!data->head.duplicate &&
670 !fw_data_check_sum(data)) {
671 pr_info("check sum fail !\n");
672 kfree(data);
673 kfree(info);
674 goto out;
675 }
676
677 if (fw_data_filter(data, info))
678 continue;
679
680 if (debug)
681 pr_info("adds %s to the fw list.\n", info->name);
682
683 info->data = data;
684 fw_add_info(info);
685 } while (try_cnt--);
686
687 /* process the fw of dup attribute. */
688 ret = fw_replace_dup_data(buf);
689 if (ret)
690 pr_err("replace dup fw failed.\n");
691 out:
692 __putname(path);
693
694 return ret;
695 }
696
fw_code_parse(struct fw_files_s * files,char * buf,int size)697 static int fw_code_parse(struct fw_files_s *files,
698 char *buf, int size)
699 {
700 struct fw_info_s *info;
701
702 info = kzalloc(sizeof(struct fw_info_s), GFP_KERNEL);
703 if (info == NULL)
704 return -ENOMEM;
705
706 info->data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL);
707 if (info->data == NULL) {
708 kfree(info);
709 return -ENOMEM;
710 }
711
712 info->file_type = files->file_type;
713 strncpy(info->src_from, files->name,
714 sizeof(info->src_from));
715 info->src_from[sizeof(info->src_from) - 1] = '\0';
716 memcpy(info->data, buf, size);
717
718 if (!fw_data_check_sum(info->data)) {
719 pr_info("check sum fail !\n");
720 kfree(info->data);
721 kfree(info);
722 return -1;
723 }
724
725 if (debug)
726 pr_info("adds %s to the fw list.\n", info->name);
727
728 fw_add_info(info);
729
730 return 0;
731 }
732
get_firmware_from_sys(const char * path,char * buf,int size)733 static int get_firmware_from_sys(const char *path,
734 char *buf, int size)
735 {
736 int len = 0;
737
738 len = request_firmware_from_sys(path, buf, size);
739 if (len < 0)
740 pr_info("get data from fsys fail.\n");
741
742 return len;
743 }
744
fw_data_binding(void)745 static int fw_data_binding(void)
746 {
747 int ret = 0, magic = 0;
748 struct fw_mgr_s *mgr = g_mgr;
749 struct fw_files_s *files, *tmp;
750 char *buf = NULL;
751 int size;
752
753 if (list_empty(&mgr->files_head)) {
754 pr_info("the file list is empty.\n");
755 return 0;
756 }
757
758 buf = vmalloc(BUFF_SIZE);
759 if (IS_ERR_OR_NULL(buf))
760 return -ENOMEM;
761
762 memset(buf, 0, BUFF_SIZE);
763
764 list_for_each_entry_safe(files, tmp, &mgr->files_head, node) {
765 size = get_firmware_from_sys(files->path, buf, BUFF_SIZE);
766 magic = fw_probe(buf);
767
768 if (files->file_type == VIDEO_PACKAGE && magic == PACK) {
769 if (!fw_check_pack_version(buf))
770 ret = fw_package_parse(files, buf, size);
771 } else if (files->file_type == VIDEO_FW_FILE && magic == CODE) {
772 ret = fw_code_parse(files, buf, size);
773 } else {
774 list_del(&files->node);
775 kfree(files);
776 pr_info("invaild file type.\n");
777 }
778
779 memset(buf, 0, BUFF_SIZE);
780 }
781
782 if (debug)
783 fw_info_walk();
784
785 vfree(buf);
786
787 return ret;
788 }
789
fw_pre_load(void)790 static int fw_pre_load(void)
791 {
792 if (fw_info_fill() < 0) {
793 pr_info("Get path fail.\n");
794 return -1;
795 }
796
797 if (fw_data_binding() < 0) {
798 pr_info("Set data fail.\n");
799 return -1;
800 }
801
802 return 0;
803 }
804
fw_mgr_init(void)805 static int fw_mgr_init(void)
806 {
807 g_mgr = kzalloc(sizeof(struct fw_mgr_s), GFP_KERNEL);
808 if (IS_ERR_OR_NULL(g_mgr))
809 return -ENOMEM;
810
811 g_mgr->cur_cpu = get_cpu_major_id();
812 INIT_LIST_HEAD(&g_mgr->files_head);
813 INIT_LIST_HEAD(&g_mgr->fw_head);
814 spin_lock_init(&g_mgr->lock);
815
816 return 0;
817 }
818
fw_ctx_clean(void)819 static void fw_ctx_clean(void)
820 {
821 struct fw_mgr_s *mgr = g_mgr;
822 struct fw_files_s *files;
823 struct fw_info_s *info;
824 unsigned long flags;
825
826 flags = fw_mgr_lock(mgr);
827 while (!list_empty(&mgr->files_head)) {
828 files = list_entry(mgr->files_head.next,
829 struct fw_files_s, node);
830 list_del(&files->node);
831 kfree(files);
832 }
833
834 while (!list_empty(&mgr->fw_head)) {
835 info = list_entry(mgr->fw_head.next,
836 struct fw_info_s, node);
837 list_del(&info->node);
838 kfree(info->data);
839 kfree(info);
840 }
841 fw_mgr_unlock(mgr, flags);
842 }
843
video_fw_reload(int mode)844 int video_fw_reload(int mode)
845 {
846 int ret = 0;
847 struct fw_mgr_s *mgr = g_mgr;
848
849 if (tee_enabled())
850 return 0;
851
852 mutex_lock(&mutex);
853
854 if (mode & FW_LOAD_FORCE) {
855 fw_ctx_clean();
856
857 ret = fw_pre_load();
858 if (ret < 0)
859 pr_err("The fw reload fail.\n");
860 } else if (mode & FW_LOAD_TRY) {
861 if (!list_empty(&mgr->fw_head)) {
862 pr_info("The fw has been loaded.\n");
863 goto out;
864 }
865
866 ret = fw_pre_load();
867 if (ret < 0)
868 pr_err("The fw try to reload fail.\n");
869 }
870 out:
871 mutex_unlock(&mutex);
872
873 return ret;
874 }
875 EXPORT_SYMBOL(video_fw_reload);
876
reload_show(struct class * class,struct class_attribute * attr,char * buf)877 static ssize_t reload_show(struct class *class,
878 struct class_attribute *attr, char *buf)
879 {
880 char *pbuf = buf;
881
882 pbuf += sprintf(pbuf, "The fw reload usage.\n");
883 pbuf += sprintf(pbuf, "> set 1 means that the fw is forced to update\n");
884 pbuf += sprintf(pbuf, "> set 2 means that the fw is try to reload\n");
885
886 return pbuf - buf;
887 }
888
reload_store(struct class * class,struct class_attribute * attr,const char * buf,size_t size)889 static ssize_t reload_store(struct class *class,
890 struct class_attribute *attr,
891 const char *buf, size_t size)
892 {
893 int ret = -1;
894 unsigned int val;
895
896 ret = kstrtoint(buf, 0, &val);
897 if (ret != 0)
898 return -EINVAL;
899
900 ret = video_fw_reload(val);
901 if (ret < 0)
902 pr_err("fw reload fail.\n");
903
904 return size;
905 }
906
debug_show(struct class * cls,struct class_attribute * attr,char * buf)907 static ssize_t debug_show(struct class *cls,
908 struct class_attribute *attr, char *buf)
909 {
910 return sprintf(buf, "%x\n", debug);
911 }
912
debug_store(struct class * cls,struct class_attribute * attr,const char * buf,size_t count)913 static ssize_t debug_store(struct class *cls,
914 struct class_attribute *attr, const char *buf, size_t count)
915 {
916 if (kstrtoint(buf, 0, &debug) < 0)
917 return -EINVAL;
918
919 return count;
920 }
921
922 static CLASS_ATTR_RW(info);
923 static CLASS_ATTR_RW(reload);
924 static CLASS_ATTR_RW(debug);
925
926 static struct attribute *fw_class_attrs[] = {
927 &class_attr_info.attr,
928 &class_attr_reload.attr,
929 &class_attr_debug.attr,
930 NULL
931 };
932
933 ATTRIBUTE_GROUPS(fw_class);
934
935 static struct class fw_class = {
936 .name = CLASS_NAME,
937 .class_groups = fw_class_groups,
938 };
939
fw_driver_init(void)940 static int fw_driver_init(void)
941 {
942 int ret = -1;
943
944 g_dev = kzalloc(sizeof(struct fw_dev_s), GFP_KERNEL);
945 if (IS_ERR_OR_NULL(g_dev))
946 return -ENOMEM;
947
948 g_dev->dev_no = MKDEV(FIRMWARE_MAJOR, 100);
949
950 ret = register_chrdev_region(g_dev->dev_no, 1, DEV_NAME);
951 if (ret < 0) {
952 pr_info("Can't get major number %d.\n", FIRMWARE_MAJOR);
953 goto err;
954 }
955
956 cdev_init(&g_dev->cdev, &fw_fops);
957 g_dev->cdev.owner = THIS_MODULE;
958
959 ret = cdev_add(&g_dev->cdev, g_dev->dev_no, 1);
960 if (ret) {
961 pr_info("Error %d adding cdev fail.\n", ret);
962 goto err;
963 }
964
965 ret = class_register(&fw_class);
966 if (ret < 0) {
967 pr_info("Failed in creating class.\n");
968 goto err;
969 }
970
971 g_dev->dev = device_create(&fw_class, NULL,
972 g_dev->dev_no, NULL, DEV_NAME);
973 if (IS_ERR_OR_NULL(g_dev->dev)) {
974 pr_info("Create device failed.\n");
975 ret = -ENODEV;
976 goto err;
977 }
978
979 pr_info("Registered firmware driver success.\n");
980 err:
981 return ret;
982 }
983
fw_driver_exit(void)984 static void fw_driver_exit(void)
985 {
986 cdev_del(&g_dev->cdev);
987 device_destroy(&fw_class, g_dev->dev_no);
988 class_unregister(&fw_class);
989 unregister_chrdev_region(g_dev->dev_no, 1);
990 kfree(g_dev);
991 kfree(g_mgr);
992 }
993
fw_module_init(void)994 static int __init fw_module_init(void)
995 {
996 int ret = -1;
997
998 ret = fw_driver_init();
999 if (ret) {
1000 pr_info("Error %d firmware driver init fail.\n", ret);
1001 goto err;
1002 }
1003
1004 ret = fw_mgr_init();
1005 if (ret) {
1006 pr_info("Error %d firmware mgr init fail.\n", ret);
1007 goto err;
1008 }
1009
1010 ret = fw_pre_load();
1011 if (ret) {
1012 pr_info("Error %d firmware pre load fail.\n", ret);
1013 goto err;
1014 }
1015 err:
1016 return ret;
1017 }
1018
fw_module_exit(void)1019 static void __exit fw_module_exit(void)
1020 {
1021 fw_ctx_clean();
1022 fw_driver_exit();
1023 pr_info("Firmware driver cleaned up.\n");
1024 }
1025
1026 module_init(fw_module_init);
1027 module_exit(fw_module_exit);
1028
1029 MODULE_LICENSE("GPL");
1030 MODULE_AUTHOR("Nanxin Qin <nanxin.qin@amlogic.com>");
1031