summaryrefslogtreecommitdiff
path: root/drivers/common/firmware/firmware_drv.c (plain)
blob: 9f5e392124a043bf8bed64b29c5c3738247ac2c6
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
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/types.h>
21#include <linux/fs.h>
22#include <linux/init.h>
23#include <linux/device.h>
24#include <linux/vmalloc.h>
25#include <linux/mm.h>
26#include <linux/slab.h>
27
28#include <linux/amlogic/media/utils/vformat.h>
29#include <linux/amlogic/cpu_version.h>
30#include "../../stream_input/amports/amports_priv.h"
31#include "../../frame_provider/decoder/utils/vdec.h"
32#include "firmware_priv.h"
33#include "../chips/chips.h"
34#include <linux/string.h>
35#include <linux/amlogic/media/utils/log.h>
36#include <linux/firmware.h>
37#include <linux/amlogic/tee.h>
38#include <linux/amlogic/major.h>
39#include <linux/cdev.h>
40#include <linux/crc32.h>
41
42#define CLASS_NAME "firmware_codec"
43#define DEV_NAME "firmware_vdec"
44#define DIR "video"
45#define FRIMWARE_SIZE (128 * 1024) /*128k*/
46#define BUFF_SIZE (1024 * 1024)
47
48#define FW_LOAD_FORCE (0x1)
49#define FW_LOAD_TRY (0X2)
50
51/*the first 256 bytes are signature data*/
52#define SEC_OFFSET (256)
53
54#define PACK ('P' << 24 | 'A' << 16 | 'C' << 8 | 'K')
55#define CODE ('C' << 24 | 'O' << 16 | 'D' << 8 | 'E')
56
57static DEFINE_MUTEX(mutex);
58
59static struct ucode_info_s ucode_info[] = {
60#include "firmware_cfg.h"
61};
62
63static const struct file_operations firmware_fops = {
64 .owner = THIS_MODULE
65};
66
67struct firmware_mgr_s *g_mgr;
68struct firmware_dev_s *g_dev;
69
70static u32 debug;
71
72int get_firmware_data(enum firmware_type_e type, char *buf)
73{
74 int data_len, ret = -1;
75 struct firmware_mgr_s *mgr = g_mgr;
76 struct firmware_info_s *info;
77
78 if (tee_enabled()) {
79 pr_info ("tee load firmware type= %d\n",(u32)type);
80 ret = tee_load_video_fw((u32)type);
81 if (ret == 0)
82 ret = 1;
83 else
84 ret = -1;
85 return ret;
86 }
87
88 mutex_lock(&mutex);
89
90 if (list_empty(&mgr->head)) {
91 pr_info("the info list is empty.\n");
92 goto out;
93 }
94
95 list_for_each_entry(info, &mgr->head, node) {
96 if (type != info->type)
97 continue;
98
99 data_len = info->data->header.data_size;
100 memcpy(buf, info->data->data, data_len);
101 ret = data_len;
102
103 break;
104 }
105out:
106 mutex_unlock(&mutex);
107
108 return ret;
109}
110EXPORT_SYMBOL(get_firmware_data);
111
112int get_data_from_name(const char *name, char *buf)
113{
114 int data_len, ret = -1;
115 struct firmware_mgr_s *mgr = g_mgr;
116 struct firmware_info_s *info;
117 char *firmware_name = __getname();
118
119 if (IS_ERR_OR_NULL(firmware_name))
120 return -ENOMEM;
121
122 strcat(firmware_name, name);
123 strcat(firmware_name, ".bin");
124
125 mutex_lock(&mutex);
126
127 if (list_empty(&mgr->head)) {
128 pr_info("the info list is empty.\n");
129 goto out;
130 }
131
132 list_for_each_entry(info, &mgr->head, node) {
133 if (strcmp(firmware_name, info->name))
134 continue;
135
136 data_len = info->data->header.data_size;
137 memcpy(buf, info->data->data, data_len);
138 ret = data_len;
139
140 break;
141 }
142out:
143 mutex_unlock(&mutex);
144
145 __putname(firmware_name);
146
147 return ret;
148}
149EXPORT_SYMBOL(get_data_from_name);
150
151static int firmware_probe(char *buf)
152{
153 int magic = 0;
154
155 memcpy(&magic, buf, sizeof(int));
156 return magic;
157}
158
159static int request_firmware_from_sys(const char *file_name,
160 char *buf, int size)
161{
162 int ret = -1;
163 const struct firmware *firmware;
164 int magic, offset = 0;
165
166 pr_info("Try load %s ...\n", file_name);
167
168 ret = request_firmware(&firmware, file_name, g_dev->dev);
169 if (ret < 0) {
170 pr_info("Error : %d can't load the %s.\n", ret, file_name);
171 goto err;
172 }
173
174 if (firmware->size > size) {
175 pr_info("Not enough memory size for ucode.\n");
176 ret = -ENOMEM;
177 goto release;
178 }
179
180 magic = firmware_probe((char *)firmware->data);
181 if (magic != PACK && magic != CODE) {
182 if (firmware->size < SEC_OFFSET) {
183 pr_info("This is an invalid firmware file.\n");
184 goto release;
185 }
186
187 magic = firmware_probe((char *)firmware->data + SEC_OFFSET);
188 if (magic != PACK) {
189 pr_info("The firmware file is not packet.\n");
190 goto release;
191 }
192
193 offset = SEC_OFFSET;
194 }
195
196 memcpy(buf, (char *)firmware->data + offset, firmware->size - offset);
197
198 pr_info("load firmware size : %zd, Name : %s.\n",
199 firmware->size, file_name);
200 ret = firmware->size;
201release:
202 release_firmware(firmware);
203err:
204 return ret;
205}
206
207int request_decoder_firmware_on_sys(enum vformat_e type,
208 const char *file_name, char *buf, int size)
209{
210 int ret;
211
212 ret = get_data_from_name(file_name, buf);
213 if (ret < 0)
214 pr_info("Get firmware fail.\n");
215
216 if (ret > size) {
217 pr_info("Not enough memory.\n");
218 return -ENOMEM;
219 }
220
221 return ret;
222}
223int get_decoder_firmware_data(enum vformat_e type,
224 const char *file_name, char *buf, int size)
225{
226 int ret;
227
228 ret = request_decoder_firmware_on_sys(type, file_name, buf, size);
229 if (ret < 0)
230 pr_info("get_decoder_firmware_data %s for format %d failed!\n",
231 file_name, type);
232
233 return ret;
234}
235EXPORT_SYMBOL(get_decoder_firmware_data);
236
237static unsigned long firmware_mgr_lock(struct firmware_mgr_s *mgr)
238{
239 unsigned long flags;
240
241 spin_lock_irqsave(&mgr->lock, flags);
242 return flags;
243}
244
245static void firmware_mgr_unlock(struct firmware_mgr_s *mgr, unsigned long flags)
246{
247 spin_unlock_irqrestore(&mgr->lock, flags);
248}
249
250static void add_info(struct firmware_info_s *info)
251{
252 unsigned long flags;
253 struct firmware_mgr_s *mgr = g_mgr;
254
255 flags = firmware_mgr_lock(mgr);
256 list_add(&info->node, &mgr->head);
257 firmware_mgr_unlock(mgr, flags);
258}
259
260static void del_info(struct firmware_info_s *info)
261{
262 unsigned long flags;
263 struct firmware_mgr_s *mgr = g_mgr;
264
265 flags = firmware_mgr_lock(mgr);
266 list_del(&info->node);
267 firmware_mgr_unlock(mgr, flags);
268}
269
270static void walk_firmware_info(void)
271{
272 struct firmware_mgr_s *mgr = g_mgr;
273 struct firmware_info_s *info;
274
275 mutex_lock(&mutex);
276
277 if (list_empty(&mgr->head)) {
278 pr_info("the info list is empty.\n");
279 return;
280 }
281
282 list_for_each_entry(info, &mgr->head, node) {
283 if (IS_ERR_OR_NULL(info->data))
284 continue;
285
286 pr_info("path : %s.\n", info->path);
287 pr_info("name : %s.\n", info->name);
288 pr_info("version : %s.\n",
289 info->data->header.version);
290 pr_info("checksum : 0x%x.\n",
291 info->data->header.checksum);
292 pr_info("data size : %d.\n",
293 info->data->header.data_size);
294 pr_info("author : %s.\n",
295 info->data->header.author);
296 pr_info("date : %s.\n",
297 info->data->header.date);
298 pr_info("commit : %s.\n\n",
299 info->data->header.commit);
300 }
301
302 mutex_unlock(&mutex);
303}
304
305static ssize_t info_show(struct class *class,
306 struct class_attribute *attr, char *buf)
307{
308 char *pbuf = buf;
309 struct firmware_mgr_s *mgr = g_mgr;
310 struct firmware_info_s *info;
311
312 mutex_lock(&mutex);
313
314 if (list_empty(&mgr->head)) {
315 pbuf += sprintf(pbuf, "No firmware.\n");
316 goto out;
317 }
318
319 list_for_each_entry(info, &mgr->head, node) {
320 if (IS_ERR_OR_NULL(info->data))
321 continue;
322
323 pr_info("%10s : %s\n", "name", info->name);
324 pr_info("%10s : %d\n", "size",
325 info->data->header.data_size);
326 pr_info("%10s : %s\n", "ver",
327 info->data->header.version);
328 pr_info("%10s : 0x%x\n", "sum",
329 info->data->header.checksum);
330 pr_info("%10s : %s\n", "commit",
331 info->data->header.commit);
332 pr_info("%10s : %s\n", "author",
333 info->data->header.author);
334 pr_info("%10s : %s\n\n", "date",
335 info->data->header.date);
336 }
337out:
338 mutex_unlock(&mutex);
339
340 return pbuf - buf;
341}
342
343static int set_firmware_info(void)
344{
345 int ret = 0, i, len;
346 struct firmware_info_s *info;
347 int info_size = ARRAY_SIZE(ucode_info);
348 int cpu = get_cpu_type();
349 char *path = __getname();
350 const char *name;
351
352 if (IS_ERR_OR_NULL(path))
353 return -ENOMEM;
354
355 for (i = 0; i < info_size; i++) {
356 if (cpu != ucode_info[i].cpu)
357 continue;
358
359 name = ucode_info[i].name;
360 if (IS_ERR_OR_NULL(name))
361 break;
362
363 len = snprintf(path, PATH_MAX, "%s/%s", DIR,
364 ucode_info[i].name);
365 if (len >= PATH_MAX)
366 continue;
367
368 info = kzalloc(sizeof(struct firmware_info_s), GFP_KERNEL);
369 if (IS_ERR_OR_NULL(info)) {
370 __putname(path);
371 return -ENOMEM;
372 }
373
374 strcpy(info->path, path);
375 strcpy(info->name, name);
376 info->type = ucode_info[i].type;
377 info->data = NULL;
378
379 add_info(info);
380 }
381
382 __putname(path);
383
384 return ret;
385}
386
387static int checksum(struct firmware_s *firmware)
388{
389 unsigned int crc;
390
391 crc = crc32_le(~0U, firmware->data, firmware->header.data_size);
392
393 if (debug)
394 pr_info("firmware crc result : 0x%x\n", crc ^ ~0U);
395
396 return firmware->header.checksum != (crc ^ ~0U) ? 0 : 1;
397}
398
399static int check_repeat(struct firmware_s *data, enum firmware_type_e type)
400{
401 struct firmware_mgr_s *mgr = g_mgr;
402 struct firmware_info_s *info;
403
404 if (list_empty(&mgr->head)) {
405 pr_info("the info list is empty.\n");
406 return -1;
407 }
408
409 list_for_each_entry(info, &mgr->head, node) {
410 if (info->type != type)
411 continue;
412
413 if (IS_ERR_OR_NULL(info->data))
414 info->data = data;
415
416 return 1;
417 }
418
419 return 0;
420}
421
422static int firmware_parse_package(char *buf, int size)
423{
424 int ret = 0;
425 struct package_info_s *pack_info;
426 struct firmware_info_s *info;
427 struct firmware_s *data;
428 char *pack_data;
429 int info_len, len;
430 int try_cnt = 100;
431 char *path = __getname();
432
433 if (IS_ERR_OR_NULL(path))
434 return -ENOMEM;
435
436 pack_data = ((struct package_s *)buf)->data;
437 pack_info = (struct package_info_s *)pack_data;
438 info_len = sizeof(struct package_info_s);
439
440 do {
441 if (!pack_info->header.length)
442 break;
443
444 len = snprintf(path, PATH_MAX, "%s/%s", DIR,
445 pack_info->header.name);
446 if (len >= PATH_MAX)
447 continue;
448
449 info = kzalloc(sizeof(struct firmware_info_s), GFP_KERNEL);
450 if (IS_ERR_OR_NULL(info)) {
451 ret = -ENOMEM;
452 goto out;
453 }
454
455 data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL);
456 if (IS_ERR_OR_NULL(data)) {
457 kfree(info);
458 ret = -ENOMEM;
459 goto out;
460 }
461
462 strcpy(info->path, path);
463 strcpy(info->name, pack_info->header.name);
464 info->type = get_firmware_type(pack_info->header.format);
465
466 len = pack_info->header.length;
467 memcpy(data, pack_info->data, len);
468
469 pack_data += (pack_info->header.length + info_len);
470 pack_info = (struct package_info_s *)pack_data;
471
472 ret = checksum(data);
473 if (!ret) {
474 pr_info("check sum fail !\n");
475 kfree(data);
476 kfree(info);
477 goto out;
478 }
479
480 ret = check_repeat(data, info->type);
481 if (ret < 0) {
482 kfree(data);
483 kfree(info);
484 goto out;
485 }
486
487 if (ret) {
488 kfree(info);
489 continue;
490 }
491
492 info->data = data;
493 add_info(info);
494 } while (try_cnt--);
495out:
496 __putname(path);
497
498 return ret;
499}
500
501static int firmware_parse_code(struct firmware_info_s *info,
502 char *buf, int size)
503{
504 if (!IS_ERR_OR_NULL(info->data))
505 kfree(info->data);
506
507 info->data = kzalloc(FRIMWARE_SIZE, GFP_KERNEL);
508 if (IS_ERR_OR_NULL(info->data))
509 return -ENOMEM;
510
511 memcpy(info->data, buf, size);
512
513 if (!checksum(info->data)) {
514 pr_info("check sum fail !\n");
515 kfree(info->data);
516 return -1;
517 }
518
519 return 0;
520}
521
522static int get_firmware_from_sys(const char *path,
523 char *buf, int size)
524{
525 int len = 0;
526
527 len = request_firmware_from_sys(path, buf, size);
528 if (len < 0)
529 pr_info("get data from fsys fail.\n");
530
531 return len;
532}
533
534static int set_firmware_data(void)
535{
536 int ret = 0, magic = 0;
537 struct firmware_mgr_s *mgr = g_mgr;
538 struct firmware_info_s *info, *temp;
539 char *buf = NULL;
540 int size;
541
542 if (list_empty(&mgr->head)) {
543 pr_info("the info list is empty.\n");
544 return 0;
545 }
546
547 buf = vmalloc(BUFF_SIZE);
548 if (IS_ERR_OR_NULL(buf))
549 return -ENOMEM;
550
551 memset(buf, 0, BUFF_SIZE);
552
553 list_for_each_entry_safe(info, temp, &mgr->head, node) {
554 size = get_firmware_from_sys(info->path, buf, BUFF_SIZE);
555 magic = firmware_probe(buf);
556
557 switch (magic) {
558 case PACK:
559 ret = firmware_parse_package(buf, size);
560
561 del_info(info);
562 kfree(info);
563 break;
564
565 case CODE:
566 ret = firmware_parse_code(info, buf, size);
567 break;
568
569 default:
570 del_info(info);
571 kfree(info);
572 pr_info("invaild type.\n");
573 }
574
575 memset(buf, 0, BUFF_SIZE);
576 }
577
578 if (debug)
579 walk_firmware_info();
580
581 vfree(buf);
582
583 return ret;
584}
585
586static int firmware_pre_load(void)
587{
588 int ret = -1;
589
590 ret = set_firmware_info();
591 if (ret < 0) {
592 pr_info("Get path fail.\n");
593 goto err;
594 }
595
596 ret = set_firmware_data();
597 if (ret < 0) {
598 pr_info("Set data fail.\n");
599 goto err;
600 }
601err:
602 return ret;
603}
604
605static int firmware_mgr_init(void)
606{
607 g_mgr = kzalloc(sizeof(struct firmware_mgr_s), GFP_KERNEL);
608 if (IS_ERR_OR_NULL(g_mgr))
609 return -ENOMEM;
610
611 INIT_LIST_HEAD(&g_mgr->head);
612 spin_lock_init(&g_mgr->lock);
613
614 return 0;
615}
616
617static ssize_t reload_show(struct class *class,
618 struct class_attribute *attr, char *buf)
619{
620 char *pbuf = buf;
621
622 pbuf += sprintf(pbuf, "The fw reload usage.\n");
623 pbuf += sprintf(pbuf, "> set 1 means that the fw is forced to update\n");
624 pbuf += sprintf(pbuf, "> set 2 means that the fw is try to reload\n");
625
626 return pbuf - buf;
627}
628
629int firmware_reload(int mode)
630{
631 int ret = 0;
632 struct firmware_mgr_s *mgr = g_mgr;
633 struct firmware_info_s *info = NULL;
634
635 if (tee_enabled())
636 return 0;
637
638 mutex_lock(&mutex);
639
640 if (mode & FW_LOAD_FORCE) {
641 while (!list_empty(&mgr->head)) {
642 info = list_entry(mgr->head.next,
643 struct firmware_info_s, node);
644 list_del(&info->node);
645 kfree(info->data);
646 kfree(info);
647 }
648
649 ret = firmware_pre_load();
650 if (ret < 0)
651 pr_err("The fw reload fail.\n");
652 } else if (mode & FW_LOAD_TRY) {
653 if (!list_empty(&mgr->head)) {
654 pr_info("The fw has been loaded.\n");
655 goto out;
656 }
657
658 ret = firmware_pre_load();
659 if (ret < 0)
660 pr_err("The fw try to reload fail.\n");
661 }
662out:
663 mutex_unlock(&mutex);
664
665 return ret;
666}
667EXPORT_SYMBOL(firmware_reload);
668
669static ssize_t reload_store(struct class *class,
670 struct class_attribute *attr,
671 const char *buf, size_t size)
672{
673 int ret = -1;
674 unsigned int val;
675
676 ret = kstrtoint(buf, 0, &val);
677 if (ret != 0)
678 return -EINVAL;
679
680 ret = firmware_reload(val);
681 if (ret < 0)
682 pr_err("fw reload fail.\n");
683
684 return size;
685}
686
687static struct class_attribute firmware_class_attrs[] = {
688 __ATTR_RO(info),
689 __ATTR(reload, 0664, reload_show, reload_store),
690 __ATTR_NULL
691};
692
693static struct class firmware_class = {
694 .name = CLASS_NAME,
695 .class_attrs = firmware_class_attrs,
696};
697
698static int firmware_driver_init(void)
699{
700 int ret = -1;
701
702 g_dev = kzalloc(sizeof(struct firmware_dev_s), GFP_KERNEL);
703 if (IS_ERR_OR_NULL(g_dev))
704 return -ENOMEM;
705
706 g_dev->dev_no = MKDEV(AMSTREAM_MAJOR, 100);
707
708 ret = register_chrdev_region(g_dev->dev_no, 1, DEV_NAME);
709 if (ret < 0) {
710 pr_info("Can't get major number %d.\n", AMSTREAM_MAJOR);
711 goto err;
712 }
713
714 cdev_init(&g_dev->cdev, &firmware_fops);
715 g_dev->cdev.owner = THIS_MODULE;
716
717 ret = cdev_add(&g_dev->cdev, g_dev->dev_no, 1);
718 if (ret) {
719 pr_info("Error %d adding cdev fail.\n", ret);
720 goto err;
721 }
722
723 ret = class_register(&firmware_class);
724 if (ret < 0) {
725 pr_info("Failed in creating class.\n");
726 goto err;
727 }
728
729 g_dev->dev = device_create(&firmware_class, NULL,
730 g_dev->dev_no, NULL, DEV_NAME);
731 if (IS_ERR_OR_NULL(g_dev->dev)) {
732 pr_info("Create device failed.\n");
733 ret = -ENODEV;
734 goto err;
735 }
736
737 pr_info("Registered firmware driver success.\n");
738err:
739 return ret;
740}
741
742static void firmware_info_clean(void)
743{
744 struct firmware_mgr_s *mgr = g_mgr;
745 struct firmware_info_s *info;
746 unsigned long flags;
747
748 flags = firmware_mgr_lock(mgr);
749 while (!list_empty(&mgr->head)) {
750 info = list_entry(mgr->head.next,
751 struct firmware_info_s, node);
752 list_del(&info->node);
753 kfree(info->data);
754 kfree(info);
755 }
756 firmware_mgr_unlock(mgr, flags);
757
758 kfree(g_mgr);
759}
760
761static void firmware_driver_exit(void)
762{
763 cdev_del(&g_dev->cdev);
764 device_destroy(&firmware_class, g_dev->dev_no);
765 class_unregister(&firmware_class);
766 unregister_chrdev_region(g_dev->dev_no, 1);
767 kfree(g_dev);
768}
769
770static int __init firmware_module_init(void)
771{
772 int ret = -1;
773
774 ret = firmware_driver_init();
775 if (ret) {
776 pr_info("Error %d firmware driver init fail.\n", ret);
777 goto err;
778 }
779
780 ret = firmware_mgr_init();
781 if (ret) {
782 pr_info("Error %d firmware mgr init fail.\n", ret);
783 goto err;
784 }
785
786 ret = firmware_pre_load();
787 if (ret) {
788 pr_info("Error %d firmware pre load fail.\n", ret);
789 goto err;
790 }
791err:
792 return ret;
793}
794
795static void __exit firmware_module_exit(void)
796{
797 firmware_info_clean();
798 firmware_driver_exit();
799 pr_info("Firmware driver cleaned up.\n");
800}
801
802module_param(debug, uint, 0664);
803
804module_init(firmware_module_init);
805module_exit(firmware_module_exit);
806
807MODULE_LICENSE("GPL");
808MODULE_AUTHOR("Nanxin Qin <nanxin.qin@amlogic.com>");
809