GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,15 @@
if TARGET_HIKEY
config SYS_BOARD
default "hikey"
config SYS_VENDOR
default "hisilicon"
config SYS_SOC
default "hi6220"
config SYS_CONFIG_NAME
default "hikey"
endif
@@ -0,0 +1,6 @@
HIKEY BOARD
M: Peter Griffin <peter.griffin@linaro.org>
S: Maintained
F: board/hisilicon/hikey
F: include/configs/hikey.h
F: configs/hikey_defconfig
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2000-2004
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
obj-y := hikey.o
@@ -0,0 +1,227 @@
Introduction
============
HiKey is the first certified 96Boards Consumer Edition board. The board/SoC has: -
* HiSilicon Kirin 6220 eight-core ARM Cortex-A53 64-bit SoC running at 1.2GHz.
* ARM Mali 450-MP4 GPU
* 1GB 800MHz LPDDR3 DRAM
* 4GB eMMC Flash Storage
* microSD
* 802.11a/b/g/n WiFi, Bluetooth
The HiKey schematic can be found here: -
https://github.com/96boards/documentation/blob/master/consumer/hikey/hikey620/hardware-docs/HiKey_schematics_LeMaker_version_Rev_A1.pdf
The SoC datasheet can be found here: -
https://github.com/96boards/documentation/blob/master/consumer/hikey/hikey620/hardware-docs/Hi6220V100_Multi-Mode_Application_Processor_Function_Description.pdf
Currently the u-boot port supports: -
* USB
* eMMC
* SD card
* GPIO
The HiKey U-Boot port has been tested with l-loader, booting ATF, which then boots
U-Boot as the bl33.bin executable.
Compile from source
===================
First get all the sources
> mkdir -p ~/hikey/src ~/hikey/bin
> cd ~/hikey/src
> git clone https://github.com/96boards-hikey/edk2 -b testing/hikey960_v2.5
> git clone https://github.com/ARM-software/arm-trusted-firmware
> git clone https://github.com/96boards-hikey/l-loader -b testing/hikey960_v1.2
> git clone https://github.com/96boards-hikey/OpenPlatformPkg -b testing/hikey960_v1.3.4
> git clone https://github.com/96boards-hikey/atf-fastboot
> wget https://snapshots.linaro.org/96boards/reference-platform/components/uefi-staging/latest/hikey/release/hisi-idt.py
Get the BL30 mcuimage.bin binary. It is shipped as part of the UEFI source.
The latest version can be obtained from the OpenPlatformPkg repo.
> cp OpenPlatformPkg/Platforms/Hisilicon/HiKey/Binary/mcuimage.bin ~/hikey/bin/
Get nvme.img binary
> wget -P ~/hikey/bin https://snapshots.linaro.org/96boards/reference-platform/components/uefi-staging/latest/hikey/release/nvme.img
Compile U-Boot
==============
> cd ~/hikey/src/u-boot
> make CROSS_COMPILE=aarch64-linux-gnu- hikey_config
> make CROSS_COMPILE=aarch64-linux-gnu-
> cp u-boot.bin ~/hikey/bin
Compile ARM Trusted Firmware (ATF)
==================================
> cd ~/hikey/src/arm-trusted-firmware
> make CROSS_COMPILE=aarch64-linux-gnu- all fip \
SCP_BL2=~/hikey/bin/mcuimage.bin \
BL33=~/hikey/bin/u-boot.bin DEBUG=1 PLAT=hikey
Copy the resulting FIP binary
> cp build/hikey/debug/fip.bin ~/hikey/bin
Compile ATF Fastboot
====================
> cd ~/hikey/src/atf-fastboot
> make CROSS_COMPILE=aarch64-linux-gnu- PLAT=hikey DEBUG=1
Compile l-loader
================
> cd ~/hikey/src/l-loader
> ln -sf ~/hikey/src/arm-trusted-firmware/build/hikey/debug/bl1.bin
> ln -sf ~/hikey/src/arm-trusted-firmware/build/hikey/debug/bl2.bin
> ln -sf ~/hikey/src/atf-fastboot/build/hikey/debug/bl1.bin fastboot.bin
> make hikey PTABLE_LST=aosp-8g
Copy the resulting binaries
> cp *.img ~/hikey/bin
> cp l-loader.bin ~/hikey/bin
> cp recovery.bin ~/hikey/bin
These instructions are adapted from
https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/plat/hikey.rst
FLASHING
========
1. Connect the second jumper on J15 BOOT SEL, to go into recovery mode and flash l-loader.bin with
the hisi-idt.py utility. Then connect a USB A to B mini cable from your PC to the USB OTG port of HiKey and execute the below command.
The command below assumes HiKey enumerated as the first USB serial port
> sudo python ~/hikey/src/hisi-idt.py -d /dev/ttyUSB0 --img1 ~/hikey/bin/recovery.bin
2. Once LED 0 comes on solid, HiKey board should be detected as a fastboot device.
> sudo fastboot devices
0123456789ABCDEF fastboot
3. Flash the images
> sudo fastboot flash ptable ~/hikey/bin/prm_ptable.img
> sudo fastboot flash loader ~/hikey/bin/l-loader.bin
> sudo fastboot flash fastboot ~/hikey/bin/fip.bin
> sudo fastboot flash nvme ~/hikey/bin/nvme.img
4. Disconnect second jumper on J15 BOOT SEL, and reset the board and you will now (hopefully)
have ATF, booting u-boot from eMMC.
Note: To get USB host working, also disconnect the USB OTG cable used for flashing. Otherwise you
will get 'dwc_otg_core_host_init: Timeout!' errors.
See working boot trace below on UART3 available at Low Speed Expansion header: -
NOTICE: BL2: v1.5(debug):v1.5-694-g6d4f6aea
NOTICE: BL2: Built : 09:21:42, Aug 29 2018
INFO: BL2: Doing platform setup
INFO: ddr3 rank1 init pass
INFO: succeed to set ddrc 150mhz
INFO: ddr3 rank1 init pass
INFO: succeed to set ddrc 266mhz
INFO: ddr3 rank1 init pass
INFO: succeed to set ddrc 400mhz
INFO: ddr3 rank1 init pass
INFO: succeed to set ddrc 533mhz
INFO: ddr3 rank1 init pass
INFO: succeed to set ddrc 800mhz
INFO: Samsung DDR
INFO: ddr test value:0xa5a55a5a
INFO: BL2: TrustZone: protecting 16777216 bytes of memory at 0x3f000000
INFO: BL2: TrustZone: protecting 4194304 bytes of memory at 0x3e800000
INFO: [BDID] [fff91c18] midr: 0x410fd033
INFO: init_acpu_dvfs: pmic version 17
INFO: init_acpu_dvfs: ACPU_CHIP_MAX_FREQ=0x186a00.
INFO: acpu_dvfs_volt_init: success!
INFO: acpu_dvfs_set_freq: support freq num is 5
INFO: acpu_dvfs_set_freq: start prof is 0x4
INFO: acpu_dvfs_set_freq: magic is 0x5a5ac5c5
INFO: acpu_dvfs_set_freq: voltage:
INFO: - 0: 0x49
INFO: - 1: 0x49
INFO: - 2: 0x50
INFO: - 3: 0x60
INFO: - 4: 0x78
NOTICE: acpu_dvfs_set_freq: set acpu freq success!INFO: BL2: Loading image id 2
INFO: Loading image id=2 at address 0x1000000
INFO: Image id=2 loaded: 0x1000000 - 0x1023d00
INFO: hisi_mcu_load_image: mcu sections 0:
INFO: hisi_mcu_load_image: src = 0x1000200
INFO: hisi_mcu_load_image: dst = 0xf6000000
INFO: hisi_mcu_load_image: size = 31184
INFO: hisi_mcu_load_image: [SRC 0x1000200] 0x8000 0x3701 0x7695 0x7689
INFO: hisi_mcu_load_image: [DST 0xf6000000] 0x8000 0x3701 0x7695 0x7689
INFO: hisi_mcu_load_image: mcu sections 1:
INFO: hisi_mcu_load_image: src = 0x1007bd0
INFO: hisi_mcu_load_image: dst = 0x5e00000
INFO: hisi_mcu_load_image: size = 93828
INFO: hisi_mcu_load_image: [SRC 0x1007bd0] 0xf000b510 0x2103fb3d 0xf0004604 0xf003fb57
INFO: hisi_mcu_load_image: [DST 0x5e00000] 0xf000b510 0x2103fb3d 0xf0004604 0xf003fb57
INFO: hisi_mcu_load_image: mcu sections 2:
INFO: hisi_mcu_load_image: src = 0x101ea54
INFO: hisi_mcu_load_image: dst = 0x5e16e84
INFO: hisi_mcu_load_image: size = 15428
INFO: hisi_mcu_load_image: [SRC 0x101ea54] 0x9 0x1020640 0x10001 0x8f0d180
INFO: hisi_mcu_load_image: [DST 0x5e16e84] 0x9 0x1020640 0x10001 0x8f0d180
INFO: hisi_mcu_load_image: mcu sections 3:
INFO: hisi_mcu_load_image: src = 0x1022698
INFO: hisi_mcu_load_image: dst = 0x5e22a10
INFO: hisi_mcu_load_image: size = 3060
INFO: hisi_mcu_load_image: [SRC 0x1022698] 0x0 0x0 0x0 0x0
INFO: hisi_mcu_load_image: [DST 0x5e22a10] 0x0 0x0 0x0 0x0
INFO: hisi_mcu_load_image: mcu sections 4:
INFO: hisi_mcu_load_image: src = 0x102328c
INFO: hisi_mcu_load_image: dst = 0x5e23604
INFO: hisi_mcu_load_image: size = 2616
INFO: hisi_mcu_load_image: [SRC 0x102328c] 0xf80000a0 0x0 0xf80000ac 0x0
INFO: hisi_mcu_load_image: [DST 0x5e23604] 0xf80000a0 0x0 0xf80000ac 0x0
INFO: hisi_mcu_start_run: AO_SC_SYS_CTRL2=0
INFO: plat_hikey_bl2_handle_scp_bl2: MCU PC is at 0x42933301
INFO: plat_hikey_bl2_handle_scp_bl2: AO_SC_PERIPH_CLKSTAT4 is 0x3b018f09
WARNING: BL2: Platform setup already done!!
INFO: BL2: Loading image id 3
INFO: Loading image id=3 at address 0xf9858000
INFO: Image id=3 loaded: 0xf9858000 - 0xf9860058
INFO: BL2: Loading image id 5
INFO: Loading image id=5 at address 0x35000000
INFO: Image id=5 loaded: 0x35000000 - 0x35061cd2
NOTICE: BL2: Booting BL31
INFO: Entry point address = 0xf9858000
INFO: SPSR = 0x3cd
NOTICE: BL31: v1.5(debug):v1.5-694-g6d4f6aea
NOTICE: BL31: Built : 09:21:44, Aug 29 2018
WARNING: Using deprecated integer interrupt array in gicv2_driver_data_t
WARNING: Please migrate to using an interrupt_prop_t array
INFO: ARM GICv2 driver initialized
INFO: BL31: Initializing runtime services
INFO: BL31: cortex_a53: CPU workaround for disable_non_temporal_hint was applied
INFO: BL31: cortex_a53: CPU workaround for 843419 was applied
INFO: BL31: cortex_a53: CPU workaround for 855873 was applied
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x35000000
INFO: SPSR = 0x3c9
U-Boot 2018.09-rc1 (Aug 22 2018 - 14:55:49 +0530)hikey
DRAM: 990 MiB
HI6553 PMIC init
MMC: config_sd_carddetect: SD card present
Hisilicon DWMMC: 0, Hisilicon DWMMC: 1
Loading Environment from FAT... Unable to use mmc 1:1... Failed (-5)
In: uart@f7113000
Out: uart@f7113000
Err: uart@f7113000
Net: Net Initialization Skipped
No ethernet found.
Hit any key to stop autoboot: 0
starting USB...
USB0: scanning bus 0 for devices... 2 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
scanning usb for ethernet devices... 0 Ethernet Device(s) found
@@ -0,0 +1,42 @@
CROSS_COMPILE := aarch64-linux-gnu-
output_dir := $(PWD)/../bin
makejobs := $(shell grep '^processor' /proc/cpuinfo | sort -u | wc -l)
makethreads := $(shell dc -e "$(makejobs) 1 + p")
make_options := GCC49_AARCH64_PREFIX=$CROSS_COMPILE \
-j$(makethreads) -l$(makejobs)
BL30_HIKEY := $(output_dir)/mcuimage.bin
BL33_HIKEY := $(output_dir)/u-boot-hikey.bin
.PHONY: help
help:
@echo "**** Common Makefile ****"
@echo "example:"
@echo "make -f build-tf.mak build"
.PHONY: have-crosscompiler
have-crosscompiler:
@echo -n "Check that $(CROSS_COMPILE)gcc is available..."
@which $(CROSS_COMPILE)gcc > /dev/null ; \
if [ ! $$? -eq 0 ] ; then \
echo "ERROR: cross-compiler $(CROSS_COMPILE)gcc not in PATH=$$PATH!" ; \
echo "ABORTING." ; \
exit 1 ; \
else \
echo "OK" ;\
fi
build: have-crosscompiler FORCE
@echo "Build TF for Hikey..."
rm -rf build/
CROSS_COMPILE=$(CROSS_COMPILE) \
make all fip \
BL30=$(BL30_HIKEY) \
BL33=$(BL33_HIKEY) \
DEBUG=1 \
PLAT=hikey
@echo "Copy resulting binaries..."
cp build/hikey/debug/bl1.bin $(output_dir)/bl1-hikey.bin
cp build/hikey/debug/fip.bin $(output_dir)/fip-hikey.bin
FORCE:
@@ -0,0 +1,487 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2015 Linaro
* Peter Griffin <peter.griffin@linaro.org>
*/
#include <common.h>
#include <dm.h>
#include <dm/platform_data/serial_pl01x.h>
#include <errno.h>
#include <malloc.h>
#include <netdev.h>
#include <asm/io.h>
#include <usb.h>
#include <power/hi6553_pmic.h>
#include <asm-generic/gpio.h>
#include <asm/arch/dwmmc.h>
#include <asm/arch/gpio.h>
#include <asm/arch/periph.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/hi6220.h>
#include <asm/armv8/mmu.h>
/*TODO drop this table in favour of device tree */
static const struct hikey_gpio_platdata hi6220_gpio[] = {
{ 0, HI6220_GPIO_BASE(0)},
{ 1, HI6220_GPIO_BASE(1)},
{ 2, HI6220_GPIO_BASE(2)},
{ 3, HI6220_GPIO_BASE(3)},
{ 4, HI6220_GPIO_BASE(4)},
{ 5, HI6220_GPIO_BASE(5)},
{ 6, HI6220_GPIO_BASE(6)},
{ 7, HI6220_GPIO_BASE(7)},
{ 8, HI6220_GPIO_BASE(8)},
{ 9, HI6220_GPIO_BASE(9)},
{ 10, HI6220_GPIO_BASE(10)},
{ 11, HI6220_GPIO_BASE(11)},
{ 12, HI6220_GPIO_BASE(12)},
{ 13, HI6220_GPIO_BASE(13)},
{ 14, HI6220_GPIO_BASE(14)},
{ 15, HI6220_GPIO_BASE(15)},
{ 16, HI6220_GPIO_BASE(16)},
{ 17, HI6220_GPIO_BASE(17)},
{ 18, HI6220_GPIO_BASE(18)},
{ 19, HI6220_GPIO_BASE(19)},
};
U_BOOT_DEVICES(hi6220_gpios) = {
{ "gpio_hi6220", &hi6220_gpio[0] },
{ "gpio_hi6220", &hi6220_gpio[1] },
{ "gpio_hi6220", &hi6220_gpio[2] },
{ "gpio_hi6220", &hi6220_gpio[3] },
{ "gpio_hi6220", &hi6220_gpio[4] },
{ "gpio_hi6220", &hi6220_gpio[5] },
{ "gpio_hi6220", &hi6220_gpio[6] },
{ "gpio_hi6220", &hi6220_gpio[7] },
{ "gpio_hi6220", &hi6220_gpio[8] },
{ "gpio_hi6220", &hi6220_gpio[9] },
{ "gpio_hi6220", &hi6220_gpio[10] },
{ "gpio_hi6220", &hi6220_gpio[11] },
{ "gpio_hi6220", &hi6220_gpio[12] },
{ "gpio_hi6220", &hi6220_gpio[13] },
{ "gpio_hi6220", &hi6220_gpio[14] },
{ "gpio_hi6220", &hi6220_gpio[15] },
{ "gpio_hi6220", &hi6220_gpio[16] },
{ "gpio_hi6220", &hi6220_gpio[17] },
{ "gpio_hi6220", &hi6220_gpio[18] },
{ "gpio_hi6220", &hi6220_gpio[19] },
};
DECLARE_GLOBAL_DATA_PTR;
#if !CONFIG_IS_ENABLED(OF_CONTROL)
static const struct pl01x_serial_platdata serial_platdata = {
#if CONFIG_CONS_INDEX == 1
.base = HI6220_UART0_BASE,
#elif CONFIG_CONS_INDEX == 4
.base = HI6220_UART3_BASE,
#else
#error "Unsupported console index value."
#endif
.type = TYPE_PL011,
.clock = 19200000
};
U_BOOT_DEVICE(hikey_seriala) = {
.name = "serial_pl01x",
.platdata = &serial_platdata,
};
#endif
static struct mm_region hikey_mem_map[] = {
{
.virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
.virt = 0x80000000UL,
.phys = 0x80000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* List terminator */
0,
}
};
struct mm_region *mem_map = hikey_mem_map;
#ifdef CONFIG_BOARD_EARLY_INIT_F
int board_uart_init(void)
{
switch (CONFIG_CONS_INDEX) {
case 1:
hi6220_pinmux_config(PERIPH_ID_UART0);
break;
case 4:
hi6220_pinmux_config(PERIPH_ID_UART3);
break;
default:
debug("%s: Unsupported UART selected\n", __func__);
return -1;
}
return 0;
}
int board_early_init_f(void)
{
board_uart_init();
return 0;
}
#endif
struct peri_sc_periph_regs *peri_sc =
(struct peri_sc_periph_regs *)HI6220_PERI_BASE;
struct alwayson_sc_regs *ao_sc =
(struct alwayson_sc_regs *)ALWAYSON_CTRL_BASE;
/* status offset from enable reg */
#define STAT_EN_OFF 0x2
void hi6220_clk_enable(u32 bitfield, unsigned int *clk_base)
{
uint32_t data;
data = readl(clk_base);
data |= bitfield;
writel(bitfield, clk_base);
do {
data = readl(clk_base + STAT_EN_OFF);
} while ((data & bitfield) == 0);
}
/* status offset from disable reg */
#define STAT_DIS_OFF 0x1
void hi6220_clk_disable(u32 bitfield, unsigned int *clk_base)
{
uint32_t data;
data = readl(clk_base);
data |= bitfield;
writel(data, clk_base);
do {
data = readl(clk_base + STAT_DIS_OFF);
} while (data & bitfield);
}
#define EYE_PATTERN 0x70533483
int board_usb_init(int index, enum usb_init_type init)
{
unsigned int data;
/* enable USB clock */
hi6220_clk_enable(PERI_CLK0_USBOTG, &peri_sc->clk0_en);
/* take usb IPs out of reset */
writel(PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY |
PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K,
&peri_sc->rst0_dis);
do {
data = readl(&peri_sc->rst0_stat);
data &= PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY |
PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K;
} while (data);
/*CTRL 5*/
data = readl(&peri_sc->ctrl5);
data &= ~PERI_CTRL5_PICOPHY_BC_MODE;
data |= PERI_CTRL5_USBOTG_RES_SEL | PERI_CTRL5_PICOPHY_ACAENB;
data |= 0x300;
writel(data, &peri_sc->ctrl5);
/*CTRL 4*/
/* configure USB PHY */
data = readl(&peri_sc->ctrl4);
/* make PHY out of low power mode */
data &= ~PERI_CTRL4_PICO_SIDDQ;
data &= ~PERI_CTRL4_PICO_OGDISABLE;
data |= PERI_CTRL4_PICO_VBUSVLDEXTSEL | PERI_CTRL4_PICO_VBUSVLDEXT;
writel(data, &peri_sc->ctrl4);
writel(EYE_PATTERN, &peri_sc->ctrl8);
mdelay(5);
return 0;
}
static int config_sd_carddetect(void)
{
int ret;
/* configure GPIO8 as nopull */
writel(0, 0xf8001830);
gpio_request(8, "SD CD");
gpio_direction_input(8);
ret = gpio_get_value(8);
if (!ret) {
printf("%s: SD card present\n", __func__);
return 1;
}
printf("%s: SD card not present\n", __func__);
return 0;
}
static void mmc1_init_pll(void)
{
uint32_t data;
/* select SYSPLL as the source of MMC1 */
/* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */
writel(1 << 11 | 1 << 27, &peri_sc->clk0_sel);
do {
data = readl(&peri_sc->clk0_sel);
} while (!(data & (1 << 11)));
/* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */
writel(1 << 30, &peri_sc->clk0_sel);
do {
data = readl(&peri_sc->clk0_sel);
} while (data & (1 << 14));
hi6220_clk_enable(PERI_CLK0_MMC1, &peri_sc->clk0_en);
hi6220_clk_enable(PERI_CLK12_MMC1_SRC, &peri_sc->clk12_en);
do {
/* 1.2GHz / 50 = 24MHz */
writel(0x31 | (1 << 7), &peri_sc->clkcfg8bit2);
data = readl(&peri_sc->clkcfg8bit2);
} while ((data & 0x31) != 0x31);
}
static void mmc1_reset_clk(void)
{
unsigned int data;
/* disable mmc1 bus clock */
hi6220_clk_disable(PERI_CLK0_MMC1, &peri_sc->clk0_dis);
/* enable mmc1 bus clock */
hi6220_clk_enable(PERI_CLK0_MMC1, &peri_sc->clk0_en);
/* reset mmc1 clock domain */
writel(PERI_RST0_MMC1, &peri_sc->rst0_en);
/* bypass mmc1 clock phase */
data = readl(&peri_sc->ctrl2);
data |= 3 << 2;
writel(data, &peri_sc->ctrl2);
/* disable low power */
data = readl(&peri_sc->ctrl13);
data |= 1 << 4;
writel(data, &peri_sc->ctrl13);
do {
data = readl(&peri_sc->rst0_stat);
} while (!(data & PERI_RST0_MMC1));
/* unreset mmc1 clock domain */
writel(PERI_RST0_MMC1, &peri_sc->rst0_dis);
do {
data = readl(&peri_sc->rst0_stat);
} while (data & PERI_RST0_MMC1);
}
static void mmc0_reset_clk(void)
{
unsigned int data;
/* disable mmc0 bus clock */
hi6220_clk_disable(PERI_CLK0_MMC0, &peri_sc->clk0_dis);
/* enable mmc0 bus clock */
hi6220_clk_enable(PERI_CLK0_MMC0, &peri_sc->clk0_en);
/* reset mmc0 clock domain */
writel(PERI_RST0_MMC0, &peri_sc->rst0_en);
/* bypass mmc0 clock phase */
data = readl(&peri_sc->ctrl2);
data |= 3;
writel(data, &peri_sc->ctrl2);
/* disable low power */
data = readl(&peri_sc->ctrl13);
data |= 1 << 3;
writel(data, &peri_sc->ctrl13);
do {
data = readl(&peri_sc->rst0_stat);
} while (!(data & PERI_RST0_MMC0));
/* unreset mmc0 clock domain */
writel(PERI_RST0_MMC0, &peri_sc->rst0_dis);
do {
data = readl(&peri_sc->rst0_stat);
} while (data & PERI_RST0_MMC0);
}
/* PMU SSI is the IP that maps the external PMU hi6553 registers as IO */
static void hi6220_pmussi_init(void)
{
uint32_t data;
/* Take PMUSSI out of reset */
writel(ALWAYSON_SC_PERIPH_RST4_DIS_PRESET_PMUSSI_N,
&ao_sc->rst4_dis);
do {
data = readl(&ao_sc->rst4_stat);
} while (data & ALWAYSON_SC_PERIPH_RST4_DIS_PRESET_PMUSSI_N);
/* set PMU SSI clock latency for read operation */
data = readl(&ao_sc->mcu_subsys_ctrl3);
data &= ~ALWAYSON_SC_MCU_SUBSYS_CTRL3_RCLK_MASK;
data |= ALWAYSON_SC_MCU_SUBSYS_CTRL3_RCLK_3;
writel(data, &ao_sc->mcu_subsys_ctrl3);
/* enable PMUSSI clock */
data = ALWAYSON_SC_PERIPH_CLK5_EN_PCLK_PMUSSI_CCPU |
ALWAYSON_SC_PERIPH_CLK5_EN_PCLK_PMUSSI_MCU;
hi6220_clk_enable(data, &ao_sc->clk5_en);
/* Output high to PMIC on PWR_HOLD_GPIO0_0 */
gpio_request(0, "PWR_HOLD_GPIO0_0");
gpio_direction_output(0, 1);
}
int misc_init_r(void)
{
return 0;
}
int board_init(void)
{
return 0;
}
#ifdef CONFIG_MMC
static int init_dwmmc(void)
{
int ret = 0;
#ifdef CONFIG_MMC_DW
/* mmc0 pll is already configured by ATF */
mmc0_reset_clk();
ret = hi6220_pinmux_config(PERIPH_ID_SDMMC0);
if (ret)
printf("%s: Error configuring pinmux for eMMC (%d)\n"
, __func__, ret);
ret |= hi6220_dwmci_add_port(0, HI6220_MMC0_BASE, 8);
if (ret)
printf("%s: Error adding eMMC port (%d)\n", __func__, ret);
/* take mmc1 (sd slot) out of reset, configure clocks and pinmuxing */
mmc1_init_pll();
mmc1_reset_clk();
ret |= hi6220_pinmux_config(PERIPH_ID_SDMMC1);
if (ret)
printf("%s: Error configuring pinmux for eMMC (%d)\n"
, __func__, ret);
config_sd_carddetect();
ret |= hi6220_dwmci_add_port(1, HI6220_MMC1_BASE, 4);
if (ret)
printf("%s: Error adding SD port (%d)\n", __func__, ret);
#endif
return ret;
}
/* setup board specific PMIC */
int power_init_board(void)
{
/* init the hi6220 pmussi ip */
hi6220_pmussi_init();
power_hi6553_init((u8 *)HI6220_PMUSSI_BASE);
return 0;
}
int board_mmc_init(bd_t *bis)
{
int ret;
/* add the eMMC and sd ports */
ret = init_dwmmc();
if (ret)
debug("init_dwmmc failed\n");
return ret;
}
#endif
int dram_init(void)
{
gd->ram_size = PHYS_SDRAM_1_SIZE;
return 0;
}
int dram_init_banksize(void)
{
/*
* Reserve regions below from DT memory node (which gets generated
* by U-Boot from the dram banks in arch_fixup_fdt() before booting
* the kernel. This will then match the kernel hikey dts memory node.
*
* 0x05e0,0000 - 0x05ef,ffff: MCU firmware runtime using
* 0x05f0,1000 - 0x05f0,1fff: Reboot reason
* 0x06df,f000 - 0x06df,ffff: Mailbox message data
* 0x0740,f000 - 0x0740,ffff: MCU firmware section
* 0x21f0,0000 - 0x21ff,ffff: pstore/ramoops buffer
* 0x3e00,0000 - 0x3fff,ffff: OP-TEE
*/
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = 0x05e00000;
gd->bd->bi_dram[1].start = 0x05f00000;
gd->bd->bi_dram[1].size = 0x00001000;
gd->bd->bi_dram[2].start = 0x05f02000;
gd->bd->bi_dram[2].size = 0x00efd000;
gd->bd->bi_dram[3].start = 0x06e00000;
gd->bd->bi_dram[3].size = 0x0060f000;
gd->bd->bi_dram[4].start = 0x07410000;
gd->bd->bi_dram[4].size = 0x1aaf0000;
gd->bd->bi_dram[5].start = 0x22000000;
gd->bd->bi_dram[5].size = 0x1c000000;
return 0;
}
void reset_cpu(ulong addr)
{
writel(0x48698284, &ao_sc->stat0);
wfi();
}
@@ -0,0 +1,15 @@
if TARGET_HIKEY960
config SYS_BOARD
default "hikey960"
config SYS_VENDOR
default "hisilicon"
config SYS_SOC
default "hi3660"
config SYS_CONFIG_NAME
default "hikey960"
endif
@@ -0,0 +1,6 @@
HIKEY960 BOARD
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
S: Maintained
F: board/hisilicon/hikey960
F: include/configs/hikey960.h
F: configs/hikey960_defconfig
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0+
obj-y := hikey960.o
@@ -0,0 +1,247 @@
Introduction
============
HiKey960 is one of the 96Boards Consumer Edition board from HiSilicon.
The board/SoC has: -
* HiSilicon Kirin960 (HI3660) SoC with 4xCortex-A73 and 4xCortex-A53
* ARM Mali G71 MP8 GPU
* 3GB LPDDR4 SDRAM
* 32GB UFS Flash Storage
* microSD
* 802.11a/b/g/n WiFi, Bluetooth
More information about this board can be found in 96Boards website:
https://www.96boards.org/product/hikey960/
Currently the u-boot port supports: -
* SD card
Compile from source
===================
First get all the sources
> mkdir -p ~/hikey960/src ~/hikey960/bin
> cd ~/hikey960/src
> git clone https://github.com/ARM-software/arm-trusted-firmware
> git clone https://github.com/96boards-hikey/OpenPlatformPkg -b testing/hikey960_v1.3.4
> git clone https://github.com/96boards-hikey/l-loader -b testing/hikey960_v1.2
> wget http://snapshots.linaro.org/96boards/reference-platform/components/uefi-staging/latest/hikey960/release/config
> wget http://snapshots.linaro.org/96boards/reference-platform/components/uefi-staging/latest/hikey960/release/hisi-sec_usb_xloader.img
> wget http://snapshots.linaro.org/96boards/reference-platform/components/uefi-staging/latest/hikey960/release/hisi-sec_uce_boot.img
> wget http://snapshots.linaro.org/96boards/reference-platform/components/uefi-staging/latest/hikey960/release/sec_xloader.img
> wget http://snapshots.linaro.org/96boards/reference-platform/components/uefi-staging/latest/hikey960/release/recovery.bin
> wget http://snapshots.linaro.org/96boards/reference-platform/components/uefi-staging/latest/hikey960/release/hikey_idt
Get the SCP_BL2 lpm3.img binary. It is shipped as part of the UEFI source.
The latest version can be obtained from the OpenPlatformPkg repo.
> cp OpenPlatformPkg/Platforms/Hisilicon/HiKey960/Binary/lpm3.img ~/hikey960/bin/
Compile U-Boot
==============
> cd ~/hikey960/src/u-boot
> make CROSS_COMPILE=aarch64-linux-gnu- hikey960_defconfig
> make CROSS_COMPILE=aarch64-linux-gnu-
> cp u-boot.bin ~/hikey960/bin/
Compile ARM Trusted Firmware (ATF)
==================================
> cd ~/hikey960/src/arm-trusted-firmware
> make CROSS_COMPILE=aarch64-linux-gnu- all fip \
SCP_BL2=~/hikey960/bin/lpm3.img \
BL33=~/hikey960/bin/u-boot.bin DEBUG=1 PLAT=hikey960
Copy the resulting FIP binary
> cp build/hikey960/debug/fip.bin ~/hikey960/bin
Compile l-loader
================
> cd ~/hikey960/src/l-loader
> ln -sf ~/hikey960/src/arm-trusted-firmware/build/hikey960/debug/bl1.bin
> ln -sf ~/hikey960/src/arm-trusted-firmware/build/hikey960/debug/bl2.bin
> ln -sf ~/hikey960/src/arm-trusted-firmware/build/hikey960/debug/fip.bin
> ln -sf ~/hikey960/bin/u-boot.bin
> make hikey960 PTABLE_LST=linux-32g NS_BL1U=u-boot.bin
Copy the resulting binaries
> cp *.img ~/hikey960/bin
> cp l-loader.bin ~/hikey960/bin
These instructions are adapted from
https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/plat/hikey960.rst
Setup Console
=============
Install ser2net. Use telnet as the console since UEFI in recovery mode
output window fails to display in minicom.
> sudo apt-get install ser2net
Configure ser2net
> sudo vi /etc/ser2net.conf
Append one line for serial-over-USB in #ser2net.conf
> 2004:telnet:0:/dev/ttyUSB0:115200 8DATABITS NONE 1STOPBIT banner
Start ser2net
> sudo killall ser2net
> sudo ser2net -u
Open the console.
> telnet localhost 2004
And you could open the console remotely, too.
Flashing
========
1. Boot Hikey960 into recovery mode as per the below document:
https://github.com/96boards/documentation/blob/master/consumer/hikey/hikey960/installation/board-recovery.md
Once Hikey960 is in recovery mode, flash the recovery binary:
> cd ~/hikey960/src
> chmod +x ./hikey_idt
> sudo ./hikey_idt -c config -p /dev/ttyUSB1
Now move to the Hikey960 console and press `f` during UEFI boot. This
will allow the board to boot into fastboot mode. Once the board is in
fastboot mode, you should see the ID of the HiKey960 board using the
following command
> sudo fastboot devices
1ED3822A018E3372 fastboot
3. Flash the images
Now, the images can be flashed using fastboot:
> sudo fastboot flash ptable ~/hikey960/bin/prm_ptable.img
> sudo fastboot flash xloader ~/hikey960/bin/sec_xloader.img
> sudo fastboot flash fastboot ~/hikey960/bin/l-loader.bin
> sudo fastboot flash fip ~/hikey960/bin/fip.bin
4. Set the "Boot Mode" switch to OFF position for normal boot mode.
Then power on HiKey960
Observe the console traces using UART6 on the Low Speed Expansion header:
NOTICE: BL2: v2.1(debug):v2.1-531-g3ee48f40
NOTICE: BL2: Built : 18:15:58, Aug 2 2019
INFO: BL2: Doing platform setup
INFO: UFS LUN0 contains 1024 blocks with 4096-byte size
INFO: UFS LUN1 contains 1024 blocks with 4096-byte size
INFO: UFS LUN2 contains 2048 blocks with 4096-byte size
INFO: UFS LUN3 contains 7805952 blocks with 4096-byte size
INFO: ufs: change power mode success
INFO: BL2: Loading image id 2
INFO: Loading image id=2 at address 0x89c80000
INFO: Image id=2 loaded: 0x89c80000 - 0x89cb5088
INFO: BL2: Initiating SCP_BL2 transfer to SCP
INFO: BL2: SCP_BL2: 0x89c80000@0x35088
INFO: BL2: SCP_BL2 HEAD:
INFO: BL2: SCP_BL2 0x7000 0x179 0x159 0x149
INFO: BL2: SCP_BL2 0x189 0x18b 0x18d 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x18f
INFO: BL2: SCP_BL2 0x191 0x0 0x193 0x195
INFO: BL2: SCP_BL2 0x18fd 0x18fd 0x18fd 0x18fd
INFO: BL2: SCP_BL2 0x18fd 0x18fd 0x18fd 0x18fd
INFO: BL2: SCP_BL2 0x18fd 0x18fd 0x18fd 0x18fd
INFO: BL2: SCP_BL2 0x4d454355 0x43494741 0x424d554e 0x21215245
INFO: BL2: SCP_BL2 0x4a054904 0x42912000 0xf841bfbc 0xe7fa0b04
INFO: BL2: SCP_BL2 0xb88cf000 0x3b18 0x3d1c 0x6809493e
INFO: BL2: SCP_BL2 0x4613680a 0x201f102 0xf0002a04 0x600a804c
INFO: BL2: SCP_BL2 0x204f04f 0xf203fb02 0xf102440a 0x60100204
INFO: BL2: SCP_BL2 0x160f04f 0xf103fb01 0x68004834 0x61044408
INFO: BL2: SCP_BL2 0x61866145 0xf8c061c7 0xf8c08020 0xf8c09024
INFO: BL2: SCP_BL2 0xf8c0a028 0xf3efb02c 0xf3ef8208 0x68118309
INFO: BL2: SCP_BL2 0xf1026401 0xf0110204 0xbf070f04 0x46113220
INFO: BL2: SCP_BL2 TAIL:
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x19cad151 0x19b80040 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 0x0 0x0 0x0 0x0
INFO: BL2: SCP_BL2 transferred to SCP
INFO: start fw loading
INFO: fw load success
WARNING: BL2: Platform setup already done!!
INFO: BL2: Loading image id 3
INFO: Loading image id=3 at address 0x1ac58000
INFO: Image id=3 loaded: 0x1ac58000 - 0x1ac63024
INFO: BL2: Loading image id 5
INFO: Loading image id=5 at address 0x1ac98000
INFO: Image id=5 loaded: 0x1ac98000 - 0x1ad0819c
NOTICE: BL2: Booting BL31
INFO: Entry point address = 0x1ac58000
INFO: SPSR = 0x3cd
NOTICE: BL31: v2.1(debug):v2.1-531-g3ee48f40
NOTICE: BL31: Built : 18:16:01, Aug 2 2019
INFO: ARM GICv2 driver initialized
INFO: BL31: Initializing runtime services
INFO: BL31: cortex_a53: CPU workaround for 855873 was applied
INFO: plat_setup_psci_ops: sec_entrypoint=0x1ac580fc
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x1ac98000
INFO: SPSR = 0x3c9
U-Boot 2019.07-00628-g286f05a6fc-dirty (Aug 02 2019 - 17:14:05 +0530)
Hikey960
DRAM: 3 GiB
PSCI: v1.1
MMC: dwmmc1@ff37f000: 0
Loading Environment from EXT4... ** File not found /uboot.env **
** Unable to read "/uboot.env" from mmc0:2 **
In: serial@fff32000
Out: serial@fff32000
Err: serial@fff32000
Net: Net Initialization Skipped
No ethernet found.
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found /extlinux/extlinux.conf
Retrieving file: /extlinux/extlinux.conf
201 bytes read in 12 ms (15.6 KiB/s)
1: hikey960-kernel
Retrieving file: /Image
24689152 bytes read in 4377 ms (5.4 MiB/s)
append: earlycon=pl011,mmio32,0xfff32000 console=ttyAMA6,115200 rw root=/dev/mmcblk0p2 rot
Retrieving file: /hi3660-hikey960.dtb
35047 bytes read in 14 ms (2.4 MiB/s)
## Flattened Device Tree blob at 10000000
Booting using the fdt blob at 0x10000000
Using Device Tree in place at 0000000010000000, end 000000001000b8e6
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[ 0.000000] Linux version 5.2.0-03138-gd75da80dce39 (mani@Mani-XPS-13-9360) (gcc versi9
[ 0.000000] Machine model: HiKey960
[ 0.000000] earlycon: pl11 at MMIO32 0x00000000fff32000 (options '')
[ 0.000000] printk: bootconsole [pl11] enabled
[ 0.000000] efi: Getting EFI parameters from FDT:
@@ -0,0 +1,186 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2019 Linaro
* Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/arch/hi3660.h>
#include <asm/armv8/mmu.h>
#include <asm/psci.h>
#include <linux/arm-smccc.h>
#include <linux/psci.h>
#define PMIC_REG_TO_BUS_ADDR(x) (x << 2)
#define PMIC_VSEL_MASK 0x7
DECLARE_GLOBAL_DATA_PTR;
#if !CONFIG_IS_ENABLED(OF_CONTROL)
#include <dm/platform_data/serial_pl01x.h>
static const struct pl01x_serial_platdata serial_platdata = {
.base = HI3660_UART6_BASE,
.type = TYPE_PL011,
.clock = 19200000
};
U_BOOT_DEVICE(hikey960_serial0) = {
.name = "serial_pl01x",
.platdata = &serial_platdata,
};
#endif
static struct mm_region hikey_mem_map[] = {
{
.virt = 0x0UL, /* DDR */
.phys = 0x0UL,
.size = 0xC0000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
.virt = 0xE0000000UL, /* Peripheral block */
.phys = 0xE0000000UL,
.size = 0x20000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* List terminator */
0,
}
};
struct mm_region *mem_map = hikey_mem_map;
int board_early_init_f(void)
{
return 0;
}
int misc_init_r(void)
{
return 0;
}
int dram_init(void)
{
gd->ram_size = PHYS_SDRAM_1_SIZE;
return 0;
}
int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = gd->ram_size;
return 0;
}
void hikey960_sd_init(void)
{
u32 data;
/* Enable FPLL0 */
data = readl(SCTRL_SCFPLLCTRL0);
data |= SCTRL_SCFPLLCTRL0_FPLL0_EN;
writel(data, SCTRL_SCFPLLCTRL0);
/* Configure LDO16 */
data = readl(PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x79)) &
PMIC_VSEL_MASK;
data |= 6;
writel(data, PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x79));
data = readl(PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x78));
data |= 2;
writel(data, PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x78));
udelay(100);
/* Configure LDO9 */
data = readl(PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x6b)) &
PMIC_VSEL_MASK;
data |= 5;
writel(data, PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x6b));
data = readl(PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x6a));
data |= 2;
writel(data, PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x6a));
udelay(100);
/* GPIO CD */
writel(0, PINMUX4_SDDET);
/* SD Pinconf */
writel(15 << 4, PINCONF3_SDCLK);
writel((1 << 0) | (8 << 4), PINCONF3_SDCMD);
writel((1 << 0) | (8 << 4), PINCONF3_SDDATA0);
writel((1 << 0) | (8 << 4), PINCONF3_SDDATA1);
writel((1 << 0) | (8 << 4), PINCONF3_SDDATA2);
writel((1 << 0) | (8 << 4), PINCONF3_SDDATA3);
/* Set SD clock mux */
do {
data = readl(CRG_REG_BASE + 0xb8);
data |= ((1 << 6) | (1 << 6 << 16) | (0 << 4) | (3 << 4 << 16));
writel(data, CRG_REG_BASE + 0xb8);
data = readl(CRG_REG_BASE + 0xb8);
} while ((data & ((1 << 6) | (3 << 4))) != ((1 << 6) | (0 << 4)));
/* Take SD out of reset */
writel(1 << 18, CRG_PERRSTDIS4);
do {
data = readl(CRG_PERRSTSTAT4);
} while ((data & (1 << 18)) == (1 << 18));
/* Enable hclk_gate_sd */
data = readl(CRG_REG_BASE + 0);
data |= (1 << 30);
writel(data, CRG_REG_BASE + 0);
/* Enable clk_andgt_mmc */
data = readl(CRG_REG_BASE + 0xf4);
data |= ((1 << 3) | (1 << 3 << 16));
writel(data, CRG_REG_BASE + 0xf4);
/* Enable clk_gate_sd */
data = readl(CRG_PEREN4);
data |= (1 << 17);
writel(data, CRG_PEREN4);
do {
data = readl(CRG_PERCLKEN4);
} while ((data & (1 << 17)) != (1 << 17));
}
static void show_psci_version(void)
{
struct arm_smccc_res res;
arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
printf("PSCI: v%ld.%ld\n",
PSCI_VERSION_MAJOR(res.a0),
PSCI_VERSION_MINOR(res.a0));
}
int board_init(void)
{
/* Init SD */
hikey960_sd_init();
show_psci_version();
return 0;
}
void reset_cpu(ulong addr)
{
psci_system_reset();
}
@@ -0,0 +1,15 @@
if TARGET_POPLAR
config SYS_BOARD
default "poplar"
config SYS_VENDOR
default "hisilicon"
config SYS_SOC
default "hi3798cv200"
config SYS_CONFIG_NAME
default "poplar"
endif
@@ -0,0 +1,7 @@
Poplar BOARD
M: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
M: Shawn Guo <shawn.guo@linaro.org>
S: Maintained
F: board/hisilicon/poplar
F: include/configs/poplar.h
F: configs/poplar_defconfig
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2017 Linaro
# Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
obj-y := poplar.o
@@ -0,0 +1,288 @@
================================================================================
Board Information
================================================================================
Developed by HiSilicon, the board features the Hi3798C V200 with an
integrated quad-core 64-bit ARM Cortex A53 processor and high
performance Mali T720 GPU, making it capable of running any commercial
set-top solution based on Linux or Android. Its high performance
specification also supports a premium user experience with up to H.265
HEVC decoding of 4K video at 60 frames per second.
SOC Hisilicon Hi3798CV200
CPU Quad-core ARM Cortex-A53 64 bit
DRAM DDR3/3L/4 SDRAM interface, maximum 32-bit data width 2 GB
USB Two USB 2.0 ports One USB 3.0 ports
CONSOLE USB-micro port for console support
ETHERNET 1 GBe Ethernet
PCIE One PCIe 2.0 interfaces
JTAG 8-Pin JTAG
EXPANSION INTERFACE Linaro 96Boards Low Speed Expansion slot
DIMENSION Standard 160×120 mm 96Boards Enterprice Edition form factor
WIFI 802.11AC 2*2 with Bluetooth
CONNECTORS One connector for Smart Card One connector for TSI
================================================================================
BUILD INSTRUCTIONS
================================================================================
Note of warning:
================
U-boot has a *strong* dependency with the l-loader and the arm trusted firmware
repositories.
The boot sequence is:
l-loader --> arm_trusted_firmware --> u-boot
U-Boot needs to be aware of the BL31 runtime location and size to avoid writing
over it. Currently, BL31 is being placed below the kernel text offset (check
poplar.c) but this could change in the future.
The current version of u-boot has been tested with:
- https://github.com/Linaro/poplar-l-loader.git
commit f0988698dcc5c08bd0a8f50aa0457e138a5f438c
Author: Alex Elder <elder@linaro.org>
Date: Fri Jun 16 08:57:59 2017 -0500
l-loader: use external memory region definitions
The ARM Trusted Firmware code now has a header file that collects
all the definitions for the memory regions used for its boot stages.
Include that file where needed, and use the definitions found therein
Signed-off-by: Alex Elder <elder@linaro.org>
- https://github.com/Linaro/poplar-arm-trusted-firmware.git
commit 6ac42dd3be13c99aa8ce29a15073e2f19d935f68
Author: Alex Elder <elder@linaro.org>
Date: Fri Jun 16 09:24:50 2017 -0500
poplar: define memory regions in a separate file
Separate the definitions for memory regions used for the BL stage
images and FIP into a new file. The "l-loader" image uses knowledge
of the sizes and locations of these memory regions, and it can now
include this (external) header to get these definitions, rather than
having to make coordinated changes to both code bases.
The new file has a complete set of definitions (more than may be
required by one or the other user). It also includes a summary of
how the boot process works, and how it uses these regions.
It should now be relatively easy to adjust the sizes and locations
of these memory regions, or to add to them (e.g. for TEE).
Signed-off-by: Alex Elder <elder@linaro.org>
Compile from source:
====================
Get all the sources
> mkdir -p ~/poplar/src ~/poplar/bin
> cd ~/poplar/src
> git clone https://github.com/Linaro/poplar-l-loader.git l-loader
> git clone https://github.com/Linaro/poplar-arm-trusted-firmware.git atf
> git clone https://github.com/Linaro/poplar-u-boot.git u-boot
Make sure you are using the correct branch on each one of these repositories.
The definition of "correct" might change over time (at this moment in time this
would be the "latest" branch).
Compile U-Boot:
===============
Prerequisite:
# sudo apt-get install device-tree-compiler
> cd ~/poplar/src/u-boot
> make CROSS_COMPILE=aarch64-linux-gnu- poplar_defconfig
> make CROSS_COMPILE=aarch64-linux-gnu-
> cp u-boot.bin ~/poplar/bin
Compile ARM Trusted Firmware (ATF):
===================================
> cd ~/poplar/src/atf
> make CROSS_COMPILE=aarch64-linux-gnu- all fip \
SPD=none BL33=~/poplar/bin/u-boot.bin DEBUG=1 PLAT=poplar
Copy resulting binaries
> cp build/hi3798cv200/debug/bl1.bin ~/poplar/src/l-loader/atf/
> cp build/hi3798cv200/debug/fip.bin ~/poplar/src/l-loader/atf/
Compile l-loader:
=================
> cd ~/poplar/src/l-loader
> make clean
> make CROSS_COMPILE=arm-linux-gnueabi-
Due to BootROM requiremets, rename l-loader.bin to fastboot.bin:
> cp l-loader.bin ~/poplar/bin/fastboot.bin
================================================================================
FLASH INSTRUCTIONS
================================================================================
Two methods:
Using USB debrick support:
Copy fastboot.bin to a FAT partition on the USB drive and reboot the
poplar board while pressing S3(usb_boot).
The system will execute the new u-boot and boot into a shell which you
can then use to write to eMMC.
Using U-BOOT from shell:
1) using AXIS usb ethernet dongle and tftp
2) using FAT formated USB drive
1. TFTP (USB ethernet dongle)
=============================
Plug a USB AXIS ethernet dongle on any of the USB2 ports on the Poplar board.
Copy fastboot.bin to your tftp server.
In u-boot make sure your network is properly setup.
Then
=> tftp 0x30000000 fastboot.bin
starting USB...
USB0: USB EHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found
USB1: USB EHCI 1.00
scanning bus 1 for devices... 3 USB Device(s) found
scanning usb for storage devices... 0 Storage Device(s) found
scanning usb for ethernet devices... 1 Ethernet Device(s) found
Waiting for Ethernet connection... done.
Using asx0 device
TFTP from server 192.168.1.4; our IP address is 192.168.1.10
Filename 'poplar/fastboot.bin'.
Load address: 0x30000000
Loading: #################################################################
#################################################################
###############################################################
2 MiB/s
done
Bytes transferred = 983040 (f0000 hex)
=> mmc write 0x30000000 0 0x780
MMC write: dev # 0, block # 0, count 1920 ... 1920 blocks written: OK
=> reset
2. USING USB FAT DRIVE
=======================
Copy fastboot.bin to any partition on a FAT32 formated usb flash drive.
Enter the uboot prompt
=> fatls usb 0:2
983040 fastboot.bin
1 file(s), 0 dir(s)
=> fatload usb 0:2 0x30000000 fastboot.bin
reading fastboot.bin
983040 bytes read in 44 ms (21.3 MiB/s)
=> mmc write 0x30000000 0 0x780
MMC write: dev # 0, block # 0, count 1920 ... 1920 blocks written: OK
================================================================================
BOOT TRACE
================================================================================
Bootrom start
Boot Media: eMMC
Decrypt auxiliary code ...OK
lsadc voltage min: 000000FE, max: 000000FF, aver: 000000FE, index: 00000000
Entry boot auxiliary code
Auxiliary code - v1.00
DDR code - V1.1.2 20160205
Build: Mar 24 2016 - 17:09:44
Reg Version: v134
Reg Time: 2016/03/18 09:44:55
Reg Name: hi3798cv2dmb_hi3798cv200_ddr3_2gbyte_8bitx4_4layers.reg
Boot auxiliary code success
Bootrom success
LOADER: Switched to aarch64 mode
LOADER: Entering ARM TRUSTED FIRMWARE
LOADER: CPU0 executes at 0x000ce000
INFO: BL1: 0xe1000 - 0xe7000 [size = 24576]
NOTICE: Booting Trusted Firmware
NOTICE: BL1: v1.3(debug):v1.3-372-g1ba9c60
NOTICE: BL1: Built : 17:51:33, Apr 30 2017
INFO: BL1: RAM 0xe1000 - 0xe7000
INFO: BL1: Loading BL2
INFO: Loading image id=1 at address 0xe9000
INFO: Image id=1 loaded at address 0xe9000, size = 0x5008
NOTICE: BL1: Booting BL2
INFO: Entry point address = 0xe9000
INFO: SPSR = 0x3c5
NOTICE: BL2: v1.3(debug):v1.3-372-g1ba9c60
NOTICE: BL2: Built : 17:51:33, Apr 30 2017
INFO: BL2: Loading BL31
INFO: Loading image id=3 at address 0x129000
INFO: Image id=3 loaded at address 0x129000, size = 0x8038
INFO: BL2: Loading BL33
INFO: Loading image id=5 at address 0x37000000
INFO: Image id=5 loaded at address 0x37000000, size = 0x58f17
NOTICE: BL1: Booting BL31
INFO: Entry point address = 0x129000
INFO: SPSR = 0x3cd
INFO: Boot bl33 from 0x37000000 for 364311 Bytes
NOTICE: BL31: v1.3(debug):v1.3-372-g1ba9c60
NOTICE: BL31: Built : 17:51:33, Apr 30 2017
INFO: BL31: Initializing runtime services
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x37000000
INFO: SPSR = 0x3c9
U-Boot 2017.05-rc2-00130-gd2255b0 (Apr 30 2017 - 17:51:28 +0200)poplar
Model: HiSilicon Poplar Development Board
BOARD: Hisilicon HI3798cv200 Poplar
DRAM: 1 GiB
MMC: Hisilicon DWMMC: 0
In: serial@f8b00000
Out: serial@f8b00000
Err: serial@f8b00000
Net: Net Initialization Skipped
No ethernet found.
Hit any key to stop autoboot: 0
starting USB...
USB0: USB EHCI 1.00
scanning bus 0 for devices... 1 USB Device(s) found
USB1: USB EHCI 1.00
scanning bus 1 for devices... 4 USB Device(s) found
scanning usb for storage devices... 1 Storage Device(s) found
scanning usb for ethernet devices... 1 Ethernet Device(s) found
USB device 0:
Device 0: Vendor: SanDisk Rev: 1.00 Prod: Cruzer Blade
Type: Removable Hard Disk
Capacity: 7632.0 MB = 7.4 GB (15630336 x 512)
... is now current device
Scanning usb 0:1...
=>
@@ -0,0 +1,192 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2017 Linaro
* Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
*/
#include <dm.h>
#include <common.h>
#include <asm/io.h>
#include <dm/platform_data/serial_pl01x.h>
#include <asm/arch/hi3798cv200.h>
#include <asm/armv8/mmu.h>
DECLARE_GLOBAL_DATA_PTR;
static struct mm_region poplar_mem_map[] = {
{
.virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
.virt = 0x80000000UL,
.phys = 0x80000000UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
0,
}
};
struct mm_region *mem_map = poplar_mem_map;
#if !CONFIG_IS_ENABLED(OF_CONTROL)
static const struct pl01x_serial_platdata serial_platdata = {
.base = REG_BASE_UART0,
.type = TYPE_PL010,
.clock = 75000000,
};
U_BOOT_DEVICE(poplar_serial) = {
.name = "serial_pl01x",
.platdata = &serial_platdata,
};
#endif
int checkboard(void)
{
puts("BOARD: Hisilicon HI3798cv200 Poplar\n");
return 0;
}
void reset_cpu(ulong addr)
{
psci_system_reset();
}
int dram_init(void)
{
gd->ram_size = get_ram_size(NULL, 0x80000000);
return 0;
}
/*
* Some linux kernel versions don't use memory before its load address, so to
* be generic we just pretend it isn't there. In previous uboot versions we
* carved the space used by BL31 (runs in DDR on this platfomr) so the PSCI code
* could persist in memory and be left alone by the kernel.
*
* That led to a problem when mapping memory in older kernels. That PSCI code
* now lies in memory below the kernel load offset; it therefore won't be
* touched by the kernel, and by not specially reserving it we avoid the mapping
* problem as well.
*
*/
#define KERNEL_TEXT_OFFSET 0x00080000
int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = KERNEL_TEXT_OFFSET;
gd->bd->bi_dram[0].size = gd->ram_size - gd->bd->bi_dram[0].start;
return 0;
}
static void usb2_phy_config(void)
{
const u32 config[] = {
/* close EOP pre-emphasis. open data pre-emphasis */
0xa1001c,
/* Rcomp = 150mW, increase DC level */
0xa00607,
/* keep Rcomp working */
0xa10700,
/* Icomp = 212mW, increase current drive */
0xa00aab,
/* EMI fix: rx_active not stay 1 when error packets received */
0xa11140,
/* Comp mode select */
0xa11041,
/* adjust eye diagram */
0xa0098c,
/* adjust eye diagram */
0xa10a0a,
};
int i;
for (i = 0; i < ARRAY_SIZE(config); i++) {
writel(config[i], PERI_CTRL_USB0);
clrsetbits_le32(PERI_CTRL_USB0, BIT(21), BIT(20) | BIT(22));
udelay(20);
}
}
static void usb2_phy_init(void)
{
/* reset usb2 controller bus/utmi/roothub */
setbits_le32(PERI_CRG46, USB2_BUS_SRST_REQ | USB2_UTMI0_SRST_REQ |
USB2_HST_PHY_SYST_REQ | USB2_OTG_PHY_SYST_REQ);
udelay(200);
/* reset usb2 phy por/utmi */
setbits_le32(PERI_CRG47, USB2_PHY01_SRST_REQ | USB2_PHY01_SRST_TREQ1);
udelay(200);
/* open usb2 ref clk */
setbits_le32(PERI_CRG47, USB2_PHY01_REF_CKEN);
udelay(300);
/* cancel usb2 power on reset */
clrbits_le32(PERI_CRG47, USB2_PHY01_SRST_REQ);
udelay(500);
usb2_phy_config();
/* cancel usb2 port reset, wait comp circuit stable */
clrbits_le32(PERI_CRG47, USB2_PHY01_SRST_TREQ1);
mdelay(10);
/* open usb2 controller clk */
setbits_le32(PERI_CRG46, USB2_BUS_CKEN | USB2_OHCI48M_CKEN |
USB2_OHCI12M_CKEN | USB2_OTG_UTMI_CKEN |
USB2_HST_PHY_CKEN | USB2_UTMI0_CKEN);
udelay(200);
/* cancel usb2 control reset */
clrbits_le32(PERI_CRG46, USB2_BUS_SRST_REQ | USB2_UTMI0_SRST_REQ |
USB2_HST_PHY_SYST_REQ | USB2_OTG_PHY_SYST_REQ);
udelay(200);
}
#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
#include <env.h>
#include <usb.h>
#include <usb/dwc2_udc.h>
#include <g_dnl.h>
static struct dwc2_plat_otg_data poplar_otg_data = {
.regs_otg = HIOTG_BASE_ADDR
};
static void set_usb_to_device(void)
{
setbits_le32(PERI_CTRL_USB3, USB2_2P_CHIPID);
}
int board_usb_init(int index, enum usb_init_type init)
{
set_usb_to_device();
return dwc2_udc_probe(&poplar_otg_data);
}
int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
{
if (!env_get("serial#"))
g_dnl_set_serialnumber("0123456789POPLAR");
return 0;
}
#endif
int board_init(void)
{
usb2_phy_init();
return 0;
}