Commit 1f9ef0dc authored by Tom Rini's avatar Tom Rini

Merge branch 'master' of http://git.denx.de/u-boot-sunxi

parents 926fbcc0 b7073965
......@@ -120,8 +120,8 @@ endif
ifdef CONFIG_ARM64
OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
else
OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j \
.got -j .got.plt -j .u_boot_list -j .rel.dyn
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \
-j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn
endif
ifdef CONFIG_OF_EMBED
......
......@@ -19,7 +19,7 @@ endif
endif
obj-$(CONFIG_ARMV7_NONSEC) += nonsec_virt.o virt-v7.o virt-dt.o
obj-$(CONFIG_ARMV7_PSCI) += psci.o
obj-$(CONFIG_ARMV7_PSCI) += psci.o psci-common.o
obj-$(CONFIG_IPROC) += iproc-common/
obj-$(CONFIG_KONA) += kona-common/
......
......@@ -29,16 +29,16 @@
@ r2 = target PC
.globl psci_cpu_on
psci_cpu_on:
push {lr}
push {r4, r5, r6, lr}
@ Clear and Get the correct CPU number
@ r1 = 0xf01
and r1, r1, #0xff
and r4, r1, #0xff
mov r0, r1
bl psci_get_cpu_stack_top
str r2, [r0]
dsb
mov r0, r4
mov r1, r2
bl psci_save_target_pc
mov r1, r4
@ Get DCFG base address
movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
......@@ -101,7 +101,7 @@ holdoff_release:
@ Return
mov r0, #ARM_PSCI_RET_SUCCESS
pop {lr}
pop {r4, r5, r6, lr}
bx lr
.globl psci_cpu_off
......@@ -111,16 +111,4 @@ psci_cpu_off:
1: wfi
b 1b
.globl psci_arch_init
psci_arch_init:
mov r6, lr
bl psci_get_cpu_id
bl psci_get_cpu_stack_top
mov sp, r0
bx r6
.globl psci_text_end
psci_text_end:
.popsection
#include <asm/io.h>
#include <asm/psci.h>
#include <asm/secure.h>
#include <asm/arch/imx-regs.h>
#include <common.h>
#define __secure __attribute__((section("._secure.text")))
#define GPC_CPU_PGC_SW_PDN_REQ 0xfc
#define GPC_CPU_PGC_SW_PUP_REQ 0xf0
......
......@@ -9,35 +9,22 @@
.arch_extension sec
@ r1 = target CPU
@ r2 = target PC
.globl psci_arch_init
psci_arch_init:
mov r6, lr
bl psci_get_cpu_id
bl psci_get_cpu_stack_top
mov sp, r0
bx r6
@ r1 = target CPU
@ r2 = target PC
.globl psci_cpu_on
psci_cpu_on:
push {lr}
push {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r0, r1
bl psci_get_cpu_stack_top
str r2, [r0]
dsb
mov r1, r2
bl psci_save_target_pc
mov r0, r4
mov r1, r5
ldr r2, =psci_cpu_entry
bl imx_cpu_on
pop {pc}
pop {r4, r5, pc}
.globl psci_cpu_off
psci_cpu_off:
......@@ -49,6 +36,4 @@ psci_cpu_off:
1: wfi
b 1b
.globl psci_text_end
psci_text_end:
.popsection
......@@ -49,8 +49,13 @@ _secure_monitor:
mcr p15, 0, r5, c12, c0, 1
isb
@ Obtain a secure stack, and configure the PSCI backend
@ Obtain a secure stack
bl psci_stack_setup
@ Configure the PSCI backend
push {r0, r1, r2, ip}
bl psci_arch_init
pop {r0, r1, r2, ip}
#endif
#ifdef CONFIG_ARM_ERRATA_773022
......
/*
* Copyright (C) 2013 - ARM Ltd
* Author: Marc Zyngier <marc.zyngier@arm.com>
* Common PSCI functions
*
* Based on code by Carl van Schaik <carl@ok-labs.com>.
* Copyright (C) 2016 Chen-Yu Tsai
* Author: Chen-Yu Tsai <wens@csie.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -18,49 +18,22 @@
*/
#include <config.h>
#include <linux/linkage.h>
#include <asm/arch-armv7/generictimer.h>
#include <asm/gic.h>
#include <asm/armv7.h>
#include <asm/macro.h>
#include <asm/psci.h>
#include <asm/arch/cpu.h>
/*
* Memory layout:
*
* SECURE_RAM to text_end :
* ._secure_text section
* text_end to ALIGN_PAGE(text_end):
* nothing
* ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000)
* 1kB of stack per CPU (4 CPUs max).
*/
.pushsection ._secure.text, "ax"
.arch_extension sec
#include <asm/secure.h>
#include <linux/linkage.h>
#define GICD_BASE (SUNXI_GIC400_BASE + 0x1000)
#define GICC_BASE (SUNXI_GIC400_BASE + 0x2000)
static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 };
@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in
@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across
@ this function.
ENTRY(psci_arch_init)
mov r6, lr
mov r7, r0
bl psci_get_cpu_id @ CPU ID => r0
bl psci_get_cpu_stack_top @ stack top => r0
sub r0, r0, #4 @ Save space for target PC
mov sp, r0
mov r0, r7
mov lr, r6
void __secure psci_save_target_pc(int cpu, u32 pc)
{
psci_target_pc[cpu] = pc;
DSB;
}
push {r0, r1, r2, ip, lr}
bl sunxi_gic_init
pop {r0, r1, r2, ip, pc}
ENDPROC(psci_arch_init)
u32 __secure psci_get_target_pc(int cpu)
{
return psci_target_pc[cpu];
}
ENTRY(psci_text_end)
.popsection
......@@ -196,29 +196,56 @@ ENTRY(psci_cpu_off_common)
bx lr
ENDPROC(psci_cpu_off_common)
@ expects CPU ID in r0 and returns stack top in r0
ENTRY(psci_get_cpu_stack_top)
mov r3, #0x400 @ 1kB of stack per CPU
mul r0, r0, r3
ldr r3, =psci_text_end @ end of monitor text
add r3, r3, #0x2000 @ Skip two pages
lsr r3, r3, #12 @ Align to start of page
lsl r3, r3, #12
sub r3, r3, #4 @ reserve 1 word for target PC
sub r0, r3, r0 @ here's our stack!
@ The stacks are allocated in reverse order, i.e.
@ the stack for CPU0 has the highest memory address.
@
@ -------------------- __secure_stack_end
@ | CPU0 target PC |
@ |------------------|
@ | |
@ | CPU0 stack |
@ | |
@ |------------------| __secure_stack_end - 1KB
@ | . |
@ | . |
@ | . |
@ | . |
@ -------------------- __secure_stack_start
@
@ This expects CPU ID in r0 and returns stack top in r0
LENTRY(psci_get_cpu_stack_top)
@ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT)
ldr r3, =__secure_stack_end
sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT
sub r0, r0, #4 @ Save space for target PC
bx lr
ENDPROC(psci_get_cpu_stack_top)
@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in
@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across
@ this function.
ENTRY(psci_stack_setup)
mov r6, lr
mov r7, r0
bl psci_get_cpu_id @ CPU ID => r0
bl psci_get_cpu_stack_top @ stack top => r0
mov sp, r0
mov r0, r7
bx r6
ENDPROC(psci_stack_setup)
ENTRY(psci_arch_init)
mov pc, lr
ENDPROC(psci_arch_init)
.weak psci_arch_init
ENTRY(psci_cpu_entry)
bl psci_enable_smp
bl _nonsec_init
bl psci_get_cpu_id @ CPU ID => r0
bl psci_get_cpu_stack_top @ stack top => r0
ldr r0, [r0] @ target PC at stack top
bl psci_get_target_pc @ target PC => r0
b _do_nonsec_entry
ENDPROC(psci_cpu_entry)
......
......@@ -14,7 +14,6 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_ARMV7_PSCI) += psci.o
obj-$(CONFIG_ARMV7_PSCI) += psci_head.o
endif
ifdef CONFIG_SPL_BUILD
......
......@@ -17,11 +17,11 @@
#include <asm/gic.h>
#include <asm/io.h>
#include <asm/psci.h>
#include <asm/secure.h>
#include <asm/system.h>
#include <linux/bitops.h>
#define __secure __attribute__ ((section ("._secure.text")))
#define __irq __attribute__ ((interrupt ("IRQ")))
#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
......@@ -209,9 +209,8 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc)
(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
u32 cpu = (mpidr & 0x3);
/* store target PC at target CPU stack top */
writel(pc, psci_get_cpu_stack_top(cpu));
DSB;
/* store target PC */
psci_save_target_pc(cpu, pc);
/* Set secondary core power on PC */
writel((u32)&psci_cpu_entry, &cpucfg->priv0);
......@@ -250,7 +249,7 @@ void __secure psci_cpu_off(void)
wfi();
}
void __secure sunxi_gic_init(void)
void __secure psci_arch_init(void)
{
u32 reg;
......
......@@ -8,6 +8,7 @@
*/
#include <config.h>
#include <asm/psci.h>
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
......@@ -48,34 +49,67 @@ SECTIONS
#ifdef CONFIG_ARMV7_NONSEC
/* Align the secure section only if we're going to use it in situ */
.__secure_start :
#ifndef CONFIG_ARMV7_SECURE_BASE
ALIGN(CONSTANT(COMMONPAGESIZE))
#endif
{
KEEP(*(.__secure_start))
}
#ifndef CONFIG_ARMV7_SECURE_BASE
#define CONFIG_ARMV7_SECURE_BASE
#define __ARMV7_PSCI_STACK_IN_RAM
#endif
.__secure_start : {
. = ALIGN(0x1000);
*(.__secure_start)
}
.secure_text CONFIG_ARMV7_SECURE_BASE :
AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
{
*(._secure.text)
}
. = LOADADDR(.__secure_start) +
SIZEOF(.__secure_start) +
SIZEOF(.secure_text);
.secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text))
{
*(._secure.data)
}
.secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data),
CONSTANT(COMMONPAGESIZE)) (NOLOAD) :
#ifdef __ARMV7_PSCI_STACK_IN_RAM
/* Align to page boundary and skip 2 pages */
. = (. & ~ 0xfff) + 0x2000;
#undef __ARMV7_PSCI_STACK_IN_RAM
AT(ADDR(.secure_stack))
#else
AT(LOADADDR(.secure_data) + SIZEOF(.secure_data))
#endif
{
KEEP(*(.__secure_stack_start))
/* Skip addreses for stack */
. = . + CONFIG_ARMV7_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE;
/* Align end of stack section to page boundary */
. = ALIGN(CONSTANT(COMMONPAGESIZE));
KEEP(*(.__secure_stack_end))
#ifdef CONFIG_ARMV7_SECURE_MAX_SIZE
/*
* We are not checking (__secure_end - __secure_start) here,
* as these are the load addresses, and do not include the
* stack section. Instead, use the end of the stack section
* and the start of the text section.
*/
ASSERT((. - ADDR(.secure_text)) <= CONFIG_ARMV7_SECURE_MAX_SIZE,
"Error: secure section exceeds secure memory size");
#endif
}
#ifndef __ARMV7_PSCI_STACK_IN_RAM
/* Reset VMA but don't allocate space if we have secure SRAM */
. = LOADADDR(.secure_stack);
#endif
__secure_end_lma = .;
.__secure_end : AT(__secure_end_lma) {
.__secure_end : AT(ADDR(.__secure_end)) {
*(.__secure_end)
LONG(0x1d1071c); /* Must output something to reset LMA */
}
......
......@@ -242,6 +242,7 @@ dtb-$(CONFIG_MACH_SUN8I_A83T) += \
sun8i-a83t-sinovoip-bpi-m3.dtb
dtb-$(CONFIG_MACH_SUN8I_H3) += \
sun8i-h3-orangepi-2.dtb \
sun8i-h3-orangepi-lite.dtb \
sun8i-h3-orangepi-one.dtb \
sun8i-h3-orangepi-pc.dtb \
sun8i-h3-orangepi-plus.dtb
......
......@@ -57,3 +57,16 @@
reg = <0x40000000 0x40000000>;
};
};
&emac {
pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>;
phy-mode = "rgmii";
phy = <&phy1>;
status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
};
};
......@@ -506,6 +506,25 @@
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
rmii_pins: rmii_pins {
allwinner,pins = "PD10", "PD11", "PD13", "PD14",
"PD17", "PD18", "PD19", "PD20",
"PD22", "PD23";
allwinner,function = "emac";
allwinner,drive = <SUN4I_PINCTRL_40_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
rgmii_pins: rgmii_pins {
allwinner,pins = "PD8", "PD9", "PD10", "PD11",
"PD12", "PD13", "PD15",
"PD16", "PD17", "PD18", "PD19",
"PD20", "PD21", "PD22", "PD23";
allwinner,function = "emac";
allwinner,drive = <SUN4I_PINCTRL_40_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
ahb_rst: reset@1c202c0 {
......@@ -620,5 +639,19 @@
#address-cells = <1>;
#size-cells = <0>;
};
emac: ethernet@01c30000 {
compatible = "allwinner,sun50i-a64-emac";
reg = <0x01c30000 0x2000>, <0x01c00030 0x4>;
reg-names = "emac", "syscon";
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
resets = <&ahb_rst 17>;
reset-names = "ahb";
clocks = <&bus_gates 17>;
clock-names = "ahb";
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
};
};
......@@ -184,3 +184,16 @@
usb1_vbus-supply = <&reg_usb1_vbus>;
status = "okay";
};
&emac {
pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>;
phy-mode = "rgmii";
phy = <&phy1>;
status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
};
};
/*
* Copyright (C) 2016 Hans de Goede <hdegoede@redhat.com>
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
#include "sun8i-h3.dtsi"
#include "sunxi-common-regulators.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "Xunlong Orange Pi Lite";
compatible = "xunlong,orangepi-lite", "allwinner,sun8i-h3";
aliases {
/* The H3 emac is not used so the wifi is ethernet0 */
ethernet1 = &rtl8189ftv;
serial0 = &uart0;
};
chosen {
stdout-path = "serial0:115200n8";
};
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&leds_opc>, <&leds_r_opc>;
pwr_led {
label = "orangepi:green:pwr";
gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
status_led {
label = "orangepi:red:status";
gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>;
};
};
r_gpio_keys {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&sw_r_opc>;
sw4 {
label = "sw4";
linux,code = <BTN_0>;
gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
};
};
};
&ehci1 {
status = "okay";
};
&ehci2 {
status = "okay";
};
&ir {
pinctrl-names = "default";
pinctrl-0 = <&ir_pins_a>;
status = "okay";
};
&mmc0 {
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
cd-inverted;
status = "okay";
};
&mmc1 {
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pins_a>;
vmmc-supply = <&reg_vcc3v3>;
bus-width = <4>;
non-removable;
status = "okay";
/*
* Explicitly define the sdio device, so that we can add an ethernet
* alias for it (which e.g. makes u-boot set a mac-address).
*/
rtl8189ftv: sdio_wifi@1 {
reg = <1>;
};
};
&ohci1 {
status = "okay";
};
&ohci2 {
status = "okay";
};
&pio {
leds_opc: led_pins@0 {
allwinner,pins = "PA15";
allwinner,function = "gpio_out";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
&r_pio {
leds_r_opc: led_pins@0 {
allwinner,pins = "PL10";
allwinner,function = "gpio_out";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
sw_r_opc: key_pins@0 {
allwinner,pins = "PL3";
allwinner,function = "gpio_in";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_a>;
status = "okay";
};
&usbphy {
/* USB VBUS is always on */
status = "okay";
};
......@@ -173,3 +173,15 @@
/* USB VBUS is always on */
status = "okay";
};
&emac {
phy = <&phy1>;
phy-mode = "mii";
allwinner,use-internal-phy;
allwinner,leds-active-low;
status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
};
};
......@@ -40,26 +40,13 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
#include "sun8i-h3.dtsi"
#include "sunxi-common-regulators.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>