commit
5747ecab6c
|
@ -0,0 +1,134 @@
|
|||
|
||||
Description
|
||||
====================
|
||||
HiKey960 is one of 96boards. Hisilicon Hi3660 processor is installed on HiKey960.
|
||||
|
||||
More information are listed in [link](http://www.96boards.org/documentation/ConsumerEdition/HiKey960/README.md).
|
||||
|
||||
|
||||
How to build
|
||||
====================
|
||||
|
||||
1. Code Locations
|
||||
-----------------
|
||||
|
||||
* ARM Trusted Firmware:
|
||||
[link](https://github.com/ARM-software/arm-trusted-firmware)
|
||||
|
||||
* edk2:
|
||||
[link](https://github.com/96boards-hikey/edk2/tree/testing/hikey960_v2.5)
|
||||
|
||||
* OpenPlatformPkg:
|
||||
[link](https://github.com/96boards-hikey/OpenPlatformPkg/tree/testing/hikey960_v1.3.4)
|
||||
|
||||
* l-loader:
|
||||
[link](https://github.com/96boards-hikey/l-loader/tree/testing/hikey960_v1.2)
|
||||
|
||||
* uefi-tools:
|
||||
[link](https://github.com/96boards-hikey/uefi-tools/tree/hikey960_v1)
|
||||
|
||||
|
||||
2. Build Procedure
|
||||
------------------
|
||||
|
||||
* Fetch all the above 5 repositories into local host.
|
||||
Make all the repositories in the same ${BUILD_PATH}.
|
||||
|
||||
* Create the symbol link to OpenPlatformPkg in edk2.
|
||||
<br>`$cd ${BUILD_PATH}/edk2`</br>
|
||||
<br>`$ln -sf ../OpenPlatformPkg`</br>
|
||||
|
||||
* Prepare AARCH64 toolchain.
|
||||
|
||||
* If your hikey960 hardware is v1, update _uefi-tools/platform.config_ first. _(optional)_
|
||||
<br>__Uncomment the below sentence. Otherwise, UEFI can't output messages on serial
|
||||
console on hikey960 v1.__</br>
|
||||
<br>`BUILDFLAGS=-DSERIAL_BASE=0xFDF05000`</br>
|
||||
<br>If your hikey960 hardware is v2 or newer, nothing to do.</br>
|
||||
|
||||
* Build it as debug mode. Create script file for build.
|
||||
<br>`BUILD_OPTION=DEBUG`</br>
|
||||
<br>`export AARCH64_TOOLCHAIN=GCC48`</br>
|
||||
<br>`export UEFI_TOOLS_DIR=${BUILD_PATH}/uefi-tools`<br>
|
||||
<br>`export EDK2_DIR=${BUILD_PATH}/edk2`</br>
|
||||
<br>`EDK2_OUTPUT_DIR=${EDK2_DIR}/Build/HiKey960/${BUILD_OPTION}_${AARCH64_TOOLCHAIN}`</br>
|
||||
<br>`cd ${EDK2_DIR}`</br>
|
||||
<br>`# Build UEFI & ARM Trust Firmware`</br>
|
||||
<br>`${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware hikey960`</br>
|
||||
<br>`# Generate l-loader.bin`</br>
|
||||
<br>`cd ${BUILD_PATH}/l-loader`</br>
|
||||
<br>`ln -sf ${EDK2_OUTPUT_DIR}/FV/bl1.bin`</br>
|
||||
<br>`ln -sf ${EDK2_OUTPUT_DIR}/FV/fip.bin`</br>
|
||||
<br>`ln -sf ${EDK2_OUTPUT_DIR}/FV/BL33_AP_UEFI.fd`</br>
|
||||
<br>`python gen_loader.py -o l-loader.bin --img_bl1=bl1.bin --img_ns_bl1u=BL33_AP_UEFI.fd`</br>
|
||||
|
||||
* Generate partition table.
|
||||
<br>_Make sure that you're using the sgdisk in the l-loader directory._</br>
|
||||
<br>`$PTABLE=aosp-32g SECTOR_SIZE=4096 SGDISK=./sgdisk bash -x generate_ptable.sh`</br>
|
||||
|
||||
|
||||
3. Setup Console
|
||||
----------------
|
||||
|
||||
* Install ser2net. Use telnet as the console since UEFI will output window
|
||||
that fails to display in minicom.
|
||||
<br>`$sudo apt-get install ser2net`</br>
|
||||
|
||||
* Configure ser2net.
|
||||
<br>`$sudo vi /etc/ser2net.conf`</br>
|
||||
<br>Append one line for serial-over-USB in below.</br>
|
||||
<br>_#ser2net.conf_</br>
|
||||
<br>`2004:telnet:0:/dev/ttyUSB0:115200 8DATABITS NONE 1STOPBIT banner`</br>
|
||||
|
||||
* Open the console.
|
||||
<br>`$telnet localhost 2004`</br>
|
||||
<br>And you could open the console remotely, too.</br>
|
||||
|
||||
|
||||
4. Boot UEFI in recovery mode
|
||||
-----------------------------
|
||||
|
||||
* Fetch that are used in recovery mode. The code location is in below.
|
||||
[link](https://github.com/96boards-hikey/tools-images-hikey960)
|
||||
|
||||
* Generate l-loader.bin.
|
||||
<br>`$cd tools-images-hikey960`</br>
|
||||
<br>`$ln -sf ${BUILD_PATH}/l-loader/l-loader.bin`</br>
|
||||
|
||||
* Prepare config file.
|
||||
<br>_$vi config_</br>
|
||||
<br>_# The content of config file_</br>
|
||||
<br>`./sec_user_xloader.img 0x00020000`</br>
|
||||
<br>`./sec_uce_boot.img 0x6A908000`</br>
|
||||
<br>`./l-loader.bin 0x1AC00000`</br>
|
||||
|
||||
* Remove the modemmanager package. This package may causes hikey_idt tool failure.
|
||||
<br>`$sudo apt-get purge modemmanager`</br>
|
||||
|
||||
* Run the command to download l-loader.bin into HiKey960.
|
||||
<br>`$sudo ./hikey_idt -c config -p /dev/ttyUSB1`</br>
|
||||
|
||||
* UEFI running in recovery mode.
|
||||
<br>When prompt '.' is displayed on console, press hotkey 'f' in keyboard. Then Android fastboot app is running.</br>
|
||||
<br>The timeout of prompt '.' is 10 seconds.</br>
|
||||
|
||||
* Update images.
|
||||
<br>`$sudo fastboot flash ptable prm_ptable.img`</br>
|
||||
<br>`$sudo fastboot flash xloader sec_xloader.img`</br>
|
||||
<br>`$sudo fastboot flash fastboot l-loader.bin`</br>
|
||||
<br>`$sudo fastboot flash fip fip.bin`</br>
|
||||
<br>`$sudo fastboot flash boot boot.img`</br>
|
||||
<br>`$sudo fastboot flash cache cache.img`</br>
|
||||
<br>`$sudo fastboot flash system system.img`</br>
|
||||
<br>`$sudo fastboot flash userdata userdata.img`</br>
|
||||
|
||||
* Notice: UEFI could also boot kernel in recovery mode, but BL31 isn't loaded in
|
||||
recovery mode.
|
||||
|
||||
|
||||
5. Boot UEFI in normal mode
|
||||
-----------------------------
|
||||
|
||||
* Make sure "Boot Mode" switch is OFF for normal boot mode. Then power on HiKey960.
|
||||
|
||||
* Reference [link](https://github.com/96boards-hikey/tools-images-hikey960/blob/master/build-from-source/README-ATF-UEFI-build-from-source.md)
|
|
@ -0,0 +1,168 @@
|
|||
/*-
|
||||
* Copyright (c) 2001 David E. O'Brien
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)endian.h 8.1 (Berkeley) 6/10/93
|
||||
* $NetBSD: endian.h,v 1.7 1999/08/21 05:53:51 simonb Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Portions copyright (c) 2017, ARM Limited and Contributors.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_ENDIAN_H_
|
||||
#define _MACHINE_ENDIAN_H_
|
||||
|
||||
#include <sys/_types.h>
|
||||
|
||||
/*
|
||||
* Definitions for byte order, according to byte significance from low
|
||||
* address to high.
|
||||
*/
|
||||
#define _LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
|
||||
#define _BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
|
||||
#define _PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */
|
||||
|
||||
#define _BYTE_ORDER _LITTLE_ENDIAN
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
#define LITTLE_ENDIAN _LITTLE_ENDIAN
|
||||
#define BIG_ENDIAN _BIG_ENDIAN
|
||||
#define PDP_ENDIAN _PDP_ENDIAN
|
||||
#define BYTE_ORDER _BYTE_ORDER
|
||||
#endif
|
||||
|
||||
#define _QUAD_HIGHWORD 1
|
||||
#define _QUAD_LOWWORD 0
|
||||
#define __ntohl(x) (__bswap32(x))
|
||||
#define __ntohs(x) (__bswap16(x))
|
||||
#define __htonl(x) (__bswap32(x))
|
||||
#define __htons(x) (__bswap16(x))
|
||||
|
||||
#ifdef AARCH32
|
||||
static __inline __uint64_t
|
||||
__bswap64(__uint64_t _x)
|
||||
{
|
||||
|
||||
return ((_x >> 56) | ((_x >> 40) & 0xff00) | ((_x >> 24) & 0xff0000) |
|
||||
((_x >> 8) & 0xff000000) | ((_x << 8) & ((__uint64_t)0xff << 32)) |
|
||||
((_x << 24) & ((__uint64_t)0xff << 40)) |
|
||||
((_x << 40) & ((__uint64_t)0xff << 48)) | ((_x << 56)));
|
||||
}
|
||||
|
||||
static __inline __uint32_t
|
||||
__bswap32_var(__uint32_t v)
|
||||
{
|
||||
__uint32_t t1;
|
||||
|
||||
__asm __volatile("eor %1, %0, %0, ror #16\n"
|
||||
"bic %1, %1, #0x00ff0000\n"
|
||||
"mov %0, %0, ror #8\n"
|
||||
"eor %0, %0, %1, lsr #8\n"
|
||||
: "+r" (v), "=r" (t1));
|
||||
|
||||
return (v);
|
||||
}
|
||||
|
||||
static __inline __uint16_t
|
||||
__bswap16_var(__uint16_t v)
|
||||
{
|
||||
__uint32_t ret = v & 0xffff;
|
||||
|
||||
__asm __volatile(
|
||||
"mov %0, %0, ror #8\n"
|
||||
"orr %0, %0, %0, lsr #16\n"
|
||||
"bic %0, %0, %0, lsl #16"
|
||||
: "+r" (ret));
|
||||
|
||||
return ((__uint16_t)ret);
|
||||
}
|
||||
#elif defined AARCH64
|
||||
static __inline __uint64_t
|
||||
__bswap64(__uint64_t x)
|
||||
{
|
||||
__uint64_t ret;
|
||||
|
||||
__asm __volatile("rev %0, %1\n"
|
||||
: "=&r" (ret), "+r" (x));
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline __uint32_t
|
||||
__bswap32_var(__uint32_t v)
|
||||
{
|
||||
__uint32_t ret;
|
||||
|
||||
__asm __volatile("rev32 %x0, %x1\n"
|
||||
: "=&r" (ret), "+r" (v));
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline __uint16_t
|
||||
__bswap16_var(__uint16_t v)
|
||||
{
|
||||
__uint32_t ret;
|
||||
|
||||
__asm __volatile("rev16 %w0, %w1\n"
|
||||
: "=&r" (ret), "+r" (v));
|
||||
|
||||
return ((__uint16_t)ret);
|
||||
}
|
||||
#else
|
||||
#error "Only AArch32 or AArch64 supported"
|
||||
#endif /* AARCH32 */
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
|
||||
#define __bswap32_constant(x) \
|
||||
((((x) & 0xff000000U) >> 24) | \
|
||||
(((x) & 0x00ff0000U) >> 8) | \
|
||||
(((x) & 0x0000ff00U) << 8) | \
|
||||
(((x) & 0x000000ffU) << 24))
|
||||
|
||||
#define __bswap16_constant(x) \
|
||||
((((x) & 0xff00) >> 8) | \
|
||||
(((x) & 0x00ff) << 8))
|
||||
|
||||
#define __bswap16(x) \
|
||||
((__uint16_t)(__builtin_constant_p(x) ? \
|
||||
__bswap16_constant(x) : \
|
||||
__bswap16_var(x)))
|
||||
|
||||
#define __bswap32(x) \
|
||||
((__uint32_t)(__builtin_constant_p(x) ? \
|
||||
__bswap32_constant(x) : \
|
||||
__bswap32_var(x)))
|
||||
|
||||
#else
|
||||
#define __bswap16(x) __bswap16_var(x)
|
||||
#define __bswap32(x) __bswap32_var(x)
|
||||
|
||||
#endif /* __OPTIMIZE__ */
|
||||
#endif /* !_MACHINE_ENDIAN_H_ */
|
|
@ -0,0 +1,205 @@
|
|||
/*-
|
||||
* Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ENDIAN_H_
|
||||
#define _SYS_ENDIAN_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_types.h>
|
||||
#include <machine/endian.h>
|
||||
|
||||
#ifndef _UINT8_T_DECLARED
|
||||
typedef __uint8_t uint8_t;
|
||||
#define _UINT8_T_DECLARED
|
||||
#endif
|
||||
|
||||
#ifndef _UINT16_T_DECLARED
|
||||
typedef __uint16_t uint16_t;
|
||||
#define _UINT16_T_DECLARED
|
||||
#endif
|
||||
|
||||
#ifndef _UINT32_T_DECLARED
|
||||
typedef __uint32_t uint32_t;
|
||||
#define _UINT32_T_DECLARED
|
||||
#endif
|
||||
|
||||
#ifndef _UINT64_T_DECLARED
|
||||
typedef __uint64_t uint64_t;
|
||||
#define _UINT64_T_DECLARED
|
||||
#endif
|
||||
|
||||
/*
|
||||
* General byte order swapping functions.
|
||||
*/
|
||||
#define bswap16(x) __bswap16(x)
|
||||
#define bswap32(x) __bswap32(x)
|
||||
#define bswap64(x) __bswap64(x)
|
||||
|
||||
/*
|
||||
* Host to big endian, host to little endian, big endian to host, and little
|
||||
* endian to host byte order functions as detailed in byteorder(9).
|
||||
*/
|
||||
#if _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
#define htobe16(x) bswap16((x))
|
||||
#define htobe32(x) bswap32((x))
|
||||
#define htobe64(x) bswap64((x))
|
||||
#define htole16(x) ((uint16_t)(x))
|
||||
#define htole32(x) ((uint32_t)(x))
|
||||
#define htole64(x) ((uint64_t)(x))
|
||||
|
||||
#define be16toh(x) bswap16((x))
|
||||
#define be32toh(x) bswap32((x))
|
||||
#define be64toh(x) bswap64((x))
|
||||
#define le16toh(x) ((uint16_t)(x))
|
||||
#define le32toh(x) ((uint32_t)(x))
|
||||
#define le64toh(x) ((uint64_t)(x))
|
||||
#else /* _BYTE_ORDER != _LITTLE_ENDIAN */
|
||||
#define htobe16(x) ((uint16_t)(x))
|
||||
#define htobe32(x) ((uint32_t)(x))
|
||||
#define htobe64(x) ((uint64_t)(x))
|
||||
#define htole16(x) bswap16((x))
|
||||
#define htole32(x) bswap32((x))
|
||||
#define htole64(x) bswap64((x))
|
||||
|
||||
#define be16toh(x) ((uint16_t)(x))
|
||||
#define be32toh(x) ((uint32_t)(x))
|
||||
#define be64toh(x) ((uint64_t)(x))
|
||||
#define le16toh(x) bswap16((x))
|
||||
#define le32toh(x) bswap32((x))
|
||||
#define le64toh(x) bswap64((x))
|
||||
#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
|
||||
|
||||
/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
|
||||
|
||||
static __inline uint16_t
|
||||
be16dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return ((p[0] << 8) | p[1]);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
be32dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
be64dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4));
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
le16dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return ((p[1] << 8) | p[0]);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
le32dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
|
||||
}
|
||||
|
||||
static __inline uint64_t
|
||||
le64dec(const void *pp)
|
||||
{
|
||||
uint8_t const *p = (uint8_t const *)pp;
|
||||
|
||||
return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
be16enc(void *pp, uint16_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
p[0] = (u >> 8) & 0xff;
|
||||
p[1] = u & 0xff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
be32enc(void *pp, uint32_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
p[0] = (u >> 24) & 0xff;
|
||||
p[1] = (u >> 16) & 0xff;
|
||||
p[2] = (u >> 8) & 0xff;
|
||||
p[3] = u & 0xff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
be64enc(void *pp, uint64_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
be32enc(p, (uint32_t)(u >> 32));
|
||||
be32enc(p + 4, (uint32_t)(u & 0xffffffffU));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
le16enc(void *pp, uint16_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
p[0] = u & 0xff;
|
||||
p[1] = (u >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
le32enc(void *pp, uint32_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
p[0] = u & 0xff;
|
||||
p[1] = (u >> 8) & 0xff;
|
||||
p[2] = (u >> 16) & 0xff;
|
||||
p[3] = (u >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
le64enc(void *pp, uint64_t u)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)pp;
|
||||
|
||||
le32enc(p, (uint32_t)(u & 0xffffffffU));
|
||||
le32enc(p + 4, (uint32_t)(u >> 32));
|
||||
}
|
||||
|
||||
#endif /* _SYS_ENDIAN_H_ */
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <arm_gic.h>
|
||||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <debug.h>
|
||||
#include <mmio.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <xlat_tables.h>
|
||||
|
||||
#include "../hikey960_def.h"
|
||||
#include "../hikey960_private.h"
|
||||
|
||||
#define MAP_DDR MAP_REGION_FLAT(DDR_BASE, \
|
||||
DDR_SIZE, \
|
||||
MT_MEMORY | MT_RW | MT_NS)
|
||||
|
||||
#define MAP_DEVICE MAP_REGION_FLAT(DEVICE_BASE, \
|
||||
DEVICE_SIZE, \
|
||||
MT_DEVICE | MT_RW | MT_SECURE)
|
||||
|
||||
#define MAP_BL1_RW MAP_REGION_FLAT(BL1_RW_BASE, \
|
||||
BL1_RW_LIMIT - BL1_RW_BASE, \
|
||||
MT_MEMORY | MT_RW | MT_NS)
|
||||
|
||||
#define MAP_UFS_DATA MAP_REGION_FLAT(HIKEY960_UFS_DATA_BASE, \
|
||||
HIKEY960_UFS_DATA_SIZE, \
|
||||
MT_MEMORY | MT_RW | MT_NS)
|
||||
|
||||
#define MAP_UFS_DESC MAP_REGION_FLAT(HIKEY960_UFS_DESC_BASE, \
|
||||
HIKEY960_UFS_DESC_SIZE, \
|
||||
MT_MEMORY | MT_RW | MT_NS)
|
||||
|
||||
/*
|
||||
* Table of regions for different BL stages to map using the MMU.
|
||||
* This doesn't include Trusted RAM as the 'mem_layout' argument passed to
|
||||
* hikey960_init_mmu_elx() will give the available subset of that,
|
||||
*/
|
||||
#if IMAGE_BL1
|
||||
static const mmap_region_t hikey960_mmap[] = {
|
||||
MAP_UFS_DATA,
|
||||
MAP_BL1_RW,
|
||||
MAP_UFS_DESC,
|
||||
MAP_DEVICE,
|
||||
{0}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if IMAGE_BL2
|
||||
static const mmap_region_t hikey960_mmap[] = {
|
||||
MAP_DDR,
|
||||
MAP_DEVICE,
|
||||
{0}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if IMAGE_BL31
|
||||
static const mmap_region_t hikey960_mmap[] = {
|
||||
MAP_DEVICE,
|
||||
{0}
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro generating the code for the function setting up the pagetables as per
|
||||
* the platform memory map & initialize the mmu, for the given exception level
|
||||
*/
|
||||
#define HIKEY960_CONFIGURE_MMU_EL(_el) \
|
||||
void hikey960_init_mmu_el##_el(unsigned long total_base, \
|
||||
unsigned long total_size, \
|
||||
unsigned long ro_start, \
|
||||
unsigned long ro_limit, \
|
||||
unsigned long coh_start, \
|
||||
unsigned long coh_limit) \
|
||||
{ \
|
||||
mmap_add_region(total_base, total_base, \
|
||||
total_size, \
|
||||
MT_MEMORY | MT_RW | MT_SECURE); \
|
||||
mmap_add_region(ro_start, ro_start, \
|
||||
ro_limit - ro_start, \
|
||||
MT_MEMORY | MT_RO | MT_SECURE); \
|
||||
mmap_add_region(coh_start, coh_start, \
|
||||
coh_limit - coh_start, \
|
||||
MT_DEVICE | MT_RW | MT_SECURE); \
|
||||
mmap_add(hikey960_mmap); \
|
||||
init_xlat_tables(); \
|
||||
\
|
||||
enable_mmu_el##_el(0); \
|
||||
}
|
||||
|
||||
/* Define EL1 and EL3 variants of the function initialising the MMU */
|
||||
HIKEY960_CONFIGURE_MMU_EL(1)
|
||||
HIKEY960_CONFIGURE_MMU_EL(3)
|
||||
|
||||
unsigned long plat_get_ns_image_entrypoint(void)
|
||||
{
|
||||
return NS_BL1U_BASE;
|
||||
}
|
||||
|
||||
unsigned int plat_get_syscnt_freq2(void)
|
||||
{
|
||||
return 1920000;
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <cortex_a53.h>
|
||||
#include <cortex_a73.h>
|
||||
#include "../hikey960_def.h"
|
||||
|
||||
.globl plat_my_core_pos
|
||||
.globl platform_mem_init
|
||||
.globl plat_crash_console_init
|
||||
.globl plat_crash_console_putc
|
||||
.globl plat_report_exception
|
||||
.globl plat_reset_handler
|
||||
.globl set_retention_ticks
|
||||
.globl clr_retention_ticks
|
||||
.globl clr_ex
|
||||
.globl nop
|
||||
|
||||
func plat_my_core_pos
|
||||
mrs x0, mpidr_el1
|
||||
and x1, x0, #MPIDR_CPU_MASK
|
||||
and x0, x0, #MPIDR_CLUSTER_MASK
|
||||
add x0, x1, x0, LSR #6
|
||||
ret
|
||||
endfunc plat_my_core_pos
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* void platform_mem_init(void);
|
||||
*
|
||||
* We don't need to carry out any memory initialization
|
||||
* on HIKEY. The Secure RAM is accessible straight away.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func platform_mem_init
|
||||
ret
|
||||
endfunc platform_mem_init
|
||||
|
||||
/* ---------------------------------------------
|
||||
* int plat_crash_console_init(void)
|
||||
* Function to initialize the crash console
|
||||
* without a C Runtime to print crash report.
|
||||
* Clobber list : x0, x1, x2
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_init
|
||||
mov_imm x0, CRASH_CONSOLE_BASE
|
||||
mov_imm x1, PL011_UART_CLK_IN_HZ
|
||||
mov_imm x2, PL011_BAUDRATE
|
||||
b console_core_init
|
||||
endfunc plat_crash_console_init
|
||||
|
||||
/* ---------------------------------------------
|
||||
* int plat_crash_console_putc(int c)
|
||||
* Function to print a character on the crash
|
||||
* console without a C Runtime.
|
||||
* Clobber list : x1, x2
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
func plat_crash_console_putc
|
||||
mov_imm x1, CRASH_CONSOLE_BASE
|
||||
b console_core_putc
|
||||
endfunc plat_crash_console_putc
|
||||
|
||||
/* ---------------------------------------------
|
||||
* void plat_report_exception(unsigned int type)
|
||||
* Function to report an unhandled exception
|
||||
* with platform-specific means.
|
||||
* On HIKEY platform, it updates the LEDs
|
||||
* to indicate where we are
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
func plat_report_exception
|
||||
mov x8, x30
|
||||
|
||||
/* Turn on LED according to x0 (0 -- f) */
|
||||
ldr x2, =0xf7020000
|
||||
and x1, x0, #1
|
||||
str w1, [x2, #4]
|
||||
and x1, x0, #2
|
||||
str w1, [x2, #8]
|
||||
and x1, x0, #4
|
||||
str w1, [x2, #16]
|
||||
and x1, x0, #8
|
||||
str w1, [x2, #32]
|
||||
|
||||
mrs x2, currentel
|
||||
and x2, x2, #0x0c
|
||||
/* Check EL1 */
|
||||
cmp x2, #0x04
|
||||
beq plat_report_el1
|
||||
|
||||
adr x4, plat_err_str
|
||||
bl asm_print_str
|
||||
|
||||
adr x4, esr_el3_str
|
||||
bl asm_print_str
|
||||
|
||||
mrs x4, esr_el3
|
||||
bl asm_print_hex
|
||||
|
||||
adr x4, elr_el3_str
|
||||
bl asm_print_str
|
||||
|
||||
mrs x4, elr_el3
|
||||
bl asm_print_hex
|
||||
b plat_report_end
|
||||
|
||||
plat_report_el1:
|
||||
adr x4, plat_err_str
|
||||
bl asm_print_str
|
||||
|
||||
adr x4, esr_el1_str
|
||||
bl asm_print_str
|
||||
|
||||
mrs x4, esr_el1
|
||||
bl asm_print_hex
|
||||
|
||||
adr x4, elr_el1_str
|
||||
bl asm_print_str
|
||||
|
||||
mrs x4, elr_el1
|
||||
bl asm_print_hex
|
||||
plat_report_end:
|
||||
mov x30, x8
|
||||
ret
|
||||
endfunc plat_report_exception
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* void plat_reset_handler(void);
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func plat_reset_handler
|
||||
ret
|
||||
endfunc plat_reset_handler
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* void set_retention_ticks(unsigned int val);
|
||||
* Clobber list : x0
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func set_retention_ticks
|
||||
mrs x0, CPUECTLR_EL1
|
||||
bic x0, x0, #CPUECTLR_CPU_RET_CTRL_MASK
|
||||
orr x0, x0, #RETENTION_ENTRY_TICKS_8
|
||||
msr CPUECTLR_EL1, x0
|
||||
isb
|
||||
dsb sy
|
||||
ret
|
||||
endfunc set_retention_ticks
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* void clr_retention_ticks(unsigned int val);
|
||||
* Clobber list : x0
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func clr_retention_ticks
|
||||
mrs x0, CPUECTLR_EL1
|
||||
bic x0, x0, #CPUECTLR_CPU_RET_CTRL_MASK
|
||||
msr CPUECTLR_EL1, x0
|
||||
isb
|
||||
dsb sy
|
||||
ret
|
||||
endfunc clr_retention_ticks
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* void clrex(void);
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func clr_ex
|
||||
clrex
|
||||
ret
|
||||
endfunc clr_ex
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* void nop(void);
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func nop
|
||||
nop
|
||||
ret
|
||||
endfunc nop
|
||||
|
||||
.section .rodata.rev_err_str, "aS"
|
||||
plat_err_str:
|
||||
.asciz "\nPlatform exception reporting:"
|
||||
esr_el3_str:
|
||||
.asciz "\nESR_EL3: "
|
||||
elr_el3_str:
|
||||
.asciz "\nELR_EL3: "
|
||||
esr_el1_str:
|
||||
.asciz "\nESR_EL1: "
|
||||
elr_el1_str:
|
||||
.asciz "\nELR_EL1: "
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <hi3660.h>
|
||||
#include <mmio.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <hisi_ipc.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../../hikey960_private.h"
|
||||
|
||||
#define IPC_MBX_SOURCE_REG(m) (IPC_BASE + ((m) << 6))
|
||||
#define IPC_MBX_DSET_REG(m) (IPC_BASE + ((m) << 6) + 0x04)
|
||||
#define IPC_MBX_DCLEAR_REG(m) (IPC_BASE + ((m) << 6) + 0x08)
|
||||
#define IPC_MBX_DSTATUS_REG(m) (IPC_BASE + ((m) << 6) + 0x0C)
|
||||
#define IPC_MBX_MODE_REG(m) (IPC_BASE + ((m) << 6) + 0x10)
|
||||
#define IPC_MBX_IMASK_REG(m) (IPC_BASE + ((m) << 6) + 0x14)
|
||||
#define IPC_MBX_ICLR_REG(m) (IPC_BASE + ((m) << 6) + 0x18)
|
||||
#define IPC_MBX_SEND_REG(m) (IPC_BASE + ((m) << 6) + 0x1C)
|
||||
#define IPC_MBX_DATA_REG(m, d) (IPC_BASE + ((m) << 6) + 0x20 + \
|
||||
((d) * 4))
|
||||
#define IPC_CPU_IMST_REG(m) (IPC_BASE + ((m) << 3))
|
||||
#define IPC_LOCK_REG (IPC_BASE + 0xA00)
|
||||
#define IPC_ACK_BIT_SHIFT (1 << 7)
|
||||
#define IPC_UNLOCK_VALUE (0x1ACCE551)
|
||||
|
||||
/*********************************************************
|
||||
*bit[31:24]:0~AP
|
||||
*bit[23:16]:0x1~A15, 0x2~A7
|
||||
*bit[15:8]:0~ON, 1~OFF
|
||||
*bit[7:0]:0x3 cpu power mode
|
||||
*********************************************************/
|
||||
#define IPC_CMD_TYPE(src_obj, cluster_obj, is_off, mode) \
|
||||
((src_obj << 24) | (((cluster_obj) + 1) << 16) | (is_off << 8) | (mode))
|
||||
|
||||
/*********************************************************
|
||||
*bit[15:8]:0~no idle, 1~idle
|
||||
*bit[7:0]:cpux
|
||||
*********************************************************/
|
||||
|
||||
#define IPC_CMD_PARA(is_idle, cpu) \
|
||||
((is_idle << 8) | (cpu))
|
||||
|
||||
#define IPC_STATE_IDLE 0x10
|
||||
|
||||
enum src_id {
|
||||
SRC_IDLE = 0,
|
||||
SRC_A15 = 1 << 0,
|
||||
SRC_A7 = 1 << 1,
|
||||
SRC_IOM3 = 1 << 2,
|
||||
SRC_LPM3 = 1 << 3
|
||||
};
|
||||
|
||||
/*lpm3's mailboxs are 13~17*/
|
||||
enum lpm3_mbox_id {
|
||||
LPM3_MBX0 = 13,
|
||||
LPM3_MBX1,
|
||||
LPM3_MBX2,
|
||||
LPM3_MBX3,
|
||||
LPM3_MBX4,
|
||||
};
|
||||
|
||||
static void cpu_relax(void)
|
||||
{
|
||||
volatile int i;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
nop();
|
||||
}
|
||||
|
||||
static inline void
|
||||
hisi_ipc_clear_ack(enum src_id source, enum lpm3_mbox_id mbox)
|
||||
{
|
||||
unsigned int int_status = 0;
|
||||
|
||||
do {
|
||||
int_status = mmio_read_32(IPC_MBX_MODE_REG(mbox));
|
||||
int_status &= 0xF0;
|
||||
cpu_relax();
|
||||
} while (int_status != IPC_ACK_BIT_SHIFT);
|
||||
|
||||
mmio_write_32(IPC_MBX_ICLR_REG(mbox), source);
|
||||
}
|
||||
|
||||
static void
|
||||
hisi_ipc_send_cmd_with_ack(enum src_id source, enum lpm3_mbox_id mbox,
|
||||
unsigned int cmdtype, unsigned int cmdpara)
|
||||
{
|
||||
unsigned int regval;
|
||||
unsigned int mask;
|
||||
unsigned int state;
|
||||
|
||||
mmio_write_32(IPC_LOCK_REG, IPC_UNLOCK_VALUE);
|
||||
/* wait for idle and occupy */
|
||||
do {
|
||||
state = mmio_read_32(IPC_MBX_MODE_REG(mbox));
|
||||
if (state == IPC_STATE_IDLE) {
|
||||
mmio_write_32(IPC_MBX_SOURCE_REG(mbox), source);
|
||||
regval = mmio_read_32(IPC_MBX_SOURCE_REG(mbox));
|
||||
if (regval == source)
|
||||
break;
|
||||
}
|
||||
cpu_relax();
|
||||
|
||||
} while (1);
|
||||
|
||||
/* auto answer */
|
||||
mmio_write_32(IPC_MBX_MODE_REG(mbox), 0x1);
|
||||
|
||||
mask = (~((int)source | SRC_LPM3) & 0x3F);
|
||||
/* mask the other cpus */
|
||||
mmio_write_32(IPC_MBX_IMASK_REG(mbox), mask);
|
||||
/* set data */
|
||||
mmio_write_32(IPC_MBX_DATA_REG(mbox, 0), cmdtype);
|
||||
mmio_write_32(IPC_MBX_DATA_REG(mbox, 1), cmdpara);
|
||||
/* send cmd */
|
||||
mmio_write_32(IPC_MBX_SEND_REG(mbox), source);
|
||||
/* wait ack and clear */
|
||||
hisi_ipc_clear_ack(source, mbox);
|
||||
|
||||
/* release mailbox */
|
||||
mmio_write_32(IPC_MBX_SOURCE_REG(mbox), source);
|
||||
}
|
||||
|
||||
void hisi_ipc_pm_on_off(unsigned int core, unsigned int cluster,
|
||||
enum pm_mode mode)
|
||||
{
|
||||
unsigned int cmdtype = 0;
|
||||
unsigned int cmdpara = 0;
|
||||
enum src_id source = SRC_IDLE;
|
||||
enum lpm3_mbox_id mailbox = (enum lpm3_mbox_id)(LPM3_MBX0 + core);
|
||||
|
||||
cmdtype = IPC_CMD_TYPE(0, cluster, mode, 0x3);
|
||||
cmdpara = IPC_CMD_PARA(0, core);
|
||||
source = cluster ? SRC_A7 : SRC_A15;
|
||||
hisi_ipc_send_cmd_with_ack(source, mailbox, cmdtype, cmdpara);
|
||||
}
|
||||
|
||||
void hisi_ipc_pm_suspend(unsigned int core, unsigned int cluster,
|
||||
unsigned int affinity_level)
|
||||
{
|
||||
unsigned int cmdtype = 0;
|
||||
unsigned int cmdpara = 0;
|
||||
enum src_id source = SRC_IDLE;
|
||||
enum lpm3_mbox_id mailbox = (enum lpm3_mbox_id)(LPM3_MBX0 + core);
|
||||
|
||||
if (affinity_level == 0x3)
|
||||
cmdtype = IPC_CMD_TYPE(0, -1, 0x1, 0x3 + affinity_level);
|
||||
else
|
||||
cmdtype = IPC_CMD_TYPE(0, cluster, 0x1, 0x3 + affinity_level);
|
||||
|
||||
cmdpara = IPC_CMD_PARA(1, core);
|
||||
source = cluster ? SRC_A7 : SRC_A15;
|
||||
hisi_ipc_send_cmd_with_ack(source, mailbox, cmdtype, cmdpara);
|
||||
}
|
||||
|
||||
void hisi_ipc_psci_system_off(unsigned int core, unsigned int cluster)
|
||||
{
|
||||
unsigned int cmdtype = 0;
|
||||
unsigned int cmdpara = 0;
|
||||
enum src_id source = SRC_IDLE;
|
||||
enum lpm3_mbox_id mailbox = (enum lpm3_mbox_id)(LPM3_MBX0 + core);
|
||||
|
||||
cmdtype = IPC_CMD_TYPE(0, (0x10 - 1), 0x1, 0x0);
|
||||
cmdpara = IPC_CMD_PARA(0, 0);
|
||||
source = cluster ? SRC_A7 : SRC_A15;
|
||||
hisi_ipc_send_cmd_with_ack(source, mailbox, cmdtype, cmdpara);
|
||||
}
|
||||
|
||||
void hisi_ipc_psci_system_reset(unsigned int core, unsigned int cluster,
|
||||
unsigned int cmd_id)
|
||||
{
|
||||
unsigned int cmdtype = 0;
|
||||
unsigned int cmdpara = 0;
|
||||
enum src_id source = SRC_IDLE;
|
||||
enum lpm3_mbox_id mailbox = (enum lpm3_mbox_id)(LPM3_MBX0 + core);
|
||||
|
||||
cmdtype = IPC_CMD_TYPE(0, (0x10 - 1), 0x0, 0x0);
|
||||
cmdpara = cmd_id;
|
||||
source = cluster ? SRC_A7 : SRC_A15;
|
||||
hisi_ipc_send_cmd_with_ack(source, mailbox, cmdtype, cmdpara);
|
||||
}
|
||||
|
||||
int hisi_ipc_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
enum lpm3_mbox_id i = LPM3_MBX0;
|
||||
|
||||
mmio_write_32(IPC_LOCK_REG, IPC_UNLOCK_VALUE);
|
||||
for (i = LPM3_MBX0; i <= LPM3_MBX4; i++) {
|
||||
mmio_write_32(IPC_MBX_MODE_REG(i), 1);
|
||||
mmio_write_32(IPC_MBX_IMASK_REG(i),
|
||||
((int)SRC_IOM3 | (int)SRC_A15 | (int)SRC_A7));
|
||||
mmio_write_32(IPC_MBX_ICLR_REG(i), SRC_A7);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <mmio.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <../hikey960_def.h>
|
||||
#include <hisi_ipc.h>
|
||||
#include "hisi_pwrc.h"
|
||||
|
||||
|
||||
/* resource lock api */
|
||||
#define RES0_LOCK_BASE (SOC_PCTRL_RESOURCE0_LOCK_ADDR(PCTRL_BASE))
|
||||
#define RES1_LOCK_BASE (SOC_PCTRL_RESOURCE1_LOCK_ADDR(PCTRL_BASE))
|
||||
#define RES2_LOCK_BASE (SOC_PCTRL_RESOURCE2_LOCK_ADDR(PCTRL_BASE))
|
||||
|
||||
#define LOCK_BIT (0x1 << 28)
|
||||
#define LOCK_ID_MASK (0x7 << 29)
|
||||
#define CPUIDLE_LOCK_ID(core) (0x6 - (core))
|
||||
#define LOCK_UNLOCK_OFFSET 0x4
|
||||
#define LOCK_STAT_OFFSET 0x8
|
||||
|
||||
#define CLUSTER0_CPUS_ONLINE_MASK (0xF << 16)
|
||||
#define CLUSTER1_CPUS_ONLINE_MASK (0xF << 20)
|
||||
|
||||
/* cpu hotplug flag api */
|
||||
#define SCTRL_BASE (SOC_ACPU_SCTRL_BASE_ADDR)
|
||||
#define REG_SCBAKDATA3_OFFSET (SOC_SCTRL_SCBAKDATA3_ADDR(SCTRL_BASE))
|
||||
#define REG_SCBAKDATA8_OFFSET (SOC_SCTRL_SCBAKDATA8_ADDR(SCTRL_BASE))
|
||||
#define REG_SCBAKDATA9_OFFSET (SOC_SCTRL_SCBAKDATA9_ADDR(SCTRL_BASE))
|
||||
|
||||
#define CPUIDLE_FLAG_REG(cluster) \
|
||||
((cluster == 0) ? REG_SCBAKDATA8_OFFSET : \
|
||||
REG_SCBAKDATA9_OFFSET)
|
||||
#define CLUSTER_IDLE_BIT BIT(8)
|
||||
#define CLUSTER_IDLE_MASK (CLUSTER_IDLE_BIT | 0x0F)
|
||||
|
||||
#define AP_SUSPEND_FLAG (1 << 16)
|
||||
|
||||
#define CLUSTER_PWDN_IDLE (0<<28)
|
||||
#define CLUSTER_PWDN_HOTPLUG (1<<28)
|
||||
#define CLUSTER_PWDN_SR (2<<28)
|
||||
|
||||
#define CLUSTER0_PDC_OFFSET 0x260
|
||||
#define CLUSTER1_PDC_OFFSET 0x300
|
||||
|
||||
#define PDC_EN_OFFSET 0x0
|
||||
#define PDC_COREPWRINTEN_OFFSET 0x4
|
||||
#define PDC_COREPWRINTSTAT_OFFSET 0x8
|
||||
#define PDC_COREGICMASK_OFFSET 0xc
|
||||
#define PDC_COREPOWERUP_OFFSET 0x10
|
||||
#define PDC_COREPOWERDN_OFFSET 0x14
|
||||
#define PDC_COREPOWERSTAT_OFFSET 0x18
|
||||
|
||||
#define PDC_COREPWRSTAT_MASK (0XFFFF)
|
||||
|
||||
enum pdc_gic_mask {
|
||||
PDC_MASK_GIC_WAKE_IRQ,
|
||||
PDC_UNMASK_GIC_WAKE_IRQ
|
||||
};
|
||||
|
||||
enum pdc_finish_int_mask {
|
||||
PDC_DISABLE_FINISH_INT,
|
||||
PDC_ENABLE_FINISH_INT
|
||||
};
|
||||
|
||||
static void hisi_resource_lock(unsigned int lockid, unsigned int offset)
|
||||
{
|
||||
unsigned int lock_id = (lockid << 29);
|
||||
unsigned int lock_val = lock_id | LOCK_BIT;
|
||||
unsigned int lock_state;
|
||||
|
||||
do {
|
||||
mmio_write_32(offset, lock_val);
|
||||
lock_state = mmio_read_32(LOCK_STAT_OFFSET + (uintptr_t)offset);
|
||||
} while ((lock_state & LOCK_ID_MASK) != lock_id);
|
||||
}
|
||||
|
||||
static void hisi_resource_unlock(unsigned int lockid, unsigned int offset)
|
||||
{
|
||||
unsigned int lock_val = (lockid << 29) | LOCK_BIT;
|
||||
|
||||
mmio_write_32((LOCK_UNLOCK_OFFSET + (uintptr_t)offset), lock_val);
|
||||
}
|
||||
|
||||
|
||||
static void hisi_cpuhotplug_lock(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
unsigned int lock_id;
|
||||
|
||||
lock_id = (cluster << 2) + core;
|
||||
|
||||
hisi_resource_lock(lock_id, RES2_LOCK_BASE);
|
||||
}
|
||||
|
||||
static void hisi_cpuhotplug_unlock(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
unsigned int lock_id;
|
||||
|
||||
lock_id = (cluster << 2) + core;
|
||||
|
||||
hisi_resource_unlock(lock_id, RES2_LOCK_BASE);
|
||||
}
|
||||
|
||||
/* get the resource lock */
|
||||
void hisi_cpuidle_lock(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
unsigned int offset = (cluster == 0 ? RES0_LOCK_BASE : RES1_LOCK_BASE);
|
||||
|
||||
hisi_resource_lock(CPUIDLE_LOCK_ID(core), offset);
|
||||
}
|
||||
|
||||
/* release the resource lock */
|
||||
void hisi_cpuidle_unlock(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
unsigned int offset = (cluster == 0 ? RES0_LOCK_BASE : RES1_LOCK_BASE);
|
||||
|
||||
hisi_resource_unlock(CPUIDLE_LOCK_ID(core), offset);
|
||||
}
|
||||
|
||||
unsigned int hisi_get_cpuidle_flag(unsigned int cluster)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = mmio_read_32(CPUIDLE_FLAG_REG(cluster));
|
||||
val &= 0xF;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void hisi_set_cpuidle_flag(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
mmio_setbits_32(CPUIDLE_FLAG_REG(cluster), BIT(core));
|
||||
}
|
||||
|
||||
void hisi_clear_cpuidle_flag(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
mmio_clrbits_32(CPUIDLE_FLAG_REG(cluster), BIT(core));
|
||||
|
||||
}
|
||||
|
||||
int hisi_test_ap_suspend_flag(unsigned int cluster)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = mmio_read_32(CPUIDLE_FLAG_REG(cluster));
|
||||
val &= AP_SUSPEND_FLAG;
|
||||
return !!val;
|
||||
}
|
||||
|
||||
void hisi_set_cluster_pwdn_flag(unsigned int cluster,
|
||||
unsigned int core, unsigned int value)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
hisi_cpuhotplug_lock(cluster, core);
|
||||
|
||||
val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
|
||||
val = (value << (cluster << 1)) | (val & 0xFFFFFFF);
|
||||
mmio_write_32(REG_SCBAKDATA3_OFFSET, val);
|
||||
|
||||
hisi_cpuhotplug_unlock(cluster, core);
|
||||
}
|
||||
|
||||
unsigned int hisi_get_cpu_boot_flag(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
hisi_cpuhotplug_lock(cluster, core);
|
||||
val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
|
||||
val = val >> (16 + (cluster << 2));
|
||||
val &= 0xF;
|
||||
hisi_cpuhotplug_unlock(cluster, core);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned int hisi_test_cpu_down(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
hisi_cpuhotplug_lock(cluster, core);
|
||||
val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
|
||||
val = val >> (16 + (cluster << 2));
|
||||
val &= 0xF;
|
||||
hisi_cpuhotplug_unlock(cluster, core);
|
||||
|
||||
if (val)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void hisi_set_cpu_boot_flag(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
unsigned int flag = BIT((cluster<<2) + core + 16);
|
||||
|
||||
hisi_cpuhotplug_lock(cluster, core);
|
||||
|
||||
mmio_setbits_32(REG_SCBAKDATA3_OFFSET, flag);
|
||||
|
||||
hisi_cpuhotplug_unlock(cluster, core);
|
||||
}
|
||||
|
||||
void hisi_clear_cpu_boot_flag(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
unsigned int flag = BIT((cluster<<2) + core + 16);
|
||||
|
||||
hisi_cpuhotplug_lock(cluster, core);
|
||||
|
||||
mmio_clrbits_32(REG_SCBAKDATA3_OFFSET, flag);
|
||||
|
||||
hisi_cpuhotplug_unlock(cluster, core);
|
||||
}
|
||||
|
||||
int cluster_is_powered_on(unsigned int cluster)
|
||||
{
|
||||
unsigned int val = mmio_read_32(REG_SCBAKDATA3_OFFSET);
|
||||
int ret;
|
||||
|
||||
if (cluster == 0)
|
||||
ret = val & CLUSTER0_CPUS_ONLINE_MASK;
|
||||
else
|
||||
ret = val & CLUSTER1_CPUS_ONLINE_MASK;
|
||||
|
||||
return !!ret;
|
||||
}
|
||||
|
||||
static void *hisi_get_pdc_addr(unsigned int cluster)
|
||||
{
|
||||
void *pdc_base_addr;
|
||||
uintptr_t addr;
|
||||
|
||||
if (cluster == 0)
|
||||
addr = SOC_CRGPERIPH_A53_PDCEN_ADDR(CRG_BASE);
|
||||
else
|
||||
addr = SOC_CRGPERIPH_MAIA_PDCEN_ADDR(CRG_BASE);
|
||||
pdc_base_addr = (void *)addr;
|
||||
|
||||
return pdc_base_addr;
|
||||
}
|
||||
|
||||
static unsigned int hisi_get_pdc_stat(unsigned int cluster)
|
||||
{
|
||||
void *pdc_base_addr = hisi_get_pdc_addr(cluster);
|
||||
unsigned int val;
|
||||
|
||||
val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREPOWERSTAT_OFFSET);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int hisi_test_pwrdn_allcores(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
unsigned int mask = 0xf << (core * 4);
|
||||
unsigned int pdc_stat = hisi_get_pdc_stat(cluster);
|
||||
unsigned int boot_flag = hisi_get_cpu_boot_flag(cluster, core);
|
||||
unsigned int cpuidle_flag = hisi_get_cpuidle_flag(cluster);
|
||||
|
||||
mask = (PDC_COREPWRSTAT_MASK & (~mask));
|
||||
pdc_stat &= mask;
|
||||
|
||||
if ((boot_flag ^ cpuidle_flag) || pdc_stat)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void hisi_disable_pdc(unsigned int cluster)
|
||||
{
|
||||
void *pdc_base_addr = hisi_get_pdc_addr(cluster);
|
||||
|
||||
mmio_write_32((uintptr_t)pdc_base_addr, 0x0);
|
||||
}
|
||||
|
||||
void hisi_enable_pdc(unsigned int cluster)
|
||||
{
|
||||
void *pdc_base_addr = hisi_get_pdc_addr(cluster);
|
||||
|
||||
mmio_write_32((uintptr_t)pdc_base_addr, 0x1);
|
||||
}
|
||||
|
||||
static inline void hisi_pdc_set_intmask(void *pdc_base_addr,
|
||||
unsigned int core,
|
||||
enum pdc_finish_int_mask intmask)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET);
|
||||
if (intmask == PDC_ENABLE_FINISH_INT)
|
||||
val |= BIT(core);
|
||||
else
|
||||
val &= ~BIT(core);
|
||||
|
||||
mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET, val);
|
||||
}
|
||||
|
||||
static inline void hisi_pdc_set_gicmask(void *pdc_base_addr,
|
||||
unsigned int core,
|
||||
enum pdc_gic_mask gicmask)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = mmio_read_32((uintptr_t)pdc_base_addr + PDC_COREGICMASK_OFFSET);
|
||||
if (gicmask == PDC_MASK_GIC_WAKE_IRQ)
|
||||
val |= BIT(core);
|
||||
else
|
||||
val &= ~BIT(core);
|
||||
|
||||
mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREGICMASK_OFFSET, val);
|
||||
}
|
||||
|
||||
void hisi_pdc_mask_cluster_wakeirq(unsigned int cluster)
|
||||
{
|
||||
int i;
|
||||
void *pdc_base_addr = hisi_get_pdc_addr(cluster);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
hisi_pdc_set_gicmask(pdc_base_addr, i, PDC_MASK_GIC_WAKE_IRQ);
|
||||
}
|
||||
|
||||
static void hisi_pdc_powerup_core(unsigned int cluster, unsigned int core,
|
||||
enum pdc_gic_mask gicmask,
|
||||
enum pdc_finish_int_mask intmask)
|
||||
{
|
||||
void *pdc_base_addr = hisi_get_pdc_addr(cluster);
|
||||
|
||||
mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERUP_OFFSET,
|
||||
BIT(core));
|
||||
}
|
||||
|
||||
static void hisi_pdc_powerdn_core(unsigned int cluster, unsigned int core,
|
||||
enum pdc_gic_mask gicmask,
|
||||
enum pdc_finish_int_mask intmask)
|
||||
{
|
||||
void *pdc_base_addr = hisi_get_pdc_addr(cluster);
|
||||
|
||||
mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
|
||||
BIT(core));
|
||||
}
|
||||
|
||||
void hisi_powerup_core(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
hisi_pdc_powerup_core(cluster, core, PDC_MASK_GIC_WAKE_IRQ,
|
||||
PDC_DISABLE_FINISH_INT);
|
||||
}
|
||||
|
||||
void hisi_powerdn_core(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
hisi_pdc_powerdn_core(cluster, core, PDC_MASK_GIC_WAKE_IRQ,
|
||||
PDC_DISABLE_FINISH_INT);
|
||||
}
|
||||
|
||||
void hisi_powerup_cluster(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
hisi_ipc_pm_on_off(core, cluster, PM_ON);
|
||||
}
|
||||
|
||||
void hisi_powerdn_cluster(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
void *pdc_base_addr = hisi_get_pdc_addr(cluster);
|
||||
|
||||
hisi_set_cluster_pwdn_flag(cluster, core, CLUSTER_PWDN_HOTPLUG);
|
||||
mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET,
|
||||
(0x10001 << core));
|
||||
mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
|
||||
BIT(core));
|
||||
}
|
||||
|
||||
void hisi_enter_core_idle(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
hisi_pdc_powerdn_core(cluster, core, PDC_UNMASK_GIC_WAKE_IRQ,
|
||||
PDC_DISABLE_FINISH_INT);
|
||||
}
|
||||
|
||||
void hisi_enter_cluster_idle(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
void *pdc_base_addr = hisi_get_pdc_addr(cluster);
|
||||
|
||||
hisi_set_cluster_pwdn_flag(cluster, core, CLUSTER_PWDN_IDLE);
|
||||
mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPWRINTEN_OFFSET,
|
||||
(0x10001 << core));
|
||||
mmio_write_32((uintptr_t)pdc_base_addr + PDC_COREPOWERDN_OFFSET,
|
||||
BIT(core));
|
||||
}
|
||||
|
||||
void hisi_enter_ap_suspend(unsigned int cluster, unsigned int core)
|
||||
{
|
||||
hisi_ipc_pm_suspend(core, cluster, 0x3);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __HISI_PWRC_H__
|
||||
#define __HISI_PWRC_H__
|
||||
|
||||
#include <hi3660.h>
|
||||
#include <hi3660_crg.h>
|
||||
|
||||
#define PCTRL_BASE (PCTRL_REG_BASE)
|
||||
#define CRG_BASE (CRG_REG_BASE)
|
||||
|
||||
#define SOC_CRGPERIPH_A53_PDCEN_ADDR(base) ((base) + (0x260))
|
||||
#define SOC_CRGPERIPH_MAIA_PDCEN_ADDR(base) ((base) + (0x300))
|
||||
|
||||
#define SOC_PCTRL_RESOURCE0_LOCK_ADDR(base) ((base) + (0x400))
|
||||
#define SOC_PCTRL_RESOURCE0_UNLOCK_ADDR(base) ((base) + (0x404))
|
||||
#define SOC_PCTRL_RESOURCE0_LOCK_ST_ADDR(base) ((base) + (0x408))
|
||||
#define SOC_PCTRL_RESOURCE1_LOCK_ADDR(base) ((base) + (0x40C))
|
||||
#define SOC_PCTRL_RESOURCE1_UNLOCK_ADDR(base) ((base) + (0x410))
|
||||
#define SOC_PCTRL_RESOURCE1_LOCK_ST_ADDR(base) ((base) + (0x414))
|
||||
#define SOC_PCTRL_RESOURCE2_LOCK_ADDR(base) ((base) + (0x418))
|
||||
|
||||
#define SOC_SCTRL_SCBAKDATA3_ADDR(base) ((base) + (0x418))
|
||||
#define SOC_SCTRL_SCBAKDATA8_ADDR(base) ((base) + (0x42C))
|
||||
#define SOC_SCTRL_SCBAKDATA9_ADDR(base) ((base) + (0x430))
|
||||
|
||||
#define SOC_ACPU_SCTRL_BASE_ADDR (0xFFF0A000)
|
||||
|
||||
void hisi_cpuidle_lock(unsigned int cluster, unsigned int core);
|
||||
void hisi_cpuidle_unlock(unsigned int cluster, unsigned int core);
|
||||
void hisi_set_cpuidle_flag(unsigned int cluster, unsigned int core);
|
||||
void hisi_clear_cpuidle_flag(unsigned int cluster, unsigned int core);
|
||||
void hisi_set_cpu_boot_flag(unsigned int cluster, unsigned int core);
|
||||
void hisi_clear_cpu_boot_flag(unsigned int cluster, unsigned int core);
|
||||
int cluster_is_powered_on(unsigned int cluster);
|
||||
void hisi_enter_core_idle(unsigned int cluster, unsigned int core);
|
||||
void hisi_enter_cluster_idle(unsigned int cluster, unsigned int core);
|
||||
int hisi_test_ap_suspend_flag(unsigned int cluster);
|
||||
void hisi_enter_ap_suspend(unsigned int cluster, unsigned int core);
|
||||
|
||||
|
||||
/* pdc api */
|
||||
void hisi_pdc_mask_cluster_wakeirq(unsigned int cluster);
|
||||
int hisi_test_pwrdn_allcores(unsigned int cluster, unsigned int core);
|
||||
void hisi_disable_pdc(unsigned int cluster);
|
||||
void hisi_enable_pdc(unsigned int cluster);
|
||||
void hisi_powerup_core(unsigned int cluster, unsigned int core);
|
||||
void hisi_powerdn_core(unsigned int cluster, unsigned int core);
|
||||
void hisi_powerup_cluster(unsigned int cluster, unsigned int core);
|
||||
void hisi_powerdn_cluster(unsigned int cluster, unsigned int core);
|
||||
unsigned int hisi_test_cpu_down(unsigned int cluster, unsigned int core);
|
||||
|
||||
#endif /* __HISI_PWRC_H__ */
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <hi3660_mailbox.h>
|
||||
#include <mailbox.h>
|
||||
#include <mmio.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct hi3660_chan {
|
||||
unsigned char src;
|
||||
unsigned char dst;
|
||||
unsigned char used;
|
||||
} hi3660_chan_t;
|
||||
|
||||
static hi3660_chan_t chan_map[MBX_MAX_CHANNELS];
|
||||
|
||||
static void hi3660_mbox_check_state(int chan, unsigned int state)
|
||||
{
|
||||
unsigned int data;
|
||||
|
||||
data = mmio_read_32(MBX_MODE(chan));
|
||||
assert((data & (MBX_MODE_AUTO_ANSWER | MBX_MODE_AUTO_LINK)) == 0);
|
||||
|
||||
data &= MBX_MODE_STATE_STATUS_MASK;
|
||||
assert(data == state);
|
||||
(void)state;
|
||||
}
|
||||
|
||||
static int hi3660_mbox_send(int chan, void *message, int len)
|
||||
{
|
||||
int i;
|
||||
unsigned int *buf;
|
||||
unsigned int data;
|
||||
|
||||
assert((chan >= 0) && (chan < MBX_MAX_CHANNELS) &&
|
||||
(message != NULL) && (len <= MBX_MAX_DATA_LEN));
|
||||
assert((chan_map[chan].used != 0) &&
|
||||
(chan_map[chan].src != 0) &&
|
||||
(chan_map[chan].dst != 0));
|
||||
|
||||
buf = (unsigned int *)message;
|
||||
len = ((len + 3) >> 2); /* convert to word count */
|
||||
for (i = 0; i < len; i++)
|
||||
mmio_write_32(MBX_DATA0(chan) + (i << 2), *(buf + i));
|
||||
/* send out */
|
||||
mmio_write_32(MBX_SEND(chan), chan_map[chan].src);
|
||||
|
||||
do {
|
||||
data = mmio_read_32(MBX_ICLR(chan));
|
||||
} while ((data & chan_map[chan].src) == 0);
|
||||
/* ack */
|
||||
mmio_write_32(MBX_ICLR(chan), chan_map[chan].src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hi3660_mbox_recv(int chan, void *message, int *len)
|
||||
{
|
||||
unsigned int *buf, data;
|
||||
int i;
|
||||
|
||||
assert((chan >= 0) && (chan < MBX_MAX_CHANNELS) &&
|
||||
(message != NULL) && (len != NULL));
|
||||
assert((chan_map[chan].used != 0) &&
|
||||
(chan_map[chan].src != 0) &&
|
||||
(chan_map[chan].dst != 0));
|
||||
/* wait IPC event */
|
||||
do {
|
||||
data = mmio_read_32(MBX_MODE(chan));
|
||||
} while ((data & MBX_MODE_STATE_STATUS_MASK) != MBX_MODE_STATE_DEST);
|
||||
/* wait to clear interrupt */
|
||||
do {
|
||||
data = mmio_read_32(MBX_ICLR(chan));
|
||||
} while (data == 0);
|
||||
do {
|
||||
mmio_write_32(MBX_ICLR(chan), chan_map[chan].dst);
|
||||
data = mmio_read_32(MBX_ICLR(chan));
|
||||
} while (data);
|
||||
|
||||
/* read data from IPC */
|
||||
buf = (unsigned int *)message;
|
||||
for (i = 0; i < MBX_MAX_DATA_LEN; i += 4)
|
||||
*(buf + (i >> 2)) = mmio_read_32(MBX_DATA0(chan) + i);
|
||||
*len = MBX_MAX_DATA_LEN;
|
||||
/* ack */
|
||||
mmio_write_32(MBX_SEND(chan), chan_map[chan].dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hi3660_mbox_request(int chan, int direction)
|
||||
{
|
||||
unsigned int data;
|
||||
unsigned int src, dst;
|
||||
|
||||
assert((chan >= 0) && (chan < MBX_MAX_CHANNELS));
|
||||
|
||||
if (direction == MAILBOX_DIR_TX) {
|
||||
src = CPU_A53;
|
||||
dst = CPU_LPM3;
|
||||
} else if (direction == MAILBOX_DIR_RX) {
|
||||
src = CPU_LPM3;
|
||||
dst = CPU_A53;
|
||||
} else
|
||||
assert(0);
|
||||
mmio_write_32(MBX_SOURCE(chan), src);
|
||||
data = mmio_read_32(MBX_SOURCE(chan));
|
||||
assert(data == src);
|
||||
|
||||
/* mask all interrupts */
|
||||
mmio_write_32(MBX_IMASK(chan), CPU_MASK);
|
||||
/* unmask interrupt */
|
||||
mmio_write_32(MBX_IMASK(chan), ~(src | dst));
|
||||
|
||||
/* set destination */
|
||||
mmio_write_32(MBX_DCLEAR(chan), (~dst) & CPU_MASK);
|
||||
mmio_write_32(MBX_DSET(chan), dst);
|
||||
data = mmio_read_32(MBX_DSTATUS(chan));
|
||||
assert((data & dst) != 0);
|
||||
|
||||
/* clear auto link & auto answer */
|
||||
data = mmio_read_32(MBX_MODE(chan));
|
||||
data &= ~(MBX_MODE_AUTO_ANSWER | MBX_MODE_AUTO_LINK);
|
||||
mmio_write_32(MBX_MODE(chan), data);
|
||||
|
||||
hi3660_mbox_check_state(chan, MBX_MODE_STATE_SOURCE);
|
||||
chan_map[chan].used = 1;
|
||||
chan_map[chan].src = src;
|
||||
chan_map[chan].dst = dst;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hi3660_mbox_free(int chan)
|
||||
{
|
||||
assert((chan >= 0) && (chan < MBX_MAX_CHANNELS));
|
||||
}
|
||||
|
||||
static mbox_ops_t hi3660_mbox_ops = {
|
||||
.send = hi3660_mbox_send,
|
||||
.recv = hi3660_mbox_recv,
|
||||
.request = hi3660_mbox_request,
|
||||
.free = hi3660_mbox_free,
|
||||
};
|
||||
|
||||
int hi3660_mbox_init(mbox_params_t *params)
|
||||
{
|
||||
int result;
|
||||
unsigned int data;
|
||||
|
||||
assert(params != NULL);
|
||||
result = mbox_init(&hi3660_mbox_ops, params);
|
||||
assert(result == 0);
|
||||
memset(&chan_map, 0, sizeof(chan_map));
|
||||
|
||||
/* unlock mailbox */
|
||||
data = mmio_read_32(IPC_LOCK);
|
||||
while (data == MBX_IPC_LOCKED) {
|
||||
mmio_write_32(IPC_LOCK, MBX_IPC_UNLOCK_MAGIC);
|
||||
data = mmio_read_32(IPC_LOCK);
|
||||
}
|
||||
(void)result;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,705 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <arm_gic.h>
|
||||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <console.h>
|
||||
#include <debug.h>
|
||||
#include <delay_timer.h>
|
||||
#include <dw_ufs.h>
|
||||
#include <errno.h>
|
||||
#include <gicv2.h>
|
||||
#include <hi3660.h>
|
||||
#include <mmio.h>
|
||||
#include <generic_delay_timer.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <string.h>
|
||||
#include <tbbr/tbbr_img_desc.h>
|
||||
#include <ufs.h>
|
||||
|
||||
#include "../../bl1/bl1_private.h"
|
||||
#include "hikey960_def.h"
|
||||
#include "hikey960_private.h"
|
||||
|
||||
enum {
|
||||
BOOT_MODE_RECOVERY = 0,
|
||||
BOOT_MODE_NORMAL,
|
||||
BOOT_MODE_MASK = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Declarations of linker defined symbols which will help us find the layout
|
||||
* of trusted RAM
|
||||
*/
|
||||
extern unsigned long __COHERENT_RAM_START__;
|
||||
extern unsigned long __COHERENT_RAM_END__;
|
||||
|
||||
/*
|
||||
* The next 2 constants identify the extents of the coherent memory region.
|
||||
* These addresses are used by the MMU setup code and therefore they must be
|
||||
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||
* __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
|
||||
* page-aligned addresses.
|
||||
*/
|
||||
#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
|
||||
#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
|
||||
|
||||
/* Data structure which holds the extents of the trusted RAM for BL1 */
|
||||
static meminfo_t bl1_tzram_layout;
|
||||
|
||||
/******************************************************************************
|
||||
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
|
||||
* interrupts.
|
||||
*****************************************************************************/
|
||||
const unsigned int g0_interrupt_array[] = {
|
||||
IRQ_SEC_PHY_TIMER,
|
||||
IRQ_SEC_SGI_0
|
||||
};
|
||||
|
||||
const gicv2_driver_data_t hikey960_gic_data = {
|
||||
.gicd_base = GICD_REG_BASE,
|
||||
.gicc_base = GICC_REG_BASE,
|
||||
.g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array),
|
||||
.g0_interrupt_array = g0_interrupt_array,
|
||||
};
|
||||
|
||||
meminfo_t *bl1_plat_sec_mem_layout(void)
|
||||
{
|
||||
return &bl1_tzram_layout;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform any BL1 specific platform actions.
|
||||
*/
|
||||
void bl1_early_platform_setup(void)
|
||||
{
|
||||
const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
|
||||
unsigned int id, uart_base;
|
||||
|
||||
generic_delay_timer_init();
|
||||
hikey960_read_boardid(&id);
|
||||
if (id == 5300)
|
||||
uart_base = PL011_UART5_BASE;
|
||||
else
|
||||
uart_base = PL011_UART6_BASE;
|
||||
/* Initialize the console to provide early debug support */
|
||||
console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
|
||||
|
||||
/* Allow BL1 to see the whole Trusted RAM */
|
||||
bl1_tzram_layout.total_base = BL1_RW_BASE;
|
||||
bl1_tzram_layout.total_size = BL1_RW_SIZE;
|
||||
|
||||
/* Calculate how much RAM BL1 is using and how much remains free */
|
||||
bl1_tzram_layout.free_base = BL1_RW_BASE;
|
||||
bl1_tzram_layout.free_size = BL1_RW_SIZE;
|
||||
reserve_mem(&bl1_tzram_layout.free_base,
|
||||
&bl1_tzram_layout.free_size,
|
||||
BL1_RAM_BASE,
|
||||
bl1_size);
|
||||
|
||||
INFO("BL1: 0x%lx - 0x%lx [size = %lu]\n", BL1_RAM_BASE, BL1_RAM_LIMIT,
|
||||
bl1_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the very early platform specific architecture setup here. At the
|
||||
* moment this only does basic initialization. Later architectural setup
|
||||
* (bl1_arch_setup()) does not do anything platform specific.
|
||||
*/
|
||||
void bl1_plat_arch_setup(void)
|
||||
{
|
||||
hikey960_init_mmu_el3(bl1_tzram_layout.total_base,
|
||||
bl1_tzram_layout.total_size,
|
||||
BL1_RO_BASE,
|
||||
BL1_RO_LIMIT,
|
||||
BL1_COHERENT_RAM_BASE,
|
||||
BL1_COHERENT_RAM_LIMIT);
|
||||
}
|
||||
|
||||
static void hikey960_clk_init(void)
|
||||
{
|
||||
/* change ldi0 sel to ppll2 */
|
||||
mmio_write_32(0xfff350b4, 0xf0002000);
|
||||
/* ldi0 20' */
|
||||
mmio_write_32(0xfff350bc, 0xfc004c00);
|
||||
}
|
||||
|
||||
static void hikey960_pmu_init(void)
|
||||
{
|
||||
/* clear np_xo_abb_dig_START bit in PMIC_CLK_TOP_CTRL7 register */
|
||||
mmio_clrbits_32(PMU_SSI0_CLK_TOP_CTRL7_REG, NP_XO_ABB_DIG);
|
||||
}
|
||||
|
||||
static void hikey960_enable_ppll3(void)
|
||||
{
|
||||
/* enable ppll3 */
|
||||
mmio_write_32(PMC_PPLL3_CTRL0_REG, 0x4904305);
|
||||
mmio_write_32(PMC_PPLL3_CTRL1_REG, 0x2300000);
|
||||
mmio_write_32(PMC_PPLL3_CTRL1_REG, 0x6300000);
|
||||
}
|
||||
|
||||
static void bus_idle_clear(unsigned int value)
|
||||
{
|
||||
unsigned int pmc_value, value1, value2;
|
||||
int timeout = 100;
|
||||
|
||||
pmc_value = value << 16;
|
||||
pmc_value &= ~value;
|
||||
mmio_write_32(PMC_NOC_POWER_IDLEREQ_REG, pmc_value);
|
||||
|
||||
for (;;) {
|
||||
value1 = (unsigned int)mmio_read_32(PMC_NOC_POWER_IDLEACK_REG);
|
||||
value2 = (unsigned int)mmio_read_32(PMC_NOC_POWER_IDLE_REG);
|
||||
if (((value1 & value) == 0) && ((value2 & value) == 0))
|
||||
break;
|
||||
udelay(1);
|
||||
timeout--;
|
||||
if (timeout <= 0) {
|
||||
WARN("%s timeout\n", __func__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_vivobus_power_up(void)
|
||||
{
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV20_REG, 0x00020002);
|
||||
mmio_write_32(CRG_PEREN0_REG, 0x00001000);
|
||||
}
|
||||
|
||||
static void set_dss_power_up(void)
|
||||
{
|
||||
/* set edc0 133MHz = 1600MHz / 12 */
|
||||
mmio_write_32(CRG_CLKDIV5_REG, 0x003f000b);
|
||||
/* set ldi0 ppl0 */
|
||||
mmio_write_32(CRG_CLKDIV3_REG, 0xf0001000);
|
||||
/* set ldi0 133MHz, 1600MHz / 12 */
|
||||
mmio_write_32(CRG_CLKDIV5_REG, 0xfc002c00);
|
||||
/* mtcmos on */
|
||||
mmio_write_32(CRG_PERPWREN_REG, 0x00000020);
|
||||
udelay(100);
|
||||
/* DISP CRG */
|
||||
mmio_write_32(CRG_PERRSTDIS4_REG, 0x00000010);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV18_REG, 0x01400140);
|
||||
mmio_write_32(CRG_PEREN0_REG, 0x00002000);
|
||||
mmio_write_32(CRG_PEREN3_REG, 0x0003b000);
|
||||
udelay(1);
|
||||
/* clk disable */
|
||||
mmio_write_32(CRG_PERDIS3_REG, 0x0003b000);
|
||||
mmio_write_32(CRG_PERDIS0_REG, 0x00002000);
|
||||
mmio_write_32(CRG_CLKDIV18_REG, 0x01400000);
|
||||
udelay(1);
|
||||
/* iso disable */
|
||||
mmio_write_32(CRG_ISODIS_REG, 0x00000040);
|
||||
/* unreset */
|
||||
mmio_write_32(CRG_PERRSTDIS4_REG, 0x00000006);
|
||||
mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000c00);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV18_REG, 0x01400140);
|
||||
mmio_write_32(CRG_PEREN0_REG, 0x00002000);
|
||||
mmio_write_32(CRG_PEREN3_REG, 0x0003b000);
|
||||
/* bus idle clear */
|
||||
bus_idle_clear(PMC_NOC_POWER_IDLEREQ_DSS);
|
||||
/* set edc0 400MHz for 2K 1600MHz / 4 */
|
||||
mmio_write_32(CRG_CLKDIV5_REG, 0x003f0003);
|
||||
/* set ldi 266MHz, 1600MHz / 6 */
|
||||
mmio_write_32(CRG_CLKDIV5_REG, 0xfc001400);
|
||||
}
|
||||
|
||||
static void set_vcodec_power_up(void)
|
||||
{
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV20_REG, 0x00040004);
|
||||
mmio_write_32(CRG_PEREN0_REG, 0x00000060);
|
||||
mmio_write_32(CRG_PEREN2_REG, 0x10000000);
|
||||
/* unreset */
|
||||
mmio_write_32(CRG_PERRSTDIS0_REG, 0x00000018);
|
||||
/* bus idle clear */
|
||||
bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VCODEC);
|
||||
}
|
||||
|
||||
static void set_vdec_power_up(void)
|
||||
{
|
||||
/* mtcmos on */
|
||||
mmio_write_32(CRG_PERPWREN_REG, 0x00000004);
|
||||
udelay(100);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV18_REG, 0x80008000);
|
||||
mmio_write_32(CRG_PEREN2_REG, 0x20080000);
|
||||
mmio_write_32(CRG_PEREN3_REG, 0x00000800);
|
||||
udelay(1);
|
||||
/* clk disable */
|
||||
mmio_write_32(CRG_PERDIS3_REG, 0x00000800);
|
||||
mmio_write_32(CRG_PERDIS2_REG, 0x20080000);
|
||||
mmio_write_32(CRG_CLKDIV18_REG, 0x80000000);
|
||||
udelay(1);
|
||||
/* iso disable */
|
||||
mmio_write_32(CRG_ISODIS_REG, 0x00000004);
|
||||
/* unreset */
|
||||
mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000200);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV18_REG, 0x80008000);
|
||||
mmio_write_32(CRG_PEREN2_REG, 0x20080000);
|
||||
mmio_write_32(CRG_PEREN3_REG, 0x00000800);
|
||||
/* bus idle clear */
|
||||
bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VDEC);
|
||||
}
|
||||
|
||||
static void set_venc_power_up(void)
|
||||
{
|
||||
/* set venc ppll3 */
|
||||
mmio_write_32(CRG_CLKDIV8_REG, 0x18001000);
|
||||
/* set venc 258MHz, 1290MHz / 5 */
|
||||
mmio_write_32(CRG_CLKDIV8_REG, 0x07c00100);
|
||||
/* mtcmos on */
|
||||
mmio_write_32(CRG_PERPWREN_REG, 0x00000002);
|
||||
udelay(100);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV19_REG, 0x00010001);
|
||||
mmio_write_32(CRG_PEREN2_REG, 0x40000100);
|
||||
mmio_write_32(CRG_PEREN3_REG, 0x00000400);
|
||||
udelay(1);
|
||||
/* clk disable */
|
||||
mmio_write_32(CRG_PERDIS3_REG, 0x00000400);
|
||||
mmio_write_32(CRG_PERDIS2_REG, 0x40000100);
|
||||
mmio_write_32(CRG_CLKDIV19_REG, 0x00010000);
|
||||
udelay(1);
|
||||
/* iso disable */
|
||||
mmio_write_32(CRG_ISODIS_REG, 0x00000002);
|
||||
/* unreset */
|
||||
mmio_write_32(CRG_PERRSTDIS3_REG, 0x00000100);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV19_REG, 0x00010001);
|
||||
mmio_write_32(CRG_PEREN2_REG, 0x40000100);
|
||||
mmio_write_32(CRG_PEREN3_REG, 0x00000400);
|
||||
/* bus idle clear */
|
||||
bus_idle_clear(PMC_NOC_POWER_IDLEREQ_VENC);
|
||||
/* set venc 645MHz, 1290MHz / 2 */
|
||||
mmio_write_32(CRG_CLKDIV8_REG, 0x07c00040);
|
||||
}
|
||||
|
||||
static void set_isp_power_up(void)
|
||||
{
|
||||
/* mtcmos on */
|
||||
mmio_write_32(CRG_PERPWREN_REG, 0x00000001);
|
||||
udelay(100);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV18_REG, 0x70007000);
|
||||
mmio_write_32(CRG_CLKDIV20_REG, 0x00100010);
|
||||
mmio_write_32(CRG_PEREN5_REG, 0x01000010);
|
||||
mmio_write_32(CRG_PEREN3_REG, 0x0bf00000);
|
||||
udelay(1);
|
||||
/* clk disable */
|
||||
mmio_write_32(CRG_PERDIS5_REG, 0x01000010);
|
||||
mmio_write_32(CRG_PERDIS3_REG, 0x0bf00000);
|
||||
mmio_write_32(CRG_CLKDIV18_REG, 0x70000000);
|
||||
mmio_write_32(CRG_CLKDIV20_REG, 0x00100000);
|
||||
udelay(1);
|
||||
/* iso disable */
|
||||
mmio_write_32(CRG_ISODIS_REG, 0x00000001);
|
||||
/* unreset */
|
||||
mmio_write_32(CRG_ISP_SEC_RSTDIS_REG, 0x0000002f);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV18_REG, 0x70007000);
|
||||
mmio_write_32(CRG_CLKDIV20_REG, 0x00100010);
|
||||
mmio_write_32(CRG_PEREN5_REG, 0x01000010);
|
||||
mmio_write_32(CRG_PEREN3_REG, 0x0bf00000);
|
||||
/* bus idle clear */
|
||||
bus_idle_clear(PMC_NOC_POWER_IDLEREQ_ISP);
|
||||
/* csi clk enable */
|
||||
mmio_write_32(CRG_PEREN3_REG, 0x00700000);
|
||||
}
|
||||
|
||||
static void set_ivp_power_up(void)
|
||||
{
|
||||
/* set ivp ppll0 */
|
||||
mmio_write_32(CRG_CLKDIV0_REG, 0xc0000000);
|
||||
/* set ivp 267MHz, 1600MHz / 6 */
|
||||
mmio_write_32(CRG_CLKDIV0_REG, 0x3c001400);
|
||||
/* mtcmos on */
|
||||
mmio_write_32(CRG_PERPWREN_REG, 0x00200000);
|
||||
udelay(100);
|
||||
/* IVP CRG unreset */
|
||||
mmio_write_32(CRG_IVP_SEC_RSTDIS_REG, 0x00000001);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV20_REG, 0x02000200);
|
||||
mmio_write_32(CRG_PEREN4_REG, 0x000000a8);
|
||||
udelay(1);
|
||||
/* clk disable */
|
||||
mmio_write_32(CRG_PERDIS4_REG, 0x000000a8);
|
||||
mmio_write_32(CRG_CLKDIV20_REG, 0x02000000);
|
||||
udelay(1);
|
||||
/* iso disable */
|
||||
mmio_write_32(CRG_ISODIS_REG, 0x01000000);
|
||||
/* unreset */
|
||||
mmio_write_32(CRG_IVP_SEC_RSTDIS_REG, 0x00000002);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV20_REG, 0x02000200);
|
||||
mmio_write_32(CRG_PEREN4_REG, 0x000000a8);
|
||||
/* bus idle clear */
|
||||
bus_idle_clear(PMC_NOC_POWER_IDLEREQ_IVP);
|
||||
/* set ivp 533MHz, 1600MHz / 3 */
|
||||
mmio_write_32(CRG_CLKDIV0_REG, 0x3c000800);
|
||||
}
|
||||
|
||||
static void set_audio_power_up(void)
|
||||
{
|
||||
unsigned int ret;
|
||||
int timeout = 100;
|
||||
/* mtcmos on */
|
||||
mmio_write_32(SCTRL_SCPWREN_REG, 0x00000001);
|
||||
udelay(100);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV19_REG, 0x80108010);
|
||||
mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010001);
|
||||
mmio_write_32(SCTRL_SCPEREN0_REG, 0x0c000000);
|
||||
mmio_write_32(CRG_PEREN0_REG, 0x04000000);
|
||||
mmio_write_32(CRG_PEREN5_REG, 0x00000080);
|
||||
mmio_write_32(SCTRL_SCPEREN1_REG, 0x0000000f);
|
||||
udelay(1);
|
||||
/* clk disable */
|
||||
mmio_write_32(SCTRL_SCPERDIS1_REG, 0x0000000f);
|
||||
mmio_write_32(SCTRL_SCPERDIS0_REG, 0x0c000000);
|
||||
mmio_write_32(CRG_PERDIS5_REG, 0x00000080);
|
||||
mmio_write_32(CRG_PERDIS0_REG, 0x04000000);
|
||||
mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010000);
|
||||
mmio_write_32(CRG_CLKDIV19_REG, 0x80100000);
|
||||
udelay(1);
|
||||
/* iso disable */
|
||||
mmio_write_32(SCTRL_SCISODIS_REG, 0x00000001);
|
||||
udelay(1);
|
||||
/* unreset */
|
||||
mmio_write_32(SCTRL_PERRSTDIS1_SEC_REG, 0x00000001);
|
||||
mmio_write_32(SCTRL_SCPERRSTDIS0_REG, 0x00000780);
|
||||
/* clk enable */
|
||||
mmio_write_32(CRG_CLKDIV19_REG, 0x80108010);
|
||||
mmio_write_32(SCTRL_SCCLKDIV2_REG, 0x00010001);
|
||||
mmio_write_32(SCTRL_SCPEREN0_REG, 0x0c000000);
|
||||
mmio_write_32(CRG_PEREN0_REG, 0x04000000);
|
||||
mmio_write_32(CRG_PEREN5_REG, 0x00000080);
|
||||
mmio_write_32(SCTRL_SCPEREN1_REG, 0x0000000f);
|
||||
/* bus idle clear */
|
||||
mmio_write_32(SCTRL_SCPERCTRL7_REG, 0x00040000);
|
||||
for (;;) {
|
||||
ret = mmio_read_32(SCTRL_SCPERSTAT6_REG);
|
||||
if (((ret & (1 << 5)) == 0) && ((ret & (1 << 8)) == 0))
|
||||
break;
|
||||
udelay(1);
|
||||
timeout--;
|
||||
if (timeout <= 0) {
|
||||
WARN("%s timeout\n", __func__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mmio_write_32(ASP_CFG_MMBUF_CTRL_REG, 0x00ff0000);
|
||||
}
|
||||
|
||||
static void set_pcie_power_up(void)
|
||||
{
|
||||
/* mtcmos on */
|
||||
mmio_write_32(SCTRL_SCPWREN_REG, 0x00000010);
|
||||
udelay(100);
|
||||
/* clk enable */
|
||||
mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000800);
|
||||
mmio_write_32(SCTRL_SCPEREN2_REG, 0x00104000);
|
||||
mmio_write_32(CRG_PEREN7_REG, 0x000003a0);
|
||||
udelay(1);
|
||||
/* clk disable */
|
||||
mmio_write_32(SCTRL_SCPERDIS2_REG, 0x00104000);
|
||||
mmio_write_32(CRG_PERDIS7_REG, 0x000003a0);
|
||||
mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000000);
|
||||
udelay(1);
|
||||
/* iso disable */
|
||||
mmio_write_32(SCTRL_SCISODIS_REG, 0x00000030);
|
||||
/* unreset */
|
||||
mmio_write_32(CRG_PERRSTDIS3_REG, 0x8c000000);
|
||||
/* clk enable */
|
||||
mmio_write_32(SCTRL_SCCLKDIV6_REG, 0x08000800);
|
||||
mmio_write_32(SCTRL_SCPEREN2_REG, 0x00104000);
|
||||
mmio_write_32(CRG_PEREN7_REG, 0x000003a0);
|
||||
}
|
||||
|
||||
static void ispfunc_enable(void)
|
||||
{
|
||||
/* enable ispfunc. Otherwise powerup isp_srt causes exception. */
|
||||
mmio_write_32(0xfff35000, 0x00000008);
|
||||
mmio_write_32(0xfff35460, 0xc004ffff);
|
||||
mmio_write_32(0xfff35030, 0x02000000);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
static void isps_control_clock(int flag)
|
||||
{
|
||||
unsigned int ret;
|
||||
|
||||
/* flag: 0 -- disable clock, 1 -- enable clock */
|
||||
if (flag) {
|
||||
ret = mmio_read_32(0xe8420364);
|
||||
ret |= 1;
|
||||
mmio_write_32(0xe8420364, ret);
|
||||
} else {
|
||||
ret = mmio_read_32(0xe8420364);
|
||||
ret &= ~1;
|
||||
mmio_write_32(0xe8420364, ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_isp_srt_power_up(void)
|
||||
{
|
||||
unsigned int ret;
|
||||
|
||||
ispfunc_enable();
|
||||
/* reset */
|
||||
mmio_write_32(0xe8420374, 0x00000001);
|
||||
mmio_write_32(0xe8420350, 0x00000000);
|
||||
mmio_write_32(0xe8420358, 0x00000000);
|
||||
/* mtcmos on */
|
||||
mmio_write_32(0xfff35150, 0x00400000);
|
||||
udelay(100);
|
||||
/* clk enable */
|
||||
isps_control_clock(1);
|
||||
udelay(1);
|
||||
isps_control_clock(0);
|
||||
udelay(1);
|
||||
/* iso disable */
|
||||
mmio_write_32(0xfff35148, 0x08000000);
|
||||
/* unreset */
|
||||
ret = mmio_read_32(0xe8420374);
|
||||
ret &= ~0x1;
|
||||
mmio_write_32(0xe8420374, ret);
|
||||
/* clk enable */
|
||||
isps_control_clock(1);
|
||||
/* enable clock gating for accessing csi registers */
|
||||
mmio_write_32(0xe8420010, ~0);
|
||||
}
|
||||
|
||||
static void hikey960_regulator_enable(void)
|
||||
{
|
||||
set_vivobus_power_up();
|
||||
hikey960_enable_ppll3();
|
||||
set_dss_power_up();
|
||||
set_vcodec_power_up();
|
||||
set_vdec_power_up();
|
||||
set_venc_power_up();
|
||||
set_isp_power_up();
|
||||
set_ivp_power_up();
|
||||
set_audio_power_up();
|
||||
set_pcie_power_up();
|
||||
set_isp_srt_power_up();
|
||||
}
|
||||
|
||||
static void hikey960_ufs_reset(void)
|
||||
{
|
||||
unsigned int data, mask;
|
||||
|
||||
mmio_write_32(CRG_PERDIS7_REG, 1 << 14);
|
||||
mmio_clrbits_32(UFS_SYS_PHY_CLK_CTRL_REG, BIT_SYSCTRL_REF_CLOCK_EN);
|
||||
do {
|
||||
data = mmio_read_32(UFS_SYS_PHY_CLK_CTRL_REG);
|
||||
} while (data & BIT_SYSCTRL_REF_CLOCK_EN);
|
||||
/* use abb clk */
|
||||
mmio_clrbits_32(UFS_SYS_UFS_SYSCTRL_REG, BIT_UFS_REFCLK_SRC_SE1);
|
||||
mmio_clrbits_32(UFS_SYS_PHY_ISO_EN_REG, BIT_UFS_REFCLK_ISO_EN);
|
||||
mmio_write_32(PCTRL_PERI_CTRL3_REG, (1 << 0) | (1 << 16));
|
||||
mdelay(1);
|
||||
mmio_write_32(CRG_PEREN7_REG, 1 << 14);
|
||||
mmio_setbits_32(UFS_SYS_PHY_CLK_CTRL_REG, BIT_SYSCTRL_REF_CLOCK_EN);
|
||||
|
||||
mmio_write_32(CRG_PERRSTEN3_REG, PERI_UFS_BIT);
|
||||
do {
|
||||
data = mmio_read_32(CRG_PERRSTSTAT3_REG);
|
||||
} while ((data & PERI_UFS_BIT) == 0);
|
||||
mmio_setbits_32(UFS_SYS_PSW_POWER_CTRL_REG, BIT_UFS_PSW_MTCMOS_EN);
|
||||
mdelay(1);
|
||||
mmio_setbits_32(UFS_SYS_HC_LP_CTRL_REG, BIT_SYSCTRL_PWR_READY);
|
||||
mmio_write_32(UFS_SYS_UFS_DEVICE_RESET_CTRL_REG,
|
||||
MASK_UFS_DEVICE_RESET);
|
||||
/* clear SC_DIV_UFS_PERIBUS */
|
||||
mask = SC_DIV_UFS_PERIBUS << 16;
|
||||
mmio_write_32(CRG_CLKDIV17_REG, mask);
|
||||
/* set SC_DIV_UFSPHY_CFG(3) */
|
||||
mask = SC_DIV_UFSPHY_CFG_MASK << 16;
|
||||
data = SC_DIV_UFSPHY_CFG(3);
|
||||
mmio_write_32(CRG_CLKDIV16_REG, mask | data);
|
||||
data = mmio_read_32(UFS_SYS_PHY_CLK_CTRL_REG);
|
||||
data &= ~MASK_SYSCTRL_CFG_CLOCK_FREQ;
|
||||
data |= 0x39;
|
||||
mmio_write_32(UFS_SYS_PHY_CLK_CTRL_REG, data);
|
||||
mmio_clrbits_32(UFS_SYS_PHY_CLK_CTRL_REG, MASK_SYSCTRL_REF_CLOCK_SEL);
|
||||
mmio_setbits_32(UFS_SYS_CLOCK_GATE_BYPASS_REG,
|
||||
MASK_UFS_CLK_GATE_BYPASS);
|
||||
mmio_setbits_32(UFS_SYS_UFS_SYSCTRL_REG, MASK_UFS_SYSCTRL_BYPASS);
|
||||
|
||||
mmio_setbits_32(UFS_SYS_PSW_CLK_CTRL_REG, BIT_SYSCTRL_PSW_CLK_EN);
|
||||
mmio_clrbits_32(UFS_SYS_PSW_POWER_CTRL_REG, BIT_UFS_PSW_ISO_CTRL);
|
||||
mmio_clrbits_32(UFS_SYS_PHY_ISO_EN_REG, BIT_UFS_PHY_ISO_CTRL);
|
||||
mmio_clrbits_32(UFS_SYS_HC_LP_CTRL_REG, BIT_SYSCTRL_LP_ISOL_EN);
|
||||
mmio_write_32(CRG_PERRSTDIS3_REG, PERI_ARST_UFS_BIT);
|
||||
mmio_setbits_32(UFS_SYS_RESET_CTRL_EN_REG, BIT_SYSCTRL_LP_RESET_N);
|
||||
mdelay(1);
|
||||
mmio_write_32(UFS_SYS_UFS_DEVICE_RESET_CTRL_REG,
|
||||
MASK_UFS_DEVICE_RESET | BIT_UFS_DEVICE_RESET);
|
||||
mdelay(20);
|
||||
mmio_write_32(UFS_SYS_UFS_DEVICE_RESET_CTRL_REG,
|
||||
0x03300330);
|
||||
|
||||
mmio_write_32(CRG_PERRSTDIS3_REG, PERI_UFS_BIT);
|
||||
do {
|
||||
data = mmio_read_32(CRG_PERRSTSTAT3_REG);
|
||||
} while (data & PERI_UFS_BIT);
|
||||
}
|
||||
|
||||
static void hikey960_ufs_init(void)
|
||||
{
|
||||
dw_ufs_params_t ufs_params;
|
||||
|
||||
memset(&ufs_params, 0, sizeof(ufs_params));
|
||||
ufs_params.reg_base = UFS_REG_BASE;
|
||||
ufs_params.desc_base = HIKEY960_UFS_DESC_BASE;
|
||||
ufs_params.desc_size = HIKEY960_UFS_DESC_SIZE;
|
||||
|
||||
if ((ufs_params.flags & UFS_FLAGS_SKIPINIT) == 0)
|
||||
hikey960_ufs_reset();
|
||||
dw_ufs_init(&ufs_params);
|
||||
}
|
||||
|
||||
static void hikey960_tzc_init(void)
|
||||
{
|
||||
mmio_write_32(TZC_EN0_REG, 0x7fbff066);
|
||||
mmio_write_32(TZC_EN1_REG, 0xfffff5fc);
|
||||
mmio_write_32(TZC_EN2_REG, 0x0007005c);
|
||||
mmio_write_32(TZC_EN3_REG, 0x37030700);
|
||||
mmio_write_32(TZC_EN4_REG, 0xf63fefae);
|
||||
mmio_write_32(TZC_EN5_REG, 0x000410fd);
|
||||
mmio_write_32(TZC_EN6_REG, 0x0063ff68);
|
||||
mmio_write_32(TZC_EN7_REG, 0x030000f3);
|
||||
mmio_write_32(TZC_EN8_REG, 0x00000007);
|
||||
}
|
||||
|
||||
static void hikey960_peri_init(void)
|
||||
{
|
||||
/* unreset */
|
||||
mmio_setbits_32(CRG_PERRSTDIS4_REG, 1);
|
||||
}
|
||||
|
||||
static void hikey960_pinmux_init(void)
|
||||
{
|
||||
unsigned int id;
|
||||
|
||||
hikey960_read_boardid(&id);
|
||||
if (id == 5301) {
|
||||
/* hikey960 hardware v2 */
|
||||
/* GPIO150: LED */
|
||||
mmio_write_32(IOMG_FIX_006_REG, 0);
|
||||
/* GPIO151: LED */
|
||||
mmio_write_32(IOMG_FIX_007_REG, 0);
|
||||
/* GPIO189: LED */
|
||||
mmio_write_32(IOMG_AO_011_REG, 0);
|
||||
/* GPIO190: LED */
|
||||
mmio_write_32(IOMG_AO_012_REG, 0);
|
||||
/* GPIO46 */
|
||||
mmio_write_32(IOMG_044_REG, 0);
|
||||
/* GPIO202 */
|
||||
mmio_write_32(IOMG_AO_023_REG, 0);
|
||||
/* GPIO206 */
|
||||
mmio_write_32(IOMG_AO_026_REG, 0);
|
||||
/* GPIO219 - PD pullup */
|
||||
mmio_write_32(IOMG_AO_039_REG, 0);
|
||||
mmio_write_32(IOCG_AO_043_REG, 1 << 0);
|
||||
}
|
||||
/* GPIO005 - PMU SSI, 10mA */
|
||||
mmio_write_32(IOCG_006_REG, 2 << 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function which will perform any remaining platform-specific setup that can
|
||||
* occur after the MMU and data cache have been enabled.
|
||||
*/
|
||||
void bl1_platform_setup(void)
|
||||
{
|
||||
hikey960_clk_init();
|
||||
hikey960_pmu_init();
|
||||
hikey960_regulator_enable();
|
||||
hikey960_tzc_init();
|
||||
hikey960_peri_init();
|
||||
hikey960_ufs_init();
|
||||
hikey960_pinmux_init();
|
||||
hikey960_io_setup();
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function checks if Firmware update is needed,
|
||||
* by checking if TOC in FIP image is valid or not.
|
||||
*/
|
||||
unsigned int bl1_plat_get_next_image_id(void)
|
||||
{
|
||||
unsigned int mode, ret;
|
||||
|
||||
mode = mmio_read_32(SCTRL_BAK_DATA0_REG);
|
||||
switch (mode & BOOT_MODE_MASK) {
|
||||
case BOOT_MODE_RECOVERY:
|
||||
ret = NS_BL1U_IMAGE_ID;
|
||||
break;
|
||||
case BOOT_MODE_NORMAL:
|
||||
ret = BL2_IMAGE_ID;
|
||||
break;
|
||||
default:
|
||||
WARN("Invalid boot mode is found:%d\n", mode);
|
||||
panic();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
image_desc_t *bl1_plat_get_image_desc(unsigned int image_id)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
|
||||
while (bl1_tbbr_image_descs[index].image_id != INVALID_IMAGE_ID) {
|
||||
if (bl1_tbbr_image_descs[index].image_id == image_id)
|
||||
return &bl1_tbbr_image_descs[index];
|
||||
index++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void bl1_plat_set_ep_info(unsigned int image_id,
|
||||
entry_point_info_t *ep_info)
|
||||
{
|
||||
unsigned int data = 0;
|
||||
uintptr_t tmp = HIKEY960_NS_TMP_OFFSET;
|
||||
|
||||
if (image_id == BL2_IMAGE_ID)
|
||||
return;
|
||||
/* Copy NS BL1U from 0x1AC1_8000 to 0x1AC9_8000 */
|
||||
memcpy((void *)tmp, (void *)HIKEY960_NS_IMAGE_OFFSET,
|
||||
NS_BL1U_SIZE);
|
||||
memcpy((void *)NS_BL1U_BASE, (void *)tmp, NS_BL1U_SIZE);
|
||||
inv_dcache_range(NS_BL1U_BASE, NS_BL1U_SIZE);
|
||||
/* Initialize the GIC driver, cpu and distributor interfaces */
|
||||
gicv2_driver_init(&hikey960_gic_data);
|
||||
gicv2_distif_init();
|
||||
gicv2_pcpu_distif_init();
|
||||
gicv2_cpuif_enable();
|
||||
/* CNTFRQ is read-only in EL1 */
|
||||
write_cntfrq_el0(plat_get_syscnt_freq2());
|
||||
data = read_cpacr_el1();
|
||||
do {
|
||||
data |= 3 << 20;
|
||||
write_cpacr_el1(data);
|
||||
data = read_cpacr_el1();
|
||||
} while ((data & (3 << 20)) != (3 << 20));
|
||||
INFO("cpacr_el1:0x%x\n", data);
|
||||
|
||||
ep_info->args.arg0 = 0xffff & read_mpidr();
|
||||
ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
|
||||
DISABLE_ALL_EXCEPTIONS);
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <console.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <generic_delay_timer.h>
|
||||
#include <hi3660.h>
|
||||
#include <mmio.h>
|
||||
#include <platform_def.h>
|
||||
#include <string.h>
|
||||
#include <ufs.h>
|
||||
|
||||
#include "hikey960_def.h"
|
||||
#include "hikey960_private.h"
|
||||
|
||||
/*
|
||||
* The next 2 constants identify the extents of the code & RO data region.
|
||||
* These addresses are used by the MMU setup code and therefore they must be
|
||||
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
|
||||
*/
|
||||
#define BL2_RO_BASE (unsigned long)(&__RO_START__)
|
||||
#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
|
||||
|
||||
/*
|
||||
* The next 2 constants identify the extents of the coherent memory region.
|
||||
* These addresses are used by the MMU setup code and therefore they must be
|
||||
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||
* __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
|
||||
* page-aligned addresses.
|
||||
*/
|
||||
#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
|
||||
#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
|
||||
|
||||
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
|
||||
|
||||
typedef struct bl2_to_bl31_params_mem {
|
||||
bl31_params_t bl31_params;
|
||||
image_info_t bl31_image_info;
|
||||
image_info_t bl32_image_info;
|
||||
image_info_t bl33_image_info;
|
||||
entry_point_info_t bl33_ep_info;
|
||||
entry_point_info_t bl32_ep_info;
|
||||
entry_point_info_t bl31_ep_info;
|
||||
} bl2_to_bl31_params_mem_t;
|
||||
|
||||
static bl2_to_bl31_params_mem_t bl31_params_mem;
|
||||
|
||||
meminfo_t *bl2_plat_sec_mem_layout(void)
|
||||
{
|
||||
return &bl2_tzram_layout;
|
||||
}
|
||||
|
||||
bl31_params_t *bl2_plat_get_bl31_params(void)
|
||||
{
|
||||
bl31_params_t *bl2_to_bl31_params = NULL;
|
||||
|
||||
/*
|
||||
* Initialise the memory for all the arguments that needs to
|
||||
* be passed to BL3-1
|
||||
*/
|
||||
memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
|
||||
|
||||
/* Assign memory for TF related information */
|
||||
bl2_to_bl31_params = &bl31_params_mem.bl31_params;
|
||||
SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
|
||||
|
||||
/* Fill BL3-1 related information */
|
||||
bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
|
||||
SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
|
||||
VERSION_1, 0);
|
||||
|
||||
/* Fill BL3-2 related information if it exists */
|
||||
#if BL32_BASE
|
||||
bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
|
||||
SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
|
||||
VERSION_1, 0);
|
||||
bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
|
||||
SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
|
||||
VERSION_1, 0);
|
||||
#endif
|
||||
|
||||
/* Fill BL3-3 related information */
|
||||
bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
|
||||
SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
|
||||
PARAM_EP, VERSION_1, 0);
|
||||
|
||||
/* BL3-3 expects to receive the primary CPU MPID (through x0) */
|
||||
bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
|
||||
|
||||
bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
|
||||
SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
|
||||
VERSION_1, 0);
|
||||
|
||||
return bl2_to_bl31_params;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Populate the extents of memory available for loading SCP_BL2 (if used),
|
||||
* i.e. anywhere in trusted RAM as long as it doesn't overwrite BL2.
|
||||
******************************************************************************/
|
||||
void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
|
||||
{
|
||||
ufs_params_t ufs_params;
|
||||
|
||||
memset(&ufs_params, 0, sizeof(ufs_params_t));
|
||||
ufs_params.reg_base = UFS_REG_BASE;
|
||||
ufs_params.desc_base = HIKEY960_UFS_DESC_BASE;
|
||||
ufs_params.desc_size = HIKEY960_UFS_DESC_SIZE;
|
||||
ufs_params.flags = UFS_FLAGS_SKIPINIT;
|
||||
ufs_init(NULL, &ufs_params);
|
||||
|
||||
hikey960_io_setup();
|
||||
|
||||
*scp_bl2_meminfo = bl2_tzram_layout;
|
||||
}
|
||||
|
||||
extern int load_lpm3(void);
|
||||
|
||||
int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
|
||||
{
|
||||
int i;
|
||||
int *buf;
|
||||
|
||||
assert(scp_bl2_image_info->image_size < SCP_MEM_SIZE);
|
||||
|
||||
INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
|
||||
|
||||
INFO("BL2: SCP_BL2: 0x%lx@0x%x\n",
|
||||
scp_bl2_image_info->image_base,
|
||||
scp_bl2_image_info->image_size);
|
||||
|
||||
buf = (int *)scp_bl2_image_info->image_base;
|
||||
|
||||
INFO("BL2: SCP_BL2 HEAD:\n");
|
||||
for (i = 0; i < 64; i += 4)
|
||||
INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
|
||||
buf[i], buf[i+1], buf[i+2], buf[i+3]);
|
||||
|
||||
buf = (int *)(scp_bl2_image_info->image_base +
|
||||
scp_bl2_image_info->image_size - 256);
|
||||
|
||||
INFO("BL2: SCP_BL2 TAIL:\n");
|
||||
for (i = 0; i < 64; i += 4)
|
||||
INFO("BL2: SCP_BL2 0x%x 0x%x 0x%x 0x%x\n",
|
||||
buf[i], buf[i+1], buf[i+2], buf[i+3]);
|
||||
|
||||
memcpy((void *)SCP_MEM_BASE,
|
||||
(void *)scp_bl2_image_info->image_base,
|
||||
scp_bl2_image_info->image_size);
|
||||
|
||||
INFO("BL2: SCP_BL2 transferred to SCP\n");
|
||||
|
||||
load_lpm3();
|
||||
(void)buf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
|
||||
{
|
||||
return &bl31_params_mem.bl31_ep_info;
|
||||
}
|
||||
|
||||
void bl2_plat_set_bl31_ep_info(image_info_t *image,
|
||||
entry_point_info_t *bl31_ep_info)
|
||||
{
|
||||
SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
|
||||
bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
|
||||
DISABLE_ALL_EXCEPTIONS);
|
||||
}
|
||||
|
||||
void bl2_plat_set_bl33_ep_info(image_info_t *image,
|
||||
entry_point_info_t *bl33_ep_info)
|
||||
{
|
||||
unsigned long el_status;
|
||||
unsigned int mode;
|
||||
|
||||
/* Figure out what mode we enter the non-secure world in */
|
||||
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
|
||||
el_status &= ID_AA64PFR0_ELX_MASK;
|
||||
|
||||
if (el_status)
|
||||
mode = MODE_EL2;
|
||||
else
|
||||
mode = MODE_EL1;
|
||||
|
||||
/*
|
||||
* TODO: Consider the possibility of specifying the SPSR in
|
||||
* the FIP ToC and allowing the platform to have a say as
|
||||
* well.
|
||||
*/
|
||||
bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
|
||||
DISABLE_ALL_EXCEPTIONS);
|
||||
SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
|
||||
}
|
||||
|
||||
void bl2_plat_flush_bl31_params(void)
|
||||
{
|
||||
flush_dcache_range((unsigned long)&bl31_params_mem,
|
||||
sizeof(bl2_to_bl31_params_mem_t));
|
||||
}
|
||||
|
||||
void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
|
||||
{
|
||||
bl33_meminfo->total_base = DDR_BASE;
|
||||
bl33_meminfo->total_size = DDR_SIZE;
|
||||
bl33_meminfo->free_base = DDR_BASE;
|
||||
bl33_meminfo->free_size = DDR_SIZE;
|
||||
}
|
||||
|
||||
void bl2_early_platform_setup(meminfo_t *mem_layout)
|
||||
{
|
||||
unsigned int id, uart_base;
|
||||
|
||||
generic_delay_timer_init();
|
||||
hikey960_read_boardid(&id);
|
||||
if (id == 5300)
|
||||
uart_base = PL011_UART5_BASE;
|
||||
else
|
||||
uart_base = PL011_UART6_BASE;
|
||||
|
||||
/* Initialize the console to provide early debug support */
|
||||
console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
|
||||
|
||||
/* Setup the BL2 memory layout */
|
||||
bl2_tzram_layout = *mem_layout;
|
||||
}
|
||||
|
||||
void bl2_plat_arch_setup(void)
|
||||
{
|
||||
hikey960_init_mmu_el1(bl2_tzram_layout.total_base,
|
||||
bl2_tzram_layout.total_size,
|
||||
BL2_RO_BASE,
|
||||
BL2_RO_LIMIT,
|
||||
BL2_COHERENT_RAM_BASE,
|
||||
BL2_COHERENT_RAM_LIMIT);
|
||||
}
|
||||
|
||||
void bl2_platform_setup(void)
|
||||
{
|
||||
/* disable WDT0 */
|
||||
if (mmio_read_32(WDT0_REG_BASE + WDT_LOCK_OFFSET) == WDT_LOCKED) {
|
||||
mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, WDT_UNLOCK);
|
||||
mmio_write_32(WDT0_REG_BASE + WDT_CONTROL_OFFSET, 0);
|
||||
mmio_write_32(WDT0_REG_BASE + WDT_LOCK_OFFSET, 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <arm_gic.h>
|
||||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <cci.h>
|
||||
#include <console.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <generic_delay_timer.h>
|
||||
#include <gicv2.h>
|
||||
#include <hi3660.h>
|
||||
#include <hisi_ipc.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
#include "hikey960_def.h"
|
||||
#include "hikey960_private.h"
|
||||
|
||||
/*
|
||||
* The next 2 constants identify the extents of the code & RO data region.
|
||||
* These addresses are used by the MMU setup code and therefore they must be
|
||||
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
|
||||
*/
|
||||
#define BL31_RO_BASE (unsigned long)(&__RO_START__)
|
||||
#define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
|
||||
|
||||
/*
|
||||
* The next 2 constants identify the extents of the coherent memory region.
|
||||
* These addresses are used by the MMU setup code and therefore they must be
|
||||
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||
* __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
|
||||
* page-aligned addresses.
|
||||
*/
|
||||
#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
|
||||
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
|
||||
|
||||
static entry_point_info_t bl32_ep_info;
|
||||
static entry_point_info_t bl33_ep_info;
|
||||
|
||||
/******************************************************************************
|
||||
* On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
|
||||
* interrupts.
|
||||
*****************************************************************************/
|
||||
const unsigned int g0_interrupt_array[] = {
|
||||
IRQ_SEC_PHY_TIMER,
|
||||
IRQ_SEC_SGI_0
|
||||
};
|
||||
|
||||
const gicv2_driver_data_t hikey960_gic_data = {
|
||||
.gicd_base = GICD_REG_BASE,
|
||||
.gicc_base = GICC_REG_BASE,
|
||||
.g0_interrupt_num = ARRAY_SIZE(g0_interrupt_array),
|
||||
.g0_interrupt_array = g0_interrupt_array,
|
||||
};
|
||||
|
||||
static const int cci_map[] = {
|
||||
CCI400_SL_IFACE3_CLUSTER_IX,
|
||||
CCI400_SL_IFACE4_CLUSTER_IX
|
||||
};
|
||||
|
||||
entry_point_info_t *bl31_plat_get_next_image_ep_info(unsigned int type)
|
||||
{
|
||||
entry_point_info_t *next_image_info;
|
||||
|
||||
next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
|
||||
|
||||
/* None of the images on this platform can have 0x0 as the entrypoint */
|
||||
if (next_image_info->pc)
|
||||
return next_image_info;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void bl31_early_platform_setup(bl31_params_t *from_bl2,
|
||||
void *plat_params_from_bl2)
|
||||
{
|
||||
unsigned int id, uart_base;
|
||||
|
||||
generic_delay_timer_init();
|
||||
hikey960_read_boardid(&id);
|
||||
if (id == 5300)
|
||||
uart_base = PL011_UART5_BASE;
|
||||
else
|
||||
uart_base = PL011_UART6_BASE;
|
||||
|
||||
/* Initialize the console to provide early debug support */
|
||||
console_init(uart_base, PL011_UART_CLK_IN_HZ, PL011_BAUDRATE);
|
||||
|
||||
/* Initialize CCI driver */
|
||||
cci_init(CCI400_REG_BASE, cci_map, ARRAY_SIZE(cci_map));
|
||||
cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
|
||||
|
||||
/*
|
||||
* Copy BL3-2 and BL3-3 entry point information.
|
||||
* They are stored in Secure RAM, in BL2's address space.
|
||||
*/
|
||||
bl32_ep_info = *from_bl2->bl32_ep_info;
|
||||
bl33_ep_info = *from_bl2->bl33_ep_info;
|
||||
}
|
||||
|
||||
void bl31_plat_arch_setup(void)
|
||||
{
|
||||
hikey960_init_mmu_el3(BL31_BASE,
|
||||
BL31_LIMIT - BL31_BASE,
|
||||
BL31_RO_BASE,
|
||||
BL31_RO_LIMIT,
|
||||
BL31_COHERENT_RAM_BASE,
|
||||
BL31_COHERENT_RAM_LIMIT);
|
||||
}
|
||||
|
||||
void bl31_platform_setup(void)
|
||||
{
|
||||
/* Initialize the GIC driver, cpu and distributor interfaces */
|
||||
gicv2_driver_init(&hikey960_gic_data);
|
||||
gicv2_distif_init();
|
||||
gicv2_pcpu_distif_init();
|
||||
gicv2_cpuif_enable();
|
||||
|
||||
hisi_ipc_init();
|
||||
}
|
||||
|
||||
void bl31_plat_runtime_setup(void)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <delay_timer.h>
|
||||
#include <errno.h>
|
||||
#include <hi3660.h>
|
||||
#include <mmio.h>
|
||||
|
||||
#include "hikey960_private.h"
|
||||
|
||||
#define ADC_ADCIN0 0
|
||||
#define ADC_ADCIN1 1
|
||||
#define ADC_ADCIN2 2
|
||||
|
||||
#define HKADC_DATA_GRADE0 0
|
||||
#define HKADC_DATA_GRADE1 100
|
||||
#define HKADC_DATA_GRADE2 300
|
||||
#define HKADC_DATA_GRADE3 500
|
||||
#define HKADC_DATA_GRADE4 700
|
||||
#define HKADC_DATA_GRADE5 900
|
||||
#define HKADC_DATA_GRADE6 1100
|
||||
#define HKADC_DATA_GRADE7 1300
|
||||
#define HKADC_DATA_GRADE8 1500
|
||||
#define HKADC_DATA_GRADE9 1700
|
||||
#define HKADC_DATA_GRADE10 1800
|
||||
|
||||
#define BOARDID_VALUE0 0
|
||||
#define BOARDID_VALUE1 1
|
||||
#define BOARDID_VALUE2 2
|
||||
#define BOARDID_VALUE3 3
|
||||
#define BOARDID_VALUE4 4
|
||||
#define BOARDID_VALUE5 5
|
||||
#define BOARDID_VALUE6 6
|
||||
#define BOARDID_VALUE7 7
|
||||
#define BOARDID_VALUE8 8
|
||||
#define BOARDID_VALUE9 9
|
||||
#define BOARDID_UNKNOWN 0xF
|
||||
|
||||
#define BOARDID3_BASE 5
|
||||
|
||||
|
||||
static void init_adc(void)
|
||||
{
|
||||
/* reset hkadc */
|
||||
mmio_write_32(CRG_PERRSTEN2_REG, PERRSTEN2_HKADCSSI);
|
||||
/* wait a few clock cycles */
|
||||
udelay(2);
|
||||
mmio_write_32(CRG_PERRSTDIS2_REG, PERRSTEN2_HKADCSSI);
|
||||
udelay(2);
|
||||
/* enable hkadc clock */
|
||||
mmio_write_32(CRG_PERDIS2_REG, PEREN2_HKADCSSI);
|
||||
udelay(2);
|
||||
mmio_write_32(CRG_PEREN2_REG, PEREN2_HKADCSSI);
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
static int get_adc(unsigned int channel, unsigned int *value)
|
||||
{
|
||||
unsigned int data, value1, value0;
|
||||
|
||||
if (channel > HKADC_CHANNEL_MAX) {
|
||||
WARN("invalid channel:%d\n", channel);
|
||||
return -EFAULT;
|
||||
}
|
||||
/* configure the read/write operation for external HKADC */
|
||||
mmio_write_32(HKADC_WR01_DATA_REG, HKADC_WR01_VALUE | channel);
|
||||
mmio_write_32(HKADC_WR23_DATA_REG, HKADC_WR23_VALUE);
|
||||
mmio_write_32(HKADC_WR45_DATA_REG, HKADC_WR45_VALUE);
|
||||
/* configure the number of accessing registers */
|
||||
mmio_write_32(HKADC_WR_NUM_REG, HKADC_WR_NUM_VALUE);
|
||||
/* configure delay of accessing registers */
|
||||
mmio_write_32(HKADC_DELAY01_REG, HKADC_CHANNEL0_DELAY01_VALUE);
|
||||
mmio_write_32(HKADC_DELAY23_REG, HKADC_DELAY23_VALUE);
|
||||
|
||||
/* start HKADC */
|
||||
mmio_write_32(HKADC_DSP_START_REG, 1);
|
||||
do {
|
||||
data = mmio_read_32(HKADC_DSP_START_REG);
|
||||
} while (data & 1);
|
||||
|
||||
/* convert AD result */
|
||||
value1 = mmio_read_32(HKADC_DSP_RD2_DATA_REG) & 0xffff;
|
||||
value0 = mmio_read_32(HKADC_DSP_RD3_DATA_REG) & 0xffff;
|
||||
|
||||
data = ((value1 << 4) & HKADC_VALUE_HIGH) |
|
||||
((value0 >> 4) & HKADC_VALUE_LOW);
|
||||
*value = data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_value(unsigned int channel, unsigned int *value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = get_adc(channel, value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* convert ADC value to micro-volt */
|
||||
ret = ((*value & HKADC_VALID_VALUE) * HKADC_VREF_1V8) / HKADC_ACCURACY;
|
||||
*value = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adcin_data_remap(unsigned int adcin_value)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (adcin_value < HKADC_DATA_GRADE0)
|
||||
ret = BOARDID_UNKNOWN;
|
||||
else if (adcin_value < HKADC_DATA_GRADE1)
|
||||
ret = BOARDID_VALUE0;
|
||||
else if (adcin_value < HKADC_DATA_GRADE2)
|
||||
ret = BOARDID_VALUE1;
|
||||
else if (adcin_value < HKADC_DATA_GRADE3)
|
||||
ret = BOARDID_VALUE2;
|
||||
else if (adcin_value < HKADC_DATA_GRADE4)
|
||||
ret = BOARDID_VALUE3;
|
||||
else if (adcin_value < HKADC_DATA_GRADE5)
|
||||
ret = BOARDID_VALUE4;
|
||||
else if (adcin_value < HKADC_DATA_GRADE6)
|
||||
ret = BOARDID_VALUE5;
|
||||
else if (adcin_value < HKADC_DATA_GRADE7)
|
||||
ret = BOARDID_VALUE6;
|
||||
else if (adcin_value < HKADC_DATA_GRADE8)
|
||||
ret = BOARDID_VALUE7;
|
||||
else if (adcin_value < HKADC_DATA_GRADE9)
|
||||
ret = BOARDID_VALUE8;
|
||||
else if (adcin_value < HKADC_DATA_GRADE10)
|
||||
ret = BOARDID_VALUE9;
|
||||
else
|
||||
ret = BOARDID_UNKNOWN;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hikey960_read_boardid(unsigned int *id)
|
||||
{
|
||||
unsigned int adcin0, adcin1, adcin2;
|
||||
unsigned int adcin0_remap, adcin1_remap, adcin2_remap;
|
||||
|
||||
assert(id != NULL);
|
||||
|
||||
init_adc();
|
||||
|
||||
/* read ADC channel0 data */
|
||||
get_value(ADC_ADCIN0, &adcin0);
|
||||
adcin0_remap = adcin_data_remap(adcin0);
|
||||
INFO("[BDID]adcin0:%d adcin0_remap:%d\n", adcin0, adcin0_remap);
|
||||
if (adcin0_remap == BOARDID_UNKNOWN)
|
||||
return -EINVAL;
|
||||
/* read ADC channel1 data */
|
||||
get_value(ADC_ADCIN1, &adcin1);
|
||||
adcin1_remap = adcin_data_remap(adcin1);
|
||||
INFO("[BDID]adcin1:%d adcin1_remap:%d\n", adcin1, adcin1_remap);
|
||||
if (adcin1_remap == BOARDID_UNKNOWN)
|
||||
return -EINVAL;
|
||||
/* read ADC channel2 data */
|
||||
get_value(ADC_ADCIN2, &adcin2);
|
||||
adcin2_remap = adcin_data_remap(adcin2);
|
||||
INFO("[BDID]adcin2:%d adcin2_remap:%d\n", adcin2, adcin2_remap);
|
||||
if (adcin2_remap == BOARDID_UNKNOWN)
|
||||
return -EINVAL;
|
||||
*id = BOARDID3_BASE * 1000 + (adcin2_remap * 100) +
|
||||
(adcin1_remap * 10) + adcin0_remap;
|
||||
INFO("[BDID]boardid: %d\n", *id);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __HIKEY960_DEF_H__
|
||||
#define __HIKEY960_DEF_H__
|
||||
|
||||
#include <common_def.h>
|
||||
#include <tbbr_img_def.h>
|
||||
|
||||
#define DDR_BASE 0x0
|
||||
#define DDR_SIZE 0xC0000000
|
||||
|
||||
#define DEVICE_BASE 0xE0000000
|
||||
#define DEVICE_SIZE 0x20000000
|
||||
|
||||
/*
|
||||
* PL011 related constants
|
||||
*/
|
||||
#define PL011_UART5_BASE 0xFDF05000
|
||||
#define PL011_UART6_BASE 0xFFF32000
|
||||
#define PL011_BAUDRATE 115200
|
||||
#define PL011_UART_CLK_IN_HZ 19200000
|
||||
|
||||
#define UFS_BASE 0
|
||||
/* FIP partition */
|
||||
#define HIKEY960_FIP_BASE (UFS_BASE + 0x1400000)
|
||||
#define HIKEY960_FIP_MAX_SIZE (12 << 20)
|
||||
|
||||
#define HIKEY960_UFS_DESC_BASE 0x20000000
|
||||
#define HIKEY960_UFS_DESC_SIZE 0x00200000 /* 2MB */
|
||||
#define HIKEY960_UFS_DATA_BASE 0x10000000
|
||||
#define HIKEY960_UFS_DATA_SIZE 0x0A000000 /* 160MB */
|
||||
|
||||
#endif /* __HIKEY960_DEF_H__ */
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <firmware_image_package.h>
|
||||
#include <io_block.h>
|
||||
#include <io_driver.h>
|
||||
#include <io_fip.h>
|
||||
#include <io_memmap.h>
|
||||
#include <io_storage.h>
|
||||
#include <mmio.h>
|
||||
#include <platform_def.h>
|
||||
#include <semihosting.h> /* For FOPEN_MODE_... */
|
||||
#include <string.h>
|
||||
#include <ufs.h>
|
||||
|
||||
struct plat_io_policy {
|
||||
uintptr_t *dev_handle;
|
||||
uintptr_t image_spec;
|
||||
int (*check)(const uintptr_t spec);
|
||||
};
|
||||
|
||||
static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
|
||||
static uintptr_t ufs_dev_handle, fip_dev_handle;
|
||||
|
||||
static int check_ufs(const uintptr_t spec);
|
||||
static int check_fip(const uintptr_t spec);
|
||||
size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
|
||||
size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
|
||||
|
||||
static const io_block_spec_t ufs_fip_spec = {
|
||||
.offset = HIKEY960_FIP_BASE,
|
||||
.length = HIKEY960_FIP_MAX_SIZE,
|
||||
};
|
||||
|
||||
static const io_block_spec_t ufs_data_spec = {
|
||||
.offset = 0,
|
||||
.length = 256 << 20,
|
||||
};
|
||||
|
||||
static const io_block_dev_spec_t ufs_dev_spec = {
|
||||
/* It's used as temp buffer in block driver. */
|
||||
.buffer = {
|
||||
.offset = HIKEY960_UFS_DATA_BASE,
|
||||
.length = HIKEY960_UFS_DATA_SIZE,
|
||||
},
|
||||
.ops = {
|
||||
.read = ufs_read_lun3_blks,
|
||||
.write = ufs_write_lun3_blks,
|
||||
},
|
||||
.block_size = UFS_BLOCK_SIZE,
|
||||
};
|
||||
|
||||
static const io_uuid_spec_t bl2_uuid_spec = {
|
||||
.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
|
||||
};
|
||||
|
||||
static const io_uuid_spec_t scp_bl2_uuid_spec = {
|
||||
.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
|
||||
};
|
||||
|
||||
static const io_uuid_spec_t bl31_uuid_spec = {
|
||||
.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
|
||||
};
|
||||
|
||||
static const io_uuid_spec_t bl33_uuid_spec = {
|
||||
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
|
||||
};
|
||||
|
||||
static const struct plat_io_policy policies[] = {
|
||||
[FIP_IMAGE_ID] = {
|
||||
&ufs_dev_handle,
|
||||
(uintptr_t)&ufs_fip_spec,
|
||||
check_ufs
|
||||
},
|
||||
[BL2_IMAGE_ID] = {
|
||||
&fip_dev_handle,
|
||||
(uintptr_t)&bl2_uuid_spec,
|
||||
check_fip
|
||||
},
|
||||
[SCP_BL2_IMAGE_ID] = {
|
||||
&fip_dev_handle,
|
||||
(uintptr_t)&scp_bl2_uuid_spec,
|
||||
check_fip
|
||||
},
|
||||
[BL31_IMAGE_ID] = {
|
||||
&fip_dev_handle,
|
||||
(uintptr_t)&bl31_uuid_spec,
|
||||
check_fip
|
||||
},
|
||||
[BL33_IMAGE_ID] = {
|
||||
&fip_dev_handle,
|
||||
(uintptr_t)&bl33_uuid_spec,
|
||||
check_fip
|
||||
},
|
||||
[BL2U_IMAGE_ID] = {
|
||||
&ufs_dev_handle,
|
||||
(uintptr_t)&ufs_data_spec,
|
||||
check_ufs
|
||||
}
|
||||
};
|
||||
|
||||
static int check_ufs(const uintptr_t spec)
|
||||
{
|
||||
int result;
|
||||
uintptr_t local_handle;
|
||||
|
||||
result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
|
||||
if (result == 0) {
|
||||
result = io_open(ufs_dev_handle, spec, &local_handle);
|
||||
if (result == 0)
|
||||
io_close(local_handle);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int check_fip(const uintptr_t spec)
|
||||
{
|
||||
int result;
|
||||
uintptr_t local_image_handle;
|
||||
|
||||
/* See if a Firmware Image Package is available */
|
||||
result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
|
||||
if (result == 0) {
|
||||
result = io_open(fip_dev_handle, spec, &local_image_handle);
|
||||
if (result == 0) {
|
||||
VERBOSE("Using FIP\n");
|
||||
io_close(local_image_handle);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void hikey960_io_setup(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = register_io_dev_block(&ufs_dev_con);
|
||||
assert(result == 0);
|
||||
|
||||
result = register_io_dev_fip(&fip_dev_con);
|
||||
assert(result == 0);
|
||||
|
||||
result = io_dev_open(ufs_dev_con, (uintptr_t)&ufs_dev_spec,
|
||||
&ufs_dev_handle);
|
||||
assert(result == 0);
|
||||
|
||||
result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
|
||||
assert(result == 0);
|
||||
|
||||
/* Ignore improbable errors in release builds */
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* Return an IO device handle and specification which can be used to access
|
||||
* an image. Use this to enforce platform load policy
|
||||
*/
|
||||
int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
|
||||
uintptr_t *image_spec)
|
||||
{
|
||||
int result;
|
||||
const struct plat_io_policy *policy;
|
||||
|
||||
assert(image_id < ARRAY_SIZE(policies));
|
||||
|
||||
policy = &policies[image_id];
|
||||
result = policy->check(policy->image_spec);
|
||||
assert(result == 0);
|
||||
|
||||
*image_spec = policy->image_spec;
|
||||
*dev_handle = *(policy->dev_handle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size)
|
||||
{
|
||||
return ufs_read_blocks(3, lba, buf, size);
|
||||
}
|
||||
|
||||
size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size)
|
||||
{
|
||||
return ufs_write_blocks(3, lba, buf, size);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <debug.h>
|
||||
#include <delay_timer.h>
|
||||
#include <errno.h>
|
||||
#include <hi3660.h>
|
||||
#include <mmio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ADDR_CONVERT(addr) ((addr) < 0x40000 ? \
|
||||
(addr) + 0xFFF30000 : \
|
||||
(addr) + 0x40000000)
|
||||
|
||||
static void fw_data_init(void)
|
||||
{
|
||||
unsigned long data_head_addr;
|
||||
unsigned int *data_addr;
|
||||
|
||||
data_head_addr = mmio_read_32((uintptr_t) HISI_DATA_HEAD_BASE) + 0x14;
|
||||
data_addr = (unsigned int *) ADDR_CONVERT(data_head_addr);
|
||||
|
||||
memcpy((void *)HISI_DATA0_BASE,
|
||||
(const void *)(unsigned long)ADDR_CONVERT(data_addr[0]),
|
||||
HISI_DATA0_SIZE);
|
||||
memcpy((void *)HISI_DATA1_BASE,
|
||||
(const void *)(unsigned long)ADDR_CONVERT(data_addr[1]),
|
||||
HISI_DATA1_SIZE);
|
||||
}
|
||||
|
||||
int load_lpm3(void)
|
||||
{
|
||||
INFO("start fw loading\n");
|
||||
|
||||
fw_data_init();
|
||||
|
||||
flush_dcache_range((uintptr_t)HISI_RESERVED_MEM_BASE,
|
||||
HISI_RESERVED_MEM_SIZE);
|
||||
|
||||
sev();
|
||||
sev();
|
||||
|
||||
INFO("fw load success\n");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <cci.h>
|
||||
#include <console.h>
|
||||
#include <debug.h>
|
||||
#include <gicv2.h>
|
||||
#include <hi3660.h>
|
||||
#include <hi3660_crg.h>
|
||||
#include <mmio.h>
|
||||
#include <psci.h>
|
||||
#include "drivers/pwrc/hisi_pwrc.h"
|
||||
|
||||
#include "hikey960_def.h"
|
||||
#include "hikey960_private.h"
|
||||
|
||||
#define CORE_PWR_STATE(state) \
|
||||
((state)->pwr_domain_state[MPIDR_AFFLVL0])
|
||||
#define CLUSTER_PWR_STATE(state) \
|
||||
((state)->pwr_domain_state[MPIDR_AFFLVL1])
|
||||
#define SYSTEM_PWR_STATE(state) \
|
||||
((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
|
||||
|
||||
#define DMAC_GLB_REG_SEC 0x694
|
||||
#define AXI_CONF_BASE 0x820
|
||||
|
||||
static uintptr_t hikey960_sec_entrypoint;
|
||||
|
||||
static void hikey960_pwr_domain_standby(plat_local_state_t cpu_state)
|
||||
{
|
||||
unsigned long scr;
|
||||
unsigned int val = 0;
|
||||
|
||||
assert(cpu_state == PLAT_MAX_RET_STATE);
|
||||
|
||||
scr = read_scr_el3();
|
||||
|
||||
/* Enable Physical IRQ and FIQ to wake the CPU*/
|
||||
write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT);
|
||||
|
||||
set_retention_ticks(val);
|
||||
wfi();
|
||||
clr_retention_ticks(val);
|
||||
|
||||
/*
|
||||
* Restore SCR to the original value, synchronisazion of
|
||||
* scr_el3 is done by eret while el3_exit to save some
|
||||
* execution cycles.
|
||||
*/
|
||||
write_scr_el3(scr);
|
||||
}
|
||||
|
||||
static int hikey960_pwr_domain_on(u_register_t mpidr)
|
||||
{
|
||||
unsigned int core = mpidr & MPIDR_CPU_MASK;
|
||||
unsigned int cluster =
|
||||
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
|
||||
int cluster_stat = cluster_is_powered_on(cluster);
|
||||
|
||||
hisi_set_cpu_boot_flag(cluster, core);
|
||||
|
||||
mmio_write_32(CRG_REG_BASE + CRG_RVBAR(cluster, core),
|
||||
hikey960_sec_entrypoint >> 2);
|
||||
|
||||
if (cluster_stat)
|
||||
hisi_powerup_core(cluster, core);
|
||||
else
|
||||
hisi_powerup_cluster(cluster, core);
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
hikey960_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
|
||||
cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
|
||||
|
||||
gicv2_pcpu_distif_init();
|
||||
gicv2_cpuif_enable();
|
||||
}
|
||||
|
||||
void hikey960_pwr_domain_off(const psci_power_state_t *target_state)
|
||||
{
|
||||
unsigned long mpidr = read_mpidr_el1();
|
||||
unsigned int core = mpidr & MPIDR_CPU_MASK;
|
||||
unsigned int cluster =
|
||||
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
|
||||
|
||||
clr_ex();
|
||||
isb();
|
||||
dsbsy();
|
||||
|
||||
gicv2_cpuif_disable();
|
||||
|
||||
hisi_clear_cpu_boot_flag(cluster, core);
|
||||
hisi_powerdn_core(cluster, core);
|
||||
|
||||
/* check if any core is powered up */
|
||||
if (hisi_test_pwrdn_allcores(cluster, core)) {
|
||||
|
||||
cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
|
||||
|
||||
isb();
|
||||
dsbsy();
|
||||
|
||||
hisi_powerdn_cluster(cluster, core);
|
||||
}
|
||||
}
|
||||
|
||||
static void __dead2 hikey960_system_reset(void)
|
||||
{
|
||||
mmio_write_32(SCTRL_SCPEREN1_REG,
|
||||
SCPEREN1_WAIT_DDR_SELFREFRESH_DONE_BYPASS);
|
||||
mmio_write_32(SCTRL_SCSYSSTAT_REG, 0xdeadbeef);
|
||||
panic();
|
||||
}
|
||||
|
||||
int hikey960_validate_power_state(unsigned int power_state,
|
||||
psci_power_state_t *req_state)
|
||||
{
|
||||
int pstate = psci_get_pstate_type(power_state);
|
||||
int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
|
||||
int i;
|
||||
|
||||
assert(req_state);
|
||||
|
||||
if (pwr_lvl > PLAT_MAX_PWR_LVL)
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
/* Sanity check the requested state */
|
||||
if (pstate == PSTATE_TYPE_STANDBY) {
|
||||
/*
|
||||
* It's possible to enter standby only on power level 0
|
||||
* Ignore any other power level.
|
||||
*/
|
||||
if (pwr_lvl != MPIDR_AFFLVL0)
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
req_state->pwr_domain_state[MPIDR_AFFLVL0] =
|
||||
PLAT_MAX_RET_STATE;
|
||||
} else {
|
||||
for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++)
|
||||
req_state->pwr_domain_state[i] =
|
||||
PLAT_MAX_OFF_STATE;
|
||||
}
|
||||
|
||||
/*
|
||||
* We expect the 'state id' to be zero.
|
||||
*/
|
||||
if (psci_get_pstate_id(power_state))
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
static int hikey960_validate_ns_entrypoint(uintptr_t entrypoint)
|
||||
{
|
||||
/*
|
||||
* Check if the non secure entrypoint lies within the non
|
||||
* secure DRAM.
|
||||
*/
|
||||
if ((entrypoint > DDR_BASE) && (entrypoint < (DDR_BASE + DDR_SIZE)))
|
||||
return PSCI_E_SUCCESS;
|
||||
|
||||
return PSCI_E_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
static void hikey960_pwr_domain_suspend(const psci_power_state_t *target_state)
|
||||
{
|
||||
u_register_t mpidr = read_mpidr_el1();
|
||||
unsigned int core = mpidr & MPIDR_CPU_MASK;
|
||||
unsigned int cluster =
|
||||
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
|
||||
|
||||
if (CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
|
||||
return;
|
||||
|
||||
if (CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
|
||||
clr_ex();
|
||||
isb();
|
||||
dsbsy();
|
||||
|
||||
gicv2_cpuif_disable();
|
||||
|
||||
hisi_cpuidle_lock(cluster, core);
|
||||
hisi_set_cpuidle_flag(cluster, core);
|
||||
hisi_cpuidle_unlock(cluster, core);
|
||||
|
||||
mmio_write_32(CRG_REG_BASE + CRG_RVBAR(cluster, core),
|
||||
hikey960_sec_entrypoint >> 2);
|
||||
|
||||
hisi_enter_core_idle(cluster, core);
|
||||
}
|
||||
|
||||
/* Perform the common cluster specific operations */
|
||||
if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
|
||||
hisi_cpuidle_lock(cluster, core);
|
||||
hisi_disable_pdc(cluster);
|
||||
|
||||
/* check if any core is powered up */
|
||||
if (hisi_test_pwrdn_allcores(cluster, core)) {
|
||||
|
||||
cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
|
||||
|
||||
isb();
|
||||
dsbsy();
|
||||
|
||||
/* mask the pdc wakeup irq, then
|
||||
* enable pdc to power down the core
|
||||
*/
|
||||
hisi_pdc_mask_cluster_wakeirq(cluster);
|
||||
hisi_enable_pdc(cluster);
|
||||
|
||||
hisi_cpuidle_unlock(cluster, core);
|
||||
|
||||
/* check the SR flag bit to determine
|
||||
* CLUSTER_IDLE_IPC or AP_SR_IPC to send
|
||||
*/
|
||||
if (hisi_test_ap_suspend_flag(cluster))
|
||||
hisi_enter_ap_suspend(cluster, core);
|
||||
else
|
||||
hisi_enter_cluster_idle(cluster, core);
|
||||
} else {
|
||||
/* enable pdc */
|
||||
hisi_enable_pdc(cluster);
|
||||
hisi_cpuidle_unlock(cluster, core);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void hikey960_sr_dma_reinit(void)
|
||||
{
|
||||
unsigned int ctr = 0;
|
||||
|
||||
mmio_write_32(DMAC_BASE + DMAC_GLB_REG_SEC, 0x3);
|
||||
|
||||
/* 1~15 channel is set non_secure */
|
||||
for (ctr = 1; ctr <= 15; ctr++)
|
||||
mmio_write_32(DMAC_BASE + AXI_CONF_BASE + ctr * (0x40),
|
||||
(1 << 6) | (1 << 18));
|
||||
}
|
||||
|
||||
static void
|
||||
hikey960_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
unsigned long mpidr = read_mpidr_el1();
|
||||
unsigned int cluster =
|
||||
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
|
||||
|
||||
/* Nothing to be done on waking up from retention from CPU level */
|
||||
if (CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
|
||||
return;
|
||||
|
||||
if (hisi_test_ap_suspend_flag(cluster)) {
|
||||
hikey960_sr_dma_reinit();
|
||||
gicv2_cpuif_enable();
|
||||
console_init(PL011_UART6_BASE, PL011_UART_CLK_IN_HZ,
|
||||
PL011_BAUDRATE);
|
||||
}
|
||||
|
||||
hikey960_pwr_domain_on_finish(target_state);
|
||||
}
|
||||
|
||||
static void hikey960_get_sys_suspend_power_state(psci_power_state_t *req_state)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
|
||||
req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
|
||||
}
|
||||
|
||||
static const plat_psci_ops_t hikey960_psci_ops = {
|
||||
.cpu_standby = hikey960_pwr_domain_standby,
|
||||
.pwr_domain_on = hikey960_pwr_domain_on,
|
||||
.pwr_domain_on_finish = hikey960_pwr_domain_on_finish,
|
||||
.pwr_domain_off = hikey960_pwr_domain_off,
|
||||
.pwr_domain_suspend = hikey960_pwr_domain_suspend,
|
||||
.pwr_domain_suspend_finish = hikey960_pwr_domain_suspend_finish,
|
||||
.system_off = NULL,
|
||||
.system_reset = hikey960_system_reset,
|
||||
.validate_power_state = hikey960_validate_power_state,
|
||||
.validate_ns_entrypoint = hikey960_validate_ns_entrypoint,
|
||||
.get_sys_suspend_power_state = hikey960_get_sys_suspend_power_state,
|
||||
};
|
||||
|
||||
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
|
||||
const plat_psci_ops_t **psci_ops)
|
||||
{
|
||||
hikey960_sec_entrypoint = sec_entrypoint;
|
||||
|
||||
INFO("%s: sec_entrypoint=0x%lx\n", __func__,
|
||||
(unsigned long)hikey960_sec_entrypoint);
|
||||
|
||||
/*
|
||||
* Initialize PSCI ops struct
|
||||
*/
|
||||
*psci_ops = &hikey960_psci_ops;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __HIKEY960_PRIVATE_H__
|
||||
#define __HIKEY960_PRIVATE_H__
|
||||
|
||||
#include <bl_common.h>
|
||||
|
||||
/*
|
||||
* Function and variable prototypes
|
||||
*/
|
||||
void hikey960_init_mmu_el1(unsigned long total_base,
|
||||
unsigned long total_size,
|
||||
unsigned long ro_start,
|
||||
unsigned long ro_limit,
|
||||
unsigned long coh_start,
|
||||
unsigned long coh_limit);
|
||||
void hikey960_init_mmu_el3(unsigned long total_base,
|
||||
unsigned long total_size,
|
||||
unsigned long ro_start,
|
||||
unsigned long ro_limit,
|
||||
unsigned long coh_start,
|
||||
unsigned long coh_limit);
|
||||
void hikey960_io_setup(void);
|
||||
int hikey960_read_boardid(unsigned int *id);
|
||||
void set_retention_ticks(unsigned int val);
|
||||
void clr_retention_ticks(unsigned int val);
|
||||
void clr_ex(void);
|
||||
void nop(void);
|
||||
|
||||
#endif /* __HIKEY960_PRIVATE_H__ */
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <arch.h>
|
||||
#include <platform_def.h>
|
||||
#include <psci.h>
|
||||
|
||||
/*
|
||||
* The HiKey power domain tree descriptor. The cluster power domains
|
||||
* are arranged so that when the PSCI generic code creates the power
|
||||
* domain tree, the indices of the CPU power domain nodes it allocates
|
||||
* match the linear indices returned by plat_core_pos_by_mpidr().
|
||||
*/
|
||||
const unsigned char hikey960_power_domain_tree_desc[] = {
|
||||
/* Number of root nodes */
|
||||
1,
|
||||
/* Number of clusters */
|
||||
PLATFORM_CLUSTER_COUNT,
|
||||
/* Number of children for the first cluster node */
|
||||
PLATFORM_CORE_COUNT_PER_CLUSTER,
|
||||
/* Number of children for the second cluster node */
|
||||
PLATFORM_CORE_COUNT_PER_CLUSTER,
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* This function returns the HiKey topology tree information.
|
||||
******************************************************************************/
|
||||
const unsigned char *plat_get_power_domain_tree_desc(void)
|
||||
{
|
||||
return hikey960_power_domain_tree_desc;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function implements a part of the critical interface between the psci
|
||||
* generic layer and the platform that allows the former to query the platform
|
||||
* to convert an MPIDR to a unique linear index. An error code (-1) is returned
|
||||
* in case the MPIDR is invalid.
|
||||
******************************************************************************/
|
||||
int plat_core_pos_by_mpidr(u_register_t mpidr)
|
||||
{
|
||||
unsigned int cluster_id, cpu_id;
|
||||
|
||||
mpidr &= MPIDR_AFFINITY_MASK;
|
||||
|
||||
if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
|
||||
return -1;
|
||||
|
||||
cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
|
||||
cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
|
||||
|
||||
if (cluster_id >= PLATFORM_CLUSTER_COUNT)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Validate cpu_id by checking whether it represents a CPU in
|
||||
* one of the two clusters present on the platform.
|
||||
*/
|
||||
if (cpu_id >= PLATFORM_CORE_COUNT_PER_CLUSTER)
|
||||
return -1;
|
||||
|
||||
return (cpu_id + (cluster_id * 4));
|
||||
}
|
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef __HI3660_H__
|
||||
#define __HI3660_H__
|
||||
|
||||
#include <hi3660_crg.h>
|
||||
#include <hi3660_hkadc.h>
|
||||
#include <hi3660_mem_map.h>
|
||||
|
||||
#define ASP_CFG_REG_BASE 0xE804E000
|
||||
|
||||
#define ASP_CFG_MMBUF_CTRL_REG (ASP_CFG_REG_BASE + 0x148)
|
||||
|
||||
#define LP_RAM_BASE 0xFFF50000
|
||||
|
||||
#define SCTRL_REG_BASE 0xFFF0A000
|
||||
|
||||
#define SCTRL_CONTROL_REG (SCTRL_REG_BASE + 0x000)
|
||||
#define SCTRL_CONTROL_SYS_MODE(x) (((x) & 0xf) << 3)
|
||||
#define SCTRL_CONTROL_SYS_MODE_NORMAL ((1 << 2) << 3)
|
||||
#define SCTRL_CONTROL_SYS_MODE_SLOW ((1 << 1) << 3)
|
||||
#define SCTRL_CONTROL_SYS_MODE_MASK (0xf << 3)
|
||||
#define SCTRL_CONTROL_MODE_CTRL_NORMAL (1 << 2)
|
||||
#define SCTRL_CONTROL_MODE_CTRL_SLOW (1 << 1)
|
||||
#define SCTRL_CONTROL_MODE_CTRL_MASK 0x7
|
||||
|
||||
#define SCTRL_SCSYSSTAT_REG (SCTRL_REG_BASE + 0x004)
|
||||
|
||||
#define SCTRL_DEEPSLEEPED_REG (SCTRL_REG_BASE + 0x008)
|
||||
#define SCTRL_EFUSE_USB_MASK (1 << 30)
|
||||
#define SCTRL_EFUSE_USB_PLL (1 << 30)
|
||||
#define SCTRL_EFUSE_USB_ABB (0 << 30)
|
||||
#define SCTRL_EFUSE_UFS_MASK (3 << 6)
|
||||
#define SCTRL_EFUSE_UFS_PLL (1 << 6)
|
||||
#define SCTRL_EFUSE_UFS_ABB (0 << 6)
|
||||
|
||||
#define SCTRL_SCISOEN_REG (SCTRL_REG_BASE + 0x040)
|
||||
#define SCTRL_SCISODIS_REG (SCTRL_REG_BASE + 0x044)
|
||||
#define SCISO_MMBUFISO (1 << 3)
|
||||
|
||||
#define SCTRL_SCPWREN_REG (SCTRL_REG_BASE + 0x060)
|
||||
#define SCPWREN_MMBUFPWREN (1 << 3)
|
||||
|
||||
#define SCTRL_PLL_CTRL0_REG (SCTRL_REG_BASE + 0x100)
|
||||
#define SCTRL_PLL0_POSTDIV2(x) (((x) & 0x7) << 23)
|
||||
#define SCTRL_PLL0_POSTDIV1(x) (((x) & 0x7) << 20)
|
||||
#define SCTRL_PLL0_FBDIV(x) (((x) & 0xfff) << 8)
|
||||
#define SCTRL_PLL0_REFDIV(x) (((x) & 0x3f) << 2)
|
||||
#define SCTRL_PLL0_EN (1 << 0)
|
||||
|
||||
#define SCTRL_PLL_CTRL1_REG (SCTRL_REG_BASE + 0x104)
|
||||
#define SCTRL_PLL0_CLK_NO_GATE (1 << 26)
|
||||
#define SCTRL_PLL0_CFG_VLD (1 << 25)
|
||||
#define SCTRL_PLL0_FRACDIV(x) ((x) & 0xFFFFFF)
|
||||
|
||||
#define SCTRL_PLL_STAT_REG (SCTRL_REG_BASE + 0x10C)
|
||||
#define SCTRL_PLL0_STAT (1 << 0)
|
||||
|
||||
#define SCTRL_SCPEREN0_REG (SCTRL_REG_BASE + 0x160)
|
||||
#define SCTRL_SCPERDIS0_REG (SCTRL_REG_BASE + 0x164)
|
||||
#define SCTRL_SCPERSTAT0_REG (SCTRL_REG_BASE + 0x168)
|
||||
|
||||
#define SCTRL_SCPEREN1_REG (SCTRL_REG_BASE + 0x170)
|
||||
#define SCTRL_SCPERDIS1_REG (SCTRL_REG_BASE + 0x174)
|
||||
#define SCTRL_SCPEREN1_REG (SCTRL_REG_BASE + 0x170)
|
||||
#define SCTRL_SCPERDIS1_REG (SCTRL_REG_BASE + 0x174)
|
||||
#define SCPEREN1_WAIT_DDR_SELFREFRESH_DONE_BYPASS (1 << 31)
|
||||
#define SCPEREN_GT_PCLK_MMBUFCFG (1 << 25)
|
||||
#define SCPEREN_GT_PCLK_MMBUF (1 << 23)
|
||||
#define SCPEREN_GT_ACLK_MMBUF (1 << 22)
|
||||
#define SCPEREN_GT_CLK_NOC_AOBUS2MMBUF (1 << 6)
|
||||
|
||||
#define SCTRL_SCPEREN2_REG (SCTRL_REG_BASE + 0x190)
|
||||
#define SCTRL_SCPERDIS2_REG (SCTRL_REG_BASE + 0x194)
|
||||
#define SCTRL_SCPERSTAT2_REG (SCTRL_REG_BASE + 0x198)
|
||||
#define SCTRL_SCPERRSTEN0_REG (SCTRL_REG_BASE + 0x200)
|
||||
#define SCTRL_SCPERRSTDIS0_REG (SCTRL_REG_BASE + 0x204)
|
||||
#define SCTRL_SCPERRSTSTAT0_REG (SCTRL_REG_BASE + 0x208)
|
||||
#define SCTRL_SCPERRSTEN1_REG (SCTRL_REG_BASE + 0x20C)
|
||||
#define SCTRL_SCPERRSTDIS1_REG (SCTRL_REG_BASE + 0x210)
|
||||
#define SCTRL_SCPERRSTSTAT1_REG (SCTRL_REG_BASE + 0x214)
|
||||
#define IP_RST_MMBUFCFG (1 << 12)
|
||||
#define IP_RST_MMBUF (1 << 11)
|
||||
|
||||
#define SCTRL_SCPERRSTEN2_REG (SCTRL_REG_BASE + 0x218)
|
||||
#define SCTRL_SCPERRSTDIS2_REG (SCTRL_REG_BASE + 0x21C)
|
||||
#define SCTRL_SCPERRSTSTAT2_REG (SCTRL_REG_BASE + 0x220)
|
||||
|
||||
#define SCTRL_SCCLKDIV2_REG (SCTRL_REG_BASE + 0x258)
|
||||
#define SEL_CLK_MMBUF_MASK (0x3 << 8)
|
||||
#define SEL_CLK_MMBUF_PLL0 (0x3 << 8)
|
||||
#define SCCLKDIV2_GT_PCLK_MMBUF (1 << 7)
|
||||
|
||||
#define SCTRL_SCCLKDIV4_REG (SCTRL_REG_BASE + 0x260)
|
||||
#define GT_MMBUF_SYS (1 << 13)
|
||||
#define GT_MMBUF_FLL (1 << 12)
|
||||
#define GT_PLL_CLK_MMBUF (1 << 11)
|
||||
|
||||
#define SCTRL_SCCLKDIV6_REG (SCTRL_REG_BASE + 0x268)
|
||||
|
||||
#define SCTRL_SCPERCTRL7_REG (SCTRL_REG_BASE + 0x31C)
|
||||
#define SCTRL_SCPERSTAT6_REG (SCTRL_REG_BASE + 0x378)
|
||||
|
||||
#define SCTRL_SCINNERSTAT_REG (SCTRL_REG_BASE + 0x3A0)
|
||||
#define EMMC_UFS_SEL (1 << 15)
|
||||
|
||||
#define SCTRL_BAK_DATA0_REG (SCTRL_REG_BASE + 0x40C)
|
||||
#define SCTRL_BAK_DATA4_REG (SCTRL_REG_BASE + 0x41C)
|
||||
|
||||
#define SCTRL_LPMCU_CLKEN_REG (SCTRL_REG_BASE + 0x480)
|
||||
#define SCTRL_LPMCU_CLKDIS_REG (SCTRL_REG_BASE + 0x484)
|
||||
#define SCTRL_LPMCU_RSTEN_REG (SCTRL_REG_BASE + 0x500)
|
||||
#define SCTRL_LPMCU_RSTDIS_REG (SCTRL_REG_BASE + 0x504)
|
||||
#define DDRC_SOFT_BIT (1 << 6)
|
||||
#define DDRC_CLK_BIT (1 << 5)
|
||||
|
||||
#define SCTRL_SCPEREN0_SEC_REG (SCTRL_REG_BASE + 0x900)
|
||||
#define SCTRL_SCPERDIS0_SEC_REG (SCTRL_REG_BASE + 0x904)
|
||||
#define MMBUF_SEC_CTRL_MASK (0xfff << 20)
|
||||
#define MMBUF_SEC_CTRL(x) (((x) & 0xfff) << 20)
|
||||
|
||||
#define SCTRL_PERRSTEN1_SEC_REG (SCTRL_REG_BASE + 0xA50)
|
||||
#define SCTRL_PERRSTDIS1_SEC_REG (SCTRL_REG_BASE + 0xA54)
|
||||
#define SCTRL_PERRSTSTAT1_SEC_REG (SCTRL_REG_BASE + 0xA58)
|
||||
#define RST_ASP_SUBSYS_BIT (1 << 0)
|
||||
|
||||
#define SCTRL_PERRSTEN2_SEC_REG (SCTRL_REG_BASE + 0xB50)
|
||||
#define SCTRL_PERRSTDIS2_SEC_REG (SCTRL_REG_BASE + 0xB54)
|
||||
#define SCTRL_PERRSTSTAT2_SEC_REG (SCTRL_REG_BASE + 0xB58)
|
||||
|
||||
#define SCTRL_HISEECLKDIV_REG (SCTRL_REG_BASE + 0xC28)
|
||||
#define SC_SEL_HISEE_PLL_MASK (1 << 4)
|
||||
#define SC_SEL_HISEE_PLL0 (1 << 4)
|
||||
#define SC_SEL_HISEE_PLL2 (0 << 4)
|
||||
#define SC_DIV_HISEE_PLL_MASK (7 << 16)
|
||||
#define SC_DIV_HISEE_PLL(x) ((x) & 0x7)
|
||||
|
||||
#define SCTRL_SCSOCID0_REG (SCTRL_REG_BASE + 0xE00)
|
||||
|
||||
#define PMC_REG_BASE 0xFFF31000
|
||||
#define PMC_PPLL1_CTRL0_REG (PMC_REG_BASE + 0x038)
|
||||
#define PMC_PPLL1_CTRL1_REG (PMC_REG_BASE + 0x03C)
|
||||
#define PMC_PPLL2_CTRL0_REG (PMC_REG_BASE + 0x040)
|
||||
#define PMC_PPLL2_CTRL1_REG (PMC_REG_BASE + 0x044)
|
||||
#define PMC_PPLL3_CTRL0_REG (PMC_REG_BASE + 0x048)
|
||||
#define PMC_PPLL3_CTRL1_REG (PMC_REG_BASE + 0x04C)
|
||||
#define PPLLx_LOCK (1 << 26)
|
||||
#define PPLLx_WITHOUT_CLK_GATE (1 << 26)
|
||||
#define PPLLx_CFG_VLD (1 << 25)
|
||||
#define PPLLx_INT_MOD (1 << 24)
|
||||
#define PPLLx_POSTDIV2_MASK (0x7 << 23)
|
||||
#define PPLLx_POSTDIV2(x) (((x) & 0x7) << 23)
|
||||
#define PPLLx_POSTDIV1_MASK (0x7 << 20)
|
||||
#define PPLLx_POSTDIV1(x) (((x) & 0x7) << 20)
|
||||
#define PPLLx_FRACDIV_MASK (0x00FFFFFF)
|
||||
#define PPLLx_FRACDIV(x) ((x) & 0x00FFFFFF)
|
||||
#define PPLLx_FBDIV_MASK (0xfff << 8)
|
||||
#define PPLLx_FBDIV(x) (((x) & 0xfff) << 8)
|
||||
#define PPLLx_REFDIV_MASK (0x3f << 2)
|
||||
#define PPLLx_REFDIV(x) (((x) & 0x3f) << 2)
|
||||
#define PPLLx_BP (1 << 1)
|
||||
#define PPLLx_EN (1 << 0)
|
||||
|
||||
#define PMC_DDRLP_CTRL_REG (PMC_REG_BASE + 0x30C)
|
||||
#define DDRC_CSYSREQ_CFG(x) ((x) & 0xF)
|
||||
|
||||
#define PMC_NOC_POWER_IDLEREQ_REG (PMC_REG_BASE + 0x380)
|
||||
#define PMC_NOC_POWER_IDLEREQ_IVP (1 << 14)
|
||||
#define PMC_NOC_POWER_IDLEREQ_DSS (1 << 13)
|
||||
#define PMC_NOC_POWER_IDLEREQ_VENC (1 << 11)
|
||||
#define PMC_NOC_POWER_IDLEREQ_VDEC (1 << 10)
|
||||
#define PMC_NOC_POWER_IDLEREQ_ISP (1 << 5)
|
||||
#define PMC_NOC_POWER_IDLEREQ_VCODEC (1 << 4)
|
||||
#define DDRPHY_BYPASS_MODE (1 << 0)
|
||||
|
||||
#define PMC_NOC_POWER_IDLEACK_REG (PMC_REG_BASE + 0x384)
|
||||
#define PMC_NOC_POWER_IDLE_REG (PMC_REG_BASE + 0x388)
|
||||
|
||||
#define PMU_SSI0_REG_BASE 0xFFF34000
|
||||
|
||||
#define PMU_SSI0_LDO8_CTRL0_REG (PMU_SSI0_REG_BASE + (0x68 << 2))
|
||||
#define LDO8_CTRL0_EN_1_8V 0x02
|
||||
|
||||
#define PMU_SSI0_CLK_TOP_CTRL7_REG (PMU_SSI0_REG_BASE + (0x10C << 2))
|
||||
#define NP_XO_ABB_DIG (1 << 1)
|
||||
|
||||
#define LP_CONFIG_REG_BASE 0xFFF3F000
|
||||
|
||||
#define DMAC_BASE 0xFDF30000
|
||||
|
||||
#define CCI400_REG_BASE 0xE8100000
|
||||
#define CCI400_SL_IFACE3_CLUSTER_IX 0
|
||||
#define CCI400_SL_IFACE4_CLUSTER_IX 1
|
||||
|
||||
#define GICD_REG_BASE 0xE82B1000
|
||||
#define GICC_REG_BASE 0xE82B2000
|
||||
/*
|
||||
* GIC400 interrupt handling related constants
|
||||
*/
|
||||
#define IRQ_SEC_PHY_TIMER 29
|
||||
#define IRQ_SEC_SGI_0 8
|
||||
#define IRQ_SEC_SGI_1 9
|
||||
#define IRQ_SEC_SGI_2 10
|
||||
#define IRQ_SEC_SGI_3 11
|
||||
#define IRQ_SEC_SGI_4 12
|
||||
#define IRQ_SEC_SGI_5 13
|
||||
#define IRQ_SEC_SGI_6 14
|
||||
#define IRQ_SEC_SGI_7 15
|
||||
#define IRQ_SEC_SGI_8 16
|
||||
|
||||
#define IPC_REG_BASE 0xE896A000
|
||||
#define IPC_BASE (IPC_REG_BASE)
|
||||
|
||||
#define IOMG_REG_BASE 0xE896C000
|
||||
|
||||
/* GPIO46: HUB 3.3V enable. active low */
|
||||
#define IOMG_044_REG (IOMG_REG_BASE + 0x0B0)
|
||||
#define IOMG_UART5_RX_REG (IOMG_REG_BASE + 0x0BC)
|
||||
#define IOMG_UART5_TX_REG (IOMG_REG_BASE + 0x0C0)
|
||||
|
||||
#define IOCG_REG_BASE 0xE896C800
|
||||
|
||||
/* GPIO005: PMIC SSI. (2 << 4) */
|
||||
#define IOCG_006_REG (IOCG_REG_BASE + 0x018)
|
||||
|
||||
#define TIMER9_REG_BASE 0xE8A00000
|
||||
|
||||
#define WDT0_REG_BASE 0xE8A06000
|
||||
#define WDT1_REG_BASE 0xE8A07000
|
||||
#define WDT_CONTROL_OFFSET 0x008
|
||||
#define WDT_LOCK_OFFSET 0xC00
|
||||
|
||||
#define WDT_UNLOCK 0x1ACCE551
|
||||
#define WDT_LOCKED 1
|
||||
|
||||
#define PCTRL_REG_BASE 0xE8A09000
|
||||
#define PCTRL_PERI_CTRL3_REG (PCTRL_REG_BASE + 0x010)
|
||||
#define PCTRL_PERI_CTRL24_REG (PCTRL_REG_BASE + 0x064)
|
||||
|
||||
#define TZC_REG_BASE 0xE8A21000
|
||||
#define TZC_STAT0_REG (TZC_REG_BASE + 0x800)
|
||||
#define TZC_EN0_REG (TZC_REG_BASE + 0x804)
|
||||
#define TZC_DIS0_REG (TZC_REG_BASE + 0x808)
|
||||
#define TZC_STAT1_REG (TZC_REG_BASE + 0x80C)
|
||||
#define TZC_EN1_REG (TZC_REG_BASE + 0x810)
|
||||
#define TZC_DIS1_REG (TZC_REG_BASE + 0x814)
|
||||
#define TZC_STAT2_REG (TZC_REG_BASE + 0x818)
|
||||
#define TZC_EN2_REG (TZC_REG_BASE + 0x81C)
|
||||
#define TZC_DIS2_REG (TZC_REG_BASE + 0x820)
|
||||
#define TZC_STAT3_REG (TZC_REG_BASE + 0x824)
|
||||
#define TZC_EN3_REG (TZC_REG_BASE + 0x828)
|
||||
#define TZC_DIS3_REG (TZC_REG_BASE + 0x82C)
|
||||
#define TZC_STAT4_REG (TZC_REG_BASE + 0x830)
|
||||
#define TZC_EN4_REG (TZC_REG_BASE + 0x834)
|
||||
#define TZC_DIS4_REG (TZC_REG_BASE + 0x838)
|
||||
#define TZC_STAT5_REG (TZC_REG_BASE + 0x83C)
|
||||
#define TZC_EN5_REG (TZC_REG_BASE + 0x840)
|
||||
#define TZC_DIS5_REG (TZC_REG_BASE + 0x844)
|
||||
#define TZC_STAT6_REG (TZC_REG_BASE + 0x848)
|
||||
#define TZC_EN6_REG (TZC_REG_BASE + 0x84C)
|
||||
#define TZC_DIS6_REG (TZC_REG_BASE + 0x850)
|
||||
#define TZC_STAT7_REG (TZC_REG_BASE + 0x854)
|
||||
#define TZC_EN7_REG (TZC_REG_BASE + 0x858)
|
||||
#define TZC_DIS7_REG (TZC_REG_BASE + 0x85C)
|
||||
#define TZC_STAT8_REG (TZC_REG_BASE + 0x860)
|
||||
#define TZC_EN8_REG (TZC_REG_BASE + 0x864)
|
||||
#define TZC_DIS8_REG (TZC_REG_BASE + 0x868)
|
||||
|
||||
#define MMBUF_BASE 0xEA800000
|
||||
|
||||
#define ACPU_DMCPACK0_BASE 0xEA900000
|
||||
|
||||
#define ACPU_DMCPACK1_BASE 0xEA920000
|
||||
|
||||
#define ACPU_DMCPACK2_BASE 0xEA940000
|
||||
|
||||
#define ACPU_DMCPACK3_BASE 0xEA960000
|
||||
|
||||
#define UART5_REG_BASE 0xFDF05000
|
||||
|
||||
#define USB3OTG_REG_BASE 0xFF100000
|
||||
|
||||
#define UFS_REG_BASE 0xFF3B0000
|
||||
|
||||
#define UFS_SYS_REG_BASE 0xFF3B1000
|
||||
|
||||
#define UFS_SYS_PSW_POWER_CTRL_REG (UFS_SYS_REG_BASE + 0x004)
|
||||
#define UFS_SYS_PHY_ISO_EN_REG (UFS_SYS_REG_BASE + 0x008)
|
||||
#define UFS_SYS_HC_LP_CTRL_REG (UFS_SYS_REG_BASE + 0x00C)
|
||||
#define UFS_SYS_PHY_CLK_CTRL_REG (UFS_SYS_REG_BASE + 0x010)
|
||||
#define UFS_SYS_PSW_CLK_CTRL_REG (UFS_SYS_REG_BASE + 0x014)
|
||||
#define UFS_SYS_CLOCK_GATE_BYPASS_REG (UFS_SYS_REG_BASE + 0x018)
|
||||
#define UFS_SYS_RESET_CTRL_EN_REG (UFS_SYS_REG_BASE + 0x01C)
|
||||
#define UFS_SYS_MONITOR_HH_REG (UFS_SYS_REG_BASE + 0x03C)
|
||||
#define UFS_SYS_UFS_SYSCTRL_REG (UFS_SYS_REG_BASE + 0x05C)
|
||||
#define UFS_SYS_UFS_DEVICE_RESET_CTRL_REG (UFS_SYS_REG_BASE + 0x060)
|
||||
#define UFS_SYS_UFS_APB_ADDR_MASK_REG (UFS_SYS_REG_BASE + 0x064)
|
||||
|
||||
#define BIT_UFS_PSW_ISO_CTRL (1 << 16)
|
||||
#define BIT_UFS_PSW_MTCMOS_EN (1 << 0)
|
||||
#define BIT_UFS_REFCLK_ISO_EN (1 << 16)
|
||||
#define BIT_UFS_PHY_ISO_CTRL (1 << 0)
|
||||
#define BIT_SYSCTRL_LP_ISOL_EN (1 << 16)
|
||||
#define BIT_SYSCTRL_PWR_READY (1 << 8)
|
||||
#define BIT_SYSCTRL_REF_CLOCK_EN (1 << 24)
|
||||
#define MASK_SYSCTRL_REF_CLOCK_SEL (3 << 8)
|
||||
#define MASK_SYSCTRL_CFG_CLOCK_FREQ (0xFF)
|
||||
#define BIT_SYSCTRL_PSW_CLK_EN (1 << 4)
|
||||
#define MASK_UFS_CLK_GATE_BYPASS (0x3F)
|
||||
#define BIT_SYSCTRL_LP_RESET_N (1 << 0)
|
||||
#define BIT_UFS_REFCLK_SRC_SE1 (1 << 0)
|
||||
#define MASK_UFS_SYSCTRL_BYPASS (0x3F << 16)
|
||||
#define MASK_UFS_DEVICE_RESET (1 << 16)
|
||||
#define BIT_UFS_DEVICE_RESET (1 << 0)
|
||||
|
||||
#define IOMG_FIX_REG_BASE 0xFF3B6000
|
||||
|
||||
/* GPIO150: LED */
|
||||
#define IOMG_FIX_006_REG (IOMG_FIX_REG_BASE + 0x018)
|
||||
/* GPIO151: LED */
|
||||
#define IOMG_FIX_007_REG (IOMG_FIX_REG_BASE + 0x01C)
|
||||
|
||||
#define IOMG_AO_REG_BASE 0xFFF11000
|
||||
|
||||
/* GPIO189: LED */
|
||||
#define IOMG_AO_011_REG (IOMG_AO_REG_BASE + 0x02C)
|
||||
/* GPIO190: LED */
|
||||
#define IOMG_AO_012_REG (IOMG_AO_REG_BASE + 0x030)
|
||||
/* GPIO202: type C enable. active low */
|
||||
#define IOMG_AO_023_REG (IOMG_AO_REG_BASE + 0x05C)
|
||||
/* GPIO206: USB switch. active low */
|
||||
#define IOMG_AO_026_REG (IOMG_AO_REG_BASE + 0x068)
|
||||
/* GPIO219: PD interrupt. pull up */
|
||||
#define IOMG_AO_039_REG (IOMG_AO_REG_BASE + 0x09C)
|
||||
|
||||
#define IOCG_AO_REG_BASE 0xFFF1187C
|
||||
/* GPIO219: PD interrupt. pull up */
|
||||
#define IOCG_AO_043_REG (IOCG_AO_REG_BASE + 0x030)
|
||||
|
||||
#endif /* __HI3660_H__ */
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef __HI3660_CRG_H__
|
||||
#define __HI3660_CRG_H__
|
||||
|
||||
#define CRG_REG_BASE 0xFFF35000
|
||||
|
||||
#define CRG_PEREN0_REG (CRG_REG_BASE + 0x000)
|
||||
#define CRG_PERDIS0_REG (CRG_REG_BASE + 0x004)
|
||||
#define CRG_PERSTAT0_REG (CRG_REG_BASE + 0x008)
|
||||
#define PEREN0_GT_CLK_AOMM (1 << 31)
|
||||
|
||||
#define CRG_PEREN1_REG (CRG_REG_BASE + 0x010)
|
||||
#define CRG_PERDIS1_REG (CRG_REG_BASE + 0x014)
|
||||
#define CRG_PERSTAT1_REG (CRG_REG_BASE + 0x018)
|
||||
#define CRG_PEREN2_REG (CRG_REG_BASE + 0x020)
|
||||
#define CRG_PERDIS2_REG (CRG_REG_BASE + 0x024)
|
||||
#define CRG_PERSTAT2_REG (CRG_REG_BASE + 0x028)
|
||||
#define PEREN2_HKADCSSI (1 << 24)
|
||||
|
||||
#define CRG_PEREN3_REG (CRG_REG_BASE + 0x030)
|
||||
#define CRG_PERDIS3_REG (CRG_REG_BASE + 0x034)
|
||||
|
||||
#define CRG_PEREN4_REG (CRG_REG_BASE + 0x040)
|
||||
#define CRG_PERDIS4_REG (CRG_REG_BASE + 0x044)
|
||||
#define CRG_PERCLKEN4_REG (CRG_REG_BASE + 0x048)
|
||||
#define CRG_PERSTAT4_REG (CRG_REG_BASE + 0x04C)
|
||||
#define GT_ACLK_USB3OTG (1 << 1)
|
||||
#define GT_CLK_USB3OTG_REF (1 << 0)
|
||||
|
||||
#define CRG_PEREN5_REG (CRG_REG_BASE + 0x050)
|
||||
#define CRG_PERDIS5_REG (CRG_REG_BASE + 0x054)
|
||||
#define CRG_PERSTAT5_REG (CRG_REG_BASE + 0x058)
|
||||
#define CRG_PERRSTEN0_REG (CRG_REG_BASE + 0x060)
|
||||
#define CRG_PERRSTDIS0_REG (CRG_REG_BASE + 0x064)
|
||||
#define CRG_PERRSTSTAT0_REG (CRG_REG_BASE + 0x068)
|
||||
#define CRG_PERRSTEN1_REG (CRG_REG_BASE + 0x06C)
|
||||
#define CRG_PERRSTDIS1_REG (CRG_REG_BASE + 0x070)
|
||||
#define CRG_PERRSTSTAT1_REG (CRG_REG_BASE + 0x074)
|
||||
#define CRG_PERRSTEN2_REG (CRG_REG_BASE + 0x078)
|
||||
#define CRG_PERRSTDIS2_REG (CRG_REG_BASE + 0x07C)
|
||||
#define CRG_PERRSTSTAT2_REG (CRG_REG_BASE + 0x080)
|
||||
#define PERRSTEN2_HKADCSSI (1 << 24)
|
||||
|
||||
#define CRG_PERRSTEN3_REG (CRG_REG_BASE + 0x084)
|
||||
#define CRG_PERRSTDIS3_REG (CRG_REG_BASE + 0x088)
|
||||
#define CRG_PERRSTSTAT3_REG (CRG_REG_BASE + 0x08C)
|
||||
#define CRG_PERRSTEN4_REG (CRG_REG_BASE + 0x090)
|
||||
#define CRG_PERRSTDIS4_REG (CRG_REG_BASE + 0x094)
|
||||
#define CRG_PERRSTSTAT4_REG (CRG_REG_BASE + 0x098)
|
||||
#define IP_RST_USB3OTG_MUX (1 << 8)
|
||||
#define IP_RST_USB3OTG_AHBIF (1 << 7)
|
||||
#define IP_RST_USB3OTG_32K (1 << 6)
|
||||
#define IP_RST_USB3OTG (1 << 5)
|
||||
#define IP_RST_USB3OTGPHY_POR (1 << 3)
|
||||
|
||||
#define CRG_PERRSTEN5_REG (CRG_REG_BASE + 0x09C)
|
||||
#define CRG_PERRSTDIS5_REG (CRG_REG_BASE + 0x0A0)
|
||||
#define CRG_PERRSTSTAT5_REG (CRG_REG_BASE + 0x0A4)
|
||||
|
||||
/* bit fields in CRG_PERI */
|
||||
#define PERI_PCLK_PCTRL_BIT (1 << 31)
|
||||
#define PERI_TIMER12_BIT (1 << 25)
|
||||
#define PERI_TIMER11_BIT (1 << 24)
|
||||
#define PERI_TIMER10_BIT (1 << 23)
|
||||
#define PERI_TIMER9_BIT (1 << 22)
|
||||
#define PERI_UART5_BIT (1 << 15)
|
||||
#define PERI_UFS_BIT (1 << 12)
|
||||
#define PERI_ARST_UFS_BIT (1 << 7)
|
||||
#define PERI_PPLL2_EN_CPU (1 << 3)
|
||||
#define PERI_PWM_BIT (1 << 0)
|
||||
#define PERI_DDRC_BIT (1 << 0)
|
||||
#define PERI_DDRC_D_BIT (1 << 4)
|
||||
#define PERI_DDRC_C_BIT (1 << 3)
|
||||
#define PERI_DDRC_B_BIT (1 << 2)
|
||||
#define PERI_DDRC_A_BIT (1 << 1)
|
||||
#define PERI_DDRC_DMUX_BIT (1 << 0)
|
||||
|
||||
#define CRG_CLKDIV0_REG (CRG_REG_BASE + 0x0A0)
|
||||
#define SC_DIV_LPMCU_MASK ((0x1F << 5) << 16)
|
||||
#define SC_DIV_LPMCU(x) (((x) & 0x1F) << 5)
|
||||
|
||||
#define CRG_CLKDIV1_REG (CRG_REG_BASE + 0x0B0)
|
||||
#define SEL_LPMCU_PLL_MASK ((1 << 1) << 16)
|
||||
#define SEL_SYSBUS_MASK ((1 << 0) << 16)
|
||||
#define SEL_LPMCU_PLL1 (1 << 1)
|
||||
#define SEL_LPMCU_PLL0 (0 << 1)
|
||||
#define SEL_SYSBUS_PLL0 (1 << 0)
|
||||
#define SEL_SYSBUS_PLL1 (0 << 0)
|
||||
|
||||
#define CRG_CLKDIV3_REG (CRG_REG_BASE + 0x0B4)
|
||||
#define CRG_CLKDIV5_REG (CRG_REG_BASE + 0x0BC)
|
||||
#define CRG_CLKDIV8_REG (CRG_REG_BASE + 0x0C8)
|
||||
|
||||
#define CRG_CLKDIV12_REG (CRG_REG_BASE + 0x0D8)
|
||||
#define SC_DIV_A53HPM_MASK (0x7 << 13)
|
||||
#define SC_DIV_A53HPM(x) (((x) & 0x7) << 13)
|
||||
|
||||
#define CRG_CLKDIV16_REG (CRG_REG_BASE + 0x0E8)
|
||||
#define DDRC_CLK_SW_REQ_CFG_MASK (0x3 << 12)
|
||||
#define DDRC_CLK_SW_REQ_CFG(x) (((x) & 0x3) << 12)
|
||||
#define SC_DIV_UFSPHY_CFG_MASK (0x3 << 9)
|
||||
#define SC_DIV_UFSPHY_CFG(x) (((x) & 0x3) << 9)
|
||||
#define DDRCPLL_SW (1 << 8)
|
||||
|
||||
#define CRG_CLKDIV17_REG (CRG_REG_BASE + 0x0EC)
|
||||
#define SC_DIV_UFS_PERIBUS (1 << 14)
|
||||
|
||||
#define CRG_CLKDIV18_REG (CRG_REG_BASE + 0x0F0)
|
||||
#define CRG_CLKDIV19_REG (CRG_REG_BASE + 0x0F4)
|
||||
#define CRG_CLKDIV20_REG (CRG_REG_BASE + 0x0F8)
|
||||
#define CLKDIV20_GT_CLK_AOMM (1 << 3)
|
||||
|
||||
#define CRG_CLKDIV22_REG (CRG_REG_BASE + 0x100)
|
||||
#define SEL_PLL_320M_MASK (1 << 16)
|
||||
#define SEL_PLL2_320M (1 << 0)
|
||||
#define SEL_PLL0_320M (0 << 0)
|
||||
|
||||
#define CRG_CLKDIV23_REG (CRG_REG_BASE + 0x104)
|
||||
#define PERI_DDRC_SW_BIT (1 << 13)
|
||||
#define DIV_CLK_DDRSYS_MASK (0x3 << 10)
|
||||
#define DIV_CLK_DDRSYS(x) (((x) & 0x3) << 10)
|
||||
#define GET_DIV_CLK_DDRSYS(x) (((x) & DIV_CLK_DDRSYS_MASK) >> 10)
|
||||
#define DIV_CLK_DDRCFG_MASK (0x6 << 5)
|
||||
#define DIV_CLK_DDRCFG(x) (((x) & 0x6) << 5)
|
||||
#define GET_DIV_CLK_DDRCFG(x) (((x) & DIV_CLK_DDRCFG_MASK) >> 5)
|
||||
#define DIV_CLK_DDRC_MASK 0x1F
|
||||
#define DIV_CLK_DDRC(x) ((x) & DIV_CLK_DDRC_MASK)
|
||||
#define GET_DIV_CLK_DDRC(x) ((x) & DIV_CLK_DDRC_MASK)
|
||||
|
||||
#define CRG_CLKDIV25_REG (CRG_REG_BASE + 0x10C)
|
||||
#define DIV_SYSBUS_PLL_MASK (0xF << 16)
|
||||
#define DIV_SYSBUS_PLL(x) ((x) & 0xF)
|
||||
|
||||
#define CRG_PERI_CTRL2_REG (CRG_REG_BASE + 0x128)
|
||||
#define PERI_TIME_STAMP_CLK_MASK (0x7 << 28)
|
||||
#define PERI_TIME_STAMP_CLK_DIV(x) (((x) & 0x7) << 22)
|
||||
|
||||
#define CRG_ISODIS_REG (CRG_REG_BASE + 0x148)
|
||||
#define CRG_PERPWREN_REG (CRG_REG_BASE + 0x150)
|
||||
|
||||
#define CRG_PEREN7_REG (CRG_REG_BASE + 0x420)
|
||||
#define CRG_PERDIS7_REG (CRG_REG_BASE + 0x424)
|
||||
#define CRG_PERSTAT7_REG (CRG_REG_BASE + 0x428)
|
||||
#define GT_CLK_UFSPHY_CFG (1 << 14)
|
||||
|
||||
#define CRG_PEREN8_REG (CRG_REG_BASE + 0x430)
|
||||
#define CRG_PERDIS8_REG (CRG_REG_BASE + 0x434)
|
||||
#define CRG_PERSTAT8_REG (CRG_REG_BASE + 0x438)
|
||||
#define PERI_DMC_D_BIT (1 << 22)
|
||||
#define PERI_DMC_C_BIT (1 << 21)
|
||||
#define PERI_DMC_B_BIT (1 << 20)
|
||||
#define PERI_DMC_A_BIT (1 << 19)
|
||||
#define PERI_DMC_BIT (1 << 18)
|
||||
|
||||
#define CRG_PEREN11_REG (CRG_REG_BASE + 0x460)
|
||||
#define PPLL1_GATE_CPU (1 << 18)
|
||||
|
||||
#define CRG_PERSTAT11_REG (CRG_REG_BASE + 0x46C)
|
||||
#define PPLL3_EN_STAT (1 << 21)
|
||||
#define PPLL2_EN_STAT (1 << 20)
|
||||
#define PPLL1_EN_STAT (1 << 19)
|
||||
|
||||
#define CRG_IVP_SEC_RSTDIS_REG (CRG_REG_BASE + 0xC04)
|
||||
#define CRG_ISP_SEC_RSTDIS_REG (CRG_REG_BASE + 0xC84)
|
||||
|
||||
#define CRG_RVBAR(c, n) (0xE00 + (0x10 * c) + (0x4 * n))
|
||||
#define CRG_GENERAL_SEC_RSTEN_REG (CRG_REG_BASE + 0xE20)
|
||||
#define CRG_GENERAL_SEC_RSTDIS_REG (CRG_REG_BASE + 0xE24)
|
||||
#define IP_RST_GPIO0_SEC (1 << 2)
|
||||
|
||||
#define CRG_GENERAL_SEC_CLKDIV0_REG (CRG_REG_BASE + 0xE90)
|
||||
#define SC_DIV_AO_HISE_MASK 3
|
||||
#define SC_DIV_AO_HISE(x) ((x) & 0x3)
|
||||
|
||||
#endif /* __HI3660_CRG_H__ */
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef __HI3660_HKADC_H__
|
||||
#define __HI3660_HKADC_H__
|
||||
|
||||
#define HKADC_SSI_REG_BASE 0xE82B8000
|
||||
|
||||
#define HKADC_DSP_START_REG (HKADC_SSI_REG_BASE + 0x000)
|
||||
#define HKADC_WR_NUM_REG (HKADC_SSI_REG_BASE + 0x008)
|
||||
#define HKADC_DSP_START_CLR_REG (HKADC_SSI_REG_BASE + 0x01C)
|
||||
#define HKADC_WR01_DATA_REG (HKADC_SSI_REG_BASE + 0x020)
|
||||
|
||||
#define WR1_WRITE_MODE (1 << 31)
|
||||
#define WR1_READ_MODE (0 << 31)
|
||||
#define WR1_ADDR(x) (((x) & 0x7F) << 24)
|
||||
#define WR1_DATA(x) (((x) & 0xFF) << 16)
|
||||
#define WR0_WRITE_MODE (1 << 15)
|
||||
#define WR0_READ_MODE (0 << 15)
|
||||
#define WR0_ADDR(x) (((x) & 0x7F) << 8)
|
||||
#define WR0_DATA(x) ((x) & 0xFF)
|
||||
|
||||
#define HKADC_WR23_DATA_REG (HKADC_SSI_REG_BASE + 0x024)
|
||||
#define HKADC_WR45_DATA_REG (HKADC_SSI_REG_BASE + 0x028)
|
||||
#define HKADC_DELAY01_REG (HKADC_SSI_REG_BASE + 0x030)
|
||||
#define HKADC_DELAY23_REG (HKADC_SSI_REG_BASE + 0x034)
|
||||
#define HKADC_DELAY45_REG (HKADC_SSI_REG_BASE + 0x038)
|
||||
#define HKADC_DSP_RD2_DATA_REG (HKADC_SSI_REG_BASE + 0x048)
|
||||
#define HKADC_DSP_RD3_DATA_REG (HKADC_SSI_REG_BASE + 0x04C)
|
||||
|
||||
/* HKADC Internal Registers */
|
||||
#define HKADC_CTRL_ADDR 0x00
|
||||
#define HKADC_START_ADDR 0x01
|
||||
#define HKADC_DATA1_ADDR 0x03 /* high 8 bits */
|
||||
#define HKADC_DATA0_ADDR 0x04 /* low 8 bits */
|
||||
#define HKADC_MODE_CFG 0x0A
|
||||
|
||||
#define HKADC_VALUE_HIGH 0x0FF0
|
||||
#define HKADC_VALUE_LOW 0x000F
|
||||
#define HKADC_VALID_VALUE 0x0FFF
|
||||
|
||||
#define HKADC_CHANNEL_MAX 15
|
||||
#define HKADC_VREF_1V8 1800
|
||||
#define HKADC_ACCURACY 0x0FFF
|
||||
|
||||
#define HKADC_WR01_VALUE ((HKADC_START_ADDR << 24) | \
|
||||
(0x1 << 16))
|
||||
#define HKADC_WR23_VALUE ((0x1 << 31) | \
|
||||
(HKADC_DATA0_ADDR << 24) | \
|
||||
(1 << 15) | \
|
||||
(HKADC_DATA1_ADDR << 8))
|
||||
#define HKADC_WR45_VALUE (0x80)
|
||||
#define HKADC_CHANNEL0_DELAY01_VALUE ((0x0700 << 16) | 0xFFFF)
|
||||
#define HKADC_DELAY01_VALUE ((0x0700 << 16) | 0x0200)
|
||||
#define HKADC_DELAY23_VALUE ((0x00C8 << 16) | 0x00C8)
|
||||
#define START_DELAY_TIMEOUT 2000
|
||||
#define HKADC_WR_NUM_VALUE 4
|
||||
|
||||
#endif /* __HI3660_HKADC_H__ */
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __HI3660_MEM_MAP__
|
||||
#define __HI3660_MEM_MAP__
|
||||
|
||||
#define HISI_DATA_HEAD_BASE (0x89C44400)
|
||||
|
||||
#define HISI_RESERVED_MEM_BASE (0x89C80000)
|
||||
#define HISI_RESERVED_MEM_SIZE (0x00040000)
|
||||
|
||||
#define HISI_DATA0_BASE (0x89C96180)
|
||||
#define HISI_DATA0_SIZE (0x000003A0)
|
||||
#define HISI_DATA1_BASE (0x89C93480)
|
||||
#define HISI_DATA1_SIZE (0x00002D00)
|
||||
|
||||
#endif /* __HI3660_MEM_MAP__ */
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __HISI_IPC_H__
|
||||
#define __HISI_IPC_H__
|
||||
|
||||
enum pm_mode {
|
||||
PM_ON = 0,
|
||||
PM_OFF,
|
||||
};
|
||||
|
||||
void hisi_ipc_pm_on_off(unsigned int core, unsigned int cluster,
|
||||
enum pm_mode mode);
|
||||
void hisi_ipc_pm_suspend(unsigned int core, unsigned int cluster,
|
||||
unsigned int affinity_level);
|
||||
void hisi_ipc_psci_system_off(unsigned int core, unsigned int cluster);
|
||||
void hisi_ipc_psci_system_reset(unsigned int core, unsigned int cluster,
|
||||
unsigned int cmd_id);
|
||||
int hisi_ipc_init(void);
|
||||
|
||||
#endif /* __HISI_IPC_H__ */
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __PLAT_MACROS_S__
|
||||
#define __PLAT_MACROS_S__
|
||||
|
||||
#include <cci.h>
|
||||
#include <hi3660.h>
|
||||
#include <gic_v2.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
.section .rodata.gic_reg_name, "aS"
|
||||
gicc_regs:
|
||||
.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
|
||||
gicd_pend_reg:
|
||||
.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \
|
||||
" Offset:\t\t\tvalue\n"
|
||||
newline:
|
||||
.asciz "\n"
|
||||
spacer:
|
||||
.asciz ":\t\t0x"
|
||||
|
||||
.section .rodata.cci_reg_name, "aS"
|
||||
cci_iface_regs:
|
||||
.asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
|
||||
|
||||
/* ---------------------------------------------
|
||||
* The below macro prints out relevant GIC
|
||||
* registers whenever an unhandled exception is
|
||||
* taken in BL31.
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
.macro plat_crash_print_regs
|
||||
mov_imm x16, GICD_REG_BASE
|
||||
mov_imm x17, GICC_REG_BASE
|
||||
|
||||
/* Load the gicc reg list to x6 */
|
||||
adr x6, gicc_regs
|
||||
/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
|
||||
ldr w8, [x17, #GICC_HPPIR]
|
||||
ldr w9, [x17, #GICC_AHPPIR]
|
||||
ldr w10, [x17, #GICC_CTLR]
|
||||
/* Store to the crash buf and print to cosole */
|
||||
bl str_in_crash_buf_print
|
||||
|
||||
/* Print the GICD_ISPENDR regs */
|
||||
add x7, x16, #GICD_ISPENDR
|
||||
adr x4, gicd_pend_reg
|
||||
bl asm_print_str
|
||||
2:
|
||||
sub x4, x7, x16
|
||||
cmp x4, #0x280
|
||||
b.eq 1f
|
||||
bl asm_print_hex
|
||||
adr x4, spacer
|
||||
bl asm_print_str
|
||||
ldr x4, [x7], #8
|
||||
bl asm_print_hex
|
||||
adr x4, newline
|
||||
bl asm_print_str
|
||||
b 2b
|
||||
1:
|
||||
adr x6, cci_iface_regs
|
||||
/* Store in x7 the base address of the first interface */
|
||||
mov_imm x7, (CCI400_REG_BASE + SLAVE_IFACE_OFFSET( \
|
||||
CCI400_SL_IFACE3_CLUSTER_IX))
|
||||
ldr w8, [x7, #SNOOP_CTRL_REG]
|
||||
/* Store in x7 the base address of the second interface */
|
||||
mov_imm x7, (CCI400_REG_BASE + SLAVE_IFACE_OFFSET( \
|
||||
CCI400_SL_IFACE4_CLUSTER_IX))
|
||||
ldr w9, [x7, #SNOOP_CTRL_REG]
|
||||
/* Store to the crash buf and print to console */
|
||||
bl str_in_crash_buf_print
|
||||
.endm
|
||||
|
||||
#endif /* __PLAT_MACROS_S__ */
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __PLATFORM_DEF_H__
|
||||
#define __PLATFORM_DEF_H__
|
||||
|
||||
#include <arch.h>
|
||||
#include "../hikey960_def.h"
|
||||
|
||||
|
||||
/*
|
||||
* Generic platform constants
|
||||
*/
|
||||
|
||||
/* Size of cacheable stacks */
|
||||
#define PLATFORM_STACK_SIZE 0x800
|
||||
|
||||
#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
|
||||
|
||||
#define PLATFORM_CACHE_LINE_SIZE 64
|
||||
#define PLATFORM_CLUSTER_COUNT 2
|
||||
#define PLATFORM_CORE_COUNT_PER_CLUSTER 4
|
||||
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \
|
||||
PLATFORM_CORE_COUNT_PER_CLUSTER)
|
||||
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
|
||||
#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
|
||||
PLATFORM_CLUSTER_COUNT + 1)
|
||||
|
||||
#define PLAT_MAX_RET_STATE 1
|
||||
#define PLAT_MAX_OFF_STATE 2
|
||||
|
||||
#define MAX_IO_DEVICES 3
|
||||
#define MAX_IO_HANDLES 4
|
||||
/* UFS RPMB and UFS User Data */
|
||||
#define MAX_IO_BLOCK_DEVICES 2
|
||||
|
||||
|
||||
/*
|
||||
* Platform memory map related constants
|
||||
*/
|
||||
|
||||
/*
|
||||
* BL1 specific defines.
|
||||
*/
|
||||
#define BL1_RO_BASE (0x1AC00000)
|
||||
#define BL1_RO_LIMIT (BL1_RO_BASE + 0x10000)
|
||||
#define BL1_RW_BASE (BL1_RO_LIMIT) /* 1AC1_0000 */
|
||||
#define BL1_RW_SIZE (0x00188000)
|
||||
#define BL1_RW_LIMIT (0x1B000000)
|
||||
|
||||
/*
|
||||
* BL2 specific defines.
|
||||
*/
|
||||
#define BL2_BASE (BL1_RW_BASE + 0x8000) /* 1AC1_8000 */
|
||||
#define BL2_LIMIT (BL2_BASE + 0x40000) /* 1AC5_8000 */
|
||||
|
||||
/*
|
||||
* BL31 specific defines.
|
||||
*/
|
||||
#define BL31_BASE (BL2_LIMIT) /* 1AC5_8000 */
|
||||
#define BL31_LIMIT (BL31_BASE + 0x40000) /* 1AC9_8000 */
|
||||
|
||||
#define NS_BL1U_BASE (BL31_LIMIT) /* 1AC9_8000 */
|
||||
#define NS_BL1U_SIZE (0x00100000)
|
||||
#define NS_BL1U_LIMIT (NS_BL1U_BASE + NS_BL1U_SIZE)
|
||||
|
||||
#define HIKEY960_NS_IMAGE_OFFSET (0x1AC18000) /* offset in l-loader */
|
||||
#define HIKEY960_NS_TMP_OFFSET (0x1AE00000)
|
||||
|
||||
#define SCP_BL2_BASE BL31_BASE
|
||||
|
||||
#define SCP_MEM_BASE (0x89C80000)
|
||||
#define SCP_MEM_SIZE (0x00040000)
|
||||
|
||||
/*
|
||||
* Platform specific page table and MMU setup constants
|
||||
*/
|
||||
#define ADDR_SPACE_SIZE (1ull << 32)
|
||||
|
||||
#if IMAGE_BL1 || IMAGE_BL2 || IMAGE_BL31
|
||||
#define MAX_XLAT_TABLES 3
|
||||
#endif
|
||||
|
||||
#define MAX_MMAP_REGIONS 16
|
||||
|
||||
/*
|
||||
* Declarations and constants to access the mailboxes safely. Each mailbox is
|
||||
* aligned on the biggest cache line size in the platform. This is known only
|
||||
* to the platform as it might have a combination of integrated and external
|
||||
* caches. Such alignment ensures that two maiboxes do not sit on the same cache
|
||||
* line at any cache level. They could belong to different cpus/clusters &
|
||||
* get written while being protected by different locks causing corruption of
|
||||
* a valid mailbox address.
|
||||
*/
|
||||
#define CACHE_WRITEBACK_SHIFT 6
|
||||
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
|
||||
|
||||
#endif /* __PLATFORM_DEF_H__ */
|
|
@ -0,0 +1,65 @@
|
|||
#
|
||||
# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
CRASH_CONSOLE_BASE := PL011_UART6_BASE
|
||||
COLD_BOOT_SINGLE_CPU := 1
|
||||
PROGRAMMABLE_RESET_ADDRESS := 1
|
||||
|
||||
# Process flags
|
||||
$(eval $(call add_define,CRASH_CONSOLE_BASE))
|
||||
$(eval $(call FIP_ADD_IMG,SCP_BL2,--scp-fw))
|
||||
|
||||
ENABLE_PLAT_COMPAT := 0
|
||||
|
||||
USE_COHERENT_MEM := 1
|
||||
|
||||
PLAT_INCLUDES := -Iinclude/common/tbbr \
|
||||
-Iplat/hisilicon/hikey960/include
|
||||
|
||||
PLAT_BL_COMMON_SOURCES := drivers/arm/pl011/pl011_console.S \
|
||||
drivers/delay_timer/delay_timer.c \
|
||||
drivers/delay_timer/generic_delay_timer.c \
|
||||
lib/aarch64/xlat_tables.c \
|
||||
plat/hisilicon/hikey960/aarch64/hikey960_common.c \
|
||||
plat/hisilicon/hikey960/hikey960_boardid.c
|
||||
|
||||
HIKEY960_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
|
||||
drivers/arm/gic/v2/gicv2_main.c \
|
||||
drivers/arm/gic/v2/gicv2_helpers.c \
|
||||
plat/common/plat_gicv2.c
|
||||
|
||||
BL1_SOURCES += bl1/tbbr/tbbr_img_desc.c \
|
||||
drivers/io/io_block.c \
|
||||
drivers/io/io_fip.c \
|
||||
drivers/io/io_storage.c \
|
||||
drivers/synopsys/ufs/dw_ufs.c \
|
||||
drivers/ufs/ufs.c \
|
||||
lib/cpus/aarch64/cortex_a53.S \
|
||||
plat/hisilicon/hikey960/aarch64/hikey960_helpers.S \
|
||||
plat/hisilicon/hikey960/hikey960_bl1_setup.c \
|
||||
plat/hisilicon/hikey960/hikey960_io_storage.c \
|
||||
${HIKEY960_GIC_SOURCES}
|
||||
|
||||
BL2_SOURCES += drivers/io/io_block.c \
|
||||
drivers/io/io_fip.c \
|
||||
drivers/io/io_storage.c \
|
||||
drivers/ufs/ufs.c \
|
||||
plat/hisilicon/hikey960/hikey960_bl2_setup.c \
|
||||
plat/hisilicon/hikey960/hikey960_io_storage.c \
|
||||
plat/hisilicon/hikey960/hikey960_mcu_load.c
|
||||
|
||||
BL31_SOURCES += drivers/arm/cci/cci.c \
|
||||
lib/cpus/aarch64/cortex_a53.S \
|
||||
lib/cpus/aarch64/cortex_a72.S \
|
||||
lib/cpus/aarch64/cortex_a73.S \
|
||||
plat/common/aarch64/plat_psci_common.c \
|
||||
plat/hisilicon/hikey960/aarch64/hikey960_helpers.S \
|
||||
plat/hisilicon/hikey960/hikey960_bl31_setup.c \
|
||||
plat/hisilicon/hikey960/hikey960_pm.c \
|
||||
plat/hisilicon/hikey960/hikey960_topology.c \
|
||||
plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c \
|
||||
plat/hisilicon/hikey960/drivers/ipc/hisi_ipc.c \
|
||||
${HIKEY960_GIC_SOURCES}
|
Loading…
Reference in New Issue