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