
Hi Christian,
Thanks for your patch,
We need the dts from mainline kernel instead of github.
And you'd better split the dts and board support into different patches.
Thanks,
- Kever
On 2021/3/3 上午12:45, Christian Glombek wrote:
The hardware is described in detail on Kobol's wiki at https://wiki.kobol.io/helios64/intro/.
This commit is based on downstream work in Armbian by Aditya Prayoga [1]. The devicetree is taken from Linux v5.12-rc1 and was originally submitted there by Uwe Kleine-Koenig [2].
[1] https://github.com/ukleinek/armbian-build/blob/35c85295d351830aa59b624db524b... [2] https://github.com/torvalds/linux/blob/7a7fd0de4a9804299793e564a555a49c1fc92...
arch/arm/dts/Makefile | 1 + .../arm/dts/rk3399-kobol-helios64-u-boot.dtsi | 136 +++++++ arch/arm/dts/rk3399-kobol-helios64.dts | 372 ++++++++++++++++++ arch/arm/mach-rockchip/rk3399/Kconfig | 17 + board/kobol/helios64/Kconfig | 24 ++ board/kobol/helios64/MAINTAINERS | 6 + board/kobol/helios64/Makefile | 5 + board/kobol/helios64/helios64.c | 304 ++++++++++++++ board/kobol/helios64/sys_otp.c | 250 ++++++++++++ board/kobol/helios64/sys_otp.h | 12 + configs/helios64-rk3399_defconfig | 147 +++++++ include/configs/helios64.h | 47 +++ 12 files changed, 1321 insertions(+) create mode 100644 arch/arm/dts/rk3399-kobol-helios64-u-boot.dtsi create mode 100644 arch/arm/dts/rk3399-kobol-helios64.dts create mode 100644 board/kobol/helios64/Kconfig create mode 100644 board/kobol/helios64/MAINTAINERS create mode 100644 board/kobol/helios64/Makefile create mode 100644 board/kobol/helios64/helios64.c create mode 100644 board/kobol/helios64/sys_otp.c create mode 100644 board/kobol/helios64/sys_otp.h create mode 100644 configs/helios64-rk3399_defconfig create mode 100644 include/configs/helios64.h
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 33e483f4fb..2c820bc2b7 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -124,6 +124,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \ rk3399-ficus.dtb \ rk3399-firefly.dtb \ rk3399-gru-bob.dtb \
- rk3399-kobol-helios64.dtb \ rk3399-khadas-edge.dtb \ rk3399-khadas-edge-captain.dtb \ rk3399-khadas-edge-v.dtb \
diff --git a/arch/arm/dts/rk3399-kobol-helios64-u-boot.dtsi b/arch/arm/dts/rk3399-kobol-helios64-u-boot.dtsi new file mode 100644 index 0000000000..6fe9d59df3 --- /dev/null +++ b/arch/arm/dts/rk3399-kobol-helios64-u-boot.dtsi @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (c) 2020 Aditya Prayoga aditya@kobol.io
- */
+#include "rk3399-u-boot.dtsi" +#include "rk3399-sdram-lpddr4-100.dtsi" +/ {
- aliases {
spi0 = &spi1;
spi1 = &spi2;
spi2 = &spi5;
ethernet0 = &gmac;
ethernet1 = &usb_lan;
- };
- chosen {
bootargs = "earlycon=uart8250,mmio32,0xff1a0000 earlyprintk";
stdout-path = "serial2:1500000n8";
u-boot,spl-boot-order = "same-as-spl", &spiflash, &sdmmc, &sdhci;
- };
- config {
u-boot,spl-payload-offset = <0x80000>; /* @ 512KB */
- };
+};
+&gpio1 {
- usb-mux-hs {
gpio-hog;
gpios = <RK_PA4 GPIO_ACTIVE_HIGH>;
output-low;
line-name = "USB_MUX_HS";
- };
- usb-mux-oe {
gpio-hog;
gpios = <RK_PB5 GPIO_ACTIVE_LOW>;
output-high;
line-name = "USB_MUX_OE#";
- };
- soc-flash-wp {
gpio-hog;
gpios = <RK_PC2 GPIO_ACTIVE_LOW>;
output-low;
line-name = "SOC_WP#";
- };
+};
+&gpio2 {
- sata-flash-wp {
gpio-hog;
gpios = <RK_PD0 GPIO_ACTIVE_LOW>;
output-high;
line-name = "SATA_WP#_LV";
- };
+};
+&gpio4 {
- auto-on-en-d {
gpio-hog;
gpios = <RK_PD1 GPIO_ACTIVE_HIGH>;
output-low;
line-name = "AUTO_ON_EN_D";
- };
- auto-on-en-clk {
gpio-hog;
gpios = <RK_PD2 GPIO_ACTIVE_HIGH>;
output-low;
line-name = "AUTO_ON_EN_CLK";
- };
- board-rev-id-0 {
gpio-hog;
gpios = <RK_PD5 GPIO_ACTIVE_HIGH>;
input;
- };
- board-rev-id-1 {
gpio-hog;
gpios = <RK_PD6 GPIO_ACTIVE_HIGH>;
input;
- };
+};
+&int_hub {
- compatible = "usb-hub";
- usb,device-class = <USB_CLASS_HUB>;
+};
+&pcie_prst {
- rockchip,pins =
<2 RK_PD4 RK_FUNC_GPIO &pcfg_output_low>;
+};
+&pcie_pwr_en {
- rockchip,pins =
<1 RK_PD0 RK_FUNC_GPIO &pcfg_output_low>;
+};
+&pinctrl {
- usb {
usb_mux_hs: usb-mux-hs {
rockchip,pins =
<1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
};
usb_mux_oe: usb-mux-oe {
rockchip,pins =
<1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
};
- };
+};
+&spi1 {
- spiflash: flash@0 {
compatible = "jedec,spi-nor";
reg = <0x0>;
spi-max-frequency = <25000000>;
status = "okay";
m25p,fast-read;
u-boot,dm-pre-reloc;
- };
+};
+&vdd_center {
- regulator-min-microvolt = <950000>;
- regulator-max-microvolt = <950000>;
- regulator-init-microvolt = <950000>;
+};
+&vdd_log {
- regulator-init-microvolt = <900000>;
+}; diff --git a/arch/arm/dts/rk3399-kobol-helios64.dts b/arch/arm/dts/rk3399-kobol-helios64.dts new file mode 100644 index 0000000000..66c725a342 --- /dev/null +++ b/arch/arm/dts/rk3399-kobol-helios64.dts @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/*
- Copyright (c) 2020 Aditya Prayoga aditya@kobol.io
- */
+/*
- The Kobol Helios64 is a board designed to operate as a NAS and optionally
- ships with an enclosing that can host five 2.5" hard disks.
- See https://wiki.kobol.io/helios64/intro/ for further details.
- */
+/dts-v1/; +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi"
+/ {
- model = "Kobol Helios64";
- compatible = "kobol,helios64", "rockchip,rk3399";
- avdd_1v8_s0: avdd-1v8-s0 {
compatible = "regulator-fixed";
regulator-name = "avdd_1v8_s0";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
vin-supply = <&vcc3v3_sys_s3>;
- };
- clkin_gmac: external-gmac-clock {
compatible = "fixed-clock";
clock-frequency = <125000000>;
clock-output-names = "clkin_gmac";
#clock-cells = <0>;
- };
- leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&sys_grn_led_on &sys_red_led_on>;
led-0 {
label = "helios64:green:status";
gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led-1 {
label = "helios64:red:fault";
gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
default-state = "keep";
};
- };
- vcc1v8_sys_s0: vcc1v8-sys-s0 {
compatible = "regulator-fixed";
regulator-name = "vcc1v8_sys_s0";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
vin-supply = <&vcc1v8_sys_s3>;
- };
- vcc3v0_sd: vcc3v0-sd {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>;
regulator-name = "vcc3v0_sd";
regulator-boot-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc0_pwr_h>;
vin-supply = <&vcc3v3_sys_s3>;
- };
- vcc3v3_sys_s3: vcc_lan: vcc3v3-sys-s3 {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_sys_s3";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vcc5v0_sys>;
regulator-state-mem {
regulator-on-in-suspend;
};
- };
- vcc5v0_sys: vcc5v0-sys {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_sys";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc12v_dcin_bkup>;
regulator-state-mem {
regulator-on-in-suspend;
};
- };
- vcc12v_dcin: vcc12v-dcin {
compatible = "regulator-fixed";
regulator-name = "vcc12v_dcin";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
- };
- vcc12v_dcin_bkup: vcc12v-dcin-bkup {
compatible = "regulator-fixed";
regulator-name = "vcc12v_dcin_bkup";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
vin-supply = <&vcc12v_dcin>;
- };
+};
+/*
- The system doesn't run stable with cpu freq enabled, so disallow the lower
- frequencies until this problem is properly understood and resolved.
- */
+&cluster0_opp {
- /delete-node/ opp00;
- /delete-node/ opp01;
- /delete-node/ opp02;
- /delete-node/ opp03;
- /delete-node/ opp04;
+};
+&cluster1_opp {
- /delete-node/ opp00;
- /delete-node/ opp01;
- /delete-node/ opp02;
- /delete-node/ opp03;
- /delete-node/ opp04;
- /delete-node/ opp05;
- /delete-node/ opp06;
+};
+&cpu_b0 {
- cpu-supply = <&vdd_cpu_b>;
+};
+&cpu_b1 {
- cpu-supply = <&vdd_cpu_b>;
+};
+&cpu_l0 {
- cpu-supply = <&vdd_cpu_l>;
+};
+&cpu_l1 {
- cpu-supply = <&vdd_cpu_l>;
+};
+&cpu_l2 {
- cpu-supply = <&vdd_cpu_l>;
+};
+&cpu_l3 {
- cpu-supply = <&vdd_cpu_l>;
+};
+&emmc_phy {
- status = "okay";
+};
+&gmac {
- assigned-clock-parents = <&clkin_gmac>;
- assigned-clocks = <&cru SCLK_RMII_SRC>;
- clock_in_out = "input";
- phy-mode = "rgmii";
- phy-supply = <&vcc_lan>;
- pinctrl-names = "default";
- pinctrl-0 = <&rgmii_pins &gphy_reset>;
- rx_delay = <0x20>;
- tx_delay = <0x28>;
- snps,reset-active-low;
- snps,reset-delays-us = <0 10000 50000>;
- snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
- status = "okay";
+};
+&i2c0 {
- clock-frequency = <400000>;
- i2c-scl-rising-time-ns = <168>;
- i2c-scl-falling-time-ns = <4>;
- status = "okay";
- rk808: pmic@1b {
compatible = "rockchip,rk808";
reg = <0x1b>;
interrupt-parent = <&gpio0>;
interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
clock-output-names = "xin32k", "rk808-clkout2";
pinctrl-names = "default";
pinctrl-0 = <&pmic_int_l>;
vcc1-supply = <&vcc5v0_sys>;
vcc2-supply = <&vcc5v0_sys>;
vcc3-supply = <&vcc5v0_sys>;
vcc4-supply = <&vcc5v0_sys>;
vcc6-supply = <&vcc5v0_sys>;
vcc7-supply = <&vcc5v0_sys>;
vcc8-supply = <&vcc3v3_sys_s3>;
vcc9-supply = <&vcc5v0_sys>;
vcc10-supply = <&vcc5v0_sys>;
vcc11-supply = <&vcc5v0_sys>;
vcc12-supply = <&vcc3v3_sys_s3>;
vddio-supply = <&vcc3v0_s3>;
wakeup-source;
#clock-cells = <1>;
regulators {
vdd_cpu_l: DCDC_REG2 {
regulator-name = "vdd_cpu_l";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <1350000>;
regulator-ramp-delay = <6001>;
regulator-state-mem {
regulator-off-in-suspend;
};
};
vcc1v8_sys_s3: DCDC_REG4 {
regulator-name = "vcc1v8_sys_s3";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vcc_sdio_s0: LDO_REG4 {
regulator-name = "vcc_sdio_s0";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3000000>;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3000000>;
};
};
vcc3v0_s3: LDO_REG8 {
regulator-name = "vcc3v0_s3";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3000000>;
};
};
};
- };
- vdd_cpu_b: regulator@40 {
compatible = "silergy,syr827";
reg = <0x40>;
fcs,suspend-voltage-selector = <1>;
regulator-name = "vdd_cpu_b";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <712500>;
regulator-max-microvolt = <1500000>;
regulator-ramp-delay = <1000>;
vin-supply = <&vcc5v0_sys>;
regulator-state-mem {
regulator-off-in-suspend;
};
- };
+};
+&i2c2 {
- clock-frequency = <400000>;
- i2c-scl-rising-time-ns = <160>;
- i2c-scl-falling-time-ns = <30>;
- status = "okay";
- temp@4c {
compatible = "national,lm75";
reg = <0x4c>;
- };
+};
+&io_domains {
- audio-supply = <&vcc1v8_sys_s0>;
- bt656-supply = <&vcc1v8_sys_s0>;
- gpio1830-supply = <&vcc3v0_s3>;
- sdmmc-supply = <&vcc_sdio_s0>;
- status = "okay";
+};
+&pinctrl {
- gmac {
gphy_reset: gphy-reset {
rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>;
};
- };
- leds {
sys_grn_led_on: sys-grn-led-on {
rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
};
sys_red_led_on: sys-red-led-on {
rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>;
};
- };
- pmic {
pmic_int_l: pmic-int-l {
rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
};
- };
- vcc3v0-sd {
sdmmc0_pwr_h: sdmmc0-pwr-h {
rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>;
};
- };
+};
+&pmu_io_domains {
- pmu1830-supply = <&vcc3v0_s3>;
- status = "okay";
+};
+&sdhci {
- bus-width = <8>;
- mmc-hs200-1_8v;
- non-removable;
- vqmmc-supply = <&vcc1v8_sys_s0>;
- status = "okay";
+};
+&sdmmc {
- bus-width = <4>;
- cap-sd-highspeed;
- cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
- disable-wp;
- pinctrl-names = "default";
- pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
- vmmc-supply = <&vcc3v0_sd>;
- vqmmc-supply = <&vcc_sdio_s0>;
- status = "okay";
+};
+&uart2 {
- status = "okay";
+}; diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig index 17628f9171..7890bafe56 100644 --- a/arch/arm/mach-rockchip/rk3399/Kconfig +++ b/arch/arm/mach-rockchip/rk3399/Kconfig @@ -28,6 +28,22 @@ config TARGET_PINEBOOK_PRO_RK3399 with 4Gb RAM, onboard eMMC, USB-C, a USB3 and USB2 port, 1920*1080 screen and all the usual laptop features.
+config TARGET_HELIOS64
- bool "Kobol Innovations Helios64"
- select BOARD_LATE_INIT
- help
Helios64 is a Network Attached Storage board based on Rockchip RK3399.
Key features of the Helios64 include:
* on-board PCIe to 5 Ports SATA Controller JMB585
* on-board USB 3.0 hub (3x USB 3.0 host)
* USB Type-C (Support DisplayPort Alt Mode)
* on-board 1 Gigabit Ethernet
* on-board 2.5 Gigabit Ethernet (Realtek RTL8156)
* on-board eMMC
* on-board LPDDR4
* SPI, I2C, UART, GPIO
- config TARGET_PUMA_RK3399 bool "Theobroma Systems RK3399-Q7 (Puma)" help
@@ -153,6 +169,7 @@ endif # BOOTCOUNT_LIMIT
source "board/firefly/roc-pc-rk3399/Kconfig" source "board/google/gru/Kconfig" +source "board/kobol/helios64/Kconfig" source "board/pine64/pinebook-pro-rk3399/Kconfig" source "board/pine64/rockpro64_rk3399/Kconfig" source "board/rockchip/evb_rk3399/Kconfig" diff --git a/board/kobol/helios64/Kconfig b/board/kobol/helios64/Kconfig new file mode 100644 index 0000000000..644cdbd8f3 --- /dev/null +++ b/board/kobol/helios64/Kconfig @@ -0,0 +1,24 @@ +if TARGET_HELIOS64
+config SYS_BOARD
- default "helios64"
+config SYS_VENDOR
- default "kobol"
+config SYS_CONFIG_NAME
- default "helios64"
+config BOARD_SPECIFIC_OPTIONS # dummy
- def_bool y
+config ENV_SECT_SIZE
- default 0x1000 if ENV_IS_IN_SPI_FLASH
+config ENV_SIZE
- default 0x8000
+config ENV_OFFSET
- default 0x460000 if ENV_IS_IN_SPI_FLASH
+endif diff --git a/board/kobol/helios64/MAINTAINERS b/board/kobol/helios64/MAINTAINERS new file mode 100644 index 0000000000..646644d485 --- /dev/null +++ b/board/kobol/helios64/MAINTAINERS @@ -0,0 +1,6 @@ +HELIOS64 BOARD +M: Christian Glombek lorbus@fedoraproject.org +S: Maintained +F: board/kobol/helios64/ +F: include/configs/helios64.h +F: configs/helios64_defconfig diff --git a/board/kobol/helios64/Makefile b/board/kobol/helios64/Makefile new file mode 100644 index 0000000000..ab34245a6d --- /dev/null +++ b/board/kobol/helios64/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2020 Aditya Prayoga aditya@kobol.io
+obj-y := helios64.o sys_otp.o diff --git a/board/kobol/helios64/helios64.c b/board/kobol/helios64/helios64.c new file mode 100644 index 0000000000..86349339fb --- /dev/null +++ b/board/kobol/helios64/helios64.c @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2020 Aditya Prayoga aditya@kobol.io
- */
+#include <common.h> +#include <dm.h> +#include <env.h> +#include <log.h> +#include <led.h> +#include <pci.h> +#include <power/regulator.h> +#include <scsi.h> +#include <spl_gpio.h> +#include <syscon.h> +#include <usb.h> +#include <linux/delay.h> +#include <asm/io.h> +#include <asm/gpio.h> +#include <asm/arch-rockchip/clock.h> +#include <asm/arch-rockchip/gpio.h> +#include <asm/arch-rockchip/grf_rk3399.h> +#include <asm/arch-rockchip/hardware.h> +#include <asm/arch-rockchip/misc.h> +#include <asm/arch-rockchip/periph.h>
+#include "sys_otp.h"
+#ifndef CONFIG_TPL_BUILD +int board_early_init_f(void) +{ +#ifdef CONFIG_SPL_BUILD +#define GPIO0_BASE 0xff720000 +#define GRF_BASE 0xff770000
- struct rk3399_grf_regs * const grf = (void *)GRF_BASE;
- struct rockchip_gpio_regs * const gpio = (void *)GPIO0_BASE;
- /* Turn ON status LED. At this stage, FDT & DM is not initialized yet */
- spl_gpio_output(gpio, GPIO(BANK_B, 4), 1);
+#endif
- return 0;
+} +#endif
+#ifndef CONFIG_SPL_BUILD +int board_early_init_r(void) +{
- read_otp_data();
- return 0;
+} +#endif
+#ifdef CONFIG_MISC_INIT_R +#define GRF_IO_VSEL_BT565_SHIFT 0 +#define GRF_IO_VSEL_AUDIO_SHIFT 1 +#define GRF_IO_VSEL_SDMMC_SHIFT 2 +#define GRF_IO_VSEL_GPIO1830_SHIFT 3
+#define PMUGRF_CON0_VSEL_SHIFT 8 +#define PMUGRF_CON0_PMU1830_VOL_SHIFT 9 +static void setup_iodomain(void) +{
- struct rk3399_grf_regs *grf =
syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
- struct rk3399_pmugrf_regs *pmugrf =
syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
- /* BT565 is in 1.8v domain */
- rk_setreg(&grf->io_vsel, 1 << GRF_IO_VSEL_BT565_SHIFT);
- /* AUDIO is in 1.8v domain */
- rk_setreg(&grf->io_vsel, 1 << GRF_IO_VSEL_AUDIO_SHIFT);
- /* SDMMC is in 3.0v domain */
- rk_setreg(&grf->io_vsel, 0 << GRF_IO_VSEL_SDMMC_SHIFT);
- /* GPIO1830 is in 3.0v domain */
- rk_setreg(&grf->io_vsel, 0 << GRF_IO_VSEL_GPIO1830_SHIFT);
- /* Set GPIO1 1.8v/3.0v source select to PMU1830_VOL */
- rk_setreg(&pmugrf->soc_con0, 1 << PMUGRF_CON0_VSEL_SHIFT);
- rk_setreg(&pmugrf->soc_con0, 0 << PMUGRF_CON0_PMU1830_VOL_SHIFT);
+}
+/*
- Swap mmc0 and mmc1 in boot_targets if booted from SD-Card.
- If bootsource is uSD-card we can assume that we want to use the
- SD-Card instead of the eMMC as first boot_target for distroboot.
- We only want to swap the defaults and not any custom environment a
- user has set. We exit early if a changed boot_targets environment
- is detected.
- */
+static int setup_boottargets(void) +{
- const char *boot_device =
ofnode_read_chosen_string("u-boot,spl-boot-device");
- char *env_default, *env;
- if (!boot_device) {
debug("%s: /chosen/u-boot,spl-boot-device not set\n",
__func__);
return -1;
- }
- debug("%s: booted from %s\n", __func__, boot_device);
- env_default = env_get_default("boot_targets");
- env = env_get("boot_targets");
- if (!env) {
debug("%s: boot_targets does not exist\n", __func__);
return -1;
- }
- debug("%s: boot_targets current: %s - default: %s\n",
__func__, env, env_default);
- if (strcmp(env_default, env) != 0) {
debug("%s: boot_targets not default, don't change it\n",
__func__);
return 0;
- }
- /*
* Only run, if booting from mmc1 (i.e. /mmc@fe320000) and
* only consider cases where the default boot-order first
* tries to boot from mmc0 (eMMC) and then from mmc1
* (i.e. external SD).
*
* In other words: the SD card will be moved to earlier in the
* order, if U-Boot was also loaded from the SD-card.
*/
- if (!strcmp(boot_device, "/mmc@fe320000")) {
char *mmc0, *mmc1;
debug("%s: booted from SD-Card\n", __func__);
mmc0 = strstr(env, "mmc0");
mmc1 = strstr(env, "mmc1");
if (!mmc0 || !mmc1) {
debug("%s: only one mmc boot_target found\n", __func__);
return -1;
}
/*
* If mmc0 comes first in the boot order, we need to change
* the strings to make mmc1 first.
*/
if (mmc0 < mmc1) {
mmc0[3] = '1';
mmc1[3] = '0';
debug("%s: set boot_targets to: %s\n", __func__, env);
env_set("boot_targets", env);
}
- }
- return 0;
+}
+static void setup_leds(void) +{
- struct udevice *dev;
- led_get_by_label("helios64::status", &dev);
- led_set_state(dev, LEDST_OFF);
- mdelay(250);
- led_set_state(dev, LEDST_ON);
+}
+int misc_init_r(void) +{
- const u32 cpuid_offset = 0x7;
- const u32 cpuid_length = 0x10;
- u8 cpuid[cpuid_length];
- int ret;
- setup_iodomain();
- set_board_info();
- ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
- if (ret)
return ret;
- ret = rockchip_cpuid_set(cpuid, cpuid_length);
- if (ret)
return ret;
- if (mac_read_from_otp())
ret = rockchip_setup_macaddr();
- setup_boottargets();
- setup_leds();
- return ret;
+} +#endif
+#ifdef CONFIG_ROCKCHIP_ADVANCED_RECOVERY +void rockchip_prepare_download_mode(void) +{
- struct gpio_desc *enable, *mux;
- if (gpio_hog_lookup_name("USB_MUX_OE#", &enable)) {
debug("Fail to get USB_MUX_OE\n");
return;
- }
- if (gpio_hog_lookup_name("USB_MUX_HS", &mux)) {
debug("Fail to get USB_MUX_HS\n");
return;
- }
- dm_gpio_set_value(enable, 0);
- mdelay(100);
- dm_gpio_set_value(mux, 1);
- mdelay(100);
- dm_gpio_set_value(enable, 1);
+} +#endif
+#ifdef CONFIG_LAST_STAGE_INIT +static void auto_power_enable(void) +{
- struct gpio_desc *enable, *clock;
- if (gpio_hog_lookup_name("AUTO_ON_EN_D", &enable)) {
debug("Fail to get AUTO_ON_EN_D\n");
return;
- }
- if (gpio_hog_lookup_name("AUTO_ON_EN_CLK", &clock)) {
debug("Fail to get AUTO_ON_EN_CLK\n");
return;
- }
- dm_gpio_set_value(enable, 1);
- dm_gpio_set_value(clock, 1);
- mdelay(10);
- dm_gpio_set_value(clock, 0);
+}
+static void sata_power_enable(void) +{
- struct udevice *rail_a, *rail_b;
- int ret;
- ret = regulator_get_by_platname("power_hdd_a", &rail_a);
- if (!ret) {
ret = regulator_set_enable(rail_a, true);
if (!ret)
mdelay(10000);
- }
- ret = regulator_get_by_platname("power_hdd_b", &rail_b);
- if (!ret)
ret = regulator_set_enable(rail_b, true);
+}
+int last_stage_init(void) +{
- auto_power_enable();
- sata_power_enable();
+#ifdef CONFIG_PCI
- scsi_scan(true);
+#endif
- return 0;
+} +#endif
+#if defined(CONFIG_DISPLAY_BOARDINFO_LATE) +int checkboard(void) +{
- int major, minor;
- printf("Revision: ");
- if (!get_revision(&major, &minor))
printf("%i.%i - %s\n", major, minor, get_variant());
- else
printf("UNKNOWN\n");
- return 0;
+} +#endif
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{
- char *env;
- env = env_get("board_rev");
- if (env)
fdt_setprop_string(blob, fdt_path_offset(blob, "/"),
"kobol,board-rev", env);
- env = env_get("cpuid#");
- if (env)
fdt_setprop_string(blob, fdt_path_offset(blob, "/"),
"kobol,cpu-id", env);
- return 0;
+} +#endif diff --git a/board/kobol/helios64/sys_otp.c b/board/kobol/helios64/sys_otp.c new file mode 100644 index 0000000000..8c20693c0e --- /dev/null +++ b/board/kobol/helios64/sys_otp.c @@ -0,0 +1,250 @@ +/* SPDX-License-Identifier: GPL-2.0+ */
+#include <linux/types.h> +#include <dm.h> +#include <spi.h> +#include <log.h> +#include <net.h> +#include <u-boot/crc.h>
+#include "sys_otp.h"
+#define OTP_DEVICE_BUS 0 +#define OTP_DEVICE_CS 0 +#define MAX_NUM_PORTS 2
+enum board_variant {
- BOARD_VARIANT_INVALID = 0,
- BOARD_VARIANT_ENG_SAMPLE,
- BOARD_VARIANT_4G_PROD_NO_ECC,
- BOARD_VARIANT_MAX
+};
+struct __attribute__ ((__packed__)) otp_data_t {
- u8 magic[8];
- u8 part_num[16];
- u8 variant;
- u8 revision;
- u8 serial_num[6];
- u8 mfg_year[2];
- u8 mfg_month;
- u8 mfg_day;
- u8 mac_addr[MAX_NUM_PORTS][6];
- u8 reserved[204];
- u32 checksum;
+} otp;
+static struct spi_slave *slave; +static int has_been_read = 0; +static int data_valid = 0;
+static inline int is_data_valid(void) +{
- return data_valid;
+}
+static inline int is_valid_header(void) +{
- if ((otp.magic[0] == 'H') || (otp.magic[1] == '6') ||
(otp.magic[2] == '4') || (otp.magic[3] == 'N') ||
(otp.magic[4] == 'P') || (otp.magic[5] == 'V') ||
(otp.magic[6] == '1') || (otp.magic[7] == 0))
return 1;
- return 0;
+}
+static int init_system_otp(int bus, int cs) +{
- int ret;
- char name[30], *str;
- struct udevice *dev;
- snprintf(name, sizeof(name), "generic_%d:%d", bus, cs);
- str = strdup(name);
- if (!str)
return -ENOMEM;
- ret = spi_get_bus_and_cs(bus, cs, 25000000, CONFIG_DEFAULT_SPI_MODE, "spi_generic_drv",
str, &dev, &slave);
- return ret;
+}
+#ifdef DEBUG +/**
- show_otp_data - display the contents of the OTP register
- */
+static void show_otp_data(void) +{
- u32 i;
- u32 crc;
- const char* var_str[BOARD_VARIANT_MAX] = {
"Invalid variant",
"Engineering Sample",
"Production - 4GB non ECC"
- };
- printf("\n");
- printf("Register dump: (%lu bytes)\n", sizeof(otp));
- for (i = 0; i < sizeof(otp); i++) {
if ((i % 16) == 0)
printf("%02X: ", i);
printf("%02X ", ((u8 *)&otp)[i]);
if (((i % 16) == 15) || (i == sizeof(otp) - 1))
printf("\n");
- }
- if (!is_valid_header())
return;
- printf("Part Number: %s\n", otp.part_num);
- printf("Variant: %s\n", var_str[otp.variant]);
- printf("Revision: %x.%x\n", (otp.revision & 0xf0) >> 4, otp.revision & 0x0f);
- printf("Serial Number: %012llx\n", *((uint64_t*) otp.serial_num) &
0xFFFFFFFFFFFF);
- printf("Manufacturing Date: %02X-%02X-%04X (DD-MM-YYYY)\n", otp.mfg_day,
otp.mfg_month, *(u16*) otp.mfg_year);
- printf("1GbE MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
otp.mac_addr[0][0], otp.mac_addr[0][1], otp.mac_addr[0][2],
otp.mac_addr[0][3], otp.mac_addr[0][4], otp.mac_addr[0][5]);
- printf("2.5GbE MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
otp.mac_addr[1][0], otp.mac_addr[1][1], otp.mac_addr[1][2],
otp.mac_addr[1][3], otp.mac_addr[1][4], otp.mac_addr[1][5]);
- crc = crc32(0, (void *)&otp, sizeof(otp) - 4);
- if (crc == le32_to_cpu(otp.checksum))
printf("CRC: %08x\n\n", le32_to_cpu(otp.checksum));
- else
printf("CRC: %08x (should be %08x)\n\n",
le32_to_cpu(otp.checksum), crc);
+} +#endif
+int read_otp_data(void) +{
- int ret;
- u8 dout[5];
- if (has_been_read) {
if (is_data_valid())
return 0;
else
goto data_invalid;
- }
- ret = init_system_otp(OTP_DEVICE_BUS, OTP_DEVICE_CS);
- if (ret)
return ret;
- ret = spi_claim_bus(slave);
- if (ret) {
debug("SPI: Failed to claim SPI bus: %d\n", ret);
return ret;
- }
- dout[0] = 0x48;
- dout[1] = 0x00;
- dout[2] = 0x10; /* Security Register #1 */
- dout[3] = 0x00;
- dout[4] = 0x00; /* Dummy Byte */
- ret = spi_write_then_read(slave, dout, sizeof(dout), NULL, (u8 *)&otp,
sizeof(otp));
- spi_release_bus(slave);
+#ifdef DEBUG
- show_otp_data();
+#endif
- has_been_read = (ret == 0) ? 1 : 0;
- if (!is_valid_header())
goto data_invalid;
- if (crc32(0, (void *)&otp, sizeof(otp) - 4) ==
le32_to_cpu(otp.checksum))
data_valid = 1;
- if (!is_data_valid())
goto data_invalid;
- return 0;
+data_invalid:
- printf("Invalid board ID data!\n");
- return -1;
+}
+int get_revision(int *major, int *minor) +{
- if (!is_data_valid())
return -1;
- *major = (otp.revision & 0xf0) >> 4;
- *minor = otp.revision & 0x0f;
- return 0;
+}
+const char *get_variant(void) +{
- const char* var_str[BOARD_VARIANT_MAX] = {
"Unknown",
"Engineering Sample",
"4GB non ECC"
- };
- if ((otp.variant < BOARD_VARIANT_ENG_SAMPLE) ||
(otp.variant >= BOARD_VARIANT_MAX))
return var_str[0];
- return var_str[otp.variant];
+}
+void set_board_info(void) +{
- char env_str[13];
- if (!is_data_valid())
return;
- snprintf(env_str, sizeof(env_str), "%i.%i", (otp.revision & 0xf0) >> 4, otp.revision & 0x0f);
- env_set("board_rev", env_str);
- sprintf(env_str, "%012llx", *((uint64_t*) otp.serial_num) &
0xFFFFFFFFFFFF);
- env_set("serial#", env_str);
+}
+int mac_read_from_otp(void) +{
- unsigned int i;
- int ret;
- if (!is_data_valid())
return -1;
- for (i = 0; i < MAX_NUM_PORTS; i++) {
char enetvar[9];
sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i);
if (!is_valid_ethaddr(otp.mac_addr[i])) {
debug("Not valid %s!\n", enetvar);
continue;
}
/* Only initialize environment variables that are blank
* (i.e. have not yet been set)
*/
if (!env_get(enetvar))
eth_env_set_enetaddr(enetvar, otp.mac_addr[i]);
- }
- return ret;
+} diff --git a/board/kobol/helios64/sys_otp.h b/board/kobol/helios64/sys_otp.h new file mode 100644 index 0000000000..48273d4a95 --- /dev/null +++ b/board/kobol/helios64/sys_otp.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */
+#ifndef __HELIOS64_SYS_OTP_H +#define __HELIOS64_SYS_OTP_H
+int read_otp_data(void); +void set_board_info(void); +int get_revision(int *major, int *minor); +const char *get_variant(void); +int mac_read_from_otp(void);
+#endif diff --git a/configs/helios64-rk3399_defconfig b/configs/helios64-rk3399_defconfig new file mode 100644 index 0000000000..3b4ed62ab6 --- /dev/null +++ b/configs/helios64-rk3399_defconfig @@ -0,0 +1,147 @@ +CONFIG_ARM=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SYS_TEXT_BASE=0x00200000 +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_ENV_OFFSET=0x3F8000 +CONFIG_ROCKCHIP_RK3399=y +CONFIG_ROCKCHIP_ADVANCED_RECOVERY=y +CONFIG_ROCKCHIP_ADVANCED_RECOVERY_LED="helios64::status" +# CONFIG_ROCKCHIP_ADVANCED_RECOVERY_ROCKUSB is not set +CONFIG_TARGET_HELIOS64=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DEBUG_UART_BASE=0xFF1A0000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +CONFIG_DEBUG_UART=y +CONFIG_AHCI=y +# CONFIG_ANDROID_BOOT_IMAGE is not set +CONFIG_OF_BOARD_SETUP=y +CONFIG_USE_PREBOOT=y +CONFIG_CONSOLE_MUX=y +CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-kobol-helios64.dtb" +CONFIG_MISC_INIT_R=y +CONFIG_VERSION_VARIABLE=y +# CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_BOARD_TYPES=y +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_BOARD_EARLY_INIT_R=y +CONFIG_LAST_STAGE_INIT=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +CONFIG_SPL_STACK_R=y +CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000 +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_POWER_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_TPL=y +CONFIG_CMD_CONFIG=y +CONFIG_CMD_BOOTZ=y +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +CONFIG_CMD_BOOTEFI_HELLO=y +CONFIG_CMD_BOOTMENU=y +CONFIG_CRC32_VERIFY=y +CONFIG_CMD_MD5SUM=y +CONFIG_MD5SUM_VERIFY=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MX_CYCLIC=y +CONFIG_CMD_SHA1SUM=y +CONFIG_SHA1SUM_VERIFY=y +CONFIG_CMD_STRINGS=y +CONFIG_CMD_ADC=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PCI=y +CONFIG_CMD_POWEROFF=y +CONFIG_CMD_READ=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_CMD_ROCKUSB=y +CONFIG_CMD_USB_MASS_STORAGE=y +CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_EXCEPTION=y +CONFIG_CMD_TIME=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_FS_UUID=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_LIVE=y +CONFIG_DEFAULT_DEVICE_TREE="rk3399-kobol-helios64" +CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_IP_DEFRAG=y +# CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_SCSI_AHCI=y +CONFIG_AHCI_PCI=y +CONFIG_SPL_FIRMWARE=y +CONFIG_GPIO_HOG=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_I2C_SET_DEFAULT_BUS_NUM=y +CONFIG_I2C_DEFAULT_BUS_NUMBER=0x8 +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_MISC=y +CONFIG_ROCKCHIP_EFUSE=y +CONFIG_ROCKCHIP_OTP=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_PHY_REALTEK=y +CONFIG_DM_ETH=y +CONFIG_DM_MDIO=y +CONFIG_PHY_GIGE=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_RGMII=y +CONFIG_MII=y +CONFIG_GMAC_ROCKCHIP=y +CONFIG_PCI=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_TYPEC=y +CONFIG_DM_PMIC_FAN53555=y +CONFIG_PMIC_RK8XX=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_REGULATOR_PWM=y +CONFIG_SPL_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_SPL_DM_REGULATOR_GPIO=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_RAM_RK3399_LPDDR4=y +CONFIG_DM_RESET=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_ROCKCHIP_SPI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_SYSCON=y +CONFIG_DM_THERMAL=y +CONFIG_USB=y +# CONFIG_SPL_DM_USB is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_GADGET=y +CONFIG_USB_FUNCTION_ROCKUSB=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_RTL8152=y +CONFIG_SPL_TINY_MEMSET=y +CONFIG_ERRNO_STR=y +CONFIG_HEXDUMP=y diff --git a/include/configs/helios64.h b/include/configs/helios64.h new file mode 100644 index 0000000000..6fca9a6be0 --- /dev/null +++ b/include/configs/helios64.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- (C) Copyright 2020 Aditya Prayoga aditya@kobol.io
- */
+#ifndef __HELIOS64_H +#define __HELIOS64_H
+#include <configs/rk3399_common.h>
+#define SDRAM_BANK_SIZE (2UL << 30)
+#if defined(CONFIG_ENV_IS_IN_MMC)
- #define CONFIG_SYS_MMC_ENV_DEV 0
+#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
- #define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS
- #define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS
- #define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE
- #define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
+#endif
+#ifndef CONFIG_SPL_BUILD +#if CONFIG_IS_ENABLED(SCSI)
- #define CONFIG_SYS_SCSI_MAX_SCSI_ID 5
- #define CONFIG_SYS_SCSI_MAX_LUN 1
- #define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
- #define BOOT_TARGET_SCSI(func) \
func(SCSI, scsi, 0)
+#else
- #define BOOT_TARGET_SCSI(func)
+#endif
+#undef BOOT_TARGET_DEVICES +#define BOOT_TARGET_DEVICES(func) \
- BOOT_TARGET_MMC(func) \
- BOOT_TARGET_USB(func) \
- BOOT_TARGET_SCSI(func) \
- BOOT_TARGET_PXE(func) \
- BOOT_TARGET_DHCP(func)
+#endif
+#endif