xref: /OK3568_Linux_fs/u-boot/arch/arm/mach-rockchip/rk_meta.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /* SPDX-License-Identifier:     GPL-2.0+ */
2 /*
3  * (C) Copyright 2022 Rockchip Electronics Co., Ltd
4  *
5  */
6 
7 #include <common.h>
8 #include <boot_rkimg.h>
9 #include <crc.h>
10 #include <errno.h>
11 #include <fdt_support.h>
12 #include <image.h>
13 #include <misc.h>
14 #include <spl.h>
15 #include <asm/arch/rk_meta.h>
16 
17 static char *cmdline;
18 
19 #if (IS_ENABLED(CONFIG_ROCKCHIP_RV1106))
20 #define COMPRESS_LOAD_ADDR 0xa0000
21 #else
22 #error	"Please Define COMPRESS_LOAD_ADDR !!!"
23 #endif
24 
rk_meta_process(void)25 __weak void rk_meta_process(void) { }
26 
rk_meta_iq_decom(unsigned long dst,unsigned long src,unsigned long src_len,u64 * len)27 static int rk_meta_iq_decom(unsigned long dst, unsigned long src,
28 			    unsigned long src_len, u64 *len)
29 {
30 	int ret;
31 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS)
32 
33 	ret = misc_decompress_process(dst, src, src_len, DECOM_GZIP, true, len, 0);
34 	misc_decompress_sync(IH_COMP_GZIP);
35 #else
36 	ret = gunzip((void *)&dst, ALIGN(len, FIT_MAX_SPL_IMAGE_SZ),
37 		     (void *)&src, (void *)len);
38 #endif
39 
40 	return ret;
41 }
42 
spl_load_meta(struct spl_image_info * spl_image,struct spl_load_info * info)43 int spl_load_meta(struct spl_image_info *spl_image, struct spl_load_info *info)
44 {
45 	const char *part_name = PART_META;
46 	disk_partition_t part_info;
47 	struct meta_head meta;
48 	struct meta_head *meta_p;
49 	struct cmdline_info *cmd;
50 	ulong sector;
51 	char *data;
52 	u64 len;
53 	int meta_iq_item_size = 0;
54 
55 	if (part_get_info_by_name(info->dev, part_name, &part_info) <= 0) {
56 		debug("%s: no partition\n", __func__);
57 		return -EINVAL;
58 	}
59 	sector = part_info.start;
60 
61 	memset(&meta, 0, sizeof(struct meta_head));
62 	if (info->read(info, sector, 1, &meta) != 1) {
63 		debug("%s: Failed to read header\n", __func__);
64 		return -EIO;
65 	}
66 
67 	if (meta.tag != RK_META) {
68 		debug("Invalid meta tag is %x.\n", meta.tag);
69 		return -EINVAL;
70 	}
71 
72 	if (meta.crc32 != crc32(0, (const unsigned char *)&meta, sizeof(struct meta_head) - 4 - 4)) {
73 		debug("Invalid meta crc32.\n");
74 		return -EINVAL;
75 	}
76 
77 	data = (char *)meta.load;
78 	printf("Meta: 0x%08x - 0x%08x\n", meta.load, meta.load + meta.size);
79 	if (info->read(info, sector, DIV_ROUND_UP(MAX_META_SEGMENT_SIZE, info->bl_len), data)
80 			!= DIV_ROUND_UP(MAX_META_SEGMENT_SIZE, info->bl_len)) {
81 		debug("%s: Failed to read header\n", __func__);
82 		return -EIO;
83 	}
84 
85 	meta_p = (struct meta_head *)meta.load;
86 
87 	cmd = (struct cmdline_info *)(meta_p->load + CMDLINE_OFFSET);
88 	if (cmd->tag == RK_CMDLINE) {
89 		if (cmd->crc32 == crc32(0, (const unsigned char *)cmd, sizeof(struct cmdline_info) - 4))
90 			cmdline = (char *)cmd->data;
91 	}
92 
93 	/* load compress data */
94 	data = (char *)COMPRESS_LOAD_ADDR;
95 	meta_iq_item_size = meta_p->iq_item_size + meta.comp_size;
96 	if (meta_p->comp_type == META_COMPRESS_TYPE_GZ) {
97 		if (info->read(info, sector + (MAX_META_SEGMENT_SIZE / info->bl_len),
98 			       DIV_ROUND_UP(meta_iq_item_size, info->bl_len), data)
99 			       != DIV_ROUND_UP(meta_iq_item_size, info->bl_len)) {
100 			printf("%s: Failed to read compress data.\n", __func__);
101 			return -EIO;
102 		}
103 
104 		memcpy((void *)(meta_p->load + SENSOR_IQ_BIN_OFFSET), data, meta_p->iq_item_size);
105 
106 		if (rk_meta_iq_decom((meta_p->load + meta_p->comp_off),
107 				     (unsigned long)(data + meta_p->comp_off -
108 							MAX_META_SEGMENT_SIZE),
109 					 meta.comp_size, &len)) {
110 			printf("%s: Failed to decompress.\n", __func__);
111 			return -EIO;
112 		}
113 
114 	} else {
115 		if (info->read(info, sector + (MAX_META_SEGMENT_SIZE / info->bl_len),
116 			       DIV_ROUND_UP(meta_iq_item_size, info->bl_len),
117 		   (void *)(meta_p->load + MAX_META_SEGMENT_SIZE))
118 		   != DIV_ROUND_UP(meta_iq_item_size, info->bl_len)) {
119 			printf("%s: Failed to read\n", __func__);
120 			return -EIO;
121 		}
122 	}
123 
124 	meta_p->meta_flags = META_READ_DONE_FLAG;
125 	flush_cache(meta_p->load, meta_p->size);
126 	rk_meta_process();
127 
128 	printf("\nMeta: ok\n");
129 	return 0;
130 }
131 
rk_meta_bootargs_append(void * fdt)132 void rk_meta_bootargs_append(void *fdt)
133 {
134 	if (!cmdline || (!fdt || fdt_check_header(fdt)))
135 		return;
136 
137 	fdt_bootargs_append(fdt, cmdline);
138 }
139