• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hi3559av100.c
3  *
4  * The board init for hisilicon
5  *
6  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
7  *
8  * This program is free software; you can redistribute  it and/or modify it
9  * under  the terms of  the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the  License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 #include "../../../lib/hw_dec/hw_decompress_v2.h"
23 #include <config.h>
24 #include <common.h>
25 #include <asm/io.h>
26 #include <asm/arch/platform.h>
27 #include <spi_flash.h>
28 #include <linux/mtd/mtd.h>
29 #include <nand.h>
30 #include <netdev.h>
31 #include <mmc.h>
32 #include <sdhci.h>
33 #include <asm/armv8/mmu.h>
34 #include <command.h>
35 #include <hicpu_common.h>
36 #include <cpu_func.h>
37 #include <asm/mach-types.h>
38 static struct mm_region hi3559av100_mem_map[] = {
39 	{
40 		.virt = 0x0UL,
41 		.phys = 0x0UL,
42 		.size = 0x40000000UL,
43 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
44 			PTE_BLOCK_NON_SHARE
45 	}, {
46 		.virt = 0x40000000UL,
47 		.phys = 0x40000000UL,
48 		.size = 0x200000000, /* PHYS_SDRAM_1_SIZE, */
49 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
50 			PTE_BLOCK_INNER_SHARE
51 	}, {
52 		/* List terminator */
53 		0,
54 	}
55 };
56 
57 struct mm_region *mem_map = hi3559av100_mem_map;
58 static int boot_media = BOOT_MEDIA_UNKNOWN;
59 
60 #if defined(CONFIG_SHOW_BOOT_PROGRESS)
show_boot_progress(int progress)61 void show_boot_progress(int progress)
62 {
63 	printf("Boot reached stage %d\n", progress);
64 }
65 #endif
66 
67 #define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF)
68 
delay(unsigned long loops)69 static inline void delay(unsigned long loops)
70 {
71 	__asm__ volatile("1:\n"
72 			"subs %0, %1, #1\n"
73 			"bne 1b" : "=r"(loops) : "0"(loops));
74 }
75 
76 /* get uboot start media. */
get_boot_media(void)77 int get_boot_media(void)
78 {
79 	return boot_media;
80 }
81 
get_text_base(void)82 int get_text_base(void)
83 {
84 	return CONFIG_SYS_TEXT_BASE;
85 }
86 
boot_flag_init(void)87 static void boot_flag_init(void)
88 {
89 	unsigned int regval, boot_mode;
90 
91 	/* get boot mode */
92 	regval = __raw_readl(SYS_CTRL_REG_BASE + REG_SYSSTAT);
93 	boot_mode = get_sys_boot_mode(regval);
94 
95 	switch (boot_mode) {
96 	/* [5:4] 00b - boot from spi device */
97 	case BOOT_FROM_SPI:
98 		/* get SPI device type, (0: SPI nor | 1: SPI nand) */
99 		if (get_spi_device_type(regval))
100 			boot_media = BOOT_MEDIA_NAND;
101 		else
102 			boot_media = BOOT_MEDIA_SPIFLASH;
103 		break;
104 	/* [5:4] 01b - boot from Nand device */
105 	case BOOT_FROM_NAND:
106 		boot_media = BOOT_MEDIA_NAND;
107 		break;
108 	/* [5:4] 10b - boot from emmc */
109 	case BOOT_FROM_EMMC:
110 		boot_media = BOOT_MEDIA_EMMC;
111 		break;
112 	/* [5:4] 11b - boot from ufs */
113 	case BOOT_FROM_UFS:
114 		boot_media = BOOT_MEDIA_UFS;
115 		break;
116 	default:
117 		boot_media = BOOT_MEDIA_UNKNOWN;
118 		break;
119 	}
120 }
121 
board_early_init_f(void)122 int board_early_init_f(void)
123 {
124 	return 0;
125 }
126 
127 #define UBOOT_DATA_ADDR     0x41000000UL
128 #define UBOOT_DATA_SIZE     0x80000UL
data_to_spiflash(void)129 int data_to_spiflash(void)
130 {
131 	static struct spi_flash *flash = NULL;
132 	void *buf = NULL;
133 	unsigned int val;
134 
135 	/* 0:bus  0:cs  1000000:max_hz  0x3:spi_mode */
136 	flash = spi_flash_probe(0, 0, 1000000, 0x3);
137 	if (!flash) {
138 		printf("Failed to initialize SPI flash\n");
139 		return -1;  /* -1:failed */
140 	}
141 	/* erase the address range. */
142 	printf("Spi flash erase...\n");
143 	val = spi_flash_erase(flash, NUM_0, UBOOT_DATA_SIZE);
144 	if (val) {
145 		printf("SPI flash sector erase failed\n");
146 		return 1; /* 1:failed */
147 	}
148 
149 	buf = map_physmem((unsigned long)UBOOT_DATA_ADDR,
150 			UBOOT_DATA_SIZE, MAP_WRBACK);
151 	if (!buf) {
152 		puts("Failed to map physical memory\n");
153 		return 1; /* 1:failed */
154 	}
155 
156 	/* copy the data from RAM to FLASH */
157 	printf("Spi flash write...\n");
158 	val = flash->write(flash, NUM_0, UBOOT_DATA_SIZE, buf);
159 	if (val) {
160 		printf("SPI flash write failed, return %u\n", val);
161 		unmap_physmem(buf, UBOOT_DATA_SIZE);
162 		return 1; /* 1:failed */
163 	}
164 
165 	unmap_physmem(buf, UBOOT_DATA_SIZE);
166 	return 0; /* 0:success */
167 }
168 
data_to_nandflash(void)169 int data_to_nandflash(void)
170 {
171 	struct mtd_info *nand_flash = NULL;
172 	void *buf = NULL;
173 	size_t length = UBOOT_DATA_SIZE;
174 	unsigned int val;
175 
176 	nand_flash = nand_info[0];
177 
178 	printf("Nand flash erase...\n");
179 	val = nand_erase(nand_flash, 0, UBOOT_DATA_SIZE);
180 	if (val) {
181 		printf("Nand flash erase failed\n");
182 		return 1;
183 	}
184 
185 	buf = map_physmem((unsigned long)UBOOT_DATA_ADDR,
186 			UBOOT_DATA_SIZE, MAP_WRBACK);
187 	if (!buf) {
188 		puts("Failed to map physical memory\n");
189 		return 1;
190 	}
191 
192 	printf("Nand flash write...\n");
193 	val = nand_write(nand_flash, 0, &length, buf);
194 	if (val) {
195 		printf("Nand flash write failed, return %u\n", val);
196 		unmap_physmem(buf, UBOOT_DATA_SIZE);
197 		return 1;
198 	}
199 	unmap_physmem(buf, UBOOT_DATA_SIZE);
200 	return 0;
201 }
202 
data_to_emmc(void)203 int data_to_emmc(void)
204 {
205 	struct mmc *mmc = find_mmc_device(0);
206 	void *buf = NULL;
207 
208 	if (!mmc)
209 		return 1;
210 
211 	(void)mmc_init(mmc);
212 
213 	buf = map_physmem((unsigned long)UBOOT_DATA_ADDR,
214 			UBOOT_DATA_SIZE, MAP_WRBACK);
215 	if (!buf) {
216 		puts("Failed to map physical memory\n");
217 		return 1;
218 	}
219 
220 	printf("MMC write...\n");
221 	blk_dwrite(mmc_get_blk_desc(mmc), 0, (UBOOT_DATA_SIZE >> NUM_9), buf);
222 	unmap_physmem(buf, UBOOT_DATA_SIZE);
223 	return 0;
224 }
save_bootdata_to_flash(void)225 int save_bootdata_to_flash(void)
226 {
227 	unsigned int sd_update_flag = 0;
228 	int ret = 0;
229 	sd_update_flag = readl(REG_BASE_SCTL + REG_SC_GEN4);
230 	if (sd_update_flag == START_MAGIC) {
231 #if defined(CONFIG_HIFMC)
232 		if (boot_media == BOOT_MEDIA_SPIFLASH) {
233 			ret = data_to_spiflash();
234 			if (ret != 0)
235 				return ret;
236 		}
237 		if (boot_media == BOOT_MEDIA_NAND) {
238 			ret = data_to_nandflash();
239 			if (ret != 0)
240 				return ret;
241 		}
242 #endif
243 #if defined(CONFIG_MMC)
244 		if (boot_media == BOOT_MEDIA_EMMC) {
245 			ret = data_to_emmc();
246 			if (ret != 0)
247 				return ret;
248 		}
249 #endif
250 
251 		printf("update success!\n");
252 	}
253 
254 	return 0;
255 }
256 
257 int auto_update_flag = 0;
258 int bare_chip_program = 0;
259 
260 #define REG_BASE_GPIO0          0x12140000
261 #define GPIO0_0_DATA_OFST       0x4
262 #define GPIO_DIR_OFST       0x400
263 
is_bare_program(void)264 int is_bare_program(void)
265 {
266 	return 1;
267 }
268 
is_auto_update(void)269 int is_auto_update(void)
270 {
271 #if (defined CONFIG_AUTO_SD_UPDATE) || (defined CONFIG_AUTO_USB_UPDATE)
272 	/* to add some judgement if neccessary */
273 	unsigned int  val[NUM_3];
274 
275 	writel(0, REG_BASE_GPIO0 + GPIO_DIR_OFST);
276 
277 	val[NUM_0] = readl(REG_BASE_GPIO0 + GPIO0_0_DATA_OFST);
278 	if (val[NUM_0])
279 		return 0;
280 
281 	udelay(10000); /* delay 10000 us */
282 	val[NUM_1] = readl(REG_BASE_GPIO0 + GPIO0_0_DATA_OFST);
283 	udelay(10000); /* delay 10000 us */
284 	val[NUM_2] = readl(REG_BASE_GPIO0 + GPIO0_0_DATA_OFST);
285 	udelay(10000); /* delay 10000 us */
286 
287 	if (val[NUM_0] == val[NUM_1] && val[NUM_1] == val[NUM_2] && val[NUM_0] == NUM_0)
288 		return 1;    /* update enable */
289 	else
290 		return 0;
291 
292 #else
293 	return 0;
294 #endif
295 }
296 
set_pcie_para_hi3559a(void)297 void set_pcie_para_hi3559a(void)
298 {
299 	int val;
300 	val = readl(SYS_CTRL_REG_BASE + SYS_SATA);
301 	if ((val & (0x3 << PCIE_MODE)) == 0) {
302 		/* X2 release phy reset */
303 		val = readl(CRG_REG_BASE + PERI_CRG98);
304 		val &= ((~(0x1 << PHY1_SRS_REQ)) & (~(0x1 << PHY0_SRS_REQ)));
305 		writel(val, CRG_REG_BASE + PERI_CRG98);
306 
307 		/* X2 select phy reset from crg */
308 		val = readl(CRG_REG_BASE + PERI_CRG98);
309 		val |= (0x1 << PHY1_SRS_REQ_SEL) | (0x1 << PHY0_SRS_REQ_SEL);
310 		writel(val, CRG_REG_BASE + PERI_CRG98);
311 		mdelay(10);  /* delay 10 ms */
312 
313 		/*
314 		 * X2 seperate_rate=1
315 		 * */
316 		writel(0x90f, MISC_REG_BASE + MISC_CTRL5);
317 		writel(0x94f, MISC_REG_BASE + MISC_CTRL5);
318 		writel(0x90f, MISC_REG_BASE + MISC_CTRL5);
319 		writel(0x0, MISC_REG_BASE + MISC_CTRL5);
320 		writel(0x92f, MISC_REG_BASE + MISC_CTRL5);
321 		writel(0x96f, MISC_REG_BASE + MISC_CTRL5);
322 		writel(0x92f, MISC_REG_BASE + MISC_CTRL5);
323 		writel(0x0, MISC_REG_BASE + MISC_CTRL5);
324 		mdelay(10); /* delay 10 ms */
325 
326 		/*
327 		 * X2 split_cp_dis
328 		 * */
329 		writel(0xd11, MISC_REG_BASE + MISC_CTRL5);
330 		writel(0xd51, MISC_REG_BASE + MISC_CTRL5);
331 		writel(0xd11, MISC_REG_BASE + MISC_CTRL5);
332 		writel(0x0, MISC_REG_BASE + MISC_CTRL5);
333 		writel(0xd31, MISC_REG_BASE + MISC_CTRL5);
334 		writel(0xd71, MISC_REG_BASE + MISC_CTRL5);
335 		writel(0xd31, MISC_REG_BASE + MISC_CTRL5);
336 		writel(0x0, MISC_REG_BASE + MISC_CTRL5);
337 		mdelay(10); /* delay 10 ms */
338 	} else {
339 		/* X1 release phy reset */
340 		val = readl(CRG_REG_BASE + PERI_CRG98);
341 		val &= ~(0x1 << PHY0_SRS_REQ);
342 		writel(val, CRG_REG_BASE + PERI_CRG98);
343 
344 		/* X1 select phy reset from crg */
345 		val = readl(CRG_REG_BASE + PERI_CRG98);
346 		val |= (0x1 << PHY0_SRS_REQ_SEL);
347 		writel(val, CRG_REG_BASE + PERI_CRG98);
348 		mdelay(10); /* delay 10 ms */
349 
350 		/*
351 		 * X1 seperate_rate=1
352 		 * */
353 		writel(0x90f, MISC_REG_BASE + MISC_CTRL5);
354 		writel(0x94f, MISC_REG_BASE + MISC_CTRL5);
355 		writel(0x90f, MISC_REG_BASE + MISC_CTRL5);
356 		writel(0x0, MISC_REG_BASE + MISC_CTRL5);
357 		mdelay(10); /* delay 10 ms */
358 
359 		/*
360 		 * X1 split_cp_dis
361 		 * */
362 		writel(0xd11, MISC_REG_BASE + MISC_CTRL5);
363 		writel(0xd51, MISC_REG_BASE + MISC_CTRL5);
364 		writel(0xd11, MISC_REG_BASE + MISC_CTRL5);
365 		writel(0x0, MISC_REG_BASE + MISC_CTRL5);
366 		mdelay(10); /* delay 10 ms */
367 	};
368 }
369 
misc_init_r(void)370 int misc_init_r(void)
371 {
372 #ifdef CONFIG_RANDOM_ETHADDR
373 	random_init_r();
374 #endif
375 	env_set("verify", "n");
376 
377 #if (CONFIG_AUTO_UPDATE == 1)
378 	/* auto update flag */
379 	if (is_auto_update())
380 		auto_update_flag = 1;
381 	else
382 		auto_update_flag = 0;
383 
384 	/* bare chip program flag */
385 	if (is_bare_program())
386 		bare_chip_program = 1;
387 	else
388 		bare_chip_program = 0;
389 
390 #ifdef CFG_MMU_HANDLEOK
391 	dcache_stop();
392 #endif
393 
394 #ifdef CFG_MMU_HANDLEOK
395 	dcache_start();
396 #endif
397 
398 #endif /* CONFIG_AUTO_UPDATE */
399 
400 #if (CONFIG_AUTO_UPDATE == 1)
401 	if (auto_update_flag)
402 		do_auto_update();
403 	if (bare_chip_program && !auto_update_flag)
404 		save_bootdata_to_flash();
405 #endif /* CONFIG_AUTO_UPDATE */
406 	set_pcie_para_hi3559a();
407 	return 0;
408 }
409 
board_init(void)410 int board_init(void)
411 {
412 	DECLARE_GLOBAL_DATA_PTR;
413 
414 	gd->bd->bi_arch_number = MACH_TYPE_HI3559AV100;
415 	gd->bd->bi_boot_params = CFG_BOOT_PARAMS;
416 
417 	boot_flag_init();
418 
419 	return 0;
420 }
421 
dram_init(void)422 int dram_init(void)
423 {
424 	DECLARE_GLOBAL_DATA_PTR;
425 
426 	gd->ram_size = PHYS_SDRAM_1_SIZE;
427 	return 0;
428 }
429 
reset_cpu(ulong addr)430 void reset_cpu(ulong addr)
431 {
432 	/* 0x12345678:writing any value will cause a reset. */
433 	writel(0x12345678, REG_BASE_SCTL + REG_SC_SYSRES);
434 	while (1);
435 }
436 
timer_init(void)437 int timer_init(void)
438 {
439 	/*
440 	 * Under uboot, 0xffffffff is set to load register,
441 	 * timer_clk equals BUSCLK/2/256.
442 	 * e.g. BUSCLK equals 50M, it will roll back after 0xffffffff/timer_clk
443 	 * 43980s equals 12hours
444 	 */
445 	__raw_writel(0, CFG_TIMERBASE + REG_TIMER_CONTROL);
446 	__raw_writel(~0, CFG_TIMERBASE + REG_TIMER_RELOAD);
447 
448 	/* 32 bit, periodic */
449 	__raw_writel(CFG_TIMER_CTRL, CFG_TIMERBASE + REG_TIMER_CONTROL);
450 
451 	return 0;
452 }
453 
board_eth_init(bd_t * bis)454 int board_eth_init(bd_t *bis)
455 {
456 	int rc = 0;
457 
458 #ifdef CONFIG_HIGMACV300_ETH
459 	rc = higmac_initialize(bis);
460 #endif
461 	return rc;
462 }
463 
464 
465 #ifdef CONFIG_GENERIC_MMC
board_mmc_init(bd_t * bis)466 int board_mmc_init(bd_t *bis)
467 {
468 	int ret = 0;
469 	int dev_num = 0;
470 
471 #ifdef CONFIG_MMC_PHY
472 	mmc_phy_init();
473 #endif
474 
475 #ifdef CONFIG_EMMC
476 	ret = hisi_sdhci_add_port(0, EMMC_BASE_REG, MMC_TYPE_MMC);
477 	if (!ret) {
478 		ret = hisi_mmc_init(dev_num);
479 		if (ret)
480 			printf("No EMMC device found !\n");
481 	}
482 	dev_num++;
483 #endif
484 
485 #ifdef CONFIG_AUTO_SD_UPDATE
486 	if (is_auto_update()) {
487 		ret = hisi_sdhci_add_port(1, SDIO0_BASE_REG, MMC_TYPE_SD);
488 		if (ret)
489 			return ret;
490 
491 		ret = hisi_mmc_init(dev_num);
492 		if (ret)
493 			printf("No SD device found !\n");
494 	}
495 #endif
496 
497 	return ret;
498 }
499 #endif
500 
501 #define PMC_REG_BASE     0x180c0000
502 #define SENSOR_HUB_CRG_0 0x18020000
503 #define SENSOR_HUB_CRG_1 0x18020004
504 #define SENSOR_HUB_CRG_2 0x18020008
505 #define SENSOR_HUB_CRG_3 0x1802000C
506 #define SENSOR_HUB_CRG_4 0x18020010
507 #define SENSOR_HUB_CRG_11 0x1802002c
508 
start_m7(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])509 static int start_m7(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
510 {
511 	writel(0x5a5aabcd, PMC_REG_BASE + 0x58);
512 	writel(0x0, 0x180C005c);
513 	printf("cortex-M7 is running!\n");
514 	return 0;
515 }
516 
config_m7(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])517 static int config_m7(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
518 {
519 	writel(0x069E36E3, SENSOR_HUB_CRG_2);
520 	writel(0x00810001, SENSOR_HUB_CRG_1);
521 	/* wait for pll lock */
522 	while (!(readl(SENSOR_HUB_CRG_3) & 0x1));
523 	writel(0x03, SENSOR_HUB_CRG_0);
524 	writel(0x1110, SENSOR_HUB_CRG_4);
525 	writel(0x01, SENSOR_HUB_CRG_11);
526 	printf("cortex-M7 is configed!\n");
527 	return 0;
528 }
529 
530 U_BOOT_CMD(
531 		go_m7, CONFIG_SYS_MAXARGS, 1,   start_m7,
532 		"start cortex-M7",
533 		""
534 		""
535 	  );
536 
537 U_BOOT_CMD(
538 		config_m7, CONFIG_SYS_MAXARGS, 1,   config_m7,
539 		"config cortex-M7 by default configs",
540 		""
541 		""
542 	  );
543 
start_a53up(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])544 int start_a53up(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
545 {
546 	unsigned long addr;
547 
548 	if (argc < NUM_2)
549 		return CMD_RET_USAGE;
550 	addr = simple_strtoul(argv[NUM_1], NULL, 16); /* 16:base */
551 	printf("## Starting A53UP at 0x%016lX ...\n", addr);
552 
553 	writel(addr >> NUM_2, REG_PERI_CPU_RVBARADDR_A53UP);
554 
555 	/* start up a53 */
556 	{
557 		unsigned int reg;
558 		unsigned int jump_cmd = 0xea000004;
559 		unsigned int warm_reset_cmd[] = {
560 			0xe3a03000, 0xe3413d83, 0xf57ff06f, 0xf57ff04f,
561 			0xee1c3f50, 0xe3833003, 0xee0c3f50, 0xf57ff06f,
562 			0xe320f003, 0xeafffffe, 0x0
563 		};
564 		volatile uint32_t *p = (volatile uint32_t *)0x18;
565 		unsigned int *cmd = warm_reset_cmd;
566 
567 		*((volatile uint32_t *)0) = jump_cmd;
568 		while (*cmd)
569 			*p++ = *cmd++;
570 		writel((addr >> NUM_2) & 0xffffffff, REG_PERI_CPU_RVBARADDR_A53UP);
571 		flush_dcache_all();
572 		reg = readl(CRG_REG_BASE + REG_CRG_CLUSTER0_CLK_RST);
573 		reg |= CLUSTER2_GLB_CKEN;
574 		reg &= ~CLUSTER2_GLB_SRST_REQ;
575 		writel(reg, CRG_REG_BASE + REG_CRG_CLUSTER0_CLK_RST);
576 	}
577 	return 0;
578 }
579 
580 U_BOOT_CMD(
581 		go_a53up, CONFIG_SYS_MAXARGS, 1,  start_a53up,
582 		"start a53-up at address 'addr'",
583 		"addr [arg ...]\n    - start a53 application at address 'addr'\n"
584 		"      passing 'arg' as arguments"
585 	  );
586 
587 #define HEAD_SIZE   0X10
588 #define COMPRESSED_SIZE_OFFSET      0X0
589 #define UNCOMPRESSED_SIZE_OFFSET    0X4
590 
591 #define HEAD_MAGIC_NUM0 0X70697A67 /* 'g''z''i''p' */
592 #define HEAD_MAGIC_NUM0_OFFSET 0X8
593 #define HEAD_MAGIC_NUM1 0X64616568 /* 'h''e''a''d' */
594 #define HEAD_MAGIC_NUM1_OFFSET 0XC
595 
do_ugzip(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])596 int do_ugzip(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
597 {
598 	unsigned long src;
599 	unsigned long dst;
600 	int size_comparessed;
601 	int size_uncomparessed;
602 	unsigned int magic_num0;
603 	unsigned int magic_num1;
604 	int ret;
605 
606 	/* need two arguments */
607 	if (argc != NUM_3) {
608 		cmd_usage(cmdtp);
609 		return 0;
610 	}
611 	src = simple_strtoul(argv[NUM_1], NULL, 16); /* 16:base */
612 	dst = simple_strtoul(argv[NUM_2], NULL, 16); /* 16:base */
613 
614 	if (src & 0XF) {
615 		printf("ERR:\n    src[0X%08lx] is not 16Byte-aligned!\n", src);
616 		return 0;
617 	}
618 	if (dst & 0XF) {
619 		printf("ERR:\n    dst[0X%08lx] is not 16Byte-aligned!\n", dst);
620 		return 0;
621 	}
622 
623 	magic_num0 = *(unsigned int *)(src + HEAD_MAGIC_NUM0_OFFSET);
624 	magic_num1 = *(unsigned int *)(src + HEAD_MAGIC_NUM1_OFFSET);
625 	if ((magic_num0 != HEAD_MAGIC_NUM0) || (magic_num1 != HEAD_MAGIC_NUM1)) {
626 		printf("ERR:\n    The magic numbers are not correct!\n"\
627 				"    Please check the source data!\n");
628 		return 0;
629 	}
630 	size_comparessed = *(int *)(src + COMPRESSED_SIZE_OFFSET);
631 	size_uncomparessed = *(int *)(src + UNCOMPRESSED_SIZE_OFFSET);
632 	/* use direct address mode */
633 	hw_dec_type = 0;
634 	__asm_flush_dcache_all();
635 	__asm_flush_l3_dcache();
636 	/* init hw decompress IP */
637 	hw_dec_init();
638 
639 	/* start decompress. 32:high bit */
640 	ret = hw_dec_decompress((unsigned char *)(uintptr_t)((dst >> 32) & 0xffffffff),
641 			(unsigned char *)(uintptr_t)(dst & 0xffffffff), &size_uncomparessed,
642 			(unsigned char *)(uintptr_t)(src >> 32), /* high 32 bit */
643 			(unsigned char *)(uintptr_t)(src + HEAD_SIZE), size_comparessed, NULL);
644 	if (ret)
645 		printf("ERR:\n    decompress fail!\n");
646 	else
647 		printf("decompress ok!\n");
648 
649 	/* uinit hw decompress IP */
650 	hw_dec_uinit();
651 
652 	return 0;
653 }
654 
655 U_BOOT_CMD(
656 		ugzip, CONFIG_SYS_MAXARGS, 1,  do_ugzip,
657 		"Compress gzipfile with hardware IP",
658 		"ugzip <src> <dst>\n"
659 		"src and dst must be 16Byte-aligned"
660 	  );
661