M: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
S: Maintained
T: git git://git.denx.de/u-boot-rockchip.git
+F: arch/arm/include/asm/arch-rockchip/
F: arch/arm/mach-rockchip/
F: board/rockchip/
+F: drivers/clk/rockchip/
+F: drivers/gpio/rk_gpio.c
+F: drivers/misc/rockchip-efuse.c
+F: drivers/pinctrl/rockchip/
+F: drivers/ram/rockchip/
+F: drivers/sysreset/sysreset_rockchip.c
+F: tools/rkcommon.c
+F: tools/rkcommon.h
+F: tools/rkimage.c
+F: tools/rksd.c
+F: tools/rkspi.c
ARM SAMSUNG
M: Minkyu Kang <mk7.kang@samsung.com>
# SPDX-License-Identifier: GPL-2.0+
#
-VERSION = 2017
-PATCHLEVEL = 11
+VERSION = 2018
+PATCHLEVEL = 01
SUBLEVEL =
-EXTRAVERSION =
+EXTRAVERSION = -rc1
NAME =
# *DOCUMENTATION*
checkgcc6:
@if test "$(call cc-name)" = "gcc" -a \
"$(call cc-version)" -lt "0600"; then \
- echo -n '*** Your GCC is older than 6.0 and will not be '; \
- echo 'supported starting in v2018.01.'; \
+ echo '*** Your GCC is older than 6.0 and is not supported'; \
+ false; \
fi
/* Page fits, create block PTE */
debug("Setting PTE %p to block virt=%llx\n",
pte, virt);
- *pte = phys | attrs;
+ if (level == 3)
+ *pte = phys | attrs | PTE_TYPE_PAGE;
+ else
+ *pte = phys | attrs;
virt += blocksize;
phys += blocksize;
size -= blocksize;
#include <asm/macro.h>
#include <linux/linkage.h>
+/*
+ * Exception vectors.
+ */
+ .align 11
+ .globl vectors
+vectors:
+ .align 7 /* Current EL Synchronous Thread */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_bad_sync
+ b exception_exit
+
+ .align 7 /* Current EL IRQ Thread */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_bad_irq
+ b exception_exit
+
+ .align 7 /* Current EL FIQ Thread */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_bad_fiq
+ b exception_exit
+
+ .align 7 /* Current EL Error Thread */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_bad_error
+ b exception_exit
+
+ .align 7 /* Current EL Synchronous Handler */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_sync
+ b exception_exit
+
+ .align 7 /* Current EL IRQ Handler */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_irq
+ b exception_exit
+
+ .align 7 /* Current EL FIQ Handler */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_fiq
+ b exception_exit
+
+ .align 7 /* Current EL Error Handler */
+ stp x29, x30, [sp, #-16]!
+ bl _exception_entry
+ bl do_error
+ b exception_exit
+
/*
* Enter Exception.
* This will save the processor state that is ELR/X0~X30
* to the stack frame.
*/
-.macro exception_entry
- stp x29, x30, [sp, #-16]!
+_exception_entry:
stp x27, x28, [sp, #-16]!
stp x25, x26, [sp, #-16]!
stp x23, x24, [sp, #-16]!
0:
stp x2, x0, [sp, #-16]!
mov x0, sp
-.endm
+ ret
-/*
- * Exception vectors.
- */
- .align 11
- .globl vectors
-vectors:
- .align 7
- b _do_bad_sync /* Current EL Synchronous Thread */
-
- .align 7
- b _do_bad_irq /* Current EL IRQ Thread */
-
- .align 7
- b _do_bad_fiq /* Current EL FIQ Thread */
-
- .align 7
- b _do_bad_error /* Current EL Error Thread */
-
- .align 7
- b _do_sync /* Current EL Synchronous Handler */
-
- .align 7
- b _do_irq /* Current EL IRQ Handler */
-
- .align 7
- b _do_fiq /* Current EL FIQ Handler */
-
- .align 7
- b _do_error /* Current EL Error Handler */
-
-
-_do_bad_sync:
- exception_entry
- bl do_bad_sync
- b exception_exit
-
-_do_bad_irq:
- exception_entry
- bl do_bad_irq
- b exception_exit
-
-_do_bad_fiq:
- exception_entry
- bl do_bad_fiq
- b exception_exit
-
-_do_bad_error:
- exception_entry
- bl do_bad_error
- b exception_exit
-
-_do_sync:
- exception_entry
- bl do_sync
- b exception_exit
-
-_do_irq:
- exception_entry
- bl do_irq
- b exception_exit
-
-_do_fiq:
- exception_entry
- bl do_fiq
- b exception_exit
-
-_do_error:
- exception_entry
- bl do_error
- b exception_exit
exception_exit:
ldp x2, x0, [sp],#16
dtb-$(CONFIG_EXYNOS7420) += exynos7420-espresso7420.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3036-sdk.dtb \
+ rk3128-evb.dtb \
rk3188-radxarock.dtb \
rk3288-evb.dtb \
rk3288-fennec.dtb \
rv1108-evb.dtb
dtb-$(CONFIG_ARCH_MESON) += \
meson-gxbb-odroidc2.dtb \
- meson-gxl-s905x-p212.dtb
+ meson-gxl-s905x-p212.dtb \
+ meson-gxl-s905x-libretech-cc.dtb \
+ meson-gxl-s905x-khadas-vim.dtb
dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
tegra20-medcom-wide.dtb \
tegra20-paz00.dtb \
--- /dev/null
+/dts-v1/;
+#include "bcm2835.dtsi"
+#include "bcm2835-rpi.dtsi"
+#include "bcm283x-rpi-smsc9512.dtsi"
+#include "bcm283x-rpi-usb-host.dtsi"
+
+/ {
+ compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
+ model = "Raspberry Pi Zero W";
+
+ leds {
+ act {
+ gpios = <&gpio 47 0>;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_gpio14>;
+ status = "okay";
+};
+
+&hdmi {
+ hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+};
--- /dev/null
+/*
+ * Copyright (c) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>.
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+
+#include "meson-gxl-s905x-p212.dtsi"
+
+/ {
+ compatible = "khadas,vim", "amlogic,s905x", "amlogic,meson-gxl";
+ model = "Khadas VIM";
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1710000>;
+
+ button-function {
+ label = "Function";
+ linux,code = <KEY_FN>;
+ press-threshold-microvolt = <10000>;
+ };
+ };
+
+ aliases {
+ serial2 = &uart_AO_B;
+ };
+
+ gpio-keys-polled {
+ compatible = "gpio-keys-polled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ poll-interval = <100>;
+
+ button@0 {
+ label = "power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ pwmleds {
+ compatible = "pwm-leds";
+
+ power {
+ label = "vim:red:power";
+ pwms = <&pwm_AO_ab 1 7812500 0>;
+ max-brightness = <255>;
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_tmds_out>;
+ };
+ };
+ };
+};
+
+&hdmi_tx {
+ status = "okay";
+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+ pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+ hdmi_tx_tmds_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
+&i2c_A {
+ status = "okay";
+ pinctrl-0 = <&i2c_a_pins>;
+ pinctrl-names = "default";
+};
+
+&i2c_B {
+ status = "okay";
+ pinctrl-0 = <&i2c_b_pins>;
+ pinctrl-names = "default";
+
+ rtc: rtc@51 {
+ /* has to be enabled manually when a battery is connected: */
+ status = "disabled";
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ };
+};
+
+&ir {
+ linux,rc-map-name = "rc-geekbox";
+};
+
+&pwm_AO_ab {
+ status = "okay";
+ pinctrl-0 = <&pwm_ao_a_3_pins>, <&pwm_ao_b_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal> , <&xtal>;
+ clock-names = "clkin0", "clkin1" ;
+};
+
+&pwm_ef {
+ pinctrl-0 = <&pwm_e_pins>, <&pwm_f_clk_pins>;
+};
+
+&sd_emmc_a {
+ brcmf: wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+/* This is brought out on the Linux_RX (18) and Linux_TX (19) pins: */
+&uart_AO {
+ status = "okay";
+};
+
+/* This is brought out on the UART_RX_AO_B (15) and UART_TX_AO_B (16) pins: */
+&uart_AO_B {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_b_pins>;
+ pinctrl-names = "default";
+};
--- /dev/null
+/*
+ * Copyright (c) 2017 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+
+#include "meson-gxl-s905x.dtsi"
+
+/ {
+ compatible = "libretech,cc", "amlogic,s905x", "amlogic,meson-gxl";
+ model = "Libre Technology CC";
+
+ aliases {
+ serial0 = &uart_AO;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ cvbs-connector {
+ compatible = "composite-video-connector";
+
+ port {
+ cvbs_connector_in: endpoint {
+ remote-endpoint = <&cvbs_vdac_out>;
+ };
+ };
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_tmds_out>;
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ system {
+ label = "librecomputer:system-status";
+ gpios = <&gpio GPIODV_24 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ panic-indicator;
+ };
+
+ blue {
+ label = "librecomputer:blue";
+ gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_card: regulator-vcc-card {
+ compatible = "regulator-gpio";
+
+ regulator-name = "VCC_CARD";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
+ gpios-states = <0>;
+
+ states = <3300000 0>,
+ <1800000 1>;
+ };
+
+ vddio_boot: regulator-vddio_boot {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_BOOT";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&cvbs_vdac_port {
+ cvbs_vdac_out: endpoint {
+ remote-endpoint = <&cvbs_connector_in>;
+ };
+};
+
+ðmac {
+ status = "okay";
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+&hdmi_tx {
+ status = "okay";
+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+ pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+ hdmi_tx_tmds_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_card>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-names = "default";
+
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ max-frequency = <50000000>;
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
--- /dev/null
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "rk3128.dtsi"
+
+/ {
+ model = "Rockchip RK3128 Evaluation board";
+ compatible = "rockchip,rk3128-evb", "rockchip,rk3128";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ vcc5v0_otg: vcc5v0-otg-drv {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_otg";
+ gpio = <&gpio0 26 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&otg_vbus_drv>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc5v0_host: vcc5v0-host-drv {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+ gpio = <&gpio2 23 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&host_vbus_drv>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ hym8563: hym8563@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ };
+};
+
+&u2phy {
+ status = "okay";
+};
+
+&u2phy_otg {
+ status = "okay";
+};
+
+&u2phy_host {
+ status = "okay";
+};
+
+&usb_host_ehci {
+ status = "okay";
+};
+
+&usb_host_ohci {
+ status = "okay";
+};
+
+&usb_otg {
+ vbus-supply = <&vcc5v0_otg>;
+ status = "okay";
+};
+
+&emmc {
+ fifo-mode;
+ status = "okay";
+};
+
+&pinctrl {
+ usb_otg {
+ otg_vbus_drv: host-vbus-drv {
+ rockchip,pins = <0 26 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb_host {
+ host_vbus_drv: host-vbus-drv {
+ rockchip,pins = <2 23 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
--- /dev/null
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3128-cru.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "rockchip,rk3128";
+ rockchip,sram = <&sram>;
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ spi0 = &spi0;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ mmc0 = &emmc;
+ mmc1 = &sdmmc;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x60000000 0x40000000>;
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "rockchip,rk3128-smp";
+
+ cpu0:cpu@0x000 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x000>;
+ operating-points = <
+ /* KHz uV */
+ 816000 1000000
+ >;
+ #cooling-cells = <2>; /* min followed by max */
+ clock-latency = <40000>;
+ clocks = <&cru ARMCLK>;
+ };
+
+ cpu1:cpu@0x001 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x001>;
+ };
+
+ cpu2:cpu@0x002 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x002>;
+ };
+
+ cpu3:cpu@0x003 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x003>;
+ };
+ };
+
+ cpu_axi_bus: cpu_axi_bus {
+ compatible = "rockchip,cpu_axi_bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ qos {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ crypto {
+ reg = <0x10128080 0x20>;
+ };
+
+ core {
+ reg = <0x1012a000 0x20>;
+ };
+
+ peri {
+ reg = <0x1012c000 0x20>;
+ };
+
+ gpu {
+ reg = <0x1012d000 0x20>;
+ };
+
+ vpu {
+ reg = <0x1012e000 0x20>;
+ };
+
+ rga {
+ reg = <0x1012f000 0x20>;
+ };
+ ebc {
+ reg = <0x1012f080 0x20>;
+ };
+
+ iep {
+ reg = <0x1012f100 0x20>;
+ };
+
+ lcdc {
+ reg = <0x1012f180 0x20>;
+ rockchip,priority = <3 3>;
+ };
+
+ vip {
+ reg = <0x1012f200 0x20>;
+ rockchip,priority = <3 3>;
+ };
+ };
+
+ msch {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ msch@10128000 {
+ reg = <0x10128000 0x20>;
+ rockchip,read-latency = <0x3f>;
+ };
+ };
+ };
+
+ psci {
+ compatible = "arm,psci";
+ method = "smc";
+ cpu_suspend = <0x84000001>;
+ cpu_off = <0x84000002>;
+ cpu_on = <0x84000003>;
+ migrate = <0x84000005>;
+ };
+
+ amba {
+ compatible = "arm,amba-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&gic>;
+ ranges;
+
+ pdma: pdma@20078000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x20078000 0x4000>;
+ arm,pl330-broken-no-flushp;//2
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ clocks = <&cru ACLK_DMAC2>;
+ clock-names = "apb_pclk";
+ };
+ };
+
+ xin24m: xin24m {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ xin12m: xin12m {
+ compatible = "fixed-clock";
+ clocks = <&xin24m>;
+ clock-frequency = <12000000>;
+ clock-output-names = "xin12m";
+ #clock-cells = <0>;
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ arm,cpu-registers-not-fw-configured;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ clock-frequency = <24000000>;
+ };
+
+ timer@20044000 {
+ compatible = "arm,armv7-timer";
+ reg = <0x20044000 0xb8>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ rockchip,broadcast = <1>;
+ };
+
+ watchdog: wdt@2004c000 {
+ compatible = "rockchip,watch dog";
+ reg = <0x2004c000 0x100>;
+ clock-names = "pclk_wdt";
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ rockchip,irq = <1>;
+ rockchip,timeout = <60>;
+ rockchip,atboot = <1>;
+ rockchip,debug = <0>;
+ };
+
+ reset: reset@20000110 {
+ compatible = "rockchip,reset";
+ reg = <0x20000110 0x24>;
+ #reset-cells = <1>;
+ };
+
+ nandc: nandc@10500000 {
+ compatible = "rockchip,rk-nandc";
+ reg = <0x10500000 0x4000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&nandc_ale &nandc_cle &nandc_wrn &nandc_rdn &nandc_rdy &nandc_cs0 &nandc_data>;
+ nandc_id = <0>;
+ clocks = <&cru SCLK_NANDC>,
+ <&cru HCLK_NANDC>,
+ <&cru SRST_NANDC>;
+ clock-names = "clk_nandc", "g_clk_nandc", "hclk_nandc";
+ };
+
+ dmc: dmc@20004000 {
+ u-boot,dm-pre-reloc;
+ compatible = "rockchip,rk3128-dmc", "syscon";
+ reg = <0x0 0x20004000 0x0 0x1000>;
+ };
+
+ cru: clock-controller@20000000 {
+ u-boot,dm-pre-reloc;
+ compatible = "rockchip,rk3128-cru";
+ reg = <0x20000000 0x1000>;
+ rockchip,grf = <&grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ assigned-clocks = <&cru PLL_GPLL>;
+ assigned-clock-rates = <594000000>;
+ };
+
+ uart0: serial0@20060000 {
+ compatible = "rockchip,rk3128-uart", "snps,dw-apb-uart";
+ reg = <0x20060000 0x100>;
+ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+ dmas = <&pdma 2>, <&pdma 3>;
+ #dma-cells = <2>;
+ };
+
+ uart1: serial1@20064000 {
+ compatible = "rockchip,rk3128-uart", "snps,dw-apb-uart";
+ reg = <0x20064000 0x100>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+ dmas = <&pdma 4>, <&pdma 5>;
+ #dma-cells = <2>;
+ };
+
+ uart2: serial2@20068000 {
+ compatible = "rockchip,rk3128-uart", "snps,dw-apb-uart";
+ reg = <0x20068000 0x100>;
+ interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_xfer>;
+ dmas = <&pdma 6>, <&pdma 7>;
+ #dma-cells = <2>;
+ };
+
+ saradc: saradc@2006c000 {
+ compatible = "rockchip,saradc";
+ reg = <0x2006c000 0x100>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ #io-channel-cells = <1>;
+ clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ resets = <&cru SRST_SARADC>;
+ reset-names = "saradc-apb";
+ status = "disabled";
+ };
+
+ pwm0: pwm0@20050000 {
+ compatible = "rockchip,rk3128-pwm", "rockchip,rk3288-pwm";
+ reg = <0x20050000 0x10>;
+ #pwm-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ };
+
+ pwm1: pwm1@20050010 {
+ compatible = "rockchip,rk3128-pwm", "rockchip,rk3288-pwm";
+ reg = <0x20050010 0x10>;
+ #pwm-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ };
+
+ pwm2: pwm2@20050020 {
+ compatible = "rockchip,rk3128-pwm", "rockchip,rk3288-pwm";
+ reg = <0x20050020 0x10>;
+ #pwm-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ };
+
+ pwm3: pwm3@20050030 {
+ compatible = "rockchip,rk3128-pwm", "rockchip,rk3288-pwm";
+ reg = <0x20050030 0x10>;
+ #pwm-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_pin>;
+ clocks = <&cru PCLK_PWM>;
+ clock-names = "pwm";
+ };
+
+ sram: sram@10080400 {
+ compatible = "rockchip,rk3128-smp-sram", "mmio-sram";
+ reg = <0x10080400 0x1C00>;
+ map-exec;
+ map-cacheable;
+ };
+
+ pmu: syscon@100a0000 {
+ compatible = "rockchip,rk3128-pmu", "syscon", "simple-mfd";
+ reg = <0x100a0000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ gic: interrupt-controller@10139000 {
+ compatible = "arm,gic-400";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ reg = <0x10139000 0x1000>,
+ <0x1013a000 0x1000>,
+ <0x1013c000 0x2000>,
+ <0x1013e000 0x2000>;
+ interrupts = <GIC_PPI 9 0xf04>;
+ };
+
+ u2phy: usb2-phy {
+ compatible = "rockchip,rk3128-usb2phy";
+ reg = <0x017c 0x0c>;
+ rockchip,grf = <&grf>;
+ clocks = <&cru SCLK_OTGPHY0>;
+ clock-names = "phyclk";
+ #clock-cells = <0>;
+ clock-output-names = "usb480m_phy";
+ #phy-cells = <1>;
+ status = "disabled";
+
+ u2phy_otg: otg-port {
+ #phy-cells = <0>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "otg-bvalid", "otg-id",
+ "linestate";
+ status = "disabled";
+ };
+
+ u2phy_host: host-port {
+ #phy-cells = <0>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "linestate";
+ status = "disabled";
+ };
+ };
+
+ usb_otg: usb@10180000 {
+ compatible = "rockchip,rk3128-usb", "rockchip,rk3288-usb",
+ "snps,dwc2";
+ reg = <0x10180000 0x40000>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "otg";
+ g-use-dma;
+ hnp-srp-disable;
+ phys = <&u2phy 0>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usb_host_ehci: usb@101c0000 {
+ compatible = "generic-ehci";
+ reg = <0x101c0000 0x20000>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&u2phy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ usb_host_ohci: usb@101e0000 {
+ compatible = "generic-ohci";
+ reg = <0x101e0000 0x20000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&u2phy 1>;
+ phy-names = "usb";
+ status = "disabled";
+ };
+
+ sdmmc: dwmmc@10214000 {
+ compatible = "rockchip,rk312x-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x10214000 0x4000>;
+ max-frequency = <150000000>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+ fifo-depth = <0x100>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ emmc: dwmmc@1021c000 {
+ u-boot,dm-pre-reloc;
+ compatible = "rockchip,rk3128-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x1021c000 0x4000>;
+ max-frequency = <150000000>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
+ bus-width = <8>;
+ default-sample-phase = <158>;
+ num-slots = <1>;
+ fifo-depth = <0x100>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+ resets = <&cru SRST_EMMC>;
+ reset-names = "reset";
+ status = "disabled";
+ };
+
+ i2c0: i2c0@20072000 {
+ compatible = "rockchip,rk3128-i2c", "rockchip,rk3288-i2c";
+ reg = <20072000 0x1000>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_xfer>;
+ };
+
+ i2c1: i2c1@20056000 {
+ compatible = "rockchip,rk3128-i2c", "rockchip,rk3288-i2c";
+ reg = <0x20056000 0x1000>;
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_xfer>;
+ };
+
+ i2c2: i2c2@2005a000 {
+ compatible = "rockchip,rk3128-i2c", "rockchip,rk3288-i2c";
+ reg = <0x2005a000 0x1000>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_xfer>;
+ };
+
+ i2c3: i2c3@2005e000 {
+ compatible = "rockchip,rk3128-i2c", "rockchip,rk3288-i2c";
+ reg = <0x2005e000 0x1000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-names = "i2c";
+ clocks = <&cru PCLK_I2C3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_xfer>;
+ };
+
+ spi0: spi@20074000 {
+ compatible = "rockchip,rk3128-spi", "rockchip,rk3288-spi";
+ reg = <0x20074000 0x1000>;
+ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_txd_mux0 &spi0_rxd_mux0 &spi0_clk_mux0 &spi0_cs0_mux0 &spi0_cs1_mux0>;
+ rockchip,spi-src-clk = <0>;
+ num-cs = <2>;
+ clocks =<&cru SCLK_SPI>, <&cru PCLK_SPI>;
+ clock-names = "spi","pclk_spi0";
+ dmas = <&pdma 8>, <&pdma 9>;
+ #dma-cells = <2>;
+ dma-names = "tx", "rx";
+ };
+
+ grf: syscon@20008000 {
+ u-boot,dm-pre-reloc;
+ compatible = "rockchip,rk3128-grf", "syscon";
+ reg = <0x20008000 0x1000>;
+ };
+
+ pinctrl: pinctrl@20008000 {
+ compatible = "rockchip,rk3128-pinctrl";
+ reg = <0x20008000 0xA8>,
+ <0x200080A8 0x4C>,
+ <0x20008118 0x20>,
+ <0x20008100 0x04>;
+ reg-names = "base", "mux", "pull", "drv";
+ rockchip,grf = <&grf>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio0@2007c000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2007c000 0x100>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio1@20080000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20080000 0x100>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio2@20084000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20084000 0x100>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio2@20088000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20088000 0x100>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pcfg_pull_up: pcfg-pull-up {
+ bias-pull-up;
+ };
+
+ pcfg_pull_down: pcfg-pull-down {
+ bias-pull-down;
+ };
+
+ pcfg_pull_none: pcfg-pull-none {
+ bias-disable;
+ };
+
+ emmc {
+ /*
+ * We run eMMC at max speed; bump up drive strength.
+ * We also have external pulls, so disable the internal ones.
+ */
+
+ emmc_clk: emmc-clk {
+ rockchip,pins = <2 7 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_pwren: emmc-pwren {
+ rockchip,pins = <2 5 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ emmc_bus8: emmc-bus8 {
+ rockchip,pins = <1 24 RK_FUNC_2 &pcfg_pull_none>,
+ <1 25 RK_FUNC_2 &pcfg_pull_none>,
+ <1 26 RK_FUNC_2 &pcfg_pull_none>,
+ <1 27 RK_FUNC_2 &pcfg_pull_none>,
+ <1 28 RK_FUNC_2 &pcfg_pull_none>,
+ <1 29 RK_FUNC_2 &pcfg_pull_none>,
+ <1 30 RK_FUNC_2 &pcfg_pull_none>,
+ <1 31 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ nandc{
+ nandc_ale:nandc-ale {
+ rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ nandc_cle:nandc-cle {
+ rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ nandc_wrn:nandc-wrn {
+ rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ nandc_rdn:nandc-rdn {
+ rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ nandc_rdy:nandc-rdy {
+ rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ nandc_cs0:nandc-cs0 {
+ rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ nandc_data: nandc-data {
+ rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <0 16 RK_FUNC_1 &pcfg_pull_none>,
+ <0 17 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <0 19 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <2 22 RK_FUNC_1 &pcfg_pull_none>,
+ <2 23 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ uart2 {
+ uart2_xfer: uart2-xfer {
+ rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_none>,
+ <1 19 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_clk: sdmmc-clk {
+ rockchip,pins = <1 RK_PC0 1 &pcfg_pull_none>;
+ };
+
+ sdmmc_cmd: sdmmc-cmd {
+ rockchip,pins = <1 RK_PC1 1 &pcfg_pull_up>;
+ };
+
+ sdmmc_wp: sdmmc-wp {
+ rockchip,pins = <1 RK_PA7 1 &pcfg_pull_up>;
+ };
+
+ sdmmc_pwren: sdmmc-pwren {
+ rockchip,pins = <1 RK_PB6 1 &pcfg_pull_up>;
+ };
+
+ sdmmc_bus4: sdmmc-bus4 {
+ rockchip,pins = <1 RK_PC2 1 &pcfg_pull_up>,
+ <1 RK_PC3 1 &pcfg_pull_up>,
+ <1 RK_PC4 1 &pcfg_pull_up>,
+ <1 RK_PC5 1 &pcfg_pull_up>;
+ };
+ };
+
+ pwm0 {
+ pwm0_pin: pwm0-pin {
+ rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_pin: pwm1-pin {
+ rockchip,pins = <0 1 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_pin: pwm2-pin {
+ rockchip,pins = <0 1 2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_pin: pwm3-pin {
+ rockchip,pins = <0 27 1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c0 {
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>,
+ <0 1 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins = <0 2 RK_FUNC_1 &pcfg_pull_none>,
+ <0 3 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c2 {
+ i2c2_xfer: i2c2-xfer {
+ rockchip,pins = <2 20 3 &pcfg_pull_none>,
+ <2 21 3 &pcfg_pull_none>;
+ };
+ };
+
+ i2c3 {
+ i2c3_xfer: i2c3-xfer {
+ rockchip,pins = <0 6 RK_FUNC_1 &pcfg_pull_none>,
+ <0 7 RK_FUNC_1 &pcfg_pull_none>;
+ };
+ };
+
+ spi0 {
+ spi0_txd_mux0:spi0-txd-mux0 {
+ rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ spi0_rxd_mux0:spi0-rxd-mux0 {
+ rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ spi0_clk_mux0:spi0-clk-mux0 {
+ rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ spi0_cs0_mux0:spi0-cs0-mux0 {
+ rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+ };
+
+ spi0_cs1_mux0:spi0-cs1-mux0 {
+ rockchip,pins = <2 4 RK_FUNC_2 &pcfg_pull_none>;
+ };
+ };
+
+ };
+};
u-boot,mmc-env-offset = <0x4000>; /* @ 16KB */
u-boot,efi-partition-entries-offset = <0x200000>; /* 2MB */
u-boot,boot-led = "module_led";
+ sysreset-gpio = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>;
};
chosen {
&dwc3_typec1 {
status = "okay";
+ tsd,usb-port-power = "usbhub_enable";
};
&vopb {
status = "okay";
};
+&gpio1 {
+ u-boot,dm-pre-reloc;
+};
+
&gpio3 {
u-boot,dm-pre-reloc;
};
--- /dev/null
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __MESON_ETH_H__
+#define __MESON_ETH_H__
+
+#include <phy.h>
+
+enum {
+ /* Use GXL Internal RMII PHY */
+ MESON_GXL_USE_INTERNAL_RMII_PHY = 1,
+};
+
+/* Configure the Ethernet MAC with the requested interface mode
+ * with some optional flags.
+ */
+void meson_gx_eth_init(phy_interface_t mode, unsigned int flags);
+
+#endif /* __MESON_ETH_H__ */
#ifndef __GXBB_H__
#define __GXBB_H__
+#define GXBB_FIRMWARE_MEM_SIZE 0x1000000
+
+#define GXBB_AOBUS_BASE 0xc8100000
#define GXBB_PERIPHS_BASE 0xc8834400
#define GXBB_HIU_BASE 0xc883c000
#define GXBB_ETH_BASE 0xc9410000
+/* Always-On Peripherals registers */
+#define GXBB_AO_ADDR(off) (GXBB_AOBUS_BASE + ((off) << 2))
+
+#define GXBB_AO_SEC_GP_CFG0 GXBB_AO_ADDR(0x90)
+#define GXBB_AO_SEC_GP_CFG3 GXBB_AO_ADDR(0x93)
+#define GXBB_AO_SEC_GP_CFG4 GXBB_AO_ADDR(0x94)
+#define GXBB_AO_SEC_GP_CFG5 GXBB_AO_ADDR(0x95)
+
+#define GXBB_AO_MEM_SIZE_MASK 0xFFFF0000
+#define GXBB_AO_MEM_SIZE_SHIFT 16
+#define GXBB_AO_BL31_RSVMEM_SIZE_MASK 0xFFFF0000
+#define GXBB_AO_BL31_RSVMEM_SIZE_SHIFT 16
+#define GXBB_AO_BL32_RSVMEM_SIZE_MASK 0xFFFF
+
/* Peripherals registers */
#define GXBB_PERIPHS_ADDR(off) (GXBB_PERIPHS_BASE + ((off) << 2))
--- /dev/null
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __MESON_MEM_H__
+#define __MESON_MEM_H__
+
+/* Configure the reserved memory zones exported by the secure registers
+ * into EFI and DTB reserved memory entries.
+ */
+void meson_gx_init_reserved_memory(void *fdt);
+
+#endif /* __MESON_MEM_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_CRU_RK3128_H
+#define _ASM_ARCH_CRU_RK3128_H
+
+#include <common.h>
+
+#define MHz 1000000
+#define OSC_HZ (24 * MHz)
+
+#define APLL_HZ (600 * MHz)
+#define GPLL_HZ (594 * MHz)
+
+#define CORE_PERI_HZ 150000000
+#define CORE_ACLK_HZ 300000000
+
+#define BUS_ACLK_HZ 148500000
+#define BUS_HCLK_HZ 148500000
+#define BUS_PCLK_HZ 74250000
+
+#define PERI_ACLK_HZ 148500000
+#define PERI_HCLK_HZ 148500000
+#define PERI_PCLK_HZ 74250000
+
+/* Private data for the clock driver - used by rockchip_get_cru() */
+struct rk3128_clk_priv {
+ struct rk3128_cru *cru;
+};
+
+struct rk3128_cru {
+ struct rk3128_pll {
+ unsigned int con0;
+ unsigned int con1;
+ unsigned int con2;
+ unsigned int con3;
+ } pll[4];
+ unsigned int cru_mode_con;
+ unsigned int cru_clksel_con[35];
+ unsigned int cru_clkgate_con[11];
+ unsigned int reserved;
+ unsigned int cru_glb_srst_fst_value;
+ unsigned int cru_glb_srst_snd_value;
+ unsigned int reserved1[2];
+ unsigned int cru_softrst_con[9];
+ unsigned int cru_misc_con;
+ unsigned int reserved2[2];
+ unsigned int cru_glb_cnt_th;
+ unsigned int reserved3[3];
+ unsigned int cru_glb_rst_st;
+ unsigned int reserved4[(0x1c0 - 0x150) / 4 - 1];
+ unsigned int cru_sdmmc_con[2];
+ unsigned int cru_sdio_con[2];
+ unsigned int reserved5[2];
+ unsigned int cru_emmc_con[2];
+ unsigned int reserved6[4];
+ unsigned int cru_pll_prg_en;
+};
+check_member(rk3128_cru, cru_pll_prg_en, 0x01f0);
+
+struct pll_div {
+ u32 refdiv;
+ u32 fbdiv;
+ u32 postdiv1;
+ u32 postdiv2;
+ u32 frac;
+};
+
+enum {
+ /* PLLCON0*/
+ PLL_POSTDIV1_SHIFT = 12,
+ PLL_POSTDIV1_MASK = 7 << PLL_POSTDIV1_SHIFT,
+ PLL_FBDIV_SHIFT = 0,
+ PLL_FBDIV_MASK = 0xfff,
+
+ /* PLLCON1 */
+ PLL_RST_SHIFT = 14,
+ PLL_PD_SHIFT = 13,
+ PLL_PD_MASK = 1 << PLL_PD_SHIFT,
+ PLL_DSMPD_SHIFT = 12,
+ PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT,
+ PLL_LOCK_STATUS_SHIFT = 10,
+ PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT,
+ PLL_POSTDIV2_SHIFT = 6,
+ PLL_POSTDIV2_MASK = 7 << PLL_POSTDIV2_SHIFT,
+ PLL_REFDIV_SHIFT = 0,
+ PLL_REFDIV_MASK = 0x3f,
+
+ /* CRU_MODE */
+ GPLL_MODE_SHIFT = 12,
+ GPLL_MODE_MASK = 3 << GPLL_MODE_SHIFT,
+ GPLL_MODE_SLOW = 0,
+ GPLL_MODE_NORM,
+ GPLL_MODE_DEEP,
+ CPLL_MODE_SHIFT = 8,
+ CPLL_MODE_MASK = 1 << CPLL_MODE_SHIFT,
+ CPLL_MODE_SLOW = 0,
+ CPLL_MODE_NORM,
+ DPLL_MODE_SHIFT = 4,
+ DPLL_MODE_MASK = 1 << DPLL_MODE_SHIFT,
+ DPLL_MODE_SLOW = 0,
+ DPLL_MODE_NORM,
+ APLL_MODE_SHIFT = 0,
+ APLL_MODE_MASK = 1 << APLL_MODE_SHIFT,
+ APLL_MODE_SLOW = 0,
+ APLL_MODE_NORM,
+
+ /* CRU_CLK_SEL0_CON */
+ BUS_ACLK_PLL_SEL_SHIFT = 14,
+ BUS_ACLK_PLL_SEL_MASK = 3 << BUS_ACLK_PLL_SEL_SHIFT,
+ BUS_ACLK_PLL_SEL_CPLL = 0,
+ BUS_ACLK_PLL_SEL_GPLL,
+ BUS_ACLK_PLL_SEL_GPLL_DIV2,
+ BUS_ACLK_PLL_SEL_GPLL_DIV3,
+ BUS_ACLK_DIV_SHIFT = 8,
+ BUS_ACLK_DIV_MASK = 0x1f << BUS_ACLK_DIV_SHIFT,
+ CORE_CLK_PLL_SEL_SHIFT = 7,
+ CORE_CLK_PLL_SEL_MASK = 1 << CORE_CLK_PLL_SEL_SHIFT,
+ CORE_CLK_PLL_SEL_APLL = 0,
+ CORE_CLK_PLL_SEL_GPLL_DIV2,
+ CORE_DIV_CON_SHIFT = 0,
+ CORE_DIV_CON_MASK = 0x1f << CORE_DIV_CON_SHIFT,
+
+ /* CRU_CLK_SEL1_CON */
+ BUS_PCLK_DIV_SHIFT = 12,
+ BUS_PCLK_DIV_MASK = 7 << BUS_PCLK_DIV_SHIFT,
+ BUS_HCLK_DIV_SHIFT = 8,
+ BUS_HCLK_DIV_MASK = 3 << BUS_HCLK_DIV_SHIFT,
+ CORE_ACLK_DIV_SHIFT = 4,
+ CORE_ACLK_DIV_MASK = 7 << CORE_ACLK_DIV_SHIFT,
+ CORE_PERI_DIV_SHIFT = 0,
+ CORE_PERI_DIV_MASK = 0xf << CORE_PERI_DIV_SHIFT,
+
+ /* CRU_CLK_SEL2_CON */
+ NANDC_PLL_SEL_SHIFT = 14,
+ NANDC_PLL_SEL_MASK = 3 << NANDC_PLL_SEL_SHIFT,
+ NANDC_PLL_SEL_CPLL = 0,
+ NANDC_PLL_SEL_GPLL,
+ NANDC_CLK_DIV_SHIFT = 8,
+ NANDC_CLK_DIV_MASK = 0x1f << NANDC_CLK_DIV_SHIFT,
+ PVTM_CLK_DIV_SHIFT = 0,
+ PVTM_CLK_DIV_MASK = 0x3f << PVTM_CLK_DIV_SHIFT,
+
+ /* CRU_CLKSEL10_CON */
+ PERI_PLL_SEL_SHIFT = 14,
+ PERI_PLL_SEL_MASK = 1 << PERI_PLL_SEL_SHIFT,
+ PERI_PLL_APLL = 0,
+ PERI_PLL_DPLL,
+ PERI_PLL_GPLL,
+ PERI_PCLK_DIV_SHIFT = 12,
+ PERI_PCLK_DIV_MASK = 3 << PERI_PCLK_DIV_SHIFT,
+ PERI_HCLK_DIV_SHIFT = 8,
+ PERI_HCLK_DIV_MASK = 3 << PERI_HCLK_DIV_SHIFT,
+ PERI_ACLK_DIV_SHIFT = 0,
+ PERI_ACLK_DIV_MASK = 0x1f << PERI_ACLK_DIV_SHIFT,
+
+ /* CRU_CLKSEL11_CON */
+ MMC0_PLL_SHIFT = 6,
+ MMC0_PLL_MASK = 3 << MMC0_PLL_SHIFT,
+ MMC0_SEL_APLL = 0,
+ MMC0_SEL_GPLL,
+ MMC0_SEL_GPLL_DIV2,
+ MMC0_SEL_24M,
+ MMC0_DIV_SHIFT = 0,
+ MMC0_DIV_MASK = 0x3f << MMC0_DIV_SHIFT,
+
+ /* CRU_CLKSEL12_CON */
+ EMMC_PLL_SHIFT = 14,
+ EMMC_PLL_MASK = 3 << EMMC_PLL_SHIFT,
+ EMMC_SEL_APLL = 0,
+ EMMC_SEL_GPLL,
+ EMMC_SEL_GPLL_DIV2,
+ EMMC_SEL_24M,
+ EMMC_DIV_SHIFT = 8,
+ EMMC_DIV_MASK = 0x3f << EMMC_DIV_SHIFT,
+
+ /* CLKSEL_CON24 */
+ SARADC_DIV_CON_SHIFT = 8,
+ SARADC_DIV_CON_MASK = GENMASK(15, 8),
+ SARADC_DIV_CON_WIDTH = 8,
+
+ /* CRU_CLKSEL27_CON*/
+ DCLK_VOP_SEL_SHIFT = 0,
+ DCLK_VOP_SEL_MASK = 1 << DCLK_VOP_SEL_SHIFT,
+ DCLK_VOP_PLL_SEL_CPLL = 0,
+ DCLK_VOP_DIV_CON_SHIFT = 8,
+ DCLK_VOP_DIV_CON_MASK = 0xff << DCLK_VOP_DIV_CON_SHIFT,
+
+ /* CRU_CLKSEL31_CON */
+ VIO0_PLL_SHIFT = 5,
+ VIO0_PLL_MASK = 7 << VIO0_PLL_SHIFT,
+ VI00_SEL_CPLL = 0,
+ VIO0_SEL_GPLL,
+ VIO0_DIV_SHIFT = 0,
+ VIO0_DIV_MASK = 0x1f << VIO0_DIV_SHIFT,
+ VIO1_PLL_SHIFT = 13,
+ VIO1_PLL_MASK = 7 << VIO1_PLL_SHIFT,
+ VI01_SEL_CPLL = 0,
+ VIO1_SEL_GPLL,
+ VIO1_DIV_SHIFT = 8,
+ VIO1_DIV_MASK = 0x1f << VIO1_DIV_SHIFT,
+
+ /* CRU_SOFTRST5_CON */
+ DDRCTRL_PSRST_SHIFT = 11,
+ DDRCTRL_SRST_SHIFT = 10,
+ DDRPHY_PSRST_SHIFT = 9,
+ DDRPHY_SRST_SHIFT = 8,
+};
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _ASM_ARCH_GRF_RK3128_H
+#define _ASM_ARCH_GRF_RK3128_H
+
+#include <common.h>
+
+struct rk3128_grf {
+ unsigned int reserved[0x2a];
+ unsigned int gpio0a_iomux;
+ unsigned int gpio0b_iomux;
+ unsigned int gpio0c_iomux;
+ unsigned int gpio0d_iomux;
+ unsigned int gpio1a_iomux;
+ unsigned int gpio1b_iomux;
+ unsigned int gpio1c_iomux;
+ unsigned int gpio1d_iomux;
+ unsigned int gpio2a_iomux;
+ unsigned int gpio2b_iomux;
+ unsigned int gpio2c_iomux;
+ unsigned int gpio2d_iomux;
+ unsigned int gpio3a_iomux;
+ unsigned int gpio3b_iomux;
+ unsigned int gpio3c_iomux;
+ unsigned int gpio3d_iomux;
+ unsigned int gpio2c_iomux2;
+ unsigned int grf_cif_iomux;
+ unsigned int grf_cif_iomux1;
+ unsigned int reserved1[(0x118 - 0xf0) / 4 - 1];
+ unsigned int gpio0l_pull;
+ unsigned int gpio0h_pull;
+ unsigned int gpio1l_pull;
+ unsigned int gpio1h_pull;
+ unsigned int gpio2l_pull;
+ unsigned int gpio2h_pull;
+ unsigned int gpio3l_pull;
+ unsigned int gpio3h_pull;
+ unsigned int reserved2;
+ unsigned int soc_con0;
+ unsigned int soc_con1;
+ unsigned int soc_con2;
+ unsigned int soc_status0;
+ unsigned int reserved3[6];
+ unsigned int mac_con0;
+ unsigned int mac_con1;
+ unsigned int reserved4[4];
+ unsigned int uoc0_con0;
+ unsigned int reserved5;
+ unsigned int uoc1_con1;
+ unsigned int uoc1_con2;
+ unsigned int uoc1_con3;
+ unsigned int uoc1_con4;
+ unsigned int uoc1_con5;
+ unsigned int reserved6;
+ unsigned int ddrc_stat;
+ unsigned int reserved9;
+ unsigned int soc_status1;
+ unsigned int cpu_con0;
+ unsigned int cpu_con1;
+ unsigned int cpu_con2;
+ unsigned int cpu_con3;
+ unsigned int reserved10;
+ unsigned int reserved11;
+ unsigned int cpu_status0;
+ unsigned int cpu_status1;
+ unsigned int os_reg[8];
+ unsigned int reserved12[(0x280 - 0x1e4) / 4 - 1];
+ unsigned int usbphy0_con[8];
+ unsigned int usbphy1_con[8];
+ unsigned int uoc_status0;
+ unsigned int reserved13[(0x300 - 0x2c0) / 4 - 1];
+ unsigned int chip_tag;
+ unsigned int sdmmc_det_cnt;
+};
+check_member(rk3128_grf, sdmmc_det_cnt, 0x304);
+
+struct rk3128_pmu {
+ unsigned int wakeup_cfg;
+ unsigned int pwrdn_con;
+ unsigned int pwrdn_st;
+ unsigned int idle_req;
+ unsigned int idle_st;
+ unsigned int pwrmode_con;
+ unsigned int pwr_state;
+ unsigned int osc_cnt;
+ unsigned int core_pwrdwn_cnt;
+ unsigned int core_pwrup_cnt;
+ unsigned int sft_con;
+ unsigned int ddr_sref_st;
+ unsigned int int_con;
+ unsigned int int_st;
+ unsigned int sys_reg[4];
+};
+check_member(rk3128_pmu, int_st, 0x34);
+
+/* GRF_GPIO0A_IOMUX */
+enum {
+ GPIO0A7_SHIFT = 14,
+ GPIO0A7_MASK = 3 << GPIO0A7_SHIFT,
+ GPIO0A7_GPIO = 0,
+ GPIO0A7_I2C3_SDA,
+
+ GPIO0A6_SHIFT = 12,
+ GPIO0A6_MASK = 3 << GPIO0A6_SHIFT,
+ GPIO0A6_GPIO = 0,
+ GPIO0A6_I2C3_SCL,
+
+ GPIO0A3_SHIFT = 6,
+ GPIO0A3_MASK = 3 << GPIO0A3_SHIFT,
+ GPIO0A3_GPIO = 0,
+ GPIO0A3_I2C1_SDA,
+
+ GPIO0A2_SHIFT = 4,
+ GPIO0A2_MASK = 1 << GPIO0A2_SHIFT,
+ GPIO0A2_GPIO = 0,
+ GPIO0A2_I2C1_SCL,
+
+ GPIO0A1_SHIFT = 2,
+ GPIO0A1_MASK = 1 << GPIO0A1_SHIFT,
+ GPIO0A1_GPIO = 0,
+ GPIO0A1_I2C0_SDA,
+
+ GPIO0A0_SHIFT = 0,
+ GPIO0A0_MASK = 1 << GPIO0A0_SHIFT,
+ GPIO0A0_GPIO = 0,
+ GPIO0A0_I2C0_SCL,
+};
+
+/* GRF_GPIO0B_IOMUX */
+enum {
+ GPIO0B6_SHIFT = 12,
+ GPIO0B6_MASK = 3 << GPIO0B6_SHIFT,
+ GPIO0B6_GPIO = 0,
+ GPIO0B6_I2S_SDI,
+ GPIO0B6_SPI_CSN0,
+
+ GPIO0B5_SHIFT = 10,
+ GPIO0B5_MASK = 3 << GPIO0B5_SHIFT,
+ GPIO0B5_GPIO = 0,
+ GPIO0B5_I2S_SDO,
+ GPIO0B5_SPI_RXD,
+
+ GPIO0B4_SHIFT = 8,
+ GPIO0B4_MASK = 1 << GPIO0B4_SHIFT,
+ GPIO0B4_GPIO = 0,
+ GPIO0B4_I2S_LRCKTX,
+
+ GPIO0B3_SHIFT = 6,
+ GPIO0B3_MASK = 3 << GPIO0B3_SHIFT,
+ GPIO0B3_GPIO = 0,
+ GPIO0B3_I2S_LRCKRX,
+ GPIO0B3_SPI_TXD,
+
+ GPIO0B1_SHIFT = 2,
+ GPIO0B1_MASK = 3,
+ GPIO0B1_GPIO = 0,
+ GPIO0B1_I2S_SCLK,
+ GPIO0B1_SPI_CLK,
+
+ GPIO0B0_SHIFT = 0,
+ GPIO0B0_MASK = 3,
+ GPIO0B0_GPIO = 0,
+ GPIO0B0_I2S1_MCLK,
+};
+
+/* GRF_GPIO0D_IOMUX */
+enum {
+ GPIO0D4_SHIFT = 8,
+ GPIO0D4_MASK = 1 << GPIO0D4_SHIFT,
+ GPIO0D4_GPIO = 0,
+ GPIO0D4_PWM2,
+
+ GPIO0D3_SHIFT = 6,
+ GPIO0D3_MASK = 1 << GPIO0D3_SHIFT,
+ GPIO0D3_GPIO = 0,
+ GPIO0D3_PWM1,
+
+ GPIO0D2_SHIFT = 4,
+ GPIO0D2_MASK = 1 << GPIO0D2_SHIFT,
+ GPIO0D2_GPIO = 0,
+ GPIO0D2_PWM0,
+
+ GPIO0D1_SHIFT = 2,
+ GPIO0D1_MASK = 1 << GPIO0D1_SHIFT,
+ GPIO0D1_GPIO = 0,
+ GPIO0D1_UART2_CTSN,
+
+ GPIO0D0_SHIFT = 0,
+ GPIO0D0_MASK = 3 << GPIO0D0_SHIFT,
+ GPIO0D0_GPIO = 0,
+ GPIO0D0_UART2_RTSN,
+ GPIO0D0_PMIC_SLEEP,
+};
+
+/* GRF_GPIO1A_IOMUX */
+enum {
+ GPIO1A5_SHIFT = 10,
+ GPIO1A5_MASK = 3 << GPIO1A5_SHIFT,
+ GPIO1A5_GPIO = 0,
+ GPIO1A5_I2S_SDI,
+ GPIO1A5_SDMMC_DATA3,
+
+ GPIO1A4_SHIFT = 8,
+ GPIO1A4_MASK = 3 << GPIO1A4_SHIFT,
+ GPIO1A4_GPIO = 0,
+ GPIO1A4_I2S_SD0,
+ GPIO1A4_SDMMC_DATA2,
+
+ GPIO1A3_SHIFT = 6,
+ GPIO1A3_MASK = 1 << GPIO1A3_SHIFT,
+ GPIO1A3_GPIO = 0,
+ GPIO1A3_I2S_LRCKTX,
+
+ GPIO1A2_SHIFT = 4,
+ GPIO1A2_MASK = 3 << GPIO1A2_SHIFT,
+ GPIO1A2_GPIO = 0,
+ GPIO1A2_I2S_LRCKRX,
+ GPIO1A2_SDMMC_DATA1,
+
+ GPIO1A1_SHIFT = 2,
+ GPIO1A1_MASK = 3 << GPIO1A1_SHIFT,
+ GPIO1A1_GPIO = 0,
+ GPIO1A1_I2S_SCLK,
+ GPIO1A1_SDMMC_DATA0,
+ GPIO1A1_PMIC_SLEEP,
+
+ GPIO1A0_SHIFT = 0,
+ GPIO1A0_MASK = 3,
+ GPIO1A0_GPIO = 0,
+ GPIO1A0_I2S_MCLK,
+ GPIO1A0_SDMMC_CLKOUT,
+ GPIO1A0_XIN32K,
+
+};
+
+/* GRF_GPIO1B_IOMUX */
+enum {
+ GPIO1B7_SHIFT = 14,
+ GPIO1B7_MASK = 1 << GPIO1B7_SHIFT,
+ GPIO1B7_GPIO = 0,
+ GPIO1B7_MMC0_CMD,
+
+ GPIO1B6_SHIFT = 12,
+ GPIO1B6_MASK = 1 << GPIO1B6_SHIFT,
+ GPIO1B6_GPIO = 0,
+ GPIO1B6_MMC_PWREN,
+
+ GPIO1B2_SHIFT = 4,
+ GPIO1B2_MASK = 3 << GPIO1B2_SHIFT,
+ GPIO1B2_GPIO = 0,
+ GPIO1B2_SPI_RXD,
+ GPIO1B2_UART1_SIN,
+
+ GPIO1B1_SHIFT = 2,
+ GPIO1B1_MASK = 3 << GPIO1B1_SHIFT,
+ GPIO1B1_GPIO = 0,
+ GPIO1B1_SPI_TXD,
+ GPIO1B1_UART1_SOUT,
+
+ GPIO1B0_SHIFT = 0,
+ GPIO1B0_MASK = 3 << GPIO1B0_SHIFT,
+ GPIO1B0_GPIO = 0,
+ GPIO1B0_SPI_CLK,
+ GPIO1B0_UART1_CTSN
+};
+
+/* GRF_GPIO1C_IOMUX */
+enum {
+ GPIO1C6_SHIFT = 12,
+ GPIO1C6_MASK = 3 << GPIO1C6_SHIFT,
+ GPIO1C6_GPIO = 0,
+ GPIO1C6_NAND_CS2,
+ GPIO1C6_EMMC_CMD,
+
+ GPIO1C5_SHIFT = 10,
+ GPIO1C5_MASK = 3 << GPIO1C5_SHIFT,
+ GPIO1C5_GPIO = 0,
+ GPIO1C5_MMC0_D3,
+ GPIO1C5_JTAG_TMS,
+
+ GPIO1C4_SHIFT = 8,
+ GPIO1C4_MASK = 3 << GPIO1C4_SHIFT,
+ GPIO1C4_GPIO = 0,
+ GPIO1C4_MMC0_D2,
+ GPIO1C4_JTAG_TCK,
+
+ GPIO1C3_SHIFT = 6,
+ GPIO1C3_MASK = 3 << GPIO1C3_SHIFT,
+ GPIO1C3_GPIO = 0,
+ GPIO1C3_MMC0_D1,
+ GPIO1C3_UART2_RX,
+
+ GPIO1C2_SHIFT = 4,
+ GPIO1C2_MASK = 3 << GPIO1C2_SHIFT,
+ GPIO1C2_GPIO = 0,
+ GPIO1C2_MMC0_D0,
+ GPIO1C2_UART2_TX,
+
+ GPIO1C1_SHIFT = 2,
+ GPIO1C1_MASK = 1 << GPIO1C1_SHIFT,
+ GPIO1C1_GPIO = 0,
+ GPIO1C1_MMC0_DETN,
+
+ GPIO1C0_SHIFT = 0,
+ GPIO1C0_MASK = 1 << GPIO1C0_SHIFT,
+ GPIO1C0_GPIO = 0,
+ GPIO1C0_MMC0_CLKOUT,
+};
+
+/* GRF_GPIO1D_IOMUX */
+enum {
+ GPIO1D7_SHIFT = 14,
+ GPIO1D7_MASK = 3 << GPIO1D7_SHIFT,
+ GPIO1D7_GPIO = 0,
+ GPIO1D7_NAND_D7,
+ GPIO1D7_EMMC_D7,
+ GPIO1D7_SPI_CSN1,
+
+ GPIO1D6_SHIFT = 12,
+ GPIO1D6_MASK = 3 << GPIO1D6_SHIFT,
+ GPIO1D6_GPIO = 0,
+ GPIO1D6_NAND_D6,
+ GPIO1D6_EMMC_D6,
+ GPIO1D6_SPI_CSN0,
+
+ GPIO1D5_SHIFT = 10,
+ GPIO1D5_MASK = 3 << GPIO1D5_SHIFT,
+ GPIO1D5_GPIO = 0,
+ GPIO1D5_NAND_D5,
+ GPIO1D5_EMMC_D5,
+ GPIO1D5_SPI_TXD1,
+
+ GPIO1D4_SHIFT = 8,
+ GPIO1D4_MASK = 3 << GPIO1D4_SHIFT,
+ GPIO1D4_GPIO = 0,
+ GPIO1D4_NAND_D4,
+ GPIO1D4_EMMC_D4,
+ GPIO1D4_SPI_RXD1,
+
+ GPIO1D3_SHIFT = 6,
+ GPIO1D3_MASK = 3 << GPIO1D3_SHIFT,
+ GPIO1D3_GPIO = 0,
+ GPIO1D3_NAND_D3,
+ GPIO1D3_EMMC_D3,
+ GPIO1D3_SFC_SIO3,
+
+ GPIO1D2_SHIFT = 4,
+ GPIO1D2_MASK = 3 << GPIO1D2_SHIFT,
+ GPIO1D2_GPIO = 0,
+ GPIO1D2_NAND_D2,
+ GPIO1D2_EMMC_D2,
+ GPIO1D2_SFC_SIO2,
+
+ GPIO1D1_SHIFT = 2,
+ GPIO1D1_MASK = 3 << GPIO1D1_SHIFT,
+ GPIO1D1_GPIO = 0,
+ GPIO1D1_NAND_D1,
+ GPIO1D1_EMMC_D1,
+ GPIO1D1_SFC_SIO1,
+
+ GPIO1D0_SHIFT = 0,
+ GPIO1D0_MASK = 3 << GPIO1D0_SHIFT,
+ GPIO1D0_GPIO = 0,
+ GPIO1D0_NAND_D0,
+ GPIO1D0_EMMC_D0,
+ GPIO1D0_SFC_SIO0,
+};
+
+/* GRF_GPIO2A_IOMUX */
+enum {
+ GPIO2A7_SHIFT = 14,
+ GPIO2A7_MASK = 3 << GPIO2A7_SHIFT,
+ GPIO2A7_GPIO = 0,
+ GPIO2A7_NAND_DQS,
+ GPIO2A7_EMMC_CLKOUT,
+
+ GPIO2A6_SHIFT = 12,
+ GPIO2A6_MASK = 1 << GPIO2A6_SHIFT,
+ GPIO2A6_GPIO = 0,
+ GPIO2A6_NAND_CS0,
+
+ GPIO2A5_SHIFT = 10,
+ GPIO2A5_MASK = 3 << GPIO2A5_SHIFT,
+ GPIO2A5_GPIO = 0,
+ GPIO2A5_NAND_WP,
+ GPIO2A5_EMMC_PWREN,
+
+ GPIO2A4_SHIFT = 8,
+ GPIO2A4_MASK = 3 << GPIO2A4_SHIFT,
+ GPIO2A4_GPIO = 0,
+ GPIO2A4_NAND_RDY,
+ GPIO2A4_EMMC_CMD,
+ GPIO2A3_SFC_CLK,
+
+ GPIO2A3_SHIFT = 6,
+ GPIO2A3_MASK = 3 << GPIO2A3_SHIFT,
+ GPIO2A3_GPIO = 0,
+ GPIO2A3_NAND_RDN,
+ GPIO2A4_SFC_CSN1,
+
+ GPIO2A2_SHIFT = 4,
+ GPIO2A2_MASK = 3 << GPIO2A2_SHIFT,
+ GPIO2A2_GPIO = 0,
+ GPIO2A2_NAND_WRN,
+ GPIO2A4_SFC_CSN0,
+
+ GPIO2A1_SHIFT = 2,
+ GPIO2A1_MASK = 3 << GPIO2A1_SHIFT,
+ GPIO2A1_GPIO = 0,
+ GPIO2A1_NAND_CLE,
+ GPIO2A1_EMMC_CLKOUT,
+
+ GPIO2A0_SHIFT = 0,
+ GPIO2A0_MASK = 3 << GPIO2A0_SHIFT,
+ GPIO2A0_GPIO = 0,
+ GPIO2A0_NAND_ALE,
+ GPIO2A0_SPI_CLK,
+};
+
+/* GRF_GPIO2B_IOMUX */
+enum {
+ GPIO2B7_SHIFT = 14,
+ GPIO2B7_MASK = 3 << GPIO2B7_SHIFT,
+ GPIO2B7_GPIO = 0,
+ GPIO2B7_LCDC0_D13,
+ GPIO2B7_EBC_SDCE5,
+ GPIO2B7_GMAC_RXER,
+
+ GPIO2B6_SHIFT = 12,
+ GPIO2B6_MASK = 3 << GPIO2B6_SHIFT,
+ GPIO2B6_GPIO = 0,
+ GPIO2B6_LCDC0_D12,
+ GPIO2B6_EBC_SDCE4,
+ GPIO2B6_GMAC_CLK,
+
+ GPIO2B5_SHIFT = 10,
+ GPIO2B5_MASK = 3 << GPIO2B5_SHIFT,
+ GPIO2B5_GPIO = 0,
+ GPIO2B5_LCDC0_D11,
+ GPIO2B5_EBC_SDCE3,
+ GPIO2B5_GMAC_TXEN,
+
+ GPIO2B4_SHIFT = 8,
+ GPIO2B4_MASK = 3 << GPIO2B4_SHIFT,
+ GPIO2B4_GPIO = 0,
+ GPIO2B4_LCDC0_D10,
+ GPIO2B4_EBC_SDCE2,
+ GPIO2B4_GMAC_MDIO,
+
+ GPIO2B3_SHIFT = 6,
+ GPIO2B3_MASK = 3 << GPIO2B3_SHIFT,
+ GPIO2B3_GPIO = 0,
+ GPIO2B3_LCDC0_DEN,
+ GPIO2B3_EBC_GDCLK,
+ GPIO2B3_GMAC_RXCLK,
+
+ GPIO2B2_SHIFT = 4,
+ GPIO2B2_MASK = 3 << GPIO2B2_SHIFT,
+ GPIO2B2_GPIO = 0,
+ GPIO2B2_LCDC0_VSYNC,
+ GPIO2B2_EBC_SDOE,
+ GPIO2B2_GMAC_CRS,
+
+ GPIO2B1_SHIFT = 2,
+ GPIO2B1_MASK = 3 << GPIO2B1_SHIFT,
+ GPIO2B1_GPIO = 0,
+ GPIO2B1_LCDC0_HSYNC,
+ GPIO2B1_EBC_SDLE,
+ GPIO2B1_GMAC_TXCLK,
+
+ GPIO2B0_SHIFT = 0,
+ GPIO2B0_MASK = 3 << GPIO2B0_SHIFT,
+ GPIO2B0_GPIO = 0,
+ GPIO2B0_LCDC0_DCLK,
+ GPIO2B0_EBC_SDCLK,
+ GPIO2B0_GMAC_RXDV,
+};
+
+/* GRF_GPIO2C_IOMUX */
+enum {
+ GPIO2C3_SHIFT = 6,
+ GPIO2C3_MASK = 3 << GPIO2C3_SHIFT,
+ GPIO2C3_GPIO = 0,
+ GPIO2C3_LCDC0_D17,
+ GPIO2C3_EBC_GDPWR0,
+ GPIO2C3_GMAC_TXD0,
+
+ GPIO2C2_SHIFT = 4,
+ GPIO2C2_MASK = 3 << GPIO2C2_SHIFT,
+ GPIO2C2_GPIO = 0,
+ GPIO2C2_LCDC0_D16,
+ GPIO2C2_EBC_GDSP,
+ GPIO2C2_GMAC_TXD1,
+
+ GPIO2C1_SHIFT = 2,
+ GPIO2C1_MASK = 3 << GPIO2C1_SHIFT,
+ GPIO2C1_GPIO = 0,
+ GPIO2C1_LCDC0_D15,
+ GPIO2C1_EBC_GDOE,
+ GPIO2C1_GMAC_RXD0,
+
+ GPIO2C0_SHIFT = 0,
+ GPIO2C0_MASK = 3 << GPIO2C0_SHIFT,
+ GPIO2C0_GPIO = 0,
+ GPIO2C0_LCDC0_D14,
+ GPIO2C0_EBC_VCOM,
+ GPIO2C0_GMAC_RXD1,
+};
+
+/* GRF_GPIO2D_IOMUX */
+enum {
+ GPIO2D6_SHIFT = 12,
+ GPIO2D6_MASK = 3 << GPIO2D6_SHIFT,
+ GPIO2D6_GPIO = 0,
+ GPIO2D6_LCDC0_D22,
+ GPIO2D6_GMAC_COL = 4,
+
+ GPIO2D1_SHIFT = 2,
+ GPIO2D1_MASK = 3 << GPIO2D1_SHIFT,
+ GPIO2D1_GPIO = 0,
+ GPIO2D1_GMAC_MDC = 3,
+};
+
+/* GRF_GPIO2C_IOMUX2 */
+enum {
+ GPIO2C7_SHIFT = 12,
+ GPIO2C7_MASK = 7 << GPIO2C7_SHIFT,
+ GPIO2C7_GPIO = 0,
+ GPIO2C7_GMAC_TXD3 = 4,
+
+ GPIO2C6_SHIFT = 12,
+ GPIO2C6_MASK = 7 << GPIO2C6_SHIFT,
+ GPIO2C6_GPIO = 0,
+ GPIO2C6_GMAC_TXD2 = 4,
+
+ GPIO2C5_SHIFT = 4,
+ GPIO2C5_MASK = 7 << GPIO2C5_SHIFT,
+ GPIO2C5_GPIO = 0,
+ GPIO2C5_I2C2_SCL = 3,
+ GPIO2C5_GMAC_RXD2,
+
+ GPIO2C4_SHIFT = 0,
+ GPIO2C4_MASK = 7 << GPIO2C4_SHIFT,
+ GPIO2C4_GPIO = 0,
+ GPIO2C4_I2C2_SDA = 3,
+ GPIO2C4_GMAC_RXD2,
+};
+#endif
#define PTE_TYPE_MASK (3 << 0)
#define PTE_TYPE_FAULT (0 << 0)
#define PTE_TYPE_TABLE (3 << 0)
+#define PTE_TYPE_PAGE (3 << 0)
#define PTE_TYPE_BLOCK (1 << 0)
#define PTE_TYPE_VALID (1 << 0)
#ifndef _DAVINCI_NAND_H_
#define _DAVINCI_NAND_H_
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <asm/arch/hardware.h>
#define NAND_READ_START 0x00
#include <linux/compiler.h>
#include <efi_loader.h>
+DECLARE_GLOBAL_DATA_PTR;
int interrupt_init(void)
{
{
int i;
- printf("ELR: %lx\n", regs->elr);
- printf("LR: %lx\n", regs->regs[30]);
+ if (gd->flags & GD_FLG_RELOC) {
+ printf("ELR: %lx\n", regs->elr - gd->reloc_off);
+ printf("LR: %lx\n", regs->regs[30] - gd->reloc_off);
+ } else {
+ printf("ELR: %lx\n", regs->elr);
+ printf("LR: %lx\n", regs->regs[30]);
+ }
for (i = 0; i < 29; i += 2)
printf("x%-2d: %016lx x%-2d: %016lx\n",
i, regs->regs[i], i+1, regs->regs[i+1]);
This option creates a build targetting the ARM1176 ISA.
select BCM2835
+config TARGET_RPI_0_W
+ bool "Raspberry Pi Zero W"
+ help
+ Support for all ARM1176-/BCM2835-based Raspberry Pi variants, such as
+ the RPi Zero model W.
+
+ This option assumes the VideoCore firmware is configured to use the
+ mini UART (rather than PL011) for the serial console. This is the
+ default on the RPi Zero W. To enable the UART console, the following
+ non-default option must be present in config.txt: enable_uart=1.
+ This is required for U-Boot to operate correctly, even if you only
+ care about the HDMI/usbkbd console.
+
+ This option creates a build targetting the ARMv7/AArch32 ISA.
+ select BCM2835
+
config TARGET_RPI_2
bool "Raspberry Pi 2"
help
with 2 GiB of RAM, Ethernet, HDMI, 2 USB, micro-SD slot,
eMMC, IR receiver, CVBS+Audio jack and a SDIO WiFi module.
+config TARGET_LIBRETECH_CC
+ bool "LIBRETECH-CC"
+ help
+ LibreTech CC is a single board computer based on Meson GXL
+ with 2 GiB of RAM, Ethernet, HDMI, 4 USB, micro-SD slot,
+ eMMC, IR receiver and a 40-pin GPIO header.
+
+config TARGET_KHADAS_VIM
+ bool "KHADAS-VIM"
+ help
+ Khadas VIM is a single board computer based on Meson GXL
+ with 2 GiB of RAM, Ethernet, HDMI, 4 USB, micro-SD slot,
+ eMMC, IR receiver and a 40-pin GPIO header.
+
endif
config SYS_SOC
source "board/amlogic/p212/Kconfig"
+source "board/amlogic/libretech-cc/Kconfig"
+
+source "board/amlogic/khadas-vim/Kconfig"
+
endif
# SPDX-License-Identifier: GPL-2.0+
#
-obj-y += board.o sm.o
+obj-y += board.o sm.o eth.o
#include <asm/arch/sm.h>
#include <asm/armv8/mmu.h>
#include <asm/unaligned.h>
+#include <linux/sizes.h>
+#include <efi_loader.h>
+#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
return 0;
}
-int dram_init_banksize(void)
+phys_size_t get_effective_memsize(void)
{
- /* Reserve first 16 MiB of RAM for firmware */
- gd->bd->bi_dram[0].start = 0x1000000;
- gd->bd->bi_dram[0].size = 0xf000000;
- /* Reserve 2 MiB for ARM Trusted Firmware (BL31) */
- gd->bd->bi_dram[1].start = 0x10000000;
- gd->bd->bi_dram[1].size = gd->ram_size - 0x10200000;
- return 0;
+ /* Size is reported in MiB, convert it in bytes */
+ return ((readl(GXBB_AO_SEC_GP_CFG0) & GXBB_AO_MEM_SIZE_MASK)
+ >> GXBB_AO_MEM_SIZE_SHIFT) * SZ_1M;
+}
+
+static void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size)
+{
+ int ret;
+
+ ret = fdt_add_mem_rsv(fdt, start, size);
+ if (ret)
+ printf("Could not reserve zone @ 0x%llx\n", start);
+
+ if (IS_ENABLED(CONFIG_EFI_LOADER)) {
+ efi_add_memory_map(start,
+ ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
+ EFI_RESERVED_MEMORY_TYPE, false);
+ }
+}
+
+void meson_gx_init_reserved_memory(void *fdt)
+{
+ u64 bl31_size, bl31_start;
+ u64 bl32_size, bl32_start;
+ u32 reg;
+
+ /*
+ * Get ARM Trusted Firmware reserved memory zones in :
+ * - AO_SEC_GP_CFG3: bl32 & bl31 size in KiB, can be 0
+ * - AO_SEC_GP_CFG5: bl31 physical start address, can be NULL
+ * - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL
+ */
+
+ reg = readl(GXBB_AO_SEC_GP_CFG3);
+
+ bl31_size = ((reg & GXBB_AO_BL31_RSVMEM_SIZE_MASK)
+ >> GXBB_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
+ bl32_size = (reg & GXBB_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
+
+ bl31_start = readl(GXBB_AO_SEC_GP_CFG5);
+ bl32_start = readl(GXBB_AO_SEC_GP_CFG4);
+
+ /*
+ * Early Meson GXBB Firmware revisions did not provide the reserved
+ * memory zones in the registers, keep fixed memory zone handling.
+ */
+ if (IS_ENABLED(CONFIG_MESON_GXBB) &&
+ !reg && !bl31_start && !bl32_start) {
+ bl31_start = 0x10000000;
+ bl31_size = 0x200000;
+ }
+
+ /* Add first 16MiB reserved zone */
+ meson_board_add_reserved_memory(fdt, 0, GXBB_FIRMWARE_MEM_SIZE);
+
+ /* Add BL31 reserved zone */
+ if (bl31_start && bl31_size)
+ meson_board_add_reserved_memory(fdt, bl31_start, bl31_size);
+
+ /* Add BL32 reserved zone */
+ if (bl32_start && bl32_size)
+ meson_board_add_reserved_memory(fdt, bl32_start, bl32_size);
}
void reset_cpu(ulong addr)
--- /dev/null
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/gxbb.h>
+#include <asm/arch/eth.h>
+#include <phy.h>
+
+/* Configure the Ethernet MAC with the requested interface mode
+ * with some optional flags.
+ */
+void meson_gx_eth_init(phy_interface_t mode, unsigned int flags)
+{
+ switch (mode) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ /* Set RGMII mode */
+ setbits_le32(GXBB_ETH_REG_0, GXBB_ETH_REG_0_PHY_INTF |
+ GXBB_ETH_REG_0_TX_PHASE(1) |
+ GXBB_ETH_REG_0_TX_RATIO(4) |
+ GXBB_ETH_REG_0_PHY_CLK_EN |
+ GXBB_ETH_REG_0_CLK_EN);
+ break;
+
+ case PHY_INTERFACE_MODE_RMII:
+ /* Set RMII mode */
+ out_le32(GXBB_ETH_REG_0, GXBB_ETH_REG_0_INVERT_RMII_CLK |
+ GXBB_ETH_REG_0_CLK_EN);
+
+ /* Use GXL RMII Internal PHY */
+ if (IS_ENABLED(CONFIG_MESON_GXL) &&
+ (flags & MESON_GXL_USE_INTERNAL_RMII_PHY)) {
+ writel(GXBB_ETH_REG_2, 0x10110181);
+ writel(GXBB_ETH_REG_3, 0xe40908ff);
+ }
+
+ break;
+
+ default:
+ printf("Invalid Ethernet interface mode\n");
+ return;
+ }
+
+ /* Enable power and clock gate */
+ setbits_le32(GXBB_GCLK_MPEG_1, GXBB_GCLK_MPEG_1_ETH);
+ clrbits_le32(GXBB_MEM_PD_REG_0, GXBB_MEM_PD_REG_0_ETH_MASK);
+}
#include <common.h>
#include <jffs2/load_kernel.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/mtd/omap_gpmc.h>
#include <asm/io.h>
#include <asm/arch/sys_proto.h>
mac[5] = (die_id[0] >> 8) & 0xff;
eth_env_set_enetaddr("usbethaddr", mac);
+
+ if (!env_get("ethaddr"))
+ eth_env_set_enetaddr("ethaddr", mac);
}
}
and video codec support. Peripherals include Gigabit Ethernet,
USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
+config ROCKCHIP_RK3128
+ bool "Support Rockchip RK3128"
+ select CPU_V7
+ help
+ The Rockchip RK3128 is a ARM-based SoC with a quad-core Cortex-A7
+ including NEON and GPU, Mali-400 graphics, several DDR3 options
+ and video codec support. Peripherals include Gigabit Ethernet,
+ USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
+
config ROCKCHIP_RK3188
bool "Support Rockchip RK3188"
select CPU_V7
default y if !SPL_ROCKCHIP_BACK_TO_BROM
source "arch/arm/mach-rockchip/rk3036/Kconfig"
+source "arch/arm/mach-rockchip/rk3128/Kconfig"
source "arch/arm/mach-rockchip/rk3188/Kconfig"
source "arch/arm/mach-rockchip/rk322x/Kconfig"
source "arch/arm/mach-rockchip/rk3288/Kconfig"
obj-y += boot_mode.o
obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board.o
+obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128-board.o
obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x-board.o
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board.o
endif
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
+obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/
ifndef CONFIG_TPL_BUILD
obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
endif
struct rk3036_ddr_config ddr_config;
};
-/* use integer mode, 396MHz dpll setting
+/*
+ * use integer mode, dpll output 792MHz and ddr get 396MHz
* refdiv, fbdiv, postdiv1, postdiv2
*/
-const struct pll_div dpll_init_cfg = {1, 50, 3, 1};
+const struct pll_div dpll_init_cfg = {1, 66, 2, 1};
/* 396Mhz ddr timing */
const struct rk3036_ddr_timing ddr_timing = {0x18c,
struct rk3036_pll *pll = &priv->cru->pll[1];
/* pll enter slow-mode */
- rk_clrsetreg(&priv->cru->cru_mode_con,
- DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+ rk_clrsetreg(&priv->cru->cru_mode_con, DPLL_MODE_MASK,
DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
/* use integer mode */
- rk_clrreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
+ rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
rk_clrsetreg(&pll->con0,
- PLL_POSTDIV1_MASK << PLL_POSTDIV1_SHIFT | PLL_FBDIV_MASK,
+ PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
(dpll_init_cfg.postdiv1 << PLL_POSTDIV1_SHIFT) |
dpll_init_cfg.fbdiv);
- rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK << PLL_POSTDIV2_SHIFT |
- PLL_REFDIV_MASK << PLL_REFDIV_SHIFT,
- (dpll_init_cfg.postdiv2 << PLL_POSTDIV2_SHIFT |
- dpll_init_cfg.refdiv << PLL_REFDIV_SHIFT));
+ rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
+ (dpll_init_cfg.postdiv2 << PLL_POSTDIV2_SHIFT |
+ dpll_init_cfg.refdiv << PLL_REFDIV_SHIFT));
/* waiting for pll lock */
while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
rockchip_udelay(1);
/* PLL enter normal-mode */
- rk_clrsetreg(&priv->cru->cru_mode_con,
- DPLL_MODE_MASK << DPLL_MODE_SHIFT,
+ rk_clrsetreg(&priv->cru->cru_mode_con, DPLL_MODE_MASK,
DPLL_MODE_NORM << DPLL_MODE_SHIFT);
}
--- /dev/null
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/grf_rk3128.h>
+#include <asm/arch/boot_mode.h>
+#include <asm/arch/timer.h>
+#include <power/regulator.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+__weak int rk_board_late_init(void)
+{
+ return 0;
+}
+
+int board_late_init(void)
+{
+ setup_boot_mode();
+
+ return rk_board_late_init();
+}
+
+int board_init(void)
+{
+ int ret = 0;
+
+ rockchip_timer_init();
+
+ ret = regulators_enable_boot_on(false);
+ if (ret) {
+ debug("%s: Cannot enable boot on regulator\n", __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ gd->bd->bi_dram[0].size = 0x8400000;
+ /* Reserve 0xe00000(14MB) for OPTEE with TA enabled, otherwise 2MB */
+ gd->bd->bi_dram[1].start = CONFIG_SYS_SDRAM_BASE
+ + gd->bd->bi_dram[0].size + 0xe00000;
+ gd->bd->bi_dram[1].size = gd->bd->bi_dram[0].start
+ + gd->ram_size - gd->bd->bi_dram[1].start;
+
+ return 0;
+}
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+ /* Enable D-cache. I-cache is already enabled in start.S */
+ dcache_enable();
+}
+#endif
+
+#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
+#include <usb.h>
+#include <usb/dwc2_udc.h>
+
+static struct dwc2_plat_otg_data rk3128_otg_data = {
+ .rx_fifo_sz = 512,
+ .np_tx_fifo_sz = 16,
+ .tx_fifo_sz = 128,
+};
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+ int node;
+ const char *mode;
+ bool matched = false;
+ const void *blob = gd->fdt_blob;
+
+ /* find the usb_otg node */
+ node = fdt_node_offset_by_compatible(blob, -1,
+ "rockchip,rk3128-usb");
+
+ while (node > 0) {
+ mode = fdt_getprop(blob, node, "dr_mode", NULL);
+ if (mode && strcmp(mode, "otg") == 0) {
+ matched = true;
+ break;
+ }
+
+ node = fdt_node_offset_by_compatible(blob, node,
+ "rockchip,rk3128-usb");
+ }
+ if (!matched) {
+ debug("Not found usb_otg device\n");
+ return -ENODEV;
+ }
+ rk3128_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");
+
+ return dwc2_udc_probe(&rk3128_otg_data);
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_USB_FUNCTION_FASTBOOT)
+int fb_set_reboot_flag(void)
+{
+ struct rk3128_grf *grf;
+
+ printf("Setting reboot to fastboot flag ...\n");
+ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ /* Set boot mode to fastboot */
+ writel(BOOT_FASTBOOT, &grf->os_reg[0]);
+
+ return 0;
+}
+#endif
--- /dev/null
+if ROCKCHIP_RK3128
+
+choice
+ prompt "RK3128 board select"
+
+config TARGET_EVB_RK3128
+ bool "RK3128 evaluation board"
+ select BOARD_LATE_INIT
+ help
+ RK3128evb is a evaluation board for Rockchip rk3128,
+ with full function and phisical connectors support like
+ usb2.0 host ports, LVDS, JTAG, MAC, SDcard, HDMI, USB-2-serial...
+
+endchoice
+
+config SYS_SOC
+ default "rockchip"
+
+config SYS_MALLOC_F_LEN
+ default 0x0800
+
+source "board/rockchip/evb_rk3128/Kconfig"
+
+endif
--- /dev/null
+#
+# (C) Copyright 2017 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += rk3128.o
+obj-y += syscon_rk3128.o
+obj-y += clk_rk3128.o
--- /dev/null
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3128.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_GET_DRIVER(rockchip_rk3128_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3128_clk_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ ret = rockchip_get_clk(&dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv = dev_get_priv(dev);
+
+ return priv->cru;
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+int arch_cpu_init(void)
+{
+ /* We do some SoC one time setting here. */
+
+ return 0;
+}
--- /dev/null
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+
+static const struct udevice_id rk3128_syscon_ids[] = {
+ { .compatible = "rockchip,rk3128-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3128) = {
+ .name = "rk3128_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3128_syscon_ids,
+};
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <common.h>
-#include <libfdt.h>
+#include <linux/errno.h>
#include <linux/io.h>
+#include <linux/printk.h>
#include "init.h"
#include "micro-support-card.h"
-#include "sg-regs.h"
#include "soc-info.h"
-DECLARE_GLOBAL_DATA_PTR;
-
#ifdef CONFIG_ARCH_UNIPHIER_LD20
static void uniphier_ld20_misc_init(void)
{
--- /dev/null
+if TARGET_KHADAS_VIM
+
+config SYS_BOARD
+ default "khadas-vim"
+
+config SYS_VENDOR
+ default "amlogic"
+
+config SYS_CONFIG_NAME
+ default "khadas-vim"
+
+endif
--- /dev/null
+KHADAS-VIM
+M: Neil Armstrong <narmstrong@baylibre.com>
+S: Maintained
+F: board/amlogic/khadas-vim/
+F: include/configs/khadas-vim.h
+F: configs/khadas-vim_defconfig
--- /dev/null
+#
+# (C) Copyright 2016 BayLibre, SAS
+# Author: Neil Armstrong <narmstrong@baylibre.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y := khadas-vim.o
--- /dev/null
+U-Boot for Khadas VIM
+=======================
+
+Khadas VIM is an Open Source DIY Box manufactured by Shenzhen Tomato
+Technology Co., Ltd with the following specifications:
+
+ - Amlogic S905x ARM Cortex-A53 quad-core SoC @ 2GHz
+ - ARM Mali 450 GPU
+ - 2GB DDR3 SDRAM
+ - 10/100 Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 40-pin GPIO header
+ - 2 x USB 2.0 Host, 1 x USB 2.0 Type-C OTG
+ - 8GB/16GBeMMC
+ - microSD
+ - SDIO Wifi Module, Bluetooth
+ - Two channels IR receiver
+
+Currently the u-boot port supports the following devices:
+ - serial
+ - eMMC, microSD
+ - Ethernet
+
+U-Boot compilation
+==================
+
+ > export ARCH=arm
+ > export CROSS_COMPILE=aarch64-none-elf-
+ > make khadas-vim_defconfig
+ > make
+
+Image creation
+==============
+
+Amlogic doesn't provide sources for the firmware and for tools needed
+to create the bootloader image, so it is necessary to obtain them from
+the git tree published by the board vendor:
+
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH
+ > git clone https://github.com/khadas/u-boot -b Vim vim-u-boot
+ > cd vim-u-boot
+ > make kvim_defconfig
+ > make
+ > export FIPDIR=$PWD/fip
+
+Go back to mainline U-Boot source tree then :
+ > mkdir fip
+
+ > cp $FIPDIR/gxl/bl2.bin fip/
+ > cp $FIPDIR/gxl/acs.bin fip/
+ > cp $FIPDIR/gxl/bl21.bin fip/
+ > cp $FIPDIR/gxl/bl30.bin fip/
+ > cp $FIPDIR/gxl/bl301.bin fip/
+ > cp $FIPDIR/gxl/bl31.img fip/
+ > cp u-boot.bin fip/bl33.bin
+
+ > $FIPDIR/blx_fix.sh \
+ fip/bl30.bin \
+ fip/zero_tmp \
+ fip/bl30_zero.bin \
+ fip/bl301.bin \
+ fip/bl301_zero.bin \
+ fip/bl30_new.bin \
+ bl30
+
+ > $FIPDIR/acs_tool.pyc fip/bl2.bin fip/bl2_acs.bin fip/acs.bin 0
+
+ > $FIPDIR/blx_fix.sh \
+ fip/bl2_acs.bin \
+ fip/zero_tmp \
+ fip/bl2_zero.bin \
+ fip/bl21.bin \
+ fip/bl21_zero.bin \
+ fip/bl2_new.bin \
+ bl2
+
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl30_new.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl31.img
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl33.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl2sig --input fip/bl2_new.bin --output fip/bl2.n.bin.sig
+ > $FIPDIR/gxl/aml_encrypt_gxl --bootmk \
+ --output fip/u-boot.bin \
+ --bl2 fip/bl2.n.bin.sig \
+ --bl30 fip/bl30_new.bin.enc \
+ --bl31 fip/bl31.img.enc \
+ --bl33 fip/bl33.bin.enc
+
+and then write the image to SD with:
+
+ > DEV=/dev/your_sd_device
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444
--- /dev/null
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/gxbb.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/sm.h>
+#include <asm/arch/eth.h>
+
+#define EFUSE_SN_OFFSET 20
+#define EFUSE_SN_SIZE 16
+#define EFUSE_MAC_OFFSET 52
+#define EFUSE_MAC_SIZE 6
+
+int board_init(void)
+{
+ return 0;
+}
+
+int misc_init_r(void)
+{
+ u8 mac_addr[EFUSE_MAC_SIZE];
+ char serial[EFUSE_SN_SIZE];
+ ssize_t len;
+
+ meson_gx_eth_init(PHY_INTERFACE_MODE_RMII,
+ MESON_GXL_USE_INTERNAL_RMII_PHY);
+
+ if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
+ len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
+ mac_addr, EFUSE_MAC_SIZE);
+ if (len == EFUSE_MAC_SIZE && is_valid_ethaddr(mac_addr))
+ eth_env_set_enetaddr("ethaddr", mac_addr);
+ }
+
+ if (!env_get("serial#")) {
+ len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
+ EFUSE_SN_SIZE);
+ if (len == EFUSE_SN_SIZE)
+ env_set("serial#", serial);
+ }
+
+ return 0;
+}
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+ meson_gx_init_reserved_memory(blob);
+
+ return 0;
+}
--- /dev/null
+if TARGET_LIBRETECH_CC
+
+config SYS_BOARD
+ default "libretech-cc"
+
+config SYS_VENDOR
+ default "amlogic"
+
+config SYS_CONFIG_NAME
+ default "libretech-cc"
+
+endif
--- /dev/null
+LIBRETECH-CC
+M: Neil Armstrong <narmstrong@baylibre.com>
+S: Maintained
+F: board/amlogic/libretech-cc/
+F: include/configs/libretech-cc.h
+F: configs/libretech-cc_defconfig
--- /dev/null
+#
+# (C) Copyright 2016 BayLibre, SAS
+# Author: Neil Armstrong <narmstrong@baylibre.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y := libretech-cc.o
--- /dev/null
+U-Boot for LibreTech CC
+=======================
+
+LibreTech CC is a single board computer manufactured by Libre Technology
+with the following specifications:
+
+ - Amlogic S905X ARM Cortex-A53 quad-core SoC @ 2GHz
+ - ARM Mali 450 GPU
+ - 2GB DDR3 SDRAM
+ - Gigabit Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 40-pin GPIO header
+ - 4 x USB 2.0 Host, 1 x USB OTG
+ - eMMC, microSD
+ - Infrared receiver
+
+Schematics are available on the manufacturer website.
+
+Currently the U-Boot port supports the following devices:
+ - serial
+ - eMMC, microSD
+ - Ethernet
+
+U-Boot compilation
+==================
+
+ > export ARCH=arm
+ > export CROSS_COMPILE=aarch64-none-elf-
+ > make libretech-cc_defconfig
+ > make
+
+Image creation
+==============
+
+Amlogic doesn't provide sources for the firmware and for tools needed
+to create the bootloader image, so it is necessary to obtain them from
+the git tree published by the board vendor:
+
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH
+ > git clone https://github.com/BayLibre/u-boot.git -b libretech-cc amlogic-u-boot
+ > cd amlogic-u-boot
+ > make libretech_cc_defconfig
+ > make
+ > export FIPDIR=$PWD/fip
+
+Go back to mainline U-Boot source tree then :
+ > mkdir fip
+
+ > cp $FIPDIR/gxl/bl2.bin fip/
+ > cp $FIPDIR/gxl/acs.bin fip/
+ > cp $FIPDIR/gxl/bl21.bin fip/
+ > cp $FIPDIR/gxl/bl30.bin fip/
+ > cp $FIPDIR/gxl/bl301.bin fip/
+ > cp $FIPDIR/gxl/bl31.img fip/
+ > cp u-boot.bin fip/bl33.bin
+
+ > $FIPDIR/blx_fix.sh \
+ fip/bl30.bin \
+ fip/zero_tmp \
+ fip/bl30_zero.bin \
+ fip/bl301.bin \
+ fip/bl301_zero.bin \
+ fip/bl30_new.bin \
+ bl30
+
+ > $FIPDIR/acs_tool.pyc fip/bl2.bin fip/bl2_acs.bin fip/acs.bin 0
+
+ > $FIPDIR/blx_fix.sh \
+ fip/bl2_acs.bin \
+ fip/zero_tmp \
+ fip/bl2_zero.bin \
+ fip/bl21.bin \
+ fip/bl21_zero.bin \
+ fip/bl2_new.bin \
+ bl2
+
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl30_new.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl31.img
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl33.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl2sig --input fip/bl2_new.bin --output fip/bl2.n.bin.sig
+ > $FIPDIR/gxl/aml_encrypt_gxl --bootmk \
+ --output fip/u-boot.bin \
+ --bl2 fip/bl2.n.bin.sig \
+ --bl30 fip/bl30_new.bin.enc \
+ --bl31 fip/bl31.img.enc \
+ --bl33 fip/bl33.bin.enc
+
+and then write the image to SD with:
+
+ > DEV=/dev/your_sd_device
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444
--- /dev/null
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/gxbb.h>
+#include <asm/arch/sm.h>
+#include <asm/arch/eth.h>
+#include <asm/arch/mem.h>
+
+#define EFUSE_SN_OFFSET 20
+#define EFUSE_SN_SIZE 16
+#define EFUSE_MAC_OFFSET 52
+#define EFUSE_MAC_SIZE 6
+
+int board_init(void)
+{
+ return 0;
+}
+
+int misc_init_r(void)
+{
+ u8 mac_addr[EFUSE_MAC_SIZE];
+ char serial[EFUSE_SN_SIZE];
+ ssize_t len;
+
+ meson_gx_eth_init(PHY_INTERFACE_MODE_RMII,
+ MESON_GXL_USE_INTERNAL_RMII_PHY);
+
+ /* Enable power and clock gate */
+ setbits_le32(GXBB_GCLK_MPEG_1, GXBB_GCLK_MPEG_1_ETH);
+ clrbits_le32(GXBB_MEM_PD_REG_0, GXBB_MEM_PD_REG_0_ETH_MASK);
+
+ if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
+ len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
+ mac_addr, EFUSE_MAC_SIZE);
+ if (len == EFUSE_MAC_SIZE && is_valid_ethaddr(mac_addr))
+ eth_env_set_enetaddr("ethaddr", mac_addr);
+ }
+
+ if (!env_get("serial#")) {
+ len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
+ EFUSE_SN_SIZE);
+ if (len == EFUSE_SN_SIZE)
+ env_set("serial#", serial);
+ }
+
+ return 0;
+}
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+ meson_gx_init_reserved_memory(blob);
+
+ return 0;
+}
#include <asm/io.h>
#include <asm/arch/gxbb.h>
#include <asm/arch/sm.h>
-#include <phy.h>
+#include <asm/arch/eth.h>
+#include <asm/arch/mem.h>
#define EFUSE_SN_OFFSET 20
#define EFUSE_SN_SIZE 16
char serial[EFUSE_SN_SIZE];
ssize_t len;
- /* Set RGMII mode */
- setbits_le32(GXBB_ETH_REG_0, GXBB_ETH_REG_0_PHY_INTF |
- GXBB_ETH_REG_0_TX_PHASE(1) |
- GXBB_ETH_REG_0_TX_RATIO(4) |
- GXBB_ETH_REG_0_PHY_CLK_EN |
- GXBB_ETH_REG_0_CLK_EN);
+ meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
/* Enable power and clock gate */
setbits_le32(GXBB_GCLK_MPEG_0, GXBB_GCLK_MPEG_0_I2C);
- setbits_le32(GXBB_GCLK_MPEG_1, GXBB_GCLK_MPEG_1_ETH);
- clrbits_le32(GXBB_MEM_PD_REG_0, GXBB_MEM_PD_REG_0_ETH_MASK);
/* Reset PHY on GPIOZ_14 */
clrbits_le32(GXBB_GPIO_EN(3), BIT(14));
return 0;
}
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+ meson_gx_init_reserved_memory(blob);
+
+ return 0;
+}
#include <asm/io.h>
#include <asm/arch/gxbb.h>
#include <asm/arch/sm.h>
-#include <phy.h>
+#include <asm/arch/eth.h>
+#include <asm/arch/mem.h>
#define EFUSE_SN_OFFSET 20
#define EFUSE_SN_SIZE 16
char serial[EFUSE_SN_SIZE];
ssize_t len;
- /* Set RMII mode */
- out_le32(GXBB_ETH_REG_0, GXBB_ETH_REG_0_INVERT_RMII_CLK |
- GXBB_ETH_REG_0_CLK_EN);
-
- /* Use Internal PHY */
- out_le32(GXBB_ETH_REG_2, 0x10110181);
- out_le32(GXBB_ETH_REG_3, 0xe40908ff);
-
- /* Enable power and clock gate */
- setbits_le32(GXBB_GCLK_MPEG_1, GXBB_GCLK_MPEG_1_ETH);
- clrbits_le32(GXBB_MEM_PD_REG_0, GXBB_MEM_PD_REG_0_ETH_MASK);
+ meson_gx_eth_init(PHY_INTERFACE_MODE_RMII, 0);
if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
return 0;
}
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+ meson_gx_init_reserved_memory(blob);
+
+ return 0;
+}
#include <asm/arch/gpio.h>
#include <asm/arch/clk.h>
#include <lcd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <atmel_lcdc.h>
#include <asm/mach-types.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
#include <jffs2/load_kernel.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include "igep00x0.h"
DECLARE_GLOBAL_DATA_PTR;
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/mtd/onenand.h>
#include <jffs2/load_kernel.h>
#include <mtd_node.h>
#include <asm/arch/mem.h>
#include <asm/arch/sys_proto.h>
#include <jffs2/load_kernel.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include "igep00x0.h"
/*
#include <asm/arch/sys_proto.h>
#include <asm/gpio.h>
#include <asm/mach-types.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <asm/omap_musb.h>
#include <linux/errno.h>
#include <linux/usb/ch9.h>
#include <asm/arch/gpio.h>
#include <asm/arch/clk.h>
#include <lcd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <atmel_lcdc.h>
#include <atmel_mci.h>
#if defined(CONFIG_RESET_PHY_R) && defined(CONFIG_MACB)
#include <ns16550.h>
#include <netdev.h>
#include <twl4030.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <asm/io.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/mux.h>
DTB_DIR "bcm2835-rpi-zero.dtb",
false,
},
+ [0xC] = {
+ "Zero W",
+ DTB_DIR "bcm2835-rpi-zero-w.dtb",
+ false,
+ },
};
static const struct rpi_model rpi_models_old_scheme[] = {
--- /dev/null
+if TARGET_EVB_RK3128
+
+config SYS_BOARD
+ default "evb_rk3128"
+
+config SYS_VENDOR
+ default "rockchip"
+
+config SYS_CONFIG_NAME
+ default "evb_rk3128"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+
+endif
--- /dev/null
+EVB-RK3128
+M: Kever Yang <kever.yang@rock-chips.com>
+S: Maintained
+F: board/rockchip/evb_rk3128
+F: include/configs/evb_rk3128.h
+F: configs/evb-rk3128_defconfig
--- /dev/null
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += evk-rk3128.o
Get ddr init binary
==============================================================================
> git clone https://github.com/rockchip-linux/rkbin.git
- > dd if=./rkbin/rv1x/rv1108ddr.bin of=ddr.bin bs=4 skip=1
Compile U-Boot
===========================
> make CROSS_COMPILE=arm-linux-gnueabi- evb-rv1108_defconfig all
- > ./tools/mkimage -n rv1108 -T rksd -d ddr.bin spl.bin
+ > ./tools/mkimage -n rv1108 -T rksd -d ../rkbin/rv1x/rv1108ddr_v1.00.bin spl.bin
> cat spl.bin u-boot.bin > u-boot.img
Flash the image by rkdeveloptool
rkdeveloptool can get from https://github.com/rockchip-linux/rkdeveloptool.git
Power on(or reset with RESET KEY) with MASKROM KEY preesed, and then:
- > rkdeveloptool db ./rkbin/rv1x/RV1108_usb_boot.bin
+ > rkdeveloptool db ./rkbin/rv1x/rv1108usbboot_v1.00.bin
> rkdeveloptool wl 0x40 u-boot.img
> rkdeveloptool RD
#include <asm/arch/atmel_serial.h>
#include <asm/arch/clk.h>
#include <asm/gpio.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <atmel_mci.h>
#include <asm/arch/at91_spi.h>
#include <spi.h>
#include <common.h>
#include <dm.h>
#include <misc.h>
+#include <spl.h>
+#include <usb.h>
#include <dm/pinctrl.h>
#include <dm/uclass-internal.h>
+#include <asm/gpio.h>
#include <asm/setup.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3399.h>
#include <asm/arch/periph.h>
#include <power/regulator.h>
-#include <spl.h>
#include <u-boot/sha256.h>
DECLARE_GLOBAL_DATA_PTR;
return 0;
}
+static void rk3399_force_power_on_reset(void)
+{
+ ofnode node;
+ struct gpio_desc sysreset_gpio;
+
+ debug("%s: trying to force a power-on reset\n", __func__);
+
+ node = ofnode_path("/config");
+ if (!ofnode_valid(node)) {
+ debug("%s: no /config node?\n", __func__);
+ return;
+ }
+
+ if (gpio_request_by_name_nodev(node, "sysreset-gpio", 0,
+ &sysreset_gpio, GPIOD_IS_OUT)) {
+ debug("%s: could not find a /config/sysreset-gpio\n", __func__);
+ return;
+ }
+
+ dm_gpio_set_value(&sysreset_gpio, 1);
+}
+
void spl_board_init(void)
{
int ret;
+ struct rk3399_cru *cru = rockchip_get_cru();
+
+ /*
+ * The RK3399 resets only 'almost all logic' (see also in the TRM
+ * "3.9.4 Global software reset"), when issuing a software reset.
+ * This may cause issues during boot-up for some configurations of
+ * the application software stack.
+ *
+ * To work around this, we test whether the last reset reason was
+ * a power-on reset and (if not) issue an overtemp-reset to reset
+ * the entire module.
+ *
+ * While this was previously fixed by modifying the various places
+ * that could generate a software reset (e.g. U-Boot's sysreset
+ * driver, the ATF or Linux), we now have it here to ensure that
+ * we no longer have to track this through the various components.
+ */
+ if (cru->glb_rst_st != 0)
+ rk3399_force_power_on_reset();
/*
* Turning the eMMC and SPI back on (if disabled via the Qseven
serialnr->low = (u32)(serial & 0xffffffff);
}
#endif
+
+/**
+ * Switch power at an external regulator (for our root hub).
+ *
+ * @param ctrl pointer to the xHCI controller
+ * @param port port number as in the control message (one-based)
+ * @param enable boolean indicating whether to enable or disable power
+ * @return returns 0 on success, an error-code on failure
+ */
+static int board_usb_port_power_set(struct udevice *dev, int port,
+ bool enable)
+{
+#if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_REGULATOR)
+ /* We start counting ports at 0, while USB counts from 1. */
+ int index = port - 1;
+ const char *regname = NULL;
+ struct udevice *regulator;
+ const char *prop = "tsd,usb-port-power";
+ int ret;
+
+ debug("%s: ctrl '%s' port %d enable %s\n", __func__,
+ dev_read_name(dev), port, enable ? "true" : "false");
+
+ ret = dev_read_string_index(dev, prop, index, ®name);
+ if (ret < 0) {
+ debug("%s: ctrl '%s' port %d: no entry in '%s'\n",
+ __func__, dev_read_name(dev), port, prop);
+ return ret;
+ }
+
+ ret = regulator_get_by_platname(regname, ®ulator);
+ if (ret) {
+ debug("%s: ctrl '%s' port %d: could not get regulator '%s'\n",
+ __func__, dev_read_name(dev), port, regname);
+ return ret;
+ }
+
+ regulator_set_enable(regulator, enable);
+ return 0;
+#else
+ return -ENOTSUPP;
+#endif
+}
+
+void usb_hub_reset_devices(struct usb_hub_device *hub, int port)
+{
+ struct udevice *dev = hub->pusb_dev->dev;
+ struct udevice *ctrl;
+
+ /* We are only interested in our root-hubs */
+ if (usb_hub_is_root_hub(dev) == false)
+ return;
+
+ ctrl = usb_get_bus(dev);
+ if (!ctrl) {
+ debug("%s: could not retrieve ctrl for hub\n", __func__);
+ return;
+ }
+
+ /*
+ * To work around an incompatibility between the single-threaded
+ * USB stack in U-Boot and (a strange low-power mode of) the USB
+ * hub we have on-module, we need to delay powering on the hub
+ * until the first time the port is probed.
+ */
+ board_usb_port_power_set(ctrl, port, true);
+}
#include <status_led.h>
#endif
#include <twl4030.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <asm/io.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/mux.h>
#include <twl4030.h>
#include <asm/mach-types.h>
#include <asm/omap_musb.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/musb.h>
#include <cramfs/cramfs_fs.h>
#if defined(CONFIG_CMD_NAND)
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <nand.h>
#endif
#include <linux/mtd/mtd.h>
#if defined(CONFIG_CMD_NAND)
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <nand.h>
#endif
--- /dev/null
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_ROCKCHIP_RK3128=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3128-evb"
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_CMD_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x60800800
+CONFIG_FASTBOOT_BUF_SIZE=0x04000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+# CONFIG_CMD_IMLS is not set
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_PHY=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_ROCKCHIP_RK3128=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_RAM=y
+CONFIG_DM_RESET=y
+CONFIG_DEBUG_UART_BASE=0x20068000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_G_DNL_MANUFACTURER="Rockchip"
+CONFIG_G_DNL_VENDOR_NUM=0x2207
+CONFIG_G_DNL_PRODUCT_NUM=0x310c
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_ERRNO_STR=y
--- /dev/null
+CONFIG_ARM=y
+CONFIG_ARCH_MESON=y
+CONFIG_MESON_GXL=y
+CONFIG_TARGET_KHADAS_VIM=y
+CONFIG_IDENT_STRING=" khadas-vim"
+CONFIG_DEFAULT_DEVICE_TREE="meson-gxl-s905x-khadas-vim"
+CONFIG_DEBUG_UART=y
+CONFIG_ENV_IS_NOWHERE=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_OF_CONTROL=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_MESON_GX=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_PHY_MESON_GXL=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_MESON_GXL=y
+CONFIG_DEBUG_UART_MESON=y
+CONFIG_DEBUG_UART_BASE=0xc81004c0
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_MESON_SERIAL=y
+CONFIG_OF_LIBFDT_OVERLAY=y
--- /dev/null
+CONFIG_ARM=y
+CONFIG_ARCH_MESON=y
+CONFIG_MESON_GXL=y
+CONFIG_TARGET_LIBRETECH_CC=y
+CONFIG_IDENT_STRING=" libretech-cc"
+CONFIG_DEFAULT_DEVICE_TREE="meson-gxl-s905x-libretech-cc"
+CONFIG_DEBUG_UART=y
+CONFIG_ENV_IS_NOWHERE=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_OF_CONTROL=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_MESON_GX=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_PHY_MESON_GXL=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_MESON_GXL=y
+CONFIG_DEBUG_UART_MESON=y
+CONFIG_DEBUG_UART_BASE=0xc81004c0
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_MESON_SERIAL=y
+CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_CMD_MMC=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_OF_CONTROL=y
+CONFIG_OF_BOARD_SETUP=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_MPUCLK=720
CONFIG_TARGET_OMAP3_EVM=y
CONFIG_DISTRO_DEFAULTS=y
-# CONFIG_USE_BOOTCOMMAND is not set
CONFIG_BOOTDELAY=3
+CONFIG_USE_BOOTCOMMAND=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_DEFAULT_FDT_FILE="omap3-evm.dtb"
CONFIG_VERSION_VARIABLE=y
CONFIG_CMD_GPIO=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_OF_CONTROL=y
+CONFIG_OF_BOARD_SETUP=y
CONFIG_DM_GPIO=y
CONFIG_DM_MMC=y
CONFIG_MMC_MESON_GX=y
--- /dev/null
+CONFIG_ARM=y
+CONFIG_ARCH_BCM283X=y
+CONFIG_TARGET_RPI_0_W=y
+CONFIG_DEFAULT_DEVICE_TREE="bcm2835-rpi-zero-w"
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_OF_BOARD_SETUP=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_SYS_PROMPT="U-Boot> "
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_DM_ETH=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_DM_VIDEO=y
+CONFIG_SYS_WHITE_ON_BLACK=y
+CONFIG_CONSOLE_SCROLL_LINES=10
+CONFIG_PHYS_TO_BUS=y
+CONFIG_OF_LIBFDT_OVERLAY=y
If present (and SPL is controlled by the device-tree), this allows
to override the CONFIG_SYS_SPI_U_BOOT_OFFS setting using a value
from the device-tree.
+
+sysreset-gpio
+ If present (and supported by the specific board), indicates a
+ GPIO that can be set to trigger a system reset. It is assumed
+ that such a system reset will effect a complete platform reset,
+ being roughly equivalent to a power-on reset.
#
-# Copyright (c) 2016 Google, Inc
+# Copyright (c) 2017 Rockchip Electronics Co., Ltd
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3128) += clk_rk3128.o
obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK322X) += clk_rk322x.o
obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
--- /dev/null
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/cru_rk3128.h>
+#include <asm/arch/hardware.h>
+#include <bitfield.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rk3128-cru.h>
+#include <linux/log2.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+ VCO_MAX_HZ = 2400U * 1000000,
+ VCO_MIN_HZ = 600 * 1000000,
+ OUTPUT_MAX_HZ = 2400U * 1000000,
+ OUTPUT_MIN_HZ = 24 * 1000000,
+};
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
+ .refdiv = _refdiv,\
+ .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
+ .postdiv1 = _postdiv1, .postdiv2 = _postdiv2};
+
+/* use integer mode*/
+static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
+
+static int rkclk_set_pll(struct rk3128_cru *cru, enum rk_clk_id clk_id,
+ const struct pll_div *div)
+{
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3128_pll *pll = &cru->pll[pll_id];
+
+ /* All PLLs have same VCO and output frequency range restrictions. */
+ uint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000;
+ uint output_hz = vco_hz / div->postdiv1 / div->postdiv2;
+
+ debug("PLL at %p:fd=%d,rd=%d,pd1=%d,pd2=%d,vco=%uHz,output=%uHz\n",
+ pll, div->fbdiv, div->refdiv, div->postdiv1,
+ div->postdiv2, vco_hz, output_hz);
+ assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+ output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);
+
+ /* use integer mode */
+ rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
+ /* Power down */
+ rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT);
+
+ rk_clrsetreg(&pll->con0,
+ PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
+ (div->postdiv1 << PLL_POSTDIV1_SHIFT) | div->fbdiv);
+ rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
+ (div->postdiv2 << PLL_POSTDIV2_SHIFT |
+ div->refdiv << PLL_REFDIV_SHIFT));
+
+ /* Power Up */
+ rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT);
+
+ /* waiting for pll lock */
+ while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
+ udelay(1);
+
+ return 0;
+}
+
+static int pll_para_config(u32 freq_hz, struct pll_div *div)
+{
+ u32 ref_khz = OSC_HZ / 1000, refdiv, fbdiv = 0;
+ u32 postdiv1, postdiv2 = 1;
+ u32 fref_khz;
+ u32 diff_khz, best_diff_khz;
+ const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
+ const u32 max_postdiv1 = 7, max_postdiv2 = 7;
+ u32 vco_khz;
+ u32 freq_khz = freq_hz / 1000;
+
+ if (!freq_hz) {
+ printf("%s: the frequency can't be 0 Hz\n", __func__);
+ return -1;
+ }
+
+ postdiv1 = DIV_ROUND_UP(VCO_MIN_HZ / 1000, freq_khz);
+ if (postdiv1 > max_postdiv1) {
+ postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
+ postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
+ }
+
+ vco_khz = freq_khz * postdiv1 * postdiv2;
+
+ if (vco_khz < (VCO_MIN_HZ / 1000) || vco_khz > (VCO_MAX_HZ / 1000) ||
+ postdiv2 > max_postdiv2) {
+ printf("%s: Cannot find out a supported VCO for Freq (%uHz)\n",
+ __func__, freq_hz);
+ return -1;
+ }
+
+ div->postdiv1 = postdiv1;
+ div->postdiv2 = postdiv2;
+
+ best_diff_khz = vco_khz;
+ for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
+ fref_khz = ref_khz / refdiv;
+
+ fbdiv = vco_khz / fref_khz;
+ if ((fbdiv >= max_fbdiv) || (fbdiv <= min_fbdiv))
+ continue;
+ diff_khz = vco_khz - fbdiv * fref_khz;
+ if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
+ fbdiv++;
+ diff_khz = fref_khz - diff_khz;
+ }
+
+ if (diff_khz >= best_diff_khz)
+ continue;
+
+ best_diff_khz = diff_khz;
+ div->refdiv = refdiv;
+ div->fbdiv = fbdiv;
+ }
+
+ if (best_diff_khz > 4 * (1000)) {
+ printf("%s: Failed to match output frequency %u bestis %u Hz\n",
+ __func__, freq_hz,
+ best_diff_khz * 1000);
+ return -1;
+ }
+ return 0;
+}
+
+static void rkclk_init(struct rk3128_cru *cru)
+{
+ u32 aclk_div;
+ u32 hclk_div;
+ u32 pclk_div;
+
+ /* pll enter slow-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK | APLL_MODE_MASK,
+ GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
+ APLL_MODE_SLOW << APLL_MODE_SHIFT);
+
+ /* init pll */
+ rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);
+ rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
+
+ /*
+ * select apll as cpu/core clock pll source and
+ * set up dependent divisors for PERI and ACLK clocks.
+ * core hz : apll = 1:1
+ */
+ aclk_div = APLL_HZ / CORE_ACLK_HZ - 1;
+ assert((aclk_div + 1) * CORE_ACLK_HZ == APLL_HZ && aclk_div < 0x7);
+
+ pclk_div = APLL_HZ / CORE_PERI_HZ - 1;
+ assert((pclk_div + 1) * CORE_PERI_HZ == APLL_HZ && pclk_div < 0xf);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK,
+ CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
+ 0 << CORE_DIV_CON_SHIFT);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ CORE_ACLK_DIV_MASK | CORE_PERI_DIV_MASK,
+ aclk_div << CORE_ACLK_DIV_SHIFT |
+ pclk_div << CORE_PERI_DIV_SHIFT);
+
+ /*
+ * select gpll as pd_bus bus clock source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / BUS_ACLK_HZ - 1;
+ assert((aclk_div + 1) * BUS_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f);
+
+ pclk_div = BUS_ACLK_HZ / BUS_PCLK_HZ - 1;
+ assert((pclk_div + 1) * BUS_PCLK_HZ == BUS_ACLK_HZ && pclk_div <= 0x7);
+
+ hclk_div = BUS_ACLK_HZ / BUS_HCLK_HZ - 1;
+ assert((hclk_div + 1) * BUS_HCLK_HZ == BUS_ACLK_HZ && hclk_div <= 0x3);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ BUS_ACLK_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
+ BUS_ACLK_PLL_SEL_GPLL << BUS_ACLK_PLL_SEL_SHIFT |
+ aclk_div << BUS_ACLK_DIV_SHIFT);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ BUS_PCLK_DIV_MASK | BUS_HCLK_DIV_MASK,
+ pclk_div << BUS_PCLK_DIV_SHIFT |
+ hclk_div << BUS_HCLK_DIV_SHIFT);
+
+ /*
+ * select gpll as pd_peri bus clock source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
+ assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+ hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+ assert((1 << hclk_div) * PERI_HCLK_HZ ==
+ PERI_ACLK_HZ && (hclk_div < 0x4));
+
+ pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+ assert((1 << pclk_div) * PERI_PCLK_HZ ==
+ PERI_ACLK_HZ && pclk_div < 0x8);
+
+ rk_clrsetreg(&cru->cru_clksel_con[10],
+ PERI_PLL_SEL_MASK | PERI_PCLK_DIV_MASK |
+ PERI_HCLK_DIV_MASK | PERI_ACLK_DIV_MASK,
+ PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
+ pclk_div << PERI_PCLK_DIV_SHIFT |
+ hclk_div << PERI_HCLK_DIV_SHIFT |
+ aclk_div << PERI_ACLK_DIV_SHIFT);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK | APLL_MODE_MASK | CPLL_MODE_MASK,
+ GPLL_MODE_NORM << GPLL_MODE_SHIFT |
+ APLL_MODE_NORM << APLL_MODE_SHIFT |
+ CPLL_MODE_NORM << CPLL_MODE_SHIFT);
+
+ /*fix NAND controller working clock max to 150Mhz */
+ rk_clrsetreg(&cru->cru_clksel_con[2],
+ NANDC_PLL_SEL_MASK | NANDC_CLK_DIV_MASK,
+ NANDC_PLL_SEL_GPLL << NANDC_PLL_SEL_SHIFT |
+ 3 << NANDC_CLK_DIV_SHIFT);
+}
+
+/* Get pll rate by id */
+static u32 rkclk_pll_get_rate(struct rk3128_cru *cru,
+ enum rk_clk_id clk_id)
+{
+ u32 refdiv, fbdiv, postdiv1, postdiv2;
+ u32 con;
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3128_pll *pll = &cru->pll[pll_id];
+ static u8 clk_shift[CLK_COUNT] = {
+ 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
+ GPLL_MODE_SHIFT, 0xff
+ };
+ static u32 clk_mask[CLK_COUNT] = {
+ 0xff, APLL_MODE_MASK, DPLL_MODE_MASK, CPLL_MODE_MASK,
+ GPLL_MODE_MASK, 0xff
+ };
+ uint shift;
+ uint mask;
+
+ con = readl(&cru->cru_mode_con);
+ shift = clk_shift[clk_id];
+ mask = clk_mask[clk_id];
+
+ switch ((con & mask) >> shift) {
+ case GPLL_MODE_SLOW:
+ return OSC_HZ;
+ case GPLL_MODE_NORM:
+ /* normal mode */
+ con = readl(&pll->con0);
+ postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
+ fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
+ con = readl(&pll->con1);
+ postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
+ refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
+ return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+ case GPLL_MODE_DEEP:
+ default:
+ return 32768;
+ }
+}
+
+static ulong rockchip_mmc_get_clk(struct rk3128_cru *cru, uint clk_general_rate,
+ int periph)
+{
+ uint src_rate;
+ uint div, mux;
+ u32 con;
+
+ switch (periph) {
+ case HCLK_EMMC:
+ case SCLK_EMMC:
+ case SCLK_EMMC_SAMPLE:
+ con = readl(&cru->cru_clksel_con[12]);
+ mux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT;
+ div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
+ break;
+ case HCLK_SDMMC:
+ case SCLK_SDMMC:
+ con = readl(&cru->cru_clksel_con[11]);
+ mux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT;
+ div = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ src_rate = mux == EMMC_SEL_24M ? OSC_HZ : clk_general_rate;
+ return DIV_TO_RATE(src_rate, div);
+}
+
+static ulong rockchip_mmc_set_clk(struct rk3128_cru *cru, uint clk_general_rate,
+ int periph, uint freq)
+{
+ int src_clk_div;
+ int mux;
+
+ debug("%s: clk_general_rate=%u\n", __func__, clk_general_rate);
+
+ /* mmc clock defaulg div 2 internal, need provide double in cru */
+ src_clk_div = DIV_ROUND_UP(clk_general_rate / 2, freq);
+
+ if (src_clk_div > 128) {
+ src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, freq);
+ mux = EMMC_SEL_24M;
+ } else {
+ mux = EMMC_SEL_GPLL;
+ }
+
+ switch (periph) {
+ case HCLK_EMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ EMMC_PLL_MASK | EMMC_DIV_MASK,
+ mux << EMMC_PLL_SHIFT |
+ (src_clk_div - 1) << EMMC_DIV_SHIFT);
+ break;
+ case HCLK_SDMMC:
+ case SCLK_SDMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[11],
+ MMC0_PLL_MASK | MMC0_DIV_MASK,
+ mux << MMC0_PLL_SHIFT |
+ (src_clk_div - 1) << MMC0_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rockchip_mmc_get_clk(cru, clk_general_rate, periph);
+}
+
+static ulong rk3128_peri_get_pclk(struct rk3128_cru *cru, ulong clk_id)
+{
+ u32 div, con;
+
+ switch (clk_id) {
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_PWM:
+ con = readl(&cru->cru_clksel_con[10]);
+ div = con >> 12 & 0x3;
+ break;
+ default:
+ printf("do not support this peripheral bus\n");
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(PERI_ACLK_HZ, div);
+}
+
+static ulong rk3128_peri_set_pclk(struct rk3128_cru *cru, ulong clk_id, uint hz)
+{
+ int src_clk_div;
+
+ src_clk_div = PERI_ACLK_HZ / hz;
+ assert(src_clk_div - 1 < 4);
+
+ switch (clk_id) {
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_PWM:
+ rk_setreg(&cru->cru_clksel_con[10],
+ ((src_clk_div - 1) << 12));
+ break;
+ default:
+ printf("do not support this peripheral bus\n");
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(PERI_ACLK_HZ, src_clk_div);
+}
+
+static ulong rk3128_saradc_get_clk(struct rk3128_cru *cru)
+{
+ u32 div, val;
+
+ val = readl(&cru->cru_clksel_con[24]);
+ div = bitfield_extract(val, SARADC_DIV_CON_SHIFT,
+ SARADC_DIV_CON_WIDTH);
+
+ return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rk3128_saradc_set_clk(struct rk3128_cru *cru, uint hz)
+{
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
+ assert(src_clk_div < 128);
+
+ rk_clrsetreg(&cru->cru_clksel_con[24],
+ SARADC_DIV_CON_MASK,
+ src_clk_div << SARADC_DIV_CON_SHIFT);
+
+ return rk3128_saradc_get_clk(cru);
+}
+
+static ulong rk3128_vop_set_clk(struct rk3128_cru *cru, ulong clk_id, uint hz)
+{
+ int src_clk_div;
+ struct pll_div cpll_config = {0};
+
+ src_clk_div = GPLL_HZ / hz;
+ assert(src_clk_div - 1 < 31);
+
+ switch (clk_id) {
+ case ACLK_VIO0:
+ rk_clrsetreg(&cru->cru_clksel_con[31],
+ VIO0_PLL_MASK | VIO0_DIV_MASK,
+ VIO0_SEL_GPLL << VIO0_PLL_SHIFT |
+ (src_clk_div - 1) << VIO0_DIV_SHIFT);
+ break;
+ case ACLK_VIO1:
+ rk_clrsetreg(&cru->cru_clksel_con[31],
+ VIO1_PLL_MASK | VIO1_DIV_MASK,
+ VIO1_SEL_GPLL << VIO1_PLL_SHIFT |
+ (src_clk_div - 1) << VIO1_DIV_SHIFT);
+ break;
+ case DCLK_LCDC:
+ if (pll_para_config(hz, &cpll_config))
+ return -1;
+ rkclk_set_pll(cru, CLK_CODEC, &cpll_config);
+
+ rk_clrsetreg(&cru->cru_clksel_con[27],
+ DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_CON_MASK,
+ DCLK_VOP_PLL_SEL_CPLL << DCLK_VOP_SEL_SHIFT |
+ (1 - 1) << DCLK_VOP_DIV_CON_SHIFT);
+ break;
+ default:
+ printf("do not support this vop freq\n");
+ return -EINVAL;
+ }
+
+ return hz;
+}
+
+static ulong rk3128_vop_get_rate(struct rk3128_cru *cru, ulong clk_id)
+{
+ u32 div, con, parent;
+
+ switch (clk_id) {
+ case ACLK_VIO0:
+ con = readl(&cru->cru_clksel_con[31]);
+ div = con & 0x1f;
+ parent = GPLL_HZ;
+ break;
+ case ACLK_VIO1:
+ con = readl(&cru->cru_clksel_con[31]);
+ div = (con >> 8) & 0x1f;
+ parent = GPLL_HZ;
+ break;
+ case DCLK_LCDC:
+ con = readl(&cru->cru_clksel_con[27]);
+ div = (con >> 8) & 0xfff;
+ parent = rkclk_pll_get_rate(cru, CLK_CODEC);
+ break;
+ default:
+ return -ENOENT;
+ }
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rk3128_clk_get_rate(struct clk *clk)
+{
+ struct rk3128_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case 0 ... 63:
+ return rkclk_pll_get_rate(priv->cru, clk->id);
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_PWM:
+ return rk3128_peri_get_pclk(priv->cru, clk->id);
+ case SCLK_SARADC:
+ return rk3128_saradc_get_clk(priv->cru);
+ case DCLK_LCDC:
+ case ACLK_VIO0:
+ case ACLK_VIO1:
+ return rk3128_vop_get_rate(priv->cru, clk->id);
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rk3128_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rk3128_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong new_rate, gclk_rate;
+
+ gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
+ switch (clk->id) {
+ case 0 ... 63:
+ return 0;
+ case DCLK_LCDC:
+ case ACLK_VIO0:
+ case ACLK_VIO1:
+ new_rate = rk3128_vop_set_clk(priv->cru,
+ clk->id, rate);
+ break;
+ case HCLK_EMMC:
+ new_rate = rockchip_mmc_set_clk(priv->cru, gclk_rate,
+ clk->id, rate);
+ break;
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_PWM:
+ new_rate = rk3128_peri_set_pclk(priv->cru, clk->id, rate);
+ break;
+ case SCLK_SARADC:
+ new_rate = rk3128_saradc_set_clk(priv->cru, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static struct clk_ops rk3128_clk_ops = {
+ .get_rate = rk3128_clk_get_rate,
+ .set_rate = rk3128_clk_set_rate,
+};
+
+static int rk3128_clk_probe(struct udevice *dev)
+{
+ struct rk3128_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = (struct rk3128_cru *)dev_read_addr(dev);
+ rkclk_init(priv->cru);
+
+ return 0;
+}
+
+static int rk3128_clk_bind(struct udevice *dev)
+{
+ int ret;
+ struct udevice *sys_child;
+ struct sysreset_reg *priv;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
+ &sys_child);
+ if (ret) {
+ debug("Warning: No sysreset driver: ret=%d\n", ret);
+ } else {
+ priv = malloc(sizeof(struct sysreset_reg));
+ priv->glb_srst_fst_value = offsetof(struct rk3128_cru,
+ cru_glb_srst_fst_value);
+ priv->glb_srst_snd_value = offsetof(struct rk3128_cru,
+ cru_glb_srst_snd_value);
+ sys_child->priv = priv;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id rk3128_clk_ids[] = {
+ { .compatible = "rockchip,rk3128-cru" },
+ { .compatible = "rockchip,rk3126-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rk3128_cru) = {
+ .name = "clk_rk3128",
+ .id = UCLASS_CLK,
+ .of_match = rk3128_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3128_clk_priv),
+ .ops = &rk3128_clk_ops,
+ .bind = rk3128_clk_bind,
+ .probe = rk3128_clk_probe,
+};
#include <libfdt.h>
#include <linux/arm-smccc.h>
#include <linux/errno.h>
+#include <linux/printk.h>
#include <linux/psci.h>
psci_fn *invoke_psci_fn;
ret = device_bind_driver(dev, "psci-sysreset", "psci-sysreset",
NULL);
if (ret)
- debug("PSCI System Reset was not bound.\n");
+ pr_debug("PSCI System Reset was not bound.\n");
}
return 0;
method = fdt_stringlist_get(gd->fdt_blob, dev_of_offset(dev), "method",
0, NULL);
if (!method) {
- printf("missing \"method\" property\n");
+ pr_warn("missing \"method\" property\n");
return -ENXIO;
}
} else if (!strcmp("smc", method)) {
invoke_psci_fn = __invoke_psci_fn_smc;
} else {
- printf("invalid \"method\" property: %s\n", method);
+ pr_warn("invalid \"method\" property: %s\n", method);
return -EINVAL;
}
{
ushort bankId = 0;
uchar manuId;
- uchar lsbits;
+ uchar feature;
flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
flash_unlock_seq(info, 0);
}
info->manufacturer_id = manuId;
- lsbits = flash_read_uchar(info, FLASH_OFFSET_LOWER_SW_BITS);
- info->sr_supported = lsbits & BIT(0);
+ debug("info->ext_addr = 0x%x, cfi_version = 0x%x\n",
+ info->ext_addr, info->cfi_version);
+ if (info->ext_addr && info->cfi_version >= 0x3134) {
+ /* read software feature (at 0x53) */
+ feature = flash_read_uchar(info, info->ext_addr + 0x13);
+ debug("feature = 0x%x\n", feature);
+ info->sr_supported = feature & 0x1;
+ }
switch (info->chipwidth){
case FLASH_CFI_8BIT:
#include <asm/io.h>
#include <linux/errno.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/arch/hardware.h>
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <common.h>
-#include <malloc.h>
-#include <nand.h>
#include <dm.h>
+#include <nand.h>
#include <linux/bitfield.h>
#include <linux/dma-direction.h>
#include <linux/errno.h>
#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
#include "denali.h"
return irq_status & INTR__ERASE_COMP ? 0 : NAND_STATUS_FAIL;
}
-static int __maybe_unused denali_setup_data_interface(struct mtd_info *mtd, int chipnr,
+static int denali_setup_data_interface(struct mtd_info *mtd, int chipnr,
const struct nand_data_interface *conf)
{
struct denali_nand_info *denali = mtd_to_denali(mtd);
return ret;
}
-
-#ifndef CONFIG_NAND_DENALI_DT
-static int __board_nand_init(void)
-{
- struct denali_nand_info *denali;
-
- denali = kzalloc(sizeof(*denali), GFP_KERNEL);
- if (!denali)
- return -ENOMEM;
-
- /*
- * In the future, these base addresses should be taken from
- * Device Tree or platform data.
- */
- denali->reg = (void __iomem *)CONFIG_SYS_NAND_REGS_BASE;
- denali->host = (void __iomem *)CONFIG_SYS_NAND_DATA_BASE;
-
- return denali_init(denali);
-}
-
-void board_nand_init(void)
-{
- if (__board_nand_init() < 0)
- pr_warn("Failed to initialize Denali NAND controller.\n");
-}
-#endif
#define __DENALI_H__
#include <linux/bitops.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/types.h>
#define DEVICE_RESET 0x0
* SPDX-License-Identifier: GPL-2.0+
*/
-#include <common.h>
#include <clk.h>
#include <dm.h>
#include <linux/io.h>
#include <linux/ioport.h>
+#include <linux/printk.h>
#include "denali.h"
DM_GET_DRIVER(denali_nand_dt),
&dev);
if (ret && ret != -ENODEV)
- printf("Failed to initialize Denali NAND controller. (error %d)\n",
+ pr_err("Failed to initialize Denali NAND controller. (error %d)\n",
ret);
}
#include <common.h>
#include <asm/io.h>
#include <asm/unaligned.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include "denali.h"
#define DENALI_MAP01 (1 << 26) /* read/write pages in PIO */
#include <nand.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/io.h>
#include <nand.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/io.h>
#include <common.h>
#include <asm/io.h>
#include <fsl_ifc.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#ifdef CONFIG_CHAIN_OF_TRUST
#include <fsl_validate.h>
#endif
#include <common.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/types.h>
#include <malloc.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/compat.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/nand_bch.h>
#ifdef CONFIG_MTD_PARTITIONS
#include <linux/compat.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/bbm.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/bitops.h>
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/mtd/nand_bch.h>
#include <linux/bch.h>
#include <malloc.h>
*
*/
#include <common.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/sizes.h>
#define LP_OPTIONS NAND_SAMSUNG_LP_OPTIONS
*/
#include <common.h>
#include <linux/kernel.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
static const struct nand_data_interface onfi_sdr_timings[] = {
/* Mode 0 */
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/types.h>
#include "pxa3xx_nand.h"
#include <linux/kernel.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>
#include <malloc.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <nand.h>
#include <linux/errno.h>
#include <nand.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/arch/hardware.h>
the GPIO definitions and pin control functions for each available
multiplex function.
+config PINCTRL_ROCKCHIP_RK3128
+ bool "Rockchip rk3128 pin control driver"
+ depends on DM
+ help
+ Support pin multiplexing control on Rockchip rk3128 SoCs.
+
+ The driver is controlled by a device tree node which contains both
+ the GPIO definitions and pin control functions for each available
+ multiplex function.
+
config PINCTRL_ROCKCHIP_RK3188
bool "Rockchip rk3188 pin control driver"
depends on DM
#
-# Copyright (c) 2015 Google, Inc
-# Written by Simon Glass <sjg@chromium.org>
+# Copyright (c) 2017 Rockchip Electronics Co., Ltd
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3036) += pinctrl_rk3036.o
+obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3128) += pinctrl_rk3128.o
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3188) += pinctrl_rk3188.o
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK322X) += pinctrl_rk322x.o
obj-$(CONFIG_PINCTRL_ROCKCHIP_RK3288) += pinctrl_rk3288.o
--- /dev/null
+/*
+ * Pinctrl driver for Rockchip 3128 SoCs
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3128.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/periph.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct rk3128_pinctrl_priv {
+ struct rk3128_grf *grf;
+};
+
+static void pinctrl_rk3128_i2c_config(struct rk3128_grf *grf, int i2c_id)
+{
+ switch (i2c_id) {
+ case PERIPH_ID_I2C0:
+ rk_clrsetreg(&grf->gpio0a_iomux,
+ GPIO0A1_MASK | GPIO0A0_MASK,
+ GPIO0A1_I2C0_SDA << GPIO0A1_SHIFT |
+ GPIO0A0_I2C0_SCL << GPIO0A0_SHIFT);
+
+ break;
+ case PERIPH_ID_I2C1:
+ rk_clrsetreg(&grf->gpio0a_iomux,
+ GPIO0A3_MASK | GPIO0A2_MASK,
+ GPIO0A3_I2C1_SDA << GPIO0A3_SHIFT |
+ GPIO0A2_I2C1_SCL << GPIO0A2_SHIFT);
+ break;
+ case PERIPH_ID_I2C2:
+ rk_clrsetreg(&grf->gpio2c_iomux2,
+ GPIO2C5_MASK | GPIO2C4_MASK,
+ GPIO2C5_I2C2_SCL << GPIO2C5_SHIFT |
+ GPIO2C4_I2C2_SDA << GPIO2C4_SHIFT);
+ break;
+ case PERIPH_ID_I2C3:
+ rk_clrsetreg(&grf->gpio0a_iomux,
+ GPIO0A7_MASK | GPIO0A6_MASK,
+ GPIO0A7_I2C3_SDA << GPIO0A7_SHIFT |
+ GPIO0A6_I2C3_SCL << GPIO0A6_SHIFT);
+
+ break;
+ }
+}
+
+static void pinctrl_rk3128_sdmmc_config(struct rk3128_grf *grf, int mmc_id)
+{
+ switch (mmc_id) {
+ case PERIPH_ID_EMMC:
+ rk_clrsetreg(&grf->gpio1d_iomux, 0xffff,
+ GPIO1D7_EMMC_D7 << GPIO1D7_SHIFT |
+ GPIO1D6_EMMC_D6 << GPIO1D6_SHIFT |
+ GPIO1D5_EMMC_D5 << GPIO1D5_SHIFT |
+ GPIO1D4_EMMC_D4 << GPIO1D4_SHIFT |
+ GPIO1D3_EMMC_D3 << GPIO1D3_SHIFT |
+ GPIO1D2_EMMC_D2 << GPIO1D2_SHIFT |
+ GPIO1D1_EMMC_D1 << GPIO1D1_SHIFT |
+ GPIO1D0_EMMC_D0 << GPIO1D0_SHIFT);
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A5_MASK | GPIO2A7_MASK,
+ GPIO2A5_EMMC_PWREN << GPIO2A5_SHIFT |
+ GPIO2A7_EMMC_CLKOUT << GPIO2A7_SHIFT);
+ break;
+ case PERIPH_ID_SDCARD:
+ rk_clrsetreg(&grf->gpio1c_iomux, 0x0fff,
+ GPIO1C5_MMC0_D3 << GPIO1C5_SHIFT |
+ GPIO1C4_MMC0_D2 << GPIO1C4_SHIFT |
+ GPIO1C3_MMC0_D1 << GPIO1C3_SHIFT |
+ GPIO1C2_MMC0_D0 << GPIO1C2_SHIFT |
+ GPIO1C1_MMC0_DETN << GPIO1C1_SHIFT |
+ GPIO1C0_MMC0_CLKOUT << GPIO1C0_SHIFT);
+ break;
+ }
+}
+
+static int rk3128_pinctrl_request(struct udevice *dev, int func, int flags)
+{
+ struct rk3128_pinctrl_priv *priv = dev_get_priv(dev);
+
+ debug("%s: func=%x, flags=%x\n", __func__, func, flags);
+ switch (func) {
+ case PERIPH_ID_I2C0:
+ case PERIPH_ID_I2C1:
+ case PERIPH_ID_I2C2:
+ case PERIPH_ID_I2C3:
+ pinctrl_rk3128_i2c_config(priv->grf, func);
+ break;
+ case PERIPH_ID_SDMMC0:
+ case PERIPH_ID_SDMMC1:
+ pinctrl_rk3128_sdmmc_config(priv->grf, func);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rk3128_pinctrl_get_periph_id(struct udevice *dev,
+ struct udevice *periph)
+{
+ u32 cell[3];
+ int ret;
+
+ ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
+ "interrupts", cell, ARRAY_SIZE(cell));
+ if (ret < 0)
+ return -EINVAL;
+
+ switch (cell[1]) {
+ case 14:
+ return PERIPH_ID_SDCARD;
+ case 16:
+ return PERIPH_ID_EMMC;
+ case 20:
+ return PERIPH_ID_UART0;
+ case 21:
+ return PERIPH_ID_UART1;
+ case 22:
+ return PERIPH_ID_UART2;
+ case 23:
+ return PERIPH_ID_SPI0;
+ case 24:
+ return PERIPH_ID_I2C0;
+ case 25:
+ return PERIPH_ID_I2C1;
+ case 26:
+ return PERIPH_ID_I2C2;
+ case 27:
+ return PERIPH_ID_I2C3;
+ case 30:
+ return PERIPH_ID_PWM0;
+ }
+ return -ENOENT;
+}
+
+static int rk3128_pinctrl_set_state_simple(struct udevice *dev,
+ struct udevice *periph)
+{
+ int func;
+
+ func = rk3128_pinctrl_get_periph_id(dev, periph);
+ if (func < 0)
+ return func;
+ return rk3128_pinctrl_request(dev, func, 0);
+}
+
+static struct pinctrl_ops rk3128_pinctrl_ops = {
+ .set_state_simple = rk3128_pinctrl_set_state_simple,
+ .request = rk3128_pinctrl_request,
+ .get_periph_id = rk3128_pinctrl_get_periph_id,
+};
+
+static int rk3128_pinctrl_probe(struct udevice *dev)
+{
+ struct rk3128_pinctrl_priv *priv = dev_get_priv(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ debug("%s: grf=%p\n", __func__, priv->grf);
+ return 0;
+}
+
+static const struct udevice_id rk3128_pinctrl_ids[] = {
+ { .compatible = "rockchip,rk3128-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3128) = {
+ .name = "pinctrl_rk3128",
+ .id = UCLASS_PINCTRL,
+ .of_match = rk3128_pinctrl_ids,
+ .priv_auto_alloc_size = sizeof(struct rk3128_pinctrl_priv),
+ .ops = &rk3128_pinctrl_ops,
+ .bind = dm_scan_fdt_dev,
+ .probe = rk3128_pinctrl_probe,
+};
#
obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
+obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
--- /dev/null
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3128.h>
+#include <asm/arch/sdram_common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+struct dram_info {
+ struct ram_info info;
+ struct rk3128_grf *grf;
+};
+
+static int rk3128_dmc_probe(struct udevice *dev)
+{
+ struct dram_info *priv = dev_get_priv(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ debug("%s: grf=%p\n", __func__, priv->grf);
+ priv->info.base = CONFIG_SYS_SDRAM_BASE;
+ priv->info.size = rockchip_sdram_size(
+ (phys_addr_t)&priv->grf->os_reg[1]);
+
+ return 0;
+}
+
+static int rk3128_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+ struct dram_info *priv = dev_get_priv(dev);
+
+ *info = priv->info;
+
+ return 0;
+}
+
+static struct ram_ops rk3128_dmc_ops = {
+ .get_info = rk3128_dmc_get_info,
+};
+
+static const struct udevice_id rk3128_dmc_ids[] = {
+ { .compatible = "rockchip,rk3128-dmc" },
+ { }
+};
+
+U_BOOT_DRIVER(dmc_rk3128) = {
+ .name = "rockchip_rk3128_dmc",
+ .id = UCLASS_RAM,
+ .of_match = rk3128_dmc_ids,
+ .ops = &rk3128_dmc_ops,
+ .probe = rk3128_dmc_probe,
+ .priv_auto_alloc_size = sizeof(struct dram_info),
+};
#include <linux/mtd/mtd.h>
#include <linux/types.h>
#include <linux/time.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
static inline void translate_spare2oob(const struct yaffs_spare *spare, u8 *oob)
--- /dev/null
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __EVB_RK3128_H
+#define __EVB_RK3128_H
+
+#include <configs/rk3128_common.h>
+
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV 0
+
+#endif
--- /dev/null
+/*
+ * Configuration for Khadas VIM
+ *
+ * Copyright (C) 2017 Baylibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_MISC_INIT_R
+
+#define CONFIG_PHY_ADDR 8
+
+#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-khadas-vim.dtb\0"
+
+#include <configs/meson-gxbb-common.h>
+
+#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * Configuration for LibreTech CC
+ *
+ * Copyright (C) 2017 Baylibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_MISC_INIT_R
+
+#define CONFIG_PHY_ADDR 8
+
+#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-libretech-cc.dtb\0"
+
+#include <configs/meson-gxbb-common.h>
+
+#endif /* __CONFIG_H */
#define CONFIG_CPU_ARMV8
#define CONFIG_REMAKE_ELF
-#define CONFIG_NR_DRAM_BANKS 2
+#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_ENV_SIZE 0x2000
#define CONFIG_SYS_MAXARGS 32
#define CONFIG_SYS_MALLOC_LEN (32 << 20)
/* Environment */
#define CONFIG_PREBOOT "usb start"
+#if !defined(CONFIG_SPL_BUILD)
+
+#include <config_distro_defaults.h>
+
+#define MEM_LAYOUT_ENV_SETTINGS \
+ DEFAULT_LINUX_BOOT_ENV
+
+#if defined(CONFIG_NAND)
+#define BOOTENV_DEV_NAND(devtypeu, devtypel, instance) \
+ "bootcmd_" #devtypel #instance "=" \
+ "run nandboot\0"
+
+#define BOOTENV_DEV_NAME_NAND(devtypeu, devtypel, instance) \
+ #devtypel #instance " "
+#endif /* CONFIG_NAND */
+
+#define BOOTENV_DEV_UIMAGE_MMC(devtypeu, devtypel, instance) \
+ "bootcmd_" #devtypel #instance "=" \
+ "setenv mmcdev " #instance"; " \
+ "run mmcboot\0"
+
+#define BOOTENV_DEV_NAME_UIMAGE_MMC(devtypeu, devtypel, instance) \
+ #devtypel #instance " "
+
+#define BOOTENV_DEV_ZIMAGE_MMC(devtypeu, devtypel, instance) \
+ "bootcmd_" #devtypel #instance "=" \
+ "setenv mmcdev " #instance"; " \
+ "run mmcbootz\0"
+
+#define BOOTENV_DEV_NAME_ZIMAGE_MMC(devtypeu, devtypel, instance) \
+ #devtypel #instance " "
+
+#define BOOT_TARGET_DEVICES(func) \
+ func(MMC, mmc, 0) \
+ func(ZIMAGE_MMC, zimage_mmc, 0) \
+ func(UIMAGE_MMC, uimage_mmc, 0) \
+ func(NAND, nand, 0)
+
+#include <config_distro_bootcmd.h>
+
#define CONFIG_EXTRA_ENV_SETTINGS \
- DEFAULT_LINUX_BOOT_ENV \
+ MEM_LAYOUT_ENV_SETTINGS \
+ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
"mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \
"mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \
"bootenv=uEnv.txt\0" \
"loadbootenv=fatload mmc ${mmcdev} ${loadaddr} ${bootenv}\0" \
"importbootenv=echo Importing environment from mmc ...; " \
"env import -t ${loadaddr} ${filesize}\0" \
- "bootscript=echo Running bootscript from mmc ...; " \
- "source ${loadaddr}\0" \
+ "mmcbootenv=" \
+ "mmc dev ${mmcdev}; " \
+ "if mmc rescan && run loadbootenv; then " \
+ "run importbootenv; " \
+ "if test -n $uenvcmd; then " \
+ "echo Running uenvcmd ...; " \
+ "run uenvcmd; " \
+ "fi; " \
+ "fi\0" \
"loaduimage=setenv bootfile uImage; " \
"fatload mmc ${mmcdev} ${loadaddr} uImage\0" \
"loadzimage=setenv bootfile zImage; " \
"fatload mmc ${mmcdev} ${loadaddr} zImage\0" \
- "loaddtb=fatload mmc ${mmcdev} ${fdtaddr} " CONFIG_DEFAULT_FDT_FILE "\0" \
- "mmcboot=echo Booting ${bootfile} from mmc ...; " \
- "run mmcargs; " \
- "bootm ${loadaddr} - ${fdtaddr}\0" \
- "mmcbootz=echo Booting ${bootfile} from mmc ...; " \
- "run mmcargs; " \
- "bootz ${loadaddr} - ${fdtaddr}\0" \
+ "loaddtb=fatload mmc ${mmcdev} ${fdtaddr} ${fdtfile}\0" \
+ "mmcboot=run mmcbootenv; " \
+ "if run loaduimage && run loaddtb; then " \
+ "echo Booting ${bootfile} from mmc ...; " \
+ "run mmcargs; " \
+ "bootm ${loadaddr} - ${fdtaddr}; " \
+ "fi\0" \
+ "mmcbootz=run mmcbootenv; " \
+ "if run loadzimage && run loaddtb; then " \
+ "echo Booting ${bootfile} from mmc ...; " \
+ "run mmcargs; " \
+ "bootz ${loadaddr} - ${fdtaddr};" \
+ "fi\0" \
"nandboot=echo Booting uImage from nand ...; " \
"run nandargs; " \
"nand read ${loadaddr} kernel; " \
"nand read ${fdtaddr} dtb; " \
- "bootm ${loadaddr} - ${fdtaddr}\0"
+ "bootm ${loadaddr} - ${fdtaddr}\0" \
+ BOOTENV
-#define CONFIG_BOOTCOMMAND \
- "mmc dev ${mmcdev}; if mmc rescan; then " \
- "if run loadbootenv; then " \
- "run importbootenv; " \
- "if test -n $uenvcmd; then " \
- "echo Running uenvcmd ...; " \
- "run uenvcmd; " \
- "fi; " \
- "else " \
- "if run loadzimage && run loaddtb; then " \
- "run mmcbootz; fi; " \
- "if run loaduimage && run loaddtb; then " \
- "run mmcboot; fi; " \
- "run nandboot; " \
- "fi; " \
- "else run nandboot; fi"
+#endif /* !CONFIG_SPL_BUILD */
#endif /* __CONFIG_H */
--- /dev/null
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_RK3128_COMMON_H
+#define __CONFIG_RK3128_COMMON_H
+
+#include "rockchip-common.h"
+
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_MALLOC_LEN (32 << 20)
+#define CONFIG_SYS_CBSIZE 1024
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+#define CONFIG_SYS_TIMER_RATE (24 * 1000 * 1000)
+#define CONFIG_SYS_TIMER_BASE 0x200440a0 /* TIMER5 */
+#define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_BASE + 8)
+
+#define CONFIG_SYS_NS16550_MEM32
+
+#define CONFIG_SYS_TEXT_BASE 0x60000000
+#define CONFIG_SYS_INIT_SP_ADDR 0x60100000
+#define CONFIG_SYS_LOAD_ADDR 0x60800800
+
+#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* 64M */
+
+/* MMC/SD IP block */
+#define CONFIG_BOUNCE_BUFFER
+
+#define CONFIG_SUPPORT_VFAT
+#define CONFIG_FS_EXT4
+
+/* RAW SD card / eMMC locations. */
+#define CONFIG_SYS_SPI_U_BOOT_OFFS (128 << 10)
+
+#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
+#define CONFIG_SYS_SDRAM_BASE 0x60000000
+#define CONFIG_NR_DRAM_BANKS 2
+#define SDRAM_MAX_SIZE 0x80000000
+
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI
+#define CONFIG_SF_DEFAULT_SPEED 20000000
+#define CONFIG_USB_OHCI_NEW
+#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 1
+
+#ifndef CONFIG_SPL_BUILD
+
+/* usb mass storage */
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+ "scriptaddr=0x60500000\0" \
+ "pxefile_addr_r=0x60600000\0" \
+ "fdt_addr_r=0x61f00000\0" \
+ "kernel_addr_r=0x62000000\0" \
+ "ramdisk_addr_r=0x64000000\0"
+
+#include <config_distro_bootcmd.h>
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ ENV_MEM_LAYOUT_SETTINGS \
+ "partitions=" PARTS_DEFAULT \
+ BOOTENV
+
+#endif
+
+#endif
#endif
/* Console UART */
-#ifdef CONFIG_BCM2837
+#if defined (CONFIG_BCM2837) || defined(CONFIG_TARGET_RPI_0_W)
#define CONFIG_BCM283X_MU_SERIAL
#else
#define CONFIG_PL01X_SERIAL
--- /dev/null
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3128_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3128_H
+
+/* core clocks */
+#define PLL_APLL 1
+#define PLL_DPLL 2
+#define PLL_GPLL 3
+#define ARMCLK 4
+
+/* sclk gates (special clocks) */
+#define SCLK_GPU 64
+#define SCLK_SPI 65
+#define SCLK_SDMMC 68
+#define SCLK_SDIO 69
+#define SCLK_EMMC 71
+#define SCLK_NANDC 76
+#define SCLK_UART0 77
+#define SCLK_UART1 78
+#define SCLK_UART2 79
+#define SCLK_I2S 82
+#define SCLK_SPDIF 83
+#define SCLK_TIMER0 85
+#define SCLK_TIMER1 86
+#define SCLK_TIMER2 87
+#define SCLK_TIMER3 88
+#define SCLK_SARADC 91
+#define SCLK_OTGPHY0 93
+#define SCLK_LCDC 100
+#define SCLK_HDMI 109
+#define SCLK_HEVC 111
+#define SCLK_I2S_OUT 113
+#define SCLK_SDMMC_DRV 114
+#define SCLK_SDIO_DRV 115
+#define SCLK_EMMC_DRV 117
+#define SCLK_SDMMC_SAMPLE 118
+#define SCLK_SDIO_SAMPLE 119
+#define SCLK_EMMC_SAMPLE 121
+#define SCLK_PVTM_CORE 123
+#define SCLK_PVTM_GPU 124
+#define SCLK_PVTM_VIDEO 125
+#define SCLK_MAC 151
+#define SCLK_MACREF 152
+#define SCLK_SFC 160
+
+#define DCLK_LCDC 190
+
+/* aclk gates */
+#define ACLK_DMAC2 194
+#define ACLK_VIO0 197
+#define ACLK_VIO1 203
+#define ACLK_VCODEC 208
+#define ACLK_CPU 209
+#define ACLK_PERI 210
+
+/* pclk gates */
+#define PCLK_SARADC 318
+#define PCLK_GPIO0 320
+#define PCLK_GPIO1 321
+#define PCLK_GPIO2 322
+#define PCLK_GPIO3 323
+#define PCLK_GRF 329
+#define PCLK_I2C0 332
+#define PCLK_I2C1 333
+#define PCLK_I2C2 334
+#define PCLK_I2C3 335
+#define PCLK_SPI 338
+#define PCLK_UART0 341
+#define PCLK_UART1 342
+#define PCLK_UART2 343
+#define PCLK_PWM 350
+#define PCLK_TIMER 353
+#define PCLK_HDMI 360
+#define PCLK_CPU 362
+#define PCLK_PERI 363
+#define PCLK_DDRUPCTL 364
+#define PCLK_WDT 368
+
+/* hclk gates */
+#define HCLK_OTG0 449
+#define HCLK_OTG1 450
+#define HCLK_NANDC 453
+#define HCLK_SDMMC 456
+#define HCLK_SDIO 457
+#define HCLK_EMMC 459
+#define HCLK_I2S 462
+#define HCLK_LCDC 465
+#define HCLK_ROM 467
+#define HCLK_VIO_BUS 472
+#define HCLK_VCODEC 476
+#define HCLK_CPU 477
+#define HCLK_PERI 478
+
+#define CLK_NR_CLKS (HCLK_PERI + 1)
+
+/* soft-reset indices */
+#define SRST_CORE0 0
+#define SRST_CORE1 1
+#define SRST_CORE0_DBG 4
+#define SRST_CORE1_DBG 5
+#define SRST_CORE0_POR 8
+#define SRST_CORE1_POR 9
+#define SRST_L2C 12
+#define SRST_TOPDBG 13
+#define SRST_STRC_SYS_A 14
+#define SRST_PD_CORE_NIU 15
+
+#define SRST_TIMER2 16
+#define SRST_CPUSYS_H 17
+#define SRST_AHB2APB_H 19
+#define SRST_TIMER3 20
+#define SRST_INTMEM 21
+#define SRST_ROM 22
+#define SRST_PERI_NIU 23
+#define SRST_I2S 24
+#define SRST_DDR_PLL 25
+#define SRST_GPU_DLL 26
+#define SRST_TIMER0 27
+#define SRST_TIMER1 28
+#define SRST_CORE_DLL 29
+#define SRST_EFUSE_P 30
+#define SRST_ACODEC_P 31
+
+#define SRST_GPIO0 32
+#define SRST_GPIO1 33
+#define SRST_GPIO2 34
+#define SRST_UART0 39
+#define SRST_UART1 40
+#define SRST_UART2 41
+#define SRST_I2C0 43
+#define SRST_I2C1 44
+#define SRST_I2C2 45
+#define SRST_SFC 47
+
+#define SRST_PWM0 48
+#define SRST_DAP 51
+#define SRST_DAP_SYS 52
+#define SRST_GRF 55
+#define SRST_PERIPHSYS_A 57
+#define SRST_PERIPHSYS_H 58
+#define SRST_PERIPHSYS_P 59
+#define SRST_CPU_PERI 61
+#define SRST_EMEM_PERI 62
+#define SRST_USB_PERI 63
+
+#define SRST_DMA2 64
+#define SRST_MAC 66
+#define SRST_NANDC 68
+#define SRST_USBOTG0 69
+#define SRST_OTGC0 71
+#define SRST_USBOTG1 72
+#define SRST_OTGC1 74
+#define SRST_DDRMSCH 79
+
+#define SRST_MMC0 81
+#define SRST_SDIO 82
+#define SRST_EMMC 83
+#define SRST_SPI0 84
+#define SRST_WDT 86
+#define SRST_SARADC 87
+#define SRST_DDRPHY 88
+#define SRST_DDRPHY_P 89
+#define SRST_DDRCTRL 90
+#define SRST_DDRCTRL_P 91
+
+#define SRST_HDMI_P 96
+#define SRST_VIO_BUS_H 99
+#define SRST_UTMI0 103
+#define SRST_UTMI1 104
+#define SRST_USBPOR 105
+
+#define SRST_VCODEC_A 112
+#define SRST_VCODEC_H 113
+#define SRST_VIO1_A 114
+#define SRST_HEVC 115
+#define SRST_VCODEC_NIU_A 116
+#define SRST_LCDC1_A 117
+#define SRST_LCDC1_H 118
+#define SRST_LCDC1_D 119
+#define SRST_GPU 120
+#define SRST_GPU_NIU_A 122
+
+#define SRST_DBG_P 131
+
+#endif
#ifndef __LINUX_MTD_NAND_FSL_UPM
#define __LINUX_MTD_NAND_FSL_UPM
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
#define FSL_UPM_WAIT_RUN_PATTERN 0x1
#define FSL_UPM_WAIT_WRITE_BYTE 0x2
#ifndef __FSMC_NAND_H__
#define __FSMC_NAND_H__
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
struct fsmc_regs {
u32 ctrl; /* 0x00 */
+++ /dev/null
-/*
- * linux/include/linux/mtd/nand.h
- *
- * Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
- * Steven J. Hill <sjhill@realitydiluted.com>
- * Thomas Gleixner <tglx@linutronix.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * Info:
- * Contains standard defines and IDs for NAND flash devices
- *
- * Changelog:
- * See git changelog.
- */
-#ifndef __LINUX_MTD_NAND_H
-#define __LINUX_MTD_NAND_H
-
-#include <config.h>
-
-#include <linux/compat.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/flashchip.h>
-#include <linux/mtd/bbm.h>
-
-struct mtd_info;
-struct nand_flash_dev;
-struct device_node;
-
-/* Scan and identify a NAND device */
-int nand_scan(struct mtd_info *mtd, int max_chips);
-/*
- * Separate phases of nand_scan(), allowing board driver to intervene
- * and override command or ECC setup according to flash type.
- */
-int nand_scan_ident(struct mtd_info *mtd, int max_chips,
- struct nand_flash_dev *table);
-int nand_scan_tail(struct mtd_info *mtd);
-
-/* Free resources held by the NAND device */
-void nand_release(struct mtd_info *mtd);
-
-/* Internal helper for board drivers which need to override command function */
-void nand_wait_ready(struct mtd_info *mtd);
-
-/*
- * This constant declares the max. oobsize / page, which
- * is supported now. If you add a chip with bigger oobsize/page
- * adjust this accordingly.
- */
-#define NAND_MAX_OOBSIZE 1664
-#define NAND_MAX_PAGESIZE 16384
-
-/*
- * Constants for hardware specific CLE/ALE/NCE function
- *
- * These are bits which can be or'ed to set/clear multiple
- * bits in one go.
- */
-/* Select the chip by setting nCE to low */
-#define NAND_NCE 0x01
-/* Select the command latch by setting CLE to high */
-#define NAND_CLE 0x02
-/* Select the address latch by setting ALE to high */
-#define NAND_ALE 0x04
-
-#define NAND_CTRL_CLE (NAND_NCE | NAND_CLE)
-#define NAND_CTRL_ALE (NAND_NCE | NAND_ALE)
-#define NAND_CTRL_CHANGE 0x80
-
-/*
- * Standard NAND flash commands
- */
-#define NAND_CMD_READ0 0
-#define NAND_CMD_READ1 1
-#define NAND_CMD_RNDOUT 5
-#define NAND_CMD_PAGEPROG 0x10
-#define NAND_CMD_READOOB 0x50
-#define NAND_CMD_ERASE1 0x60
-#define NAND_CMD_STATUS 0x70
-#define NAND_CMD_SEQIN 0x80
-#define NAND_CMD_RNDIN 0x85
-#define NAND_CMD_READID 0x90
-#define NAND_CMD_ERASE2 0xd0
-#define NAND_CMD_PARAM 0xec
-#define NAND_CMD_GET_FEATURES 0xee
-#define NAND_CMD_SET_FEATURES 0xef
-#define NAND_CMD_RESET 0xff
-
-#define NAND_CMD_LOCK 0x2a
-#define NAND_CMD_UNLOCK1 0x23
-#define NAND_CMD_UNLOCK2 0x24
-
-/* Extended commands for large page devices */
-#define NAND_CMD_READSTART 0x30
-#define NAND_CMD_RNDOUTSTART 0xE0
-#define NAND_CMD_CACHEDPROG 0x15
-
-/* Extended commands for AG-AND device */
-/*
- * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but
- * there is no way to distinguish that from NAND_CMD_READ0
- * until the remaining sequence of commands has been completed
- * so add a high order bit and mask it off in the command.
- */
-#define NAND_CMD_DEPLETE1 0x100
-#define NAND_CMD_DEPLETE2 0x38
-#define NAND_CMD_STATUS_MULTI 0x71
-#define NAND_CMD_STATUS_ERROR 0x72
-/* multi-bank error status (banks 0-3) */
-#define NAND_CMD_STATUS_ERROR0 0x73
-#define NAND_CMD_STATUS_ERROR1 0x74
-#define NAND_CMD_STATUS_ERROR2 0x75
-#define NAND_CMD_STATUS_ERROR3 0x76
-#define NAND_CMD_STATUS_RESET 0x7f
-#define NAND_CMD_STATUS_CLEAR 0xff
-
-#define NAND_CMD_NONE -1
-
-/* Status bits */
-#define NAND_STATUS_FAIL 0x01
-#define NAND_STATUS_FAIL_N1 0x02
-#define NAND_STATUS_TRUE_READY 0x20
-#define NAND_STATUS_READY 0x40
-#define NAND_STATUS_WP 0x80
-
-#define NAND_DATA_IFACE_CHECK_ONLY -1
-
-/*
- * Constants for ECC_MODES
- */
-typedef enum {
- NAND_ECC_NONE,
- NAND_ECC_SOFT,
- NAND_ECC_HW,
- NAND_ECC_HW_SYNDROME,
- NAND_ECC_HW_OOB_FIRST,
- NAND_ECC_SOFT_BCH,
-} nand_ecc_modes_t;
-
-/*
- * Constants for Hardware ECC
- */
-/* Reset Hardware ECC for read */
-#define NAND_ECC_READ 0
-/* Reset Hardware ECC for write */
-#define NAND_ECC_WRITE 1
-/* Enable Hardware ECC before syndrome is read back from flash */
-#define NAND_ECC_READSYN 2
-
-/*
- * Enable generic NAND 'page erased' check. This check is only done when
- * ecc.correct() returns -EBADMSG.
- * Set this flag if your implementation does not fix bitflips in erased
- * pages and you want to rely on the default implementation.
- */
-#define NAND_ECC_GENERIC_ERASED_CHECK BIT(0)
-#define NAND_ECC_MAXIMIZE BIT(1)
-/*
- * If your controller already sends the required NAND commands when
- * reading or writing a page, then the framework is not supposed to
- * send READ0 and SEQIN/PAGEPROG respectively.
- */
-#define NAND_ECC_CUSTOM_PAGE_ACCESS BIT(2)
-
-/* Bit mask for flags passed to do_nand_read_ecc */
-#define NAND_GET_DEVICE 0x80
-
-
-/*
- * Option constants for bizarre disfunctionality and real
- * features.
- */
-/* Buswidth is 16 bit */
-#define NAND_BUSWIDTH_16 0x00000002
-/* Device supports partial programming without padding */
-#define NAND_NO_PADDING 0x00000004
-/* Chip has cache program function */
-#define NAND_CACHEPRG 0x00000008
-/* Chip has copy back function */
-#define NAND_COPYBACK 0x00000010
-/*
- * Chip requires ready check on read (for auto-incremented sequential read).
- * True only for small page devices; large page devices do not support
- * autoincrement.
- */
-#define NAND_NEED_READRDY 0x00000100
-
-/* Chip does not allow subpage writes */
-#define NAND_NO_SUBPAGE_WRITE 0x00000200
-
-/* Device is one of 'new' xD cards that expose fake nand command set */
-#define NAND_BROKEN_XD 0x00000400
-
-/* Device behaves just like nand, but is readonly */
-#define NAND_ROM 0x00000800
-
-/* Device supports subpage reads */
-#define NAND_SUBPAGE_READ 0x00001000
-
-/*
- * Some MLC NANDs need data scrambling to limit bitflips caused by repeated
- * patterns.
- */
-#define NAND_NEED_SCRAMBLING 0x00002000
-
-/* Device needs 3rd row address cycle */
-#define NAND_ROW_ADDR_3 0x00004000
-
-/* Options valid for Samsung large page devices */
-#define NAND_SAMSUNG_LP_OPTIONS NAND_CACHEPRG
-
-/* Macros to identify the above */
-#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
-#define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
-#define NAND_HAS_SUBPAGE_WRITE(chip) !((chip)->options & NAND_NO_SUBPAGE_WRITE)
-
-/* Non chip related options */
-/* This option skips the bbt scan during initialization. */
-#define NAND_SKIP_BBTSCAN 0x00010000
-/*
- * This option is defined if the board driver allocates its own buffers
- * (e.g. because it needs them DMA-coherent).
- */
-#define NAND_OWN_BUFFERS 0x00020000
-/* Chip may not exist, so silence any errors in scan */
-#define NAND_SCAN_SILENT_NODEV 0x00040000
-/*
- * Autodetect nand buswidth with readid/onfi.
- * This suppose the driver will configure the hardware in 8 bits mode
- * when calling nand_scan_ident, and update its configuration
- * before calling nand_scan_tail.
- */
-#define NAND_BUSWIDTH_AUTO 0x00080000
-/*
- * This option could be defined by controller drivers to protect against
- * kmap'ed, vmalloc'ed highmem buffers being passed from upper layers
- */
-#define NAND_USE_BOUNCE_BUFFER 0x00100000
-
-/* Options set by nand scan */
-/* bbt has already been read */
-#define NAND_BBT_SCANNED 0x40000000
-/* Nand scan has allocated controller struct */
-#define NAND_CONTROLLER_ALLOC 0x80000000
-
-/* Cell info constants */
-#define NAND_CI_CHIPNR_MSK 0x03
-#define NAND_CI_CELLTYPE_MSK 0x0C
-#define NAND_CI_CELLTYPE_SHIFT 2
-
-/* Keep gcc happy */
-struct nand_chip;
-
-/* ONFI features */
-#define ONFI_FEATURE_16_BIT_BUS (1 << 0)
-#define ONFI_FEATURE_EXT_PARAM_PAGE (1 << 7)
-
-/* ONFI timing mode, used in both asynchronous and synchronous mode */
-#define ONFI_TIMING_MODE_0 (1 << 0)
-#define ONFI_TIMING_MODE_1 (1 << 1)
-#define ONFI_TIMING_MODE_2 (1 << 2)
-#define ONFI_TIMING_MODE_3 (1 << 3)
-#define ONFI_TIMING_MODE_4 (1 << 4)
-#define ONFI_TIMING_MODE_5 (1 << 5)
-#define ONFI_TIMING_MODE_UNKNOWN (1 << 6)
-
-/* ONFI feature address */
-#define ONFI_FEATURE_ADDR_TIMING_MODE 0x1
-
-/* Vendor-specific feature address (Micron) */
-#define ONFI_FEATURE_ADDR_READ_RETRY 0x89
-
-/* ONFI subfeature parameters length */
-#define ONFI_SUBFEATURE_PARAM_LEN 4
-
-/* ONFI optional commands SET/GET FEATURES supported? */
-#define ONFI_OPT_CMD_SET_GET_FEATURES (1 << 2)
-
-struct nand_onfi_params {
- /* rev info and features block */
- /* 'O' 'N' 'F' 'I' */
- u8 sig[4];
- __le16 revision;
- __le16 features;
- __le16 opt_cmd;
- u8 reserved0[2];
- __le16 ext_param_page_length; /* since ONFI 2.1 */
- u8 num_of_param_pages; /* since ONFI 2.1 */
- u8 reserved1[17];
-
- /* manufacturer information block */
- char manufacturer[12];
- char model[20];
- u8 jedec_id;
- __le16 date_code;
- u8 reserved2[13];
-
- /* memory organization block */
- __le32 byte_per_page;
- __le16 spare_bytes_per_page;
- __le32 data_bytes_per_ppage;
- __le16 spare_bytes_per_ppage;
- __le32 pages_per_block;
- __le32 blocks_per_lun;
- u8 lun_count;
- u8 addr_cycles;
- u8 bits_per_cell;
- __le16 bb_per_lun;
- __le16 block_endurance;
- u8 guaranteed_good_blocks;
- __le16 guaranteed_block_endurance;
- u8 programs_per_page;
- u8 ppage_attr;
- u8 ecc_bits;
- u8 interleaved_bits;
- u8 interleaved_ops;
- u8 reserved3[13];
-
- /* electrical parameter block */
- u8 io_pin_capacitance_max;
- __le16 async_timing_mode;
- __le16 program_cache_timing_mode;
- __le16 t_prog;
- __le16 t_bers;
- __le16 t_r;
- __le16 t_ccs;
- __le16 src_sync_timing_mode;
- u8 src_ssync_features;
- __le16 clk_pin_capacitance_typ;
- __le16 io_pin_capacitance_typ;
- __le16 input_pin_capacitance_typ;
- u8 input_pin_capacitance_max;
- u8 driver_strength_support;
- __le16 t_int_r;
- __le16 t_adl;
- u8 reserved4[8];
-
- /* vendor */
- __le16 vendor_revision;
- u8 vendor[88];
-
- __le16 crc;
-} __packed;
-
-#define ONFI_CRC_BASE 0x4F4E
-
-/* Extended ECC information Block Definition (since ONFI 2.1) */
-struct onfi_ext_ecc_info {
- u8 ecc_bits;
- u8 codeword_size;
- __le16 bb_per_lun;
- __le16 block_endurance;
- u8 reserved[2];
-} __packed;
-
-#define ONFI_SECTION_TYPE_0 0 /* Unused section. */
-#define ONFI_SECTION_TYPE_1 1 /* for additional sections. */
-#define ONFI_SECTION_TYPE_2 2 /* for ECC information. */
-struct onfi_ext_section {
- u8 type;
- u8 length;
-} __packed;
-
-#define ONFI_EXT_SECTION_MAX 8
-
-/* Extended Parameter Page Definition (since ONFI 2.1) */
-struct onfi_ext_param_page {
- __le16 crc;
- u8 sig[4]; /* 'E' 'P' 'P' 'S' */
- u8 reserved0[10];
- struct onfi_ext_section sections[ONFI_EXT_SECTION_MAX];
-
- /*
- * The actual size of the Extended Parameter Page is in
- * @ext_param_page_length of nand_onfi_params{}.
- * The following are the variable length sections.
- * So we do not add any fields below. Please see the ONFI spec.
- */
-} __packed;
-
-struct nand_onfi_vendor_micron {
- u8 two_plane_read;
- u8 read_cache;
- u8 read_unique_id;
- u8 dq_imped;
- u8 dq_imped_num_settings;
- u8 dq_imped_feat_addr;
- u8 rb_pulldown_strength;
- u8 rb_pulldown_strength_feat_addr;
- u8 rb_pulldown_strength_num_settings;
- u8 otp_mode;
- u8 otp_page_start;
- u8 otp_data_prot_addr;
- u8 otp_num_pages;
- u8 otp_feat_addr;
- u8 read_retry_options;
- u8 reserved[72];
- u8 param_revision;
-} __packed;
-
-struct jedec_ecc_info {
- u8 ecc_bits;
- u8 codeword_size;
- __le16 bb_per_lun;
- __le16 block_endurance;
- u8 reserved[2];
-} __packed;
-
-/* JEDEC features */
-#define JEDEC_FEATURE_16_BIT_BUS (1 << 0)
-
-struct nand_jedec_params {
- /* rev info and features block */
- /* 'J' 'E' 'S' 'D' */
- u8 sig[4];
- __le16 revision;
- __le16 features;
- u8 opt_cmd[3];
- __le16 sec_cmd;
- u8 num_of_param_pages;
- u8 reserved0[18];
-
- /* manufacturer information block */
- char manufacturer[12];
- char model[20];
- u8 jedec_id[6];
- u8 reserved1[10];
-
- /* memory organization block */
- __le32 byte_per_page;
- __le16 spare_bytes_per_page;
- u8 reserved2[6];
- __le32 pages_per_block;
- __le32 blocks_per_lun;
- u8 lun_count;
- u8 addr_cycles;
- u8 bits_per_cell;
- u8 programs_per_page;
- u8 multi_plane_addr;
- u8 multi_plane_op_attr;
- u8 reserved3[38];
-
- /* electrical parameter block */
- __le16 async_sdr_speed_grade;
- __le16 toggle_ddr_speed_grade;
- __le16 sync_ddr_speed_grade;
- u8 async_sdr_features;
- u8 toggle_ddr_features;
- u8 sync_ddr_features;
- __le16 t_prog;
- __le16 t_bers;
- __le16 t_r;
- __le16 t_r_multi_plane;
- __le16 t_ccs;
- __le16 io_pin_capacitance_typ;
- __le16 input_pin_capacitance_typ;
- __le16 clk_pin_capacitance_typ;
- u8 driver_strength_support;
- __le16 t_adl;
- u8 reserved4[36];
-
- /* ECC and endurance block */
- u8 guaranteed_good_blocks;
- __le16 guaranteed_block_endurance;
- struct jedec_ecc_info ecc_info[4];
- u8 reserved5[29];
-
- /* reserved */
- u8 reserved6[148];
-
- /* vendor */
- __le16 vendor_rev_num;
- u8 reserved7[88];
-
- /* CRC for Parameter Page */
- __le16 crc;
-} __packed;
-
-/**
- * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices
- * @lock: protection lock
- * @active: the mtd device which holds the controller currently
- * @wq: wait queue to sleep on if a NAND operation is in
- * progress used instead of the per chip wait queue
- * when a hw controller is available.
- */
-struct nand_hw_control {
- spinlock_t lock;
- struct nand_chip *active;
-};
-
-/**
- * struct nand_ecc_step_info - ECC step information of ECC engine
- * @stepsize: data bytes per ECC step
- * @strengths: array of supported strengths
- * @nstrengths: number of supported strengths
- */
-struct nand_ecc_step_info {
- int stepsize;
- const int *strengths;
- int nstrengths;
-};
-
-/**
- * struct nand_ecc_caps - capability of ECC engine
- * @stepinfos: array of ECC step information
- * @nstepinfos: number of ECC step information
- * @calc_ecc_bytes: driver's hook to calculate ECC bytes per step
- */
-struct nand_ecc_caps {
- const struct nand_ecc_step_info *stepinfos;
- int nstepinfos;
- int (*calc_ecc_bytes)(int step_size, int strength);
-};
-
-/* a shorthand to generate struct nand_ecc_caps with only one ECC stepsize */
-#define NAND_ECC_CAPS_SINGLE(__name, __calc, __step, ...) \
-static const int __name##_strengths[] = { __VA_ARGS__ }; \
-static const struct nand_ecc_step_info __name##_stepinfo = { \
- .stepsize = __step, \
- .strengths = __name##_strengths, \
- .nstrengths = ARRAY_SIZE(__name##_strengths), \
-}; \
-static const struct nand_ecc_caps __name = { \
- .stepinfos = &__name##_stepinfo, \
- .nstepinfos = 1, \
- .calc_ecc_bytes = __calc, \
-}
-
-/**
- * struct nand_ecc_ctrl - Control structure for ECC
- * @mode: ECC mode
- * @steps: number of ECC steps per page
- * @size: data bytes per ECC step
- * @bytes: ECC bytes per step
- * @strength: max number of correctible bits per ECC step
- * @total: total number of ECC bytes per page
- * @prepad: padding information for syndrome based ECC generators
- * @postpad: padding information for syndrome based ECC generators
- * @options: ECC specific options (see NAND_ECC_XXX flags defined above)
- * @layout: ECC layout control struct pointer
- * @priv: pointer to private ECC control data
- * @hwctl: function to control hardware ECC generator. Must only
- * be provided if an hardware ECC is available
- * @calculate: function for ECC calculation or readback from ECC hardware
- * @correct: function for ECC correction, matching to ECC generator (sw/hw).
- * Should return a positive number representing the number of
- * corrected bitflips, -EBADMSG if the number of bitflips exceed
- * ECC strength, or any other error code if the error is not
- * directly related to correction.
- * If -EBADMSG is returned the input buffers should be left
- * untouched.
- * @read_page_raw: function to read a raw page without ECC. This function
- * should hide the specific layout used by the ECC
- * controller and always return contiguous in-band and
- * out-of-band data even if they're not stored
- * contiguously on the NAND chip (e.g.
- * NAND_ECC_HW_SYNDROME interleaves in-band and
- * out-of-band data).
- * @write_page_raw: function to write a raw page without ECC. This function
- * should hide the specific layout used by the ECC
- * controller and consider the passed data as contiguous
- * in-band and out-of-band data. ECC controller is
- * responsible for doing the appropriate transformations
- * to adapt to its specific layout (e.g.
- * NAND_ECC_HW_SYNDROME interleaves in-band and
- * out-of-band data).
- * @read_page: function to read a page according to the ECC generator
- * requirements; returns maximum number of bitflips corrected in
- * any single ECC step, 0 if bitflips uncorrectable, -EIO hw error
- * @read_subpage: function to read parts of the page covered by ECC;
- * returns same as read_page()
- * @write_subpage: function to write parts of the page covered by ECC.
- * @write_page: function to write a page according to the ECC generator
- * requirements.
- * @write_oob_raw: function to write chip OOB data without ECC
- * @read_oob_raw: function to read chip OOB data without ECC
- * @read_oob: function to read chip OOB data
- * @write_oob: function to write chip OOB data
- */
-struct nand_ecc_ctrl {
- nand_ecc_modes_t mode;
- int steps;
- int size;
- int bytes;
- int total;
- int strength;
- int prepad;
- int postpad;
- unsigned int options;
- struct nand_ecclayout *layout;
- void *priv;
- void (*hwctl)(struct mtd_info *mtd, int mode);
- int (*calculate)(struct mtd_info *mtd, const uint8_t *dat,
- uint8_t *ecc_code);
- int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc,
- uint8_t *calc_ecc);
- int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int oob_required, int page);
- int (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf, int oob_required, int page);
- int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int oob_required, int page);
- int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
- uint32_t offs, uint32_t len, uint8_t *buf, int page);
- int (*write_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
- uint32_t offset, uint32_t data_len,
- const uint8_t *data_buf, int oob_required, int page);
- int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
- const uint8_t *buf, int oob_required, int page);
- int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
- int page);
- int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
- int page);
- int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page);
- int (*write_oob)(struct mtd_info *mtd, struct nand_chip *chip,
- int page);
-};
-
-static inline int nand_standard_page_accessors(struct nand_ecc_ctrl *ecc)
-{
- return !(ecc->options & NAND_ECC_CUSTOM_PAGE_ACCESS);
-}
-
-/**
- * struct nand_buffers - buffer structure for read/write
- * @ecccalc: buffer pointer for calculated ECC, size is oobsize.
- * @ecccode: buffer pointer for ECC read from flash, size is oobsize.
- * @databuf: buffer pointer for data, size is (page size + oobsize).
- *
- * Do not change the order of buffers. databuf and oobrbuf must be in
- * consecutive order.
- */
-struct nand_buffers {
- uint8_t ecccalc[ALIGN(NAND_MAX_OOBSIZE, ARCH_DMA_MINALIGN)];
- uint8_t ecccode[ALIGN(NAND_MAX_OOBSIZE, ARCH_DMA_MINALIGN)];
- uint8_t databuf[ALIGN(NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE,
- ARCH_DMA_MINALIGN)];
-};
-
-/**
- * struct nand_sdr_timings - SDR NAND chip timings
- *
- * This struct defines the timing requirements of a SDR NAND chip.
- * These information can be found in every NAND datasheets and the timings
- * meaning are described in the ONFI specifications:
- * www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing
- * Parameters)
- *
- * All these timings are expressed in picoseconds.
- *
- * @tBERS_max: Block erase time
- * @tCCS_min: Change column setup time
- * @tPROG_max: Page program time
- * @tR_max: Page read time
- * @tALH_min: ALE hold time
- * @tADL_min: ALE to data loading time
- * @tALS_min: ALE setup time
- * @tAR_min: ALE to RE# delay
- * @tCEA_max: CE# access time
- * @tCEH_min: CE# high hold time
- * @tCH_min: CE# hold time
- * @tCHZ_max: CE# high to output hi-Z
- * @tCLH_min: CLE hold time
- * @tCLR_min: CLE to RE# delay
- * @tCLS_min: CLE setup time
- * @tCOH_min: CE# high to output hold
- * @tCS_min: CE# setup time
- * @tDH_min: Data hold time
- * @tDS_min: Data setup time
- * @tFEAT_max: Busy time for Set Features and Get Features
- * @tIR_min: Output hi-Z to RE# low
- * @tITC_max: Interface and Timing Mode Change time
- * @tRC_min: RE# cycle time
- * @tREA_max: RE# access time
- * @tREH_min: RE# high hold time
- * @tRHOH_min: RE# high to output hold
- * @tRHW_min: RE# high to WE# low
- * @tRHZ_max: RE# high to output hi-Z
- * @tRLOH_min: RE# low to output hold
- * @tRP_min: RE# pulse width
- * @tRR_min: Ready to RE# low (data only)
- * @tRST_max: Device reset time, measured from the falling edge of R/B# to the
- * rising edge of R/B#.
- * @tWB_max: WE# high to SR[6] low
- * @tWC_min: WE# cycle time
- * @tWH_min: WE# high hold time
- * @tWHR_min: WE# high to RE# low
- * @tWP_min: WE# pulse width
- * @tWW_min: WP# transition to WE# low
- */
-struct nand_sdr_timings {
- u64 tBERS_max;
- u32 tCCS_min;
- u64 tPROG_max;
- u64 tR_max;
- u32 tALH_min;
- u32 tADL_min;
- u32 tALS_min;
- u32 tAR_min;
- u32 tCEA_max;
- u32 tCEH_min;
- u32 tCH_min;
- u32 tCHZ_max;
- u32 tCLH_min;
- u32 tCLR_min;
- u32 tCLS_min;
- u32 tCOH_min;
- u32 tCS_min;
- u32 tDH_min;
- u32 tDS_min;
- u32 tFEAT_max;
- u32 tIR_min;
- u32 tITC_max;
- u32 tRC_min;
- u32 tREA_max;
- u32 tREH_min;
- u32 tRHOH_min;
- u32 tRHW_min;
- u32 tRHZ_max;
- u32 tRLOH_min;
- u32 tRP_min;
- u32 tRR_min;
- u64 tRST_max;
- u32 tWB_max;
- u32 tWC_min;
- u32 tWH_min;
- u32 tWHR_min;
- u32 tWP_min;
- u32 tWW_min;
-};
-
-/**
- * enum nand_data_interface_type - NAND interface timing type
- * @NAND_SDR_IFACE: Single Data Rate interface
- */
-enum nand_data_interface_type {
- NAND_SDR_IFACE,
-};
-
-/**
- * struct nand_data_interface - NAND interface timing
- * @type: type of the timing
- * @timings: The timing, type according to @type
- */
-struct nand_data_interface {
- enum nand_data_interface_type type;
- union {
- struct nand_sdr_timings sdr;
- } timings;
-};
-
-/**
- * nand_get_sdr_timings - get SDR timing from data interface
- * @conf: The data interface
- */
-static inline const struct nand_sdr_timings *
-nand_get_sdr_timings(const struct nand_data_interface *conf)
-{
- if (conf->type != NAND_SDR_IFACE)
- return ERR_PTR(-EINVAL);
-
- return &conf->timings.sdr;
-}
-
-/**
- * struct nand_chip - NAND Private Flash Chip Data
- * @mtd: MTD device registered to the MTD framework
- * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the
- * flash device
- * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the
- * flash device.
- * @flash_node: [BOARDSPECIFIC] device node describing this instance
- * @read_byte: [REPLACEABLE] read one byte from the chip
- * @read_word: [REPLACEABLE] read one word from the chip
- * @write_byte: [REPLACEABLE] write a single byte to the chip on the
- * low 8 I/O lines
- * @write_buf: [REPLACEABLE] write data from the buffer to the chip
- * @read_buf: [REPLACEABLE] read data from the chip into the buffer
- * @select_chip: [REPLACEABLE] select chip nr
- * @block_bad: [REPLACEABLE] check if a block is bad, using OOB markers
- * @block_markbad: [REPLACEABLE] mark a block bad
- * @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific function for controlling
- * ALE/CLE/nCE. Also used to write command and address
- * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accessing
- * device ready/busy line. If set to NULL no access to
- * ready/busy is available and the ready/busy information
- * is read from the chip status register.
- * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing
- * commands to the chip.
- * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on
- * ready.
- * @setup_read_retry: [FLASHSPECIFIC] flash (vendor) specific function for
- * setting the read-retry mode. Mostly needed for MLC NAND.
- * @ecc: [BOARDSPECIFIC] ECC control structure
- * @buffers: buffer structure for read/write
- * @buf_align: minimum buffer alignment required by a platform
- * @hwcontrol: platform-specific hardware control structure
- * @erase: [REPLACEABLE] erase function
- * @scan_bbt: [REPLACEABLE] function to scan bad block table
- * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transferring
- * data from array to read regs (tR).
- * @state: [INTERN] the current state of the NAND device
- * @oob_poi: "poison value buffer," used for laying out OOB data
- * before writing
- * @page_shift: [INTERN] number of address bits in a page (column
- * address bits).
- * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock
- * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
- * @chip_shift: [INTERN] number of address bits in one chip
- * @options: [BOARDSPECIFIC] various chip options. They can partly
- * be set to inform nand_scan about special functionality.
- * See the defines for further explanation.
- * @bbt_options: [INTERN] bad block specific options. All options used
- * here must come from bbm.h. By default, these options
- * will be copied to the appropriate nand_bbt_descr's.
- * @badblockpos: [INTERN] position of the bad block marker in the oob
- * area.
- * @badblockbits: [INTERN] minimum number of set bits in a good block's
- * bad block marker position; i.e., BBM == 11110111b is
- * not bad when badblockbits == 7
- * @bits_per_cell: [INTERN] number of bits per cell. i.e., 1 means SLC.
- * @ecc_strength_ds: [INTERN] ECC correctability from the datasheet.
- * Minimum amount of bit errors per @ecc_step_ds guaranteed
- * to be correctable. If unknown, set to zero.
- * @ecc_step_ds: [INTERN] ECC step required by the @ecc_strength_ds,
- * also from the datasheet. It is the recommended ECC step
- * size, if known; if unknown, set to zero.
- * @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is
- * set to the actually used ONFI mode if the chip is
- * ONFI compliant or deduced from the datasheet if
- * the NAND chip is not ONFI compliant.
- * @numchips: [INTERN] number of physical chips
- * @chipsize: [INTERN] the size of one chip for multichip arrays
- * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
- * @pagebuf: [INTERN] holds the pagenumber which is currently in
- * data_buf.
- * @pagebuf_bitflips: [INTERN] holds the bitflip count for the page which is
- * currently in data_buf.
- * @subpagesize: [INTERN] holds the subpagesize
- * @onfi_version: [INTERN] holds the chip ONFI version (BCD encoded),
- * non 0 if ONFI supported.
- * @jedec_version: [INTERN] holds the chip JEDEC version (BCD encoded),
- * non 0 if JEDEC supported.
- * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is
- * supported, 0 otherwise.
- * @jedec_params: [INTERN] holds the JEDEC parameter page when JEDEC is
- * supported, 0 otherwise.
- * @read_retries: [INTERN] the number of read retry modes supported
- * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
- * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
- * @setup_data_interface: [OPTIONAL] setup the data interface and timing. If
- * chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this
- * means the configuration should not be applied but
- * only checked.
- * @bbt: [INTERN] bad block table pointer
- * @bbt_td: [REPLACEABLE] bad block table descriptor for flash
- * lookup.
- * @bbt_md: [REPLACEABLE] bad block table mirror descriptor
- * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial
- * bad block scan.
- * @controller: [REPLACEABLE] a pointer to a hardware controller
- * structure which is shared among multiple independent
- * devices.
- * @priv: [OPTIONAL] pointer to private chip data
- * @write_page: [REPLACEABLE] High-level page write function
- */
-
-struct nand_chip {
- struct mtd_info mtd;
- void __iomem *IO_ADDR_R;
- void __iomem *IO_ADDR_W;
-
- int flash_node;
-
- uint8_t (*read_byte)(struct mtd_info *mtd);
- u16 (*read_word)(struct mtd_info *mtd);
- void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
- void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
- void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
- void (*select_chip)(struct mtd_info *mtd, int chip);
- int (*block_bad)(struct mtd_info *mtd, loff_t ofs);
- int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
- void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
- int (*dev_ready)(struct mtd_info *mtd);
- void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column,
- int page_addr);
- int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
- int (*erase)(struct mtd_info *mtd, int page);
- int (*scan_bbt)(struct mtd_info *mtd);
- int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
- uint32_t offset, int data_len, const uint8_t *buf,
- int oob_required, int page, int raw);
- int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
- int feature_addr, uint8_t *subfeature_para);
- int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
- int feature_addr, uint8_t *subfeature_para);
- int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode);
- int (*setup_data_interface)(struct mtd_info *mtd, int chipnr,
- const struct nand_data_interface *conf);
-
-
- int chip_delay;
- unsigned int options;
- unsigned int bbt_options;
-
- int page_shift;
- int phys_erase_shift;
- int bbt_erase_shift;
- int chip_shift;
- int numchips;
- uint64_t chipsize;
- int pagemask;
- int pagebuf;
- unsigned int pagebuf_bitflips;
- int subpagesize;
- uint8_t bits_per_cell;
- uint16_t ecc_strength_ds;
- uint16_t ecc_step_ds;
- int onfi_timing_mode_default;
- int badblockpos;
- int badblockbits;
-
- int onfi_version;
- int jedec_version;
- struct nand_onfi_params onfi_params;
- struct nand_jedec_params jedec_params;
-
- struct nand_data_interface *data_interface;
-
- int read_retries;
-
- flstate_t state;
-
- uint8_t *oob_poi;
- struct nand_hw_control *controller;
- struct nand_ecclayout *ecclayout;
-
- struct nand_ecc_ctrl ecc;
- struct nand_buffers *buffers;
- unsigned long buf_align;
- struct nand_hw_control hwcontrol;
-
- uint8_t *bbt;
- struct nand_bbt_descr *bbt_td;
- struct nand_bbt_descr *bbt_md;
-
- struct nand_bbt_descr *badblock_pattern;
-
- void *priv;
-};
-
-static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd)
-{
- return container_of(mtd, struct nand_chip, mtd);
-}
-
-static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip)
-{
- return &chip->mtd;
-}
-
-static inline void *nand_get_controller_data(struct nand_chip *chip)
-{
- return chip->priv;
-}
-
-static inline void nand_set_controller_data(struct nand_chip *chip, void *priv)
-{
- chip->priv = priv;
-}
-
-/*
- * NAND Flash Manufacturer ID Codes
- */
-#define NAND_MFR_TOSHIBA 0x98
-#define NAND_MFR_SAMSUNG 0xec
-#define NAND_MFR_FUJITSU 0x04
-#define NAND_MFR_NATIONAL 0x8f
-#define NAND_MFR_RENESAS 0x07
-#define NAND_MFR_STMICRO 0x20
-#define NAND_MFR_HYNIX 0xad
-#define NAND_MFR_MICRON 0x2c
-#define NAND_MFR_AMD 0x01
-#define NAND_MFR_MACRONIX 0xc2
-#define NAND_MFR_EON 0x92
-#define NAND_MFR_SANDISK 0x45
-#define NAND_MFR_INTEL 0x89
-#define NAND_MFR_ATO 0x9b
-
-/* The maximum expected count of bytes in the NAND ID sequence */
-#define NAND_MAX_ID_LEN 8
-
-/*
- * A helper for defining older NAND chips where the second ID byte fully
- * defined the chip, including the geometry (chip size, eraseblock size, page
- * size). All these chips have 512 bytes NAND page size.
- */
-#define LEGACY_ID_NAND(nm, devid, chipsz, erasesz, opts) \
- { .name = (nm), {{ .dev_id = (devid) }}, .pagesize = 512, \
- .chipsize = (chipsz), .erasesize = (erasesz), .options = (opts) }
-
-/*
- * A helper for defining newer chips which report their page size and
- * eraseblock size via the extended ID bytes.
- *
- * The real difference between LEGACY_ID_NAND and EXTENDED_ID_NAND is that with
- * EXTENDED_ID_NAND, manufacturers overloaded the same device ID so that the
- * device ID now only represented a particular total chip size (and voltage,
- * buswidth), and the page size, eraseblock size, and OOB size could vary while
- * using the same device ID.
- */
-#define EXTENDED_ID_NAND(nm, devid, chipsz, opts) \
- { .name = (nm), {{ .dev_id = (devid) }}, .chipsize = (chipsz), \
- .options = (opts) }
-
-#define NAND_ECC_INFO(_strength, _step) \
- { .strength_ds = (_strength), .step_ds = (_step) }
-#define NAND_ECC_STRENGTH(type) ((type)->ecc.strength_ds)
-#define NAND_ECC_STEP(type) ((type)->ecc.step_ds)
-
-/**
- * struct nand_flash_dev - NAND Flash Device ID Structure
- * @name: a human-readable name of the NAND chip
- * @dev_id: the device ID (the second byte of the full chip ID array)
- * @mfr_id: manufecturer ID part of the full chip ID array (refers the same
- * memory address as @id[0])
- * @dev_id: device ID part of the full chip ID array (refers the same memory
- * address as @id[1])
- * @id: full device ID array
- * @pagesize: size of the NAND page in bytes; if 0, then the real page size (as
- * well as the eraseblock size) is determined from the extended NAND
- * chip ID array)
- * @chipsize: total chip size in MiB
- * @erasesize: eraseblock size in bytes (determined from the extended ID if 0)
- * @options: stores various chip bit options
- * @id_len: The valid length of the @id.
- * @oobsize: OOB size
- * @ecc: ECC correctability and step information from the datasheet.
- * @ecc.strength_ds: The ECC correctability from the datasheet, same as the
- * @ecc_strength_ds in nand_chip{}.
- * @ecc.step_ds: The ECC step required by the @ecc.strength_ds, same as the
- * @ecc_step_ds in nand_chip{}, also from the datasheet.
- * For example, the "4bit ECC for each 512Byte" can be set with
- * NAND_ECC_INFO(4, 512).
- * @onfi_timing_mode_default: the default ONFI timing mode entered after a NAND
- * reset. Should be deduced from timings described
- * in the datasheet.
- *
- */
-struct nand_flash_dev {
- char *name;
- union {
- struct {
- uint8_t mfr_id;
- uint8_t dev_id;
- };
- uint8_t id[NAND_MAX_ID_LEN];
- };
- unsigned int pagesize;
- unsigned int chipsize;
- unsigned int erasesize;
- unsigned int options;
- uint16_t id_len;
- uint16_t oobsize;
- struct {
- uint16_t strength_ds;
- uint16_t step_ds;
- } ecc;
- int onfi_timing_mode_default;
-};
-
-/**
- * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
- * @name: Manufacturer name
- * @id: manufacturer ID code of device.
-*/
-struct nand_manufacturers {
- int id;
- char *name;
-};
-
-extern struct nand_flash_dev nand_flash_ids[];
-extern struct nand_manufacturers nand_manuf_ids[];
-
-int nand_default_bbt(struct mtd_info *mtd);
-int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);
-int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs);
-int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
-int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
- int allowbbt);
-int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, uint8_t *buf);
-
-/*
-* Constants for oob configuration
-*/
-#define NAND_SMALL_BADBLOCK_POS 5
-#define NAND_LARGE_BADBLOCK_POS 0
-
-/**
- * struct platform_nand_chip - chip level device structure
- * @nr_chips: max. number of chips to scan for
- * @chip_offset: chip number offset
- * @nr_partitions: number of partitions pointed to by partitions (or zero)
- * @partitions: mtd partition list
- * @chip_delay: R/B delay value in us
- * @options: Option flags, e.g. 16bit buswidth
- * @bbt_options: BBT option flags, e.g. NAND_BBT_USE_FLASH
- * @part_probe_types: NULL-terminated array of probe types
- */
-struct platform_nand_chip {
- int nr_chips;
- int chip_offset;
- int nr_partitions;
- struct mtd_partition *partitions;
- int chip_delay;
- unsigned int options;
- unsigned int bbt_options;
- const char **part_probe_types;
-};
-
-/* Keep gcc happy */
-struct platform_device;
-
-/**
- * struct platform_nand_ctrl - controller level device structure
- * @probe: platform specific function to probe/setup hardware
- * @remove: platform specific function to remove/teardown hardware
- * @hwcontrol: platform specific hardware control structure
- * @dev_ready: platform specific function to read ready/busy pin
- * @select_chip: platform specific chip select function
- * @cmd_ctrl: platform specific function for controlling
- * ALE/CLE/nCE. Also used to write command and address
- * @write_buf: platform specific function for write buffer
- * @read_buf: platform specific function for read buffer
- * @read_byte: platform specific function to read one byte from chip
- * @priv: private data to transport driver specific settings
- *
- * All fields are optional and depend on the hardware driver requirements
- */
-struct platform_nand_ctrl {
- int (*probe)(struct platform_device *pdev);
- void (*remove)(struct platform_device *pdev);
- void (*hwcontrol)(struct mtd_info *mtd, int cmd);
- int (*dev_ready)(struct mtd_info *mtd);
- void (*select_chip)(struct mtd_info *mtd, int chip);
- void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
- void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
- void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
- unsigned char (*read_byte)(struct mtd_info *mtd);
- void *priv;
-};
-
-/**
- * struct platform_nand_data - container structure for platform-specific data
- * @chip: chip level chip structure
- * @ctrl: controller level device structure
- */
-struct platform_nand_data {
- struct platform_nand_chip chip;
- struct platform_nand_ctrl ctrl;
-};
-
-#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
-/* return the supported features. */
-static inline int onfi_feature(struct nand_chip *chip)
-{
- return chip->onfi_version ? le16_to_cpu(chip->onfi_params.features) : 0;
-}
-
-/* return the supported asynchronous timing mode. */
-static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
-{
- if (!chip->onfi_version)
- return ONFI_TIMING_MODE_UNKNOWN;
- return le16_to_cpu(chip->onfi_params.async_timing_mode);
-}
-
-/* return the supported synchronous timing mode. */
-static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
-{
- if (!chip->onfi_version)
- return ONFI_TIMING_MODE_UNKNOWN;
- return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
-}
-#else
-static inline int onfi_feature(struct nand_chip *chip)
-{
- return 0;
-}
-
-static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
-{
- return ONFI_TIMING_MODE_UNKNOWN;
-}
-
-static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
-{
- return ONFI_TIMING_MODE_UNKNOWN;
-}
-#endif
-
-int onfi_init_data_interface(struct nand_chip *chip,
- struct nand_data_interface *iface,
- enum nand_data_interface_type type,
- int timing_mode);
-
-/*
- * Check if it is a SLC nand.
- * The !nand_is_slc() can be used to check the MLC/TLC nand chips.
- * We do not distinguish the MLC and TLC now.
- */
-static inline bool nand_is_slc(struct nand_chip *chip)
-{
- return chip->bits_per_cell == 1;
-}
-
-/**
- * Check if the opcode's address should be sent only on the lower 8 bits
- * @command: opcode to check
- */
-static inline int nand_opcode_8bits(unsigned int command)
-{
- switch (command) {
- case NAND_CMD_READID:
- case NAND_CMD_PARAM:
- case NAND_CMD_GET_FEATURES:
- case NAND_CMD_SET_FEATURES:
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-/* return the supported JEDEC features. */
-static inline int jedec_feature(struct nand_chip *chip)
-{
- return chip->jedec_version ? le16_to_cpu(chip->jedec_params.features)
- : 0;
-}
-
-/* Standard NAND functions from nand_base.c */
-void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
-void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len);
-void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
-void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
-uint8_t nand_read_byte(struct mtd_info *mtd);
-
-/* get timing characteristics from ONFI timing mode. */
-const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);
-/* get data interface from ONFI timing mode 0, used after reset. */
-const struct nand_data_interface *nand_get_default_data_interface(void);
-
-int nand_check_erased_ecc_chunk(void *data, int datalen,
- void *ecc, int ecclen,
- void *extraoob, int extraooblen,
- int threshold);
-
-int nand_check_ecc_caps(struct nand_chip *chip,
- const struct nand_ecc_caps *caps, int oobavail);
-
-int nand_match_ecc_req(struct nand_chip *chip,
- const struct nand_ecc_caps *caps, int oobavail);
-
-int nand_maximize_ecc(struct nand_chip *chip,
- const struct nand_ecc_caps *caps, int oobavail);
-
-/* Reset and initialize a NAND device */
-int nand_reset(struct nand_chip *chip, int chipnr);
-
-#endif /* __LINUX_MTD_NAND_H */
--- /dev/null
+/*
+ * Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org>
+ * Steven J. Hill <sjhill@realitydiluted.com>
+ * Thomas Gleixner <tglx@linutronix.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Info:
+ * Contains standard defines and IDs for NAND flash devices
+ *
+ * Changelog:
+ * See git changelog.
+ */
+#ifndef __LINUX_MTD_RAWNAND_H
+#define __LINUX_MTD_RAWNAND_H
+
+#include <config.h>
+
+#include <linux/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/flashchip.h>
+#include <linux/mtd/bbm.h>
+#include <asm/cache.h>
+
+struct mtd_info;
+struct nand_flash_dev;
+struct device_node;
+
+/* Scan and identify a NAND device */
+int nand_scan(struct mtd_info *mtd, int max_chips);
+/*
+ * Separate phases of nand_scan(), allowing board driver to intervene
+ * and override command or ECC setup according to flash type.
+ */
+int nand_scan_ident(struct mtd_info *mtd, int max_chips,
+ struct nand_flash_dev *table);
+int nand_scan_tail(struct mtd_info *mtd);
+
+/* Free resources held by the NAND device */
+void nand_release(struct mtd_info *mtd);
+
+/* Internal helper for board drivers which need to override command function */
+void nand_wait_ready(struct mtd_info *mtd);
+
+/*
+ * This constant declares the max. oobsize / page, which
+ * is supported now. If you add a chip with bigger oobsize/page
+ * adjust this accordingly.
+ */
+#define NAND_MAX_OOBSIZE 1664
+#define NAND_MAX_PAGESIZE 16384
+
+/*
+ * Constants for hardware specific CLE/ALE/NCE function
+ *
+ * These are bits which can be or'ed to set/clear multiple
+ * bits in one go.
+ */
+/* Select the chip by setting nCE to low */
+#define NAND_NCE 0x01
+/* Select the command latch by setting CLE to high */
+#define NAND_CLE 0x02
+/* Select the address latch by setting ALE to high */
+#define NAND_ALE 0x04
+
+#define NAND_CTRL_CLE (NAND_NCE | NAND_CLE)
+#define NAND_CTRL_ALE (NAND_NCE | NAND_ALE)
+#define NAND_CTRL_CHANGE 0x80
+
+/*
+ * Standard NAND flash commands
+ */
+#define NAND_CMD_READ0 0
+#define NAND_CMD_READ1 1
+#define NAND_CMD_RNDOUT 5
+#define NAND_CMD_PAGEPROG 0x10
+#define NAND_CMD_READOOB 0x50
+#define NAND_CMD_ERASE1 0x60
+#define NAND_CMD_STATUS 0x70
+#define NAND_CMD_SEQIN 0x80
+#define NAND_CMD_RNDIN 0x85
+#define NAND_CMD_READID 0x90
+#define NAND_CMD_ERASE2 0xd0
+#define NAND_CMD_PARAM 0xec
+#define NAND_CMD_GET_FEATURES 0xee
+#define NAND_CMD_SET_FEATURES 0xef
+#define NAND_CMD_RESET 0xff
+
+#define NAND_CMD_LOCK 0x2a
+#define NAND_CMD_UNLOCK1 0x23
+#define NAND_CMD_UNLOCK2 0x24
+
+/* Extended commands for large page devices */
+#define NAND_CMD_READSTART 0x30
+#define NAND_CMD_RNDOUTSTART 0xE0
+#define NAND_CMD_CACHEDPROG 0x15
+
+/* Extended commands for AG-AND device */
+/*
+ * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but
+ * there is no way to distinguish that from NAND_CMD_READ0
+ * until the remaining sequence of commands has been completed
+ * so add a high order bit and mask it off in the command.
+ */
+#define NAND_CMD_DEPLETE1 0x100
+#define NAND_CMD_DEPLETE2 0x38
+#define NAND_CMD_STATUS_MULTI 0x71
+#define NAND_CMD_STATUS_ERROR 0x72
+/* multi-bank error status (banks 0-3) */
+#define NAND_CMD_STATUS_ERROR0 0x73
+#define NAND_CMD_STATUS_ERROR1 0x74
+#define NAND_CMD_STATUS_ERROR2 0x75
+#define NAND_CMD_STATUS_ERROR3 0x76
+#define NAND_CMD_STATUS_RESET 0x7f
+#define NAND_CMD_STATUS_CLEAR 0xff
+
+#define NAND_CMD_NONE -1
+
+/* Status bits */
+#define NAND_STATUS_FAIL 0x01
+#define NAND_STATUS_FAIL_N1 0x02
+#define NAND_STATUS_TRUE_READY 0x20
+#define NAND_STATUS_READY 0x40
+#define NAND_STATUS_WP 0x80
+
+#define NAND_DATA_IFACE_CHECK_ONLY -1
+
+/*
+ * Constants for ECC_MODES
+ */
+typedef enum {
+ NAND_ECC_NONE,
+ NAND_ECC_SOFT,
+ NAND_ECC_HW,
+ NAND_ECC_HW_SYNDROME,
+ NAND_ECC_HW_OOB_FIRST,
+ NAND_ECC_SOFT_BCH,
+} nand_ecc_modes_t;
+
+/*
+ * Constants for Hardware ECC
+ */
+/* Reset Hardware ECC for read */
+#define NAND_ECC_READ 0
+/* Reset Hardware ECC for write */
+#define NAND_ECC_WRITE 1
+/* Enable Hardware ECC before syndrome is read back from flash */
+#define NAND_ECC_READSYN 2
+
+/*
+ * Enable generic NAND 'page erased' check. This check is only done when
+ * ecc.correct() returns -EBADMSG.
+ * Set this flag if your implementation does not fix bitflips in erased
+ * pages and you want to rely on the default implementation.
+ */
+#define NAND_ECC_GENERIC_ERASED_CHECK BIT(0)
+#define NAND_ECC_MAXIMIZE BIT(1)
+/*
+ * If your controller already sends the required NAND commands when
+ * reading or writing a page, then the framework is not supposed to
+ * send READ0 and SEQIN/PAGEPROG respectively.
+ */
+#define NAND_ECC_CUSTOM_PAGE_ACCESS BIT(2)
+
+/* Bit mask for flags passed to do_nand_read_ecc */
+#define NAND_GET_DEVICE 0x80
+
+
+/*
+ * Option constants for bizarre disfunctionality and real
+ * features.
+ */
+/* Buswidth is 16 bit */
+#define NAND_BUSWIDTH_16 0x00000002
+/* Device supports partial programming without padding */
+#define NAND_NO_PADDING 0x00000004
+/* Chip has cache program function */
+#define NAND_CACHEPRG 0x00000008
+/* Chip has copy back function */
+#define NAND_COPYBACK 0x00000010
+/*
+ * Chip requires ready check on read (for auto-incremented sequential read).
+ * True only for small page devices; large page devices do not support
+ * autoincrement.
+ */
+#define NAND_NEED_READRDY 0x00000100
+
+/* Chip does not allow subpage writes */
+#define NAND_NO_SUBPAGE_WRITE 0x00000200
+
+/* Device is one of 'new' xD cards that expose fake nand command set */
+#define NAND_BROKEN_XD 0x00000400
+
+/* Device behaves just like nand, but is readonly */
+#define NAND_ROM 0x00000800
+
+/* Device supports subpage reads */
+#define NAND_SUBPAGE_READ 0x00001000
+
+/*
+ * Some MLC NANDs need data scrambling to limit bitflips caused by repeated
+ * patterns.
+ */
+#define NAND_NEED_SCRAMBLING 0x00002000
+
+/* Device needs 3rd row address cycle */
+#define NAND_ROW_ADDR_3 0x00004000
+
+/* Options valid for Samsung large page devices */
+#define NAND_SAMSUNG_LP_OPTIONS NAND_CACHEPRG
+
+/* Macros to identify the above */
+#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
+#define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
+#define NAND_HAS_SUBPAGE_WRITE(chip) !((chip)->options & NAND_NO_SUBPAGE_WRITE)
+
+/* Non chip related options */
+/* This option skips the bbt scan during initialization. */
+#define NAND_SKIP_BBTSCAN 0x00010000
+/*
+ * This option is defined if the board driver allocates its own buffers
+ * (e.g. because it needs them DMA-coherent).
+ */
+#define NAND_OWN_BUFFERS 0x00020000
+/* Chip may not exist, so silence any errors in scan */
+#define NAND_SCAN_SILENT_NODEV 0x00040000
+/*
+ * Autodetect nand buswidth with readid/onfi.
+ * This suppose the driver will configure the hardware in 8 bits mode
+ * when calling nand_scan_ident, and update its configuration
+ * before calling nand_scan_tail.
+ */
+#define NAND_BUSWIDTH_AUTO 0x00080000
+/*
+ * This option could be defined by controller drivers to protect against
+ * kmap'ed, vmalloc'ed highmem buffers being passed from upper layers
+ */
+#define NAND_USE_BOUNCE_BUFFER 0x00100000
+
+/* Options set by nand scan */
+/* bbt has already been read */
+#define NAND_BBT_SCANNED 0x40000000
+/* Nand scan has allocated controller struct */
+#define NAND_CONTROLLER_ALLOC 0x80000000
+
+/* Cell info constants */
+#define NAND_CI_CHIPNR_MSK 0x03
+#define NAND_CI_CELLTYPE_MSK 0x0C
+#define NAND_CI_CELLTYPE_SHIFT 2
+
+/* Keep gcc happy */
+struct nand_chip;
+
+/* ONFI features */
+#define ONFI_FEATURE_16_BIT_BUS (1 << 0)
+#define ONFI_FEATURE_EXT_PARAM_PAGE (1 << 7)
+
+/* ONFI timing mode, used in both asynchronous and synchronous mode */
+#define ONFI_TIMING_MODE_0 (1 << 0)
+#define ONFI_TIMING_MODE_1 (1 << 1)
+#define ONFI_TIMING_MODE_2 (1 << 2)
+#define ONFI_TIMING_MODE_3 (1 << 3)
+#define ONFI_TIMING_MODE_4 (1 << 4)
+#define ONFI_TIMING_MODE_5 (1 << 5)
+#define ONFI_TIMING_MODE_UNKNOWN (1 << 6)
+
+/* ONFI feature address */
+#define ONFI_FEATURE_ADDR_TIMING_MODE 0x1
+
+/* Vendor-specific feature address (Micron) */
+#define ONFI_FEATURE_ADDR_READ_RETRY 0x89
+
+/* ONFI subfeature parameters length */
+#define ONFI_SUBFEATURE_PARAM_LEN 4
+
+/* ONFI optional commands SET/GET FEATURES supported? */
+#define ONFI_OPT_CMD_SET_GET_FEATURES (1 << 2)
+
+struct nand_onfi_params {
+ /* rev info and features block */
+ /* 'O' 'N' 'F' 'I' */
+ u8 sig[4];
+ __le16 revision;
+ __le16 features;
+ __le16 opt_cmd;
+ u8 reserved0[2];
+ __le16 ext_param_page_length; /* since ONFI 2.1 */
+ u8 num_of_param_pages; /* since ONFI 2.1 */
+ u8 reserved1[17];
+
+ /* manufacturer information block */
+ char manufacturer[12];
+ char model[20];
+ u8 jedec_id;
+ __le16 date_code;
+ u8 reserved2[13];
+
+ /* memory organization block */
+ __le32 byte_per_page;
+ __le16 spare_bytes_per_page;
+ __le32 data_bytes_per_ppage;
+ __le16 spare_bytes_per_ppage;
+ __le32 pages_per_block;
+ __le32 blocks_per_lun;
+ u8 lun_count;
+ u8 addr_cycles;
+ u8 bits_per_cell;
+ __le16 bb_per_lun;
+ __le16 block_endurance;
+ u8 guaranteed_good_blocks;
+ __le16 guaranteed_block_endurance;
+ u8 programs_per_page;
+ u8 ppage_attr;
+ u8 ecc_bits;
+ u8 interleaved_bits;
+ u8 interleaved_ops;
+ u8 reserved3[13];
+
+ /* electrical parameter block */
+ u8 io_pin_capacitance_max;
+ __le16 async_timing_mode;
+ __le16 program_cache_timing_mode;
+ __le16 t_prog;
+ __le16 t_bers;
+ __le16 t_r;
+ __le16 t_ccs;
+ __le16 src_sync_timing_mode;
+ u8 src_ssync_features;
+ __le16 clk_pin_capacitance_typ;
+ __le16 io_pin_capacitance_typ;
+ __le16 input_pin_capacitance_typ;
+ u8 input_pin_capacitance_max;
+ u8 driver_strength_support;
+ __le16 t_int_r;
+ __le16 t_adl;
+ u8 reserved4[8];
+
+ /* vendor */
+ __le16 vendor_revision;
+ u8 vendor[88];
+
+ __le16 crc;
+} __packed;
+
+#define ONFI_CRC_BASE 0x4F4E
+
+/* Extended ECC information Block Definition (since ONFI 2.1) */
+struct onfi_ext_ecc_info {
+ u8 ecc_bits;
+ u8 codeword_size;
+ __le16 bb_per_lun;
+ __le16 block_endurance;
+ u8 reserved[2];
+} __packed;
+
+#define ONFI_SECTION_TYPE_0 0 /* Unused section. */
+#define ONFI_SECTION_TYPE_1 1 /* for additional sections. */
+#define ONFI_SECTION_TYPE_2 2 /* for ECC information. */
+struct onfi_ext_section {
+ u8 type;
+ u8 length;
+} __packed;
+
+#define ONFI_EXT_SECTION_MAX 8
+
+/* Extended Parameter Page Definition (since ONFI 2.1) */
+struct onfi_ext_param_page {
+ __le16 crc;
+ u8 sig[4]; /* 'E' 'P' 'P' 'S' */
+ u8 reserved0[10];
+ struct onfi_ext_section sections[ONFI_EXT_SECTION_MAX];
+
+ /*
+ * The actual size of the Extended Parameter Page is in
+ * @ext_param_page_length of nand_onfi_params{}.
+ * The following are the variable length sections.
+ * So we do not add any fields below. Please see the ONFI spec.
+ */
+} __packed;
+
+struct nand_onfi_vendor_micron {
+ u8 two_plane_read;
+ u8 read_cache;
+ u8 read_unique_id;
+ u8 dq_imped;
+ u8 dq_imped_num_settings;
+ u8 dq_imped_feat_addr;
+ u8 rb_pulldown_strength;
+ u8 rb_pulldown_strength_feat_addr;
+ u8 rb_pulldown_strength_num_settings;
+ u8 otp_mode;
+ u8 otp_page_start;
+ u8 otp_data_prot_addr;
+ u8 otp_num_pages;
+ u8 otp_feat_addr;
+ u8 read_retry_options;
+ u8 reserved[72];
+ u8 param_revision;
+} __packed;
+
+struct jedec_ecc_info {
+ u8 ecc_bits;
+ u8 codeword_size;
+ __le16 bb_per_lun;
+ __le16 block_endurance;
+ u8 reserved[2];
+} __packed;
+
+/* JEDEC features */
+#define JEDEC_FEATURE_16_BIT_BUS (1 << 0)
+
+struct nand_jedec_params {
+ /* rev info and features block */
+ /* 'J' 'E' 'S' 'D' */
+ u8 sig[4];
+ __le16 revision;
+ __le16 features;
+ u8 opt_cmd[3];
+ __le16 sec_cmd;
+ u8 num_of_param_pages;
+ u8 reserved0[18];
+
+ /* manufacturer information block */
+ char manufacturer[12];
+ char model[20];
+ u8 jedec_id[6];
+ u8 reserved1[10];
+
+ /* memory organization block */
+ __le32 byte_per_page;
+ __le16 spare_bytes_per_page;
+ u8 reserved2[6];
+ __le32 pages_per_block;
+ __le32 blocks_per_lun;
+ u8 lun_count;
+ u8 addr_cycles;
+ u8 bits_per_cell;
+ u8 programs_per_page;
+ u8 multi_plane_addr;
+ u8 multi_plane_op_attr;
+ u8 reserved3[38];
+
+ /* electrical parameter block */
+ __le16 async_sdr_speed_grade;
+ __le16 toggle_ddr_speed_grade;
+ __le16 sync_ddr_speed_grade;
+ u8 async_sdr_features;
+ u8 toggle_ddr_features;
+ u8 sync_ddr_features;
+ __le16 t_prog;
+ __le16 t_bers;
+ __le16 t_r;
+ __le16 t_r_multi_plane;
+ __le16 t_ccs;
+ __le16 io_pin_capacitance_typ;
+ __le16 input_pin_capacitance_typ;
+ __le16 clk_pin_capacitance_typ;
+ u8 driver_strength_support;
+ __le16 t_adl;
+ u8 reserved4[36];
+
+ /* ECC and endurance block */
+ u8 guaranteed_good_blocks;
+ __le16 guaranteed_block_endurance;
+ struct jedec_ecc_info ecc_info[4];
+ u8 reserved5[29];
+
+ /* reserved */
+ u8 reserved6[148];
+
+ /* vendor */
+ __le16 vendor_rev_num;
+ u8 reserved7[88];
+
+ /* CRC for Parameter Page */
+ __le16 crc;
+} __packed;
+
+/**
+ * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices
+ * @lock: protection lock
+ * @active: the mtd device which holds the controller currently
+ * @wq: wait queue to sleep on if a NAND operation is in
+ * progress used instead of the per chip wait queue
+ * when a hw controller is available.
+ */
+struct nand_hw_control {
+ spinlock_t lock;
+ struct nand_chip *active;
+};
+
+/**
+ * struct nand_ecc_step_info - ECC step information of ECC engine
+ * @stepsize: data bytes per ECC step
+ * @strengths: array of supported strengths
+ * @nstrengths: number of supported strengths
+ */
+struct nand_ecc_step_info {
+ int stepsize;
+ const int *strengths;
+ int nstrengths;
+};
+
+/**
+ * struct nand_ecc_caps - capability of ECC engine
+ * @stepinfos: array of ECC step information
+ * @nstepinfos: number of ECC step information
+ * @calc_ecc_bytes: driver's hook to calculate ECC bytes per step
+ */
+struct nand_ecc_caps {
+ const struct nand_ecc_step_info *stepinfos;
+ int nstepinfos;
+ int (*calc_ecc_bytes)(int step_size, int strength);
+};
+
+/* a shorthand to generate struct nand_ecc_caps with only one ECC stepsize */
+#define NAND_ECC_CAPS_SINGLE(__name, __calc, __step, ...) \
+static const int __name##_strengths[] = { __VA_ARGS__ }; \
+static const struct nand_ecc_step_info __name##_stepinfo = { \
+ .stepsize = __step, \
+ .strengths = __name##_strengths, \
+ .nstrengths = ARRAY_SIZE(__name##_strengths), \
+}; \
+static const struct nand_ecc_caps __name = { \
+ .stepinfos = &__name##_stepinfo, \
+ .nstepinfos = 1, \
+ .calc_ecc_bytes = __calc, \
+}
+
+/**
+ * struct nand_ecc_ctrl - Control structure for ECC
+ * @mode: ECC mode
+ * @steps: number of ECC steps per page
+ * @size: data bytes per ECC step
+ * @bytes: ECC bytes per step
+ * @strength: max number of correctible bits per ECC step
+ * @total: total number of ECC bytes per page
+ * @prepad: padding information for syndrome based ECC generators
+ * @postpad: padding information for syndrome based ECC generators
+ * @options: ECC specific options (see NAND_ECC_XXX flags defined above)
+ * @layout: ECC layout control struct pointer
+ * @priv: pointer to private ECC control data
+ * @hwctl: function to control hardware ECC generator. Must only
+ * be provided if an hardware ECC is available
+ * @calculate: function for ECC calculation or readback from ECC hardware
+ * @correct: function for ECC correction, matching to ECC generator (sw/hw).
+ * Should return a positive number representing the number of
+ * corrected bitflips, -EBADMSG if the number of bitflips exceed
+ * ECC strength, or any other error code if the error is not
+ * directly related to correction.
+ * If -EBADMSG is returned the input buffers should be left
+ * untouched.
+ * @read_page_raw: function to read a raw page without ECC. This function
+ * should hide the specific layout used by the ECC
+ * controller and always return contiguous in-band and
+ * out-of-band data even if they're not stored
+ * contiguously on the NAND chip (e.g.
+ * NAND_ECC_HW_SYNDROME interleaves in-band and
+ * out-of-band data).
+ * @write_page_raw: function to write a raw page without ECC. This function
+ * should hide the specific layout used by the ECC
+ * controller and consider the passed data as contiguous
+ * in-band and out-of-band data. ECC controller is
+ * responsible for doing the appropriate transformations
+ * to adapt to its specific layout (e.g.
+ * NAND_ECC_HW_SYNDROME interleaves in-band and
+ * out-of-band data).
+ * @read_page: function to read a page according to the ECC generator
+ * requirements; returns maximum number of bitflips corrected in
+ * any single ECC step, 0 if bitflips uncorrectable, -EIO hw error
+ * @read_subpage: function to read parts of the page covered by ECC;
+ * returns same as read_page()
+ * @write_subpage: function to write parts of the page covered by ECC.
+ * @write_page: function to write a page according to the ECC generator
+ * requirements.
+ * @write_oob_raw: function to write chip OOB data without ECC
+ * @read_oob_raw: function to read chip OOB data without ECC
+ * @read_oob: function to read chip OOB data
+ * @write_oob: function to write chip OOB data
+ */
+struct nand_ecc_ctrl {
+ nand_ecc_modes_t mode;
+ int steps;
+ int size;
+ int bytes;
+ int total;
+ int strength;
+ int prepad;
+ int postpad;
+ unsigned int options;
+ struct nand_ecclayout *layout;
+ void *priv;
+ void (*hwctl)(struct mtd_info *mtd, int mode);
+ int (*calculate)(struct mtd_info *mtd, const uint8_t *dat,
+ uint8_t *ecc_code);
+ int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc,
+ uint8_t *calc_ecc);
+ int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf, int oob_required, int page);
+ int (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf, int oob_required, int page);
+ int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf, int oob_required, int page);
+ int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
+ uint32_t offs, uint32_t len, uint8_t *buf, int page);
+ int (*write_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
+ uint32_t offset, uint32_t data_len,
+ const uint8_t *data_buf, int oob_required, int page);
+ int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf, int oob_required, int page);
+ int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+ int page);
+ int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+ int page);
+ int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page);
+ int (*write_oob)(struct mtd_info *mtd, struct nand_chip *chip,
+ int page);
+};
+
+static inline int nand_standard_page_accessors(struct nand_ecc_ctrl *ecc)
+{
+ return !(ecc->options & NAND_ECC_CUSTOM_PAGE_ACCESS);
+}
+
+/**
+ * struct nand_buffers - buffer structure for read/write
+ * @ecccalc: buffer pointer for calculated ECC, size is oobsize.
+ * @ecccode: buffer pointer for ECC read from flash, size is oobsize.
+ * @databuf: buffer pointer for data, size is (page size + oobsize).
+ *
+ * Do not change the order of buffers. databuf and oobrbuf must be in
+ * consecutive order.
+ */
+struct nand_buffers {
+ uint8_t ecccalc[ALIGN(NAND_MAX_OOBSIZE, ARCH_DMA_MINALIGN)];
+ uint8_t ecccode[ALIGN(NAND_MAX_OOBSIZE, ARCH_DMA_MINALIGN)];
+ uint8_t databuf[ALIGN(NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE,
+ ARCH_DMA_MINALIGN)];
+};
+
+/**
+ * struct nand_sdr_timings - SDR NAND chip timings
+ *
+ * This struct defines the timing requirements of a SDR NAND chip.
+ * These information can be found in every NAND datasheets and the timings
+ * meaning are described in the ONFI specifications:
+ * www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing
+ * Parameters)
+ *
+ * All these timings are expressed in picoseconds.
+ *
+ * @tBERS_max: Block erase time
+ * @tCCS_min: Change column setup time
+ * @tPROG_max: Page program time
+ * @tR_max: Page read time
+ * @tALH_min: ALE hold time
+ * @tADL_min: ALE to data loading time
+ * @tALS_min: ALE setup time
+ * @tAR_min: ALE to RE# delay
+ * @tCEA_max: CE# access time
+ * @tCEH_min: CE# high hold time
+ * @tCH_min: CE# hold time
+ * @tCHZ_max: CE# high to output hi-Z
+ * @tCLH_min: CLE hold time
+ * @tCLR_min: CLE to RE# delay
+ * @tCLS_min: CLE setup time
+ * @tCOH_min: CE# high to output hold
+ * @tCS_min: CE# setup time
+ * @tDH_min: Data hold time
+ * @tDS_min: Data setup time
+ * @tFEAT_max: Busy time for Set Features and Get Features
+ * @tIR_min: Output hi-Z to RE# low
+ * @tITC_max: Interface and Timing Mode Change time
+ * @tRC_min: RE# cycle time
+ * @tREA_max: RE# access time
+ * @tREH_min: RE# high hold time
+ * @tRHOH_min: RE# high to output hold
+ * @tRHW_min: RE# high to WE# low
+ * @tRHZ_max: RE# high to output hi-Z
+ * @tRLOH_min: RE# low to output hold
+ * @tRP_min: RE# pulse width
+ * @tRR_min: Ready to RE# low (data only)
+ * @tRST_max: Device reset time, measured from the falling edge of R/B# to the
+ * rising edge of R/B#.
+ * @tWB_max: WE# high to SR[6] low
+ * @tWC_min: WE# cycle time
+ * @tWH_min: WE# high hold time
+ * @tWHR_min: WE# high to RE# low
+ * @tWP_min: WE# pulse width
+ * @tWW_min: WP# transition to WE# low
+ */
+struct nand_sdr_timings {
+ u64 tBERS_max;
+ u32 tCCS_min;
+ u64 tPROG_max;
+ u64 tR_max;
+ u32 tALH_min;
+ u32 tADL_min;
+ u32 tALS_min;
+ u32 tAR_min;
+ u32 tCEA_max;
+ u32 tCEH_min;
+ u32 tCH_min;
+ u32 tCHZ_max;
+ u32 tCLH_min;
+ u32 tCLR_min;
+ u32 tCLS_min;
+ u32 tCOH_min;
+ u32 tCS_min;
+ u32 tDH_min;
+ u32 tDS_min;
+ u32 tFEAT_max;
+ u32 tIR_min;
+ u32 tITC_max;
+ u32 tRC_min;
+ u32 tREA_max;
+ u32 tREH_min;
+ u32 tRHOH_min;
+ u32 tRHW_min;
+ u32 tRHZ_max;
+ u32 tRLOH_min;
+ u32 tRP_min;
+ u32 tRR_min;
+ u64 tRST_max;
+ u32 tWB_max;
+ u32 tWC_min;
+ u32 tWH_min;
+ u32 tWHR_min;
+ u32 tWP_min;
+ u32 tWW_min;
+};
+
+/**
+ * enum nand_data_interface_type - NAND interface timing type
+ * @NAND_SDR_IFACE: Single Data Rate interface
+ */
+enum nand_data_interface_type {
+ NAND_SDR_IFACE,
+};
+
+/**
+ * struct nand_data_interface - NAND interface timing
+ * @type: type of the timing
+ * @timings: The timing, type according to @type
+ */
+struct nand_data_interface {
+ enum nand_data_interface_type type;
+ union {
+ struct nand_sdr_timings sdr;
+ } timings;
+};
+
+/**
+ * nand_get_sdr_timings - get SDR timing from data interface
+ * @conf: The data interface
+ */
+static inline const struct nand_sdr_timings *
+nand_get_sdr_timings(const struct nand_data_interface *conf)
+{
+ if (conf->type != NAND_SDR_IFACE)
+ return ERR_PTR(-EINVAL);
+
+ return &conf->timings.sdr;
+}
+
+/**
+ * struct nand_chip - NAND Private Flash Chip Data
+ * @mtd: MTD device registered to the MTD framework
+ * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the
+ * flash device
+ * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the
+ * flash device.
+ * @flash_node: [BOARDSPECIFIC] device node describing this instance
+ * @read_byte: [REPLACEABLE] read one byte from the chip
+ * @read_word: [REPLACEABLE] read one word from the chip
+ * @write_byte: [REPLACEABLE] write a single byte to the chip on the
+ * low 8 I/O lines
+ * @write_buf: [REPLACEABLE] write data from the buffer to the chip
+ * @read_buf: [REPLACEABLE] read data from the chip into the buffer
+ * @select_chip: [REPLACEABLE] select chip nr
+ * @block_bad: [REPLACEABLE] check if a block is bad, using OOB markers
+ * @block_markbad: [REPLACEABLE] mark a block bad
+ * @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific function for controlling
+ * ALE/CLE/nCE. Also used to write command and address
+ * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accessing
+ * device ready/busy line. If set to NULL no access to
+ * ready/busy is available and the ready/busy information
+ * is read from the chip status register.
+ * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing
+ * commands to the chip.
+ * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on
+ * ready.
+ * @setup_read_retry: [FLASHSPECIFIC] flash (vendor) specific function for
+ * setting the read-retry mode. Mostly needed for MLC NAND.
+ * @ecc: [BOARDSPECIFIC] ECC control structure
+ * @buffers: buffer structure for read/write
+ * @buf_align: minimum buffer alignment required by a platform
+ * @hwcontrol: platform-specific hardware control structure
+ * @erase: [REPLACEABLE] erase function
+ * @scan_bbt: [REPLACEABLE] function to scan bad block table
+ * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transferring
+ * data from array to read regs (tR).
+ * @state: [INTERN] the current state of the NAND device
+ * @oob_poi: "poison value buffer," used for laying out OOB data
+ * before writing
+ * @page_shift: [INTERN] number of address bits in a page (column
+ * address bits).
+ * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock
+ * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
+ * @chip_shift: [INTERN] number of address bits in one chip
+ * @options: [BOARDSPECIFIC] various chip options. They can partly
+ * be set to inform nand_scan about special functionality.
+ * See the defines for further explanation.
+ * @bbt_options: [INTERN] bad block specific options. All options used
+ * here must come from bbm.h. By default, these options
+ * will be copied to the appropriate nand_bbt_descr's.
+ * @badblockpos: [INTERN] position of the bad block marker in the oob
+ * area.
+ * @badblockbits: [INTERN] minimum number of set bits in a good block's
+ * bad block marker position; i.e., BBM == 11110111b is
+ * not bad when badblockbits == 7
+ * @bits_per_cell: [INTERN] number of bits per cell. i.e., 1 means SLC.
+ * @ecc_strength_ds: [INTERN] ECC correctability from the datasheet.
+ * Minimum amount of bit errors per @ecc_step_ds guaranteed
+ * to be correctable. If unknown, set to zero.
+ * @ecc_step_ds: [INTERN] ECC step required by the @ecc_strength_ds,
+ * also from the datasheet. It is the recommended ECC step
+ * size, if known; if unknown, set to zero.
+ * @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is
+ * set to the actually used ONFI mode if the chip is
+ * ONFI compliant or deduced from the datasheet if
+ * the NAND chip is not ONFI compliant.
+ * @numchips: [INTERN] number of physical chips
+ * @chipsize: [INTERN] the size of one chip for multichip arrays
+ * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
+ * @pagebuf: [INTERN] holds the pagenumber which is currently in
+ * data_buf.
+ * @pagebuf_bitflips: [INTERN] holds the bitflip count for the page which is
+ * currently in data_buf.
+ * @subpagesize: [INTERN] holds the subpagesize
+ * @onfi_version: [INTERN] holds the chip ONFI version (BCD encoded),
+ * non 0 if ONFI supported.
+ * @jedec_version: [INTERN] holds the chip JEDEC version (BCD encoded),
+ * non 0 if JEDEC supported.
+ * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is
+ * supported, 0 otherwise.
+ * @jedec_params: [INTERN] holds the JEDEC parameter page when JEDEC is
+ * supported, 0 otherwise.
+ * @read_retries: [INTERN] the number of read retry modes supported
+ * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
+ * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
+ * @setup_data_interface: [OPTIONAL] setup the data interface and timing. If
+ * chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this
+ * means the configuration should not be applied but
+ * only checked.
+ * @bbt: [INTERN] bad block table pointer
+ * @bbt_td: [REPLACEABLE] bad block table descriptor for flash
+ * lookup.
+ * @bbt_md: [REPLACEABLE] bad block table mirror descriptor
+ * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial
+ * bad block scan.
+ * @controller: [REPLACEABLE] a pointer to a hardware controller
+ * structure which is shared among multiple independent
+ * devices.
+ * @priv: [OPTIONAL] pointer to private chip data
+ * @write_page: [REPLACEABLE] High-level page write function
+ */
+
+struct nand_chip {
+ struct mtd_info mtd;
+ void __iomem *IO_ADDR_R;
+ void __iomem *IO_ADDR_W;
+
+ int flash_node;
+
+ uint8_t (*read_byte)(struct mtd_info *mtd);
+ u16 (*read_word)(struct mtd_info *mtd);
+ void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
+ void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
+ void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
+ void (*select_chip)(struct mtd_info *mtd, int chip);
+ int (*block_bad)(struct mtd_info *mtd, loff_t ofs);
+ int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
+ void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
+ int (*dev_ready)(struct mtd_info *mtd);
+ void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column,
+ int page_addr);
+ int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
+ int (*erase)(struct mtd_info *mtd, int page);
+ int (*scan_bbt)(struct mtd_info *mtd);
+ int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+ uint32_t offset, int data_len, const uint8_t *buf,
+ int oob_required, int page, int raw);
+ int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
+ int feature_addr, uint8_t *subfeature_para);
+ int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
+ int feature_addr, uint8_t *subfeature_para);
+ int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode);
+ int (*setup_data_interface)(struct mtd_info *mtd, int chipnr,
+ const struct nand_data_interface *conf);
+
+
+ int chip_delay;
+ unsigned int options;
+ unsigned int bbt_options;
+
+ int page_shift;
+ int phys_erase_shift;
+ int bbt_erase_shift;
+ int chip_shift;
+ int numchips;
+ uint64_t chipsize;
+ int pagemask;
+ int pagebuf;
+ unsigned int pagebuf_bitflips;
+ int subpagesize;
+ uint8_t bits_per_cell;
+ uint16_t ecc_strength_ds;
+ uint16_t ecc_step_ds;
+ int onfi_timing_mode_default;
+ int badblockpos;
+ int badblockbits;
+
+ int onfi_version;
+ int jedec_version;
+ struct nand_onfi_params onfi_params;
+ struct nand_jedec_params jedec_params;
+
+ struct nand_data_interface *data_interface;
+
+ int read_retries;
+
+ flstate_t state;
+
+ uint8_t *oob_poi;
+ struct nand_hw_control *controller;
+ struct nand_ecclayout *ecclayout;
+
+ struct nand_ecc_ctrl ecc;
+ struct nand_buffers *buffers;
+ unsigned long buf_align;
+ struct nand_hw_control hwcontrol;
+
+ uint8_t *bbt;
+ struct nand_bbt_descr *bbt_td;
+ struct nand_bbt_descr *bbt_md;
+
+ struct nand_bbt_descr *badblock_pattern;
+
+ void *priv;
+};
+
+static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd)
+{
+ return container_of(mtd, struct nand_chip, mtd);
+}
+
+static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip)
+{
+ return &chip->mtd;
+}
+
+static inline void *nand_get_controller_data(struct nand_chip *chip)
+{
+ return chip->priv;
+}
+
+static inline void nand_set_controller_data(struct nand_chip *chip, void *priv)
+{
+ chip->priv = priv;
+}
+
+/*
+ * NAND Flash Manufacturer ID Codes
+ */
+#define NAND_MFR_TOSHIBA 0x98
+#define NAND_MFR_SAMSUNG 0xec
+#define NAND_MFR_FUJITSU 0x04
+#define NAND_MFR_NATIONAL 0x8f
+#define NAND_MFR_RENESAS 0x07
+#define NAND_MFR_STMICRO 0x20
+#define NAND_MFR_HYNIX 0xad
+#define NAND_MFR_MICRON 0x2c
+#define NAND_MFR_AMD 0x01
+#define NAND_MFR_MACRONIX 0xc2
+#define NAND_MFR_EON 0x92
+#define NAND_MFR_SANDISK 0x45
+#define NAND_MFR_INTEL 0x89
+#define NAND_MFR_ATO 0x9b
+
+/* The maximum expected count of bytes in the NAND ID sequence */
+#define NAND_MAX_ID_LEN 8
+
+/*
+ * A helper for defining older NAND chips where the second ID byte fully
+ * defined the chip, including the geometry (chip size, eraseblock size, page
+ * size). All these chips have 512 bytes NAND page size.
+ */
+#define LEGACY_ID_NAND(nm, devid, chipsz, erasesz, opts) \
+ { .name = (nm), {{ .dev_id = (devid) }}, .pagesize = 512, \
+ .chipsize = (chipsz), .erasesize = (erasesz), .options = (opts) }
+
+/*
+ * A helper for defining newer chips which report their page size and
+ * eraseblock size via the extended ID bytes.
+ *
+ * The real difference between LEGACY_ID_NAND and EXTENDED_ID_NAND is that with
+ * EXTENDED_ID_NAND, manufacturers overloaded the same device ID so that the
+ * device ID now only represented a particular total chip size (and voltage,
+ * buswidth), and the page size, eraseblock size, and OOB size could vary while
+ * using the same device ID.
+ */
+#define EXTENDED_ID_NAND(nm, devid, chipsz, opts) \
+ { .name = (nm), {{ .dev_id = (devid) }}, .chipsize = (chipsz), \
+ .options = (opts) }
+
+#define NAND_ECC_INFO(_strength, _step) \
+ { .strength_ds = (_strength), .step_ds = (_step) }
+#define NAND_ECC_STRENGTH(type) ((type)->ecc.strength_ds)
+#define NAND_ECC_STEP(type) ((type)->ecc.step_ds)
+
+/**
+ * struct nand_flash_dev - NAND Flash Device ID Structure
+ * @name: a human-readable name of the NAND chip
+ * @dev_id: the device ID (the second byte of the full chip ID array)
+ * @mfr_id: manufecturer ID part of the full chip ID array (refers the same
+ * memory address as @id[0])
+ * @dev_id: device ID part of the full chip ID array (refers the same memory
+ * address as @id[1])
+ * @id: full device ID array
+ * @pagesize: size of the NAND page in bytes; if 0, then the real page size (as
+ * well as the eraseblock size) is determined from the extended NAND
+ * chip ID array)
+ * @chipsize: total chip size in MiB
+ * @erasesize: eraseblock size in bytes (determined from the extended ID if 0)
+ * @options: stores various chip bit options
+ * @id_len: The valid length of the @id.
+ * @oobsize: OOB size
+ * @ecc: ECC correctability and step information from the datasheet.
+ * @ecc.strength_ds: The ECC correctability from the datasheet, same as the
+ * @ecc_strength_ds in nand_chip{}.
+ * @ecc.step_ds: The ECC step required by the @ecc.strength_ds, same as the
+ * @ecc_step_ds in nand_chip{}, also from the datasheet.
+ * For example, the "4bit ECC for each 512Byte" can be set with
+ * NAND_ECC_INFO(4, 512).
+ * @onfi_timing_mode_default: the default ONFI timing mode entered after a NAND
+ * reset. Should be deduced from timings described
+ * in the datasheet.
+ *
+ */
+struct nand_flash_dev {
+ char *name;
+ union {
+ struct {
+ uint8_t mfr_id;
+ uint8_t dev_id;
+ };
+ uint8_t id[NAND_MAX_ID_LEN];
+ };
+ unsigned int pagesize;
+ unsigned int chipsize;
+ unsigned int erasesize;
+ unsigned int options;
+ uint16_t id_len;
+ uint16_t oobsize;
+ struct {
+ uint16_t strength_ds;
+ uint16_t step_ds;
+ } ecc;
+ int onfi_timing_mode_default;
+};
+
+/**
+ * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
+ * @name: Manufacturer name
+ * @id: manufacturer ID code of device.
+*/
+struct nand_manufacturers {
+ int id;
+ char *name;
+};
+
+extern struct nand_flash_dev nand_flash_ids[];
+extern struct nand_manufacturers nand_manuf_ids[];
+
+int nand_default_bbt(struct mtd_info *mtd);
+int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);
+int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs);
+int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
+int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
+ int allowbbt);
+int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, uint8_t *buf);
+
+/*
+* Constants for oob configuration
+*/
+#define NAND_SMALL_BADBLOCK_POS 5
+#define NAND_LARGE_BADBLOCK_POS 0
+
+/**
+ * struct platform_nand_chip - chip level device structure
+ * @nr_chips: max. number of chips to scan for
+ * @chip_offset: chip number offset
+ * @nr_partitions: number of partitions pointed to by partitions (or zero)
+ * @partitions: mtd partition list
+ * @chip_delay: R/B delay value in us
+ * @options: Option flags, e.g. 16bit buswidth
+ * @bbt_options: BBT option flags, e.g. NAND_BBT_USE_FLASH
+ * @part_probe_types: NULL-terminated array of probe types
+ */
+struct platform_nand_chip {
+ int nr_chips;
+ int chip_offset;
+ int nr_partitions;
+ struct mtd_partition *partitions;
+ int chip_delay;
+ unsigned int options;
+ unsigned int bbt_options;
+ const char **part_probe_types;
+};
+
+/* Keep gcc happy */
+struct platform_device;
+
+/**
+ * struct platform_nand_ctrl - controller level device structure
+ * @probe: platform specific function to probe/setup hardware
+ * @remove: platform specific function to remove/teardown hardware
+ * @hwcontrol: platform specific hardware control structure
+ * @dev_ready: platform specific function to read ready/busy pin
+ * @select_chip: platform specific chip select function
+ * @cmd_ctrl: platform specific function for controlling
+ * ALE/CLE/nCE. Also used to write command and address
+ * @write_buf: platform specific function for write buffer
+ * @read_buf: platform specific function for read buffer
+ * @read_byte: platform specific function to read one byte from chip
+ * @priv: private data to transport driver specific settings
+ *
+ * All fields are optional and depend on the hardware driver requirements
+ */
+struct platform_nand_ctrl {
+ int (*probe)(struct platform_device *pdev);
+ void (*remove)(struct platform_device *pdev);
+ void (*hwcontrol)(struct mtd_info *mtd, int cmd);
+ int (*dev_ready)(struct mtd_info *mtd);
+ void (*select_chip)(struct mtd_info *mtd, int chip);
+ void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
+ void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
+ void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
+ unsigned char (*read_byte)(struct mtd_info *mtd);
+ void *priv;
+};
+
+/**
+ * struct platform_nand_data - container structure for platform-specific data
+ * @chip: chip level chip structure
+ * @ctrl: controller level device structure
+ */
+struct platform_nand_data {
+ struct platform_nand_chip chip;
+ struct platform_nand_ctrl ctrl;
+};
+
+#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
+/* return the supported features. */
+static inline int onfi_feature(struct nand_chip *chip)
+{
+ return chip->onfi_version ? le16_to_cpu(chip->onfi_params.features) : 0;
+}
+
+/* return the supported asynchronous timing mode. */
+static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
+{
+ if (!chip->onfi_version)
+ return ONFI_TIMING_MODE_UNKNOWN;
+ return le16_to_cpu(chip->onfi_params.async_timing_mode);
+}
+
+/* return the supported synchronous timing mode. */
+static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
+{
+ if (!chip->onfi_version)
+ return ONFI_TIMING_MODE_UNKNOWN;
+ return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
+}
+#else
+static inline int onfi_feature(struct nand_chip *chip)
+{
+ return 0;
+}
+
+static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
+{
+ return ONFI_TIMING_MODE_UNKNOWN;
+}
+
+static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
+{
+ return ONFI_TIMING_MODE_UNKNOWN;
+}
+#endif
+
+int onfi_init_data_interface(struct nand_chip *chip,
+ struct nand_data_interface *iface,
+ enum nand_data_interface_type type,
+ int timing_mode);
+
+/*
+ * Check if it is a SLC nand.
+ * The !nand_is_slc() can be used to check the MLC/TLC nand chips.
+ * We do not distinguish the MLC and TLC now.
+ */
+static inline bool nand_is_slc(struct nand_chip *chip)
+{
+ return chip->bits_per_cell == 1;
+}
+
+/**
+ * Check if the opcode's address should be sent only on the lower 8 bits
+ * @command: opcode to check
+ */
+static inline int nand_opcode_8bits(unsigned int command)
+{
+ switch (command) {
+ case NAND_CMD_READID:
+ case NAND_CMD_PARAM:
+ case NAND_CMD_GET_FEATURES:
+ case NAND_CMD_SET_FEATURES:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* return the supported JEDEC features. */
+static inline int jedec_feature(struct nand_chip *chip)
+{
+ return chip->jedec_version ? le16_to_cpu(chip->jedec_params.features)
+ : 0;
+}
+
+/* Standard NAND functions from nand_base.c */
+void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len);
+void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len);
+void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
+void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
+uint8_t nand_read_byte(struct mtd_info *mtd);
+
+/* get timing characteristics from ONFI timing mode. */
+const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);
+/* get data interface from ONFI timing mode 0, used after reset. */
+const struct nand_data_interface *nand_get_default_data_interface(void);
+
+int nand_check_erased_ecc_chunk(void *data, int datalen,
+ void *ecc, int ecclen,
+ void *extraoob, int extraooblen,
+ int threshold);
+
+int nand_check_ecc_caps(struct nand_chip *chip,
+ const struct nand_ecc_caps *caps, int oobavail);
+
+int nand_match_ecc_req(struct nand_chip *chip,
+ const struct nand_ecc_caps *caps, int oobavail);
+
+int nand_maximize_ecc(struct nand_chip *chip,
+ const struct nand_ecc_caps *caps, int oobavail);
+
+/* Reset and initialize a NAND device */
+int nand_reset(struct nand_chip *chip, int chipnr);
+#endif /* __LINUX_MTD_RAWNAND_H */
#include <linux/compat.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
+#include <linux/mtd/rawnand.h>
int nand_mtd_to_devnum(struct mtd_info *mtd);
--- /dev/null
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __TEST_COMPRESSION_H__
+#define __TEST_COMPRESSION_H__
+
+#include <test/test.h>
+
+/* Declare a new compression test */
+#define COMPRESSION_TEST(_name, _flags) \
+ UNIT_TEST(_name, _flags, compression_test)
+
+#endif /* __TEST_ENV_H__ */
#ifndef __TEST_SUITES_H__
#define __TEST_SUITES_H__
+struct unit_test;
+
+/**
+ * cmd_ut_category() - Run a category of unit tests
+ *
+ * @name: Category name
+ * @tests: List of tests to run
+ * @n_ents: Number of tests in @tests
+ * @argc: Argument count provided. Must be <= 1. If this is 1 then all
+ * tests are run, otherwise only the one named @argv[1] is run.
+ * @argv: Arguments: argv[1] is the test to run (if @argc >= 2)
+ * @return 0 if OK, CMD_RET_FAILURE on failure
+ */
+int cmd_ut_category(const char *name, struct unit_test *tests, int n_ents,
+ int argc, char * const argv[]);
+
int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
int do_ut_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
int do_ut_overlay(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
int do_ut_time(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
#endif /* __TEST_SUITES_H__ */
# Use upstream code.
obj-y += \
fdt.o \
+ fdt_wip.o \
fdt_strerror.o \
fdt_sw.o \
fdt_empty_tree.o \
# TODO: split out the local modifiction.
obj-y += \
fdt_ro.o \
- fdt_rw.o \
- fdt_wip.o \
+ fdt_rw.o
# U-Boot own file
obj-y += fdt_region.o
#include "libfdt_internal.h"
+#define FDT_MAX_DEPTH 32
+
+static int str_in_list(const char *str, char * const list[], int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ if (!strcmp(list[i], str))
+ return 1;
+
+ return 0;
+}
+
+int fdt_find_regions(const void *fdt, char * const inc[], int inc_count,
+ char * const exc_prop[], int exc_prop_count,
+ struct fdt_region region[], int max_regions,
+ char *path, int path_len, int add_string_tab)
+{
+ int stack[FDT_MAX_DEPTH] = { 0 };
+ char *end;
+ int nextoffset = 0;
+ uint32_t tag;
+ int count = 0;
+ int start = -1;
+ int depth = -1;
+ int want = 0;
+ int base = fdt_off_dt_struct(fdt);
+
+ end = path;
+ *end = '\0';
+ do {
+ const struct fdt_property *prop;
+ const char *name;
+ const char *str;
+ int include = 0;
+ int stop_at = 0;
+ int offset;
+ int len;
+
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+ stop_at = nextoffset;
+
+ switch (tag) {
+ case FDT_PROP:
+ include = want >= 2;
+ stop_at = offset;
+ prop = fdt_get_property_by_offset(fdt, offset, NULL);
+ str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+ if (str_in_list(str, exc_prop, exc_prop_count))
+ include = 0;
+ break;
+
+ case FDT_NOP:
+ include = want >= 2;
+ stop_at = offset;
+ break;
+
+ case FDT_BEGIN_NODE:
+ depth++;
+ if (depth == FDT_MAX_DEPTH)
+ return -FDT_ERR_BADSTRUCTURE;
+ name = fdt_get_name(fdt, offset, &len);
+ if (end - path + 2 + len >= path_len)
+ return -FDT_ERR_NOSPACE;
+ if (end != path + 1)
+ *end++ = '/';
+ strcpy(end, name);
+ end += len;
+ stack[depth] = want;
+ if (want == 1)
+ stop_at = offset;
+ if (str_in_list(path, inc, inc_count))
+ want = 2;
+ else if (want)
+ want--;
+ else
+ stop_at = offset;
+ include = want;
+ break;
+
+ case FDT_END_NODE:
+ include = want;
+ want = stack[depth--];
+ while (end > path && *--end != '/')
+ ;
+ *end = '\0';
+ break;
+
+ case FDT_END:
+ include = 1;
+ break;
+ }
+
+ if (include && start == -1) {
+ /* Should we merge with previous? */
+ if (count && count <= max_regions &&
+ offset == region[count - 1].offset +
+ region[count - 1].size - base)
+ start = region[--count].offset - base;
+ else
+ start = offset;
+ }
+
+ if (!include && start != -1) {
+ if (count < max_regions) {
+ region[count].offset = base + start;
+ region[count].size = stop_at - start;
+ }
+ count++;
+ start = -1;
+ }
+ } while (tag != FDT_END);
+
+ if (nextoffset != fdt_size_dt_struct(fdt))
+ return -FDT_ERR_BADLAYOUT;
+
+ /* Add a region for the END tag and the string table */
+ if (count < max_regions) {
+ region[count].offset = base + start;
+ region[count].size = nextoffset - start;
+ if (add_string_tab)
+ region[count].size += fdt_size_dt_strings(fdt);
+ }
+ count++;
+
+ return count;
+}
+
/**
* fdt_add_region() - Add a new region to our list
* @info: State information
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
- */
-#include <libfdt_env.h>
-
-#ifndef USE_HOSTCC
-#include <fdt.h>
-#include <libfdt.h>
-#else
-#include "fdt_host.h"
-#endif
-
-#include "libfdt_internal.h"
-
-int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
- const char *name, int namelen,
- uint32_t idx, const void *val,
- int len)
-{
- void *propval;
- int proplen;
-
- propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,
- &proplen);
- if (!propval)
- return proplen;
-
- if (proplen < (len + idx))
- return -FDT_ERR_NOSPACE;
-
- memcpy((char *)propval + idx, val, len);
- return 0;
-}
-
-int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
-{
- const void *propval;
- int proplen;
-
- propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
- if (!propval)
- return proplen;
-
- if (proplen != len)
- return -FDT_ERR_NOSPACE;
-
- return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
- strlen(name), 0,
- val, len);
-}
-
-static void _fdt_nop_region(void *start, int len)
-{
- fdt32_t *p;
-
- for (p = start; (char *)p < ((char *)start + len); p++)
- *p = cpu_to_fdt32(FDT_NOP);
-}
-
-int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
-{
- struct fdt_property *prop;
- int len;
-
- prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (!prop)
- return len;
-
- _fdt_nop_region(prop, len + sizeof(*prop));
-
- return 0;
-}
-
-int _fdt_node_end_offset(void *fdt, int offset)
-{
- int depth = 0;
-
- while ((offset >= 0) && (depth >= 0))
- offset = fdt_next_node(fdt, offset, &depth);
-
- return offset;
-}
-
-int fdt_nop_node(void *fdt, int nodeoffset)
-{
- int endoffset;
-
- endoffset = _fdt_node_end_offset(fdt, nodeoffset);
- if (endoffset < 0)
- return endoffset;
-
- _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
- endoffset - nodeoffset);
- return 0;
-}
-
-#define FDT_MAX_DEPTH 32
-
-static int str_in_list(const char *str, char * const list[], int count)
-{
- int i;
-
- for (i = 0; i < count; i++)
- if (!strcmp(list[i], str))
- return 1;
-
- return 0;
-}
-
-int fdt_find_regions(const void *fdt, char * const inc[], int inc_count,
- char * const exc_prop[], int exc_prop_count,
- struct fdt_region region[], int max_regions,
- char *path, int path_len, int add_string_tab)
-{
- int stack[FDT_MAX_DEPTH] = { 0 };
- char *end;
- int nextoffset = 0;
- uint32_t tag;
- int count = 0;
- int start = -1;
- int depth = -1;
- int want = 0;
- int base = fdt_off_dt_struct(fdt);
-
- end = path;
- *end = '\0';
- do {
- const struct fdt_property *prop;
- const char *name;
- const char *str;
- int include = 0;
- int stop_at = 0;
- int offset;
- int len;
-
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
- stop_at = nextoffset;
-
- switch (tag) {
- case FDT_PROP:
- include = want >= 2;
- stop_at = offset;
- prop = fdt_get_property_by_offset(fdt, offset, NULL);
- str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
- if (str_in_list(str, exc_prop, exc_prop_count))
- include = 0;
- break;
-
- case FDT_NOP:
- include = want >= 2;
- stop_at = offset;
- break;
-
- case FDT_BEGIN_NODE:
- depth++;
- if (depth == FDT_MAX_DEPTH)
- return -FDT_ERR_BADSTRUCTURE;
- name = fdt_get_name(fdt, offset, &len);
- if (end - path + 2 + len >= path_len)
- return -FDT_ERR_NOSPACE;
- if (end != path + 1)
- *end++ = '/';
- strcpy(end, name);
- end += len;
- stack[depth] = want;
- if (want == 1)
- stop_at = offset;
- if (str_in_list(path, inc, inc_count))
- want = 2;
- else if (want)
- want--;
- else
- stop_at = offset;
- include = want;
- break;
-
- case FDT_END_NODE:
- include = want;
- want = stack[depth--];
- while (end > path && *--end != '/')
- ;
- *end = '\0';
- break;
-
- case FDT_END:
- include = 1;
- break;
- }
-
- if (include && start == -1) {
- /* Should we merge with previous? */
- if (count && count <= max_regions &&
- offset == region[count - 1].offset +
- region[count - 1].size - base)
- start = region[--count].offset - base;
- else
- start = offset;
- }
-
- if (!include && start != -1) {
- if (count < max_regions) {
- region[count].offset = base + start;
- region[count].size = stop_at - start;
- }
- count++;
- start = -1;
- }
- } while (tag != FDT_END);
-
- if (nextoffset != fdt_size_dt_struct(fdt))
- return -FDT_ERR_BADLAYOUT;
-
- /* Add a region for the END tag and the string table */
- if (count < max_regions) {
- region[count].offset = base + start;
- region[count].size = nextoffset - start;
- if (add_string_tab)
- region[count].size += fdt_size_dt_strings(fdt);
- }
- count++;
-
- return count;
-}
+#include <linux/libfdt_env.h>
+#include "../../scripts/dtc/libfdt/fdt_wip.c"
ifndef CONFIG_SPL_DM
CONFIG_DM_SERIAL=
CONFIG_DM_GPIO=
-CONIFG_DM_I2C=
+CONFIG_DM_I2C=
CONFIG_DM_SPI=
CONFIG_DM_SPI_FLASH=
endif
#include <common.h>
#include <command.h>
#include <test/suites.h>
+#include <test/test.h>
static int do_ut_all(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int cmd_ut_category(const char *name, struct unit_test *tests, int n_ents,
+ int argc, char * const argv[])
+{
+ struct unit_test_state uts = { .fail_count = 0 };
+ struct unit_test *test;
+
+ if (argc == 1)
+ printf("Running %d %s tests\n", n_ents, name);
+
+ for (test = tests; test < tests + n_ents; test++) {
+ if (argc > 1 && strcmp(argv[1], test->name))
+ continue;
+ printf("Test: %s\n", test->name);
+
+ uts.start = mallinfo();
+
+ test->func(&uts);
+ }
+
+ printf("Failures: %d\n", uts.fail_count);
+
+ return uts.fail_count ? CMD_RET_FAILURE : 0;
+}
+
static cmd_tbl_t cmd_ut_sub[] = {
U_BOOT_CMD_MKENT(all, CONFIG_SYS_MAXARGS, 1, do_ut_all, "", ""),
#if defined(CONFIG_UT_DM)
#ifdef CONFIG_UT_TIME
U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""),
#endif
+#ifdef CONFIG_SANDBOX
+ U_BOOT_CMD_MKENT(compression, CONFIG_SYS_MAXARGS, 1, do_ut_compression,
+ "", ""),
+#endif
};
static int do_ut_all(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#endif
#ifdef CONFIG_UT_TIME
"ut time - Very basic test of time functions\n"
+#endif
+#ifdef CONFIG_SANDBOX
+ "ut compression - Test compressors and bootm decompression\n"
#endif
;
#endif
* SPDX-License-Identifier: GPL-2.0+
*/
-#define DEBUG
-
#include <common.h>
#include <bootm.h>
#include <command.h>
#include <lzma/LzmaTools.h>
#include <linux/lzo.h>
+#include <test/compression.h>
+#include <test/suites.h>
+#include <test/ut.h>
static const char plain[] =
"I am a highly compressable bit of text.\n"
#define TEST_BUFFER_SIZE 512
-typedef int (*mutate_func)(void *, unsigned long, void *, unsigned long,
- unsigned long *);
+typedef int (*mutate_func)(struct unit_test_state *uts, void *, unsigned long,
+ void *, unsigned long, unsigned long *);
-static int compress_using_gzip(void *in, unsigned long in_size,
+static int compress_using_gzip(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
return ret;
}
-static int uncompress_using_gzip(void *in, unsigned long in_size,
+static int uncompress_using_gzip(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
return ret;
}
-static int compress_using_bzip2(void *in, unsigned long in_size,
+static int compress_using_bzip2(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
/* There is no bzip2 compression in u-boot, so fake it. */
- assert(in_size == strlen(plain));
- assert(memcmp(plain, in, in_size) == 0);
+ ut_asserteq(in_size, strlen(plain));
+ ut_asserteq(0, memcmp(plain, in, in_size));
if (bzip2_compressed_size > out_max)
return -1;
return 0;
}
-static int uncompress_using_bzip2(void *in, unsigned long in_size,
+static int uncompress_using_bzip2(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
return (ret != BZ_OK);
}
-static int compress_using_lzma(void *in, unsigned long in_size,
+static int compress_using_lzma(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
/* There is no lzma compression in u-boot, so fake it. */
- assert(in_size == strlen(plain));
- assert(memcmp(plain, in, in_size) == 0);
+ ut_asserteq(in_size, strlen(plain));
+ ut_asserteq(0, memcmp(plain, in, in_size));
if (lzma_compressed_size > out_max)
return -1;
return 0;
}
-static int uncompress_using_lzma(void *in, unsigned long in_size,
+static int uncompress_using_lzma(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
return (ret != SZ_OK);
}
-static int compress_using_lzo(void *in, unsigned long in_size,
+static int compress_using_lzo(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
/* There is no lzo compression in u-boot, so fake it. */
- assert(in_size == strlen(plain));
- assert(memcmp(plain, in, in_size) == 0);
+ ut_asserteq(in_size, strlen(plain));
+ ut_asserteq(0, memcmp(plain, in, in_size));
if (lzo_compressed_size > out_max)
return -1;
return 0;
}
-static int uncompress_using_lzo(void *in, unsigned long in_size,
+static int uncompress_using_lzo(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
return (ret != LZO_E_OK);
}
-static int compress_using_lz4(void *in, unsigned long in_size,
+static int compress_using_lz4(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
/* There is no lz4 compression in u-boot, so fake it. */
- assert(in_size == strlen(plain));
- assert(memcmp(plain, in, in_size) == 0);
+ ut_asserteq(in_size, strlen(plain));
+ ut_asserteq(0, memcmp(plain, in, in_size));
if (lz4_compressed_size > out_max)
return -1;
return 0;
}
-static int uncompress_using_lz4(void *in, unsigned long in_size,
+static int uncompress_using_lz4(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
goto out; \
}
-static int run_test(char *name, mutate_func compress, mutate_func uncompress)
-{
- ulong orig_size, compressed_size, uncompressed_size;
+struct buf_state {
+ ulong orig_size;
+ ulong compressed_size;
+ ulong uncompressed_size;
void *orig_buf;
- void *compressed_buf = NULL;
- void *uncompressed_buf = NULL;
- void *compare_buf = NULL;
+ void *compressed_buf;
+ void *uncompressed_buf;
+ void *compare_buf;
+};
+
+static int run_test_internal(struct unit_test_state *uts, char *name,
+ mutate_func compress, mutate_func uncompress,
+ struct buf_state *buf)
+{
int ret;
- printf(" testing %s ...\n", name);
-
- orig_buf = (void *)plain;
- orig_size = strlen(orig_buf); /* Trailing NULL not included. */
- errcheck(orig_size > 0);
-
- compressed_size = uncompressed_size = TEST_BUFFER_SIZE;
- compressed_buf = malloc(compressed_size);
- errcheck(compressed_buf != NULL);
- uncompressed_buf = malloc(uncompressed_size);
- errcheck(uncompressed_buf != NULL);
- compare_buf = malloc(uncompressed_size);
- errcheck(compare_buf != NULL);
-
/* Compress works as expected. */
- printf("\torig_size:%lu\n", orig_size);
- memset(compressed_buf, 'A', TEST_BUFFER_SIZE);
- errcheck(compress(orig_buf, orig_size,
- compressed_buf, compressed_size,
- &compressed_size) == 0);
- printf("\tcompressed_size:%lu\n", compressed_size);
- errcheck(compressed_size > 0);
- errcheck(compressed_size < orig_size);
- errcheck(((char *)compressed_buf)[compressed_size-1] != 'A');
- errcheck(((char *)compressed_buf)[compressed_size] == 'A');
+ printf("\torig_size:%lu\n", buf->orig_size);
+ memset(buf->compressed_buf, 'A', TEST_BUFFER_SIZE);
+ errcheck(compress(uts, buf->orig_buf, buf->orig_size,
+ buf->compressed_buf, buf->compressed_size,
+ &buf->compressed_size) == 0);
+ printf("\tcompressed_size:%lu\n", buf->compressed_size);
+ errcheck(buf->compressed_size > 0);
+ errcheck(buf->compressed_size < buf->orig_size);
+ errcheck(((char *)buf->compressed_buf)[buf->compressed_size - 1] !=
+ 'A');
+ errcheck(((char *)buf->compressed_buf)[buf->compressed_size] == 'A');
/* Uncompresses with space remaining. */
- errcheck(uncompress(compressed_buf, compressed_size,
- uncompressed_buf, uncompressed_size,
- &uncompressed_size) == 0);
- printf("\tuncompressed_size:%lu\n", uncompressed_size);
- errcheck(uncompressed_size == orig_size);
- errcheck(memcmp(orig_buf, uncompressed_buf, orig_size) == 0);
+ errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
+ buf->uncompressed_buf, buf->uncompressed_size,
+ &buf->uncompressed_size) == 0);
+ printf("\tuncompressed_size:%lu\n", buf->uncompressed_size);
+ errcheck(buf->uncompressed_size == buf->orig_size);
+ errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
+ buf->orig_size) == 0);
/* Uncompresses with exactly the right size output buffer. */
- memset(uncompressed_buf, 'A', TEST_BUFFER_SIZE);
- errcheck(uncompress(compressed_buf, compressed_size,
- uncompressed_buf, orig_size,
- &uncompressed_size) == 0);
- errcheck(uncompressed_size == orig_size);
- errcheck(memcmp(orig_buf, uncompressed_buf, orig_size) == 0);
- errcheck(((char *)uncompressed_buf)[orig_size] == 'A');
+ memset(buf->uncompressed_buf, 'A', TEST_BUFFER_SIZE);
+ errcheck(uncompress(uts, buf->compressed_buf, buf->compressed_size,
+ buf->uncompressed_buf, buf->orig_size,
+ &buf->uncompressed_size) == 0);
+ errcheck(buf->uncompressed_size == buf->orig_size);
+ errcheck(memcmp(buf->orig_buf, buf->uncompressed_buf,
+ buf->orig_size) == 0);
+ errcheck(((char *)buf->uncompressed_buf)[buf->orig_size] == 'A');
/* Make sure compression does not over-run. */
- memset(compare_buf, 'A', TEST_BUFFER_SIZE);
- ret = compress(orig_buf, orig_size,
- compare_buf, compressed_size - 1,
+ memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
+ ret = compress(uts, buf->orig_buf, buf->orig_size,
+ buf->compare_buf, buf->compressed_size - 1,
NULL);
- errcheck(((char *)compare_buf)[compressed_size] == 'A');
+ errcheck(((char *)buf->compare_buf)[buf->compressed_size] == 'A');
errcheck(ret != 0);
printf("\tcompress does not overrun\n");
/* Make sure decompression does not over-run. */
- memset(compare_buf, 'A', TEST_BUFFER_SIZE);
- ret = uncompress(compressed_buf, compressed_size,
- compare_buf, uncompressed_size - 1,
+ memset(buf->compare_buf, 'A', TEST_BUFFER_SIZE);
+ ret = uncompress(uts, buf->compressed_buf, buf->compressed_size,
+ buf->compare_buf, buf->uncompressed_size - 1,
NULL);
- errcheck(((char *)compare_buf)[uncompressed_size - 1] == 'A');
+ errcheck(((char *)buf->compare_buf)[buf->uncompressed_size - 1] == 'A');
errcheck(ret != 0);
printf("\tuncompress does not overrun\n");
/* Got here, everything is fine. */
ret = 0;
+out:
+ return ret;
+}
+
+static int run_test(struct unit_test_state *uts, char *name,
+ mutate_func compress, mutate_func uncompress)
+{
+ struct buf_state sbuf, *buf = &sbuf;
+ int ret;
+
+ printf(" testing %s ...\n", name);
+
+ buf->orig_buf = (void *)plain;
+ buf->orig_size = strlen(buf->orig_buf); /* Trailing NUL not included */
+ errcheck(buf->orig_size > 0);
+
+ buf->compressed_size = TEST_BUFFER_SIZE;
+ buf->uncompressed_size = TEST_BUFFER_SIZE;
+ buf->compressed_buf = malloc(buf->compressed_size);
+ errcheck(buf->compressed_buf);
+ buf->uncompressed_buf = malloc(buf->uncompressed_size);
+ errcheck(buf->uncompressed_buf);
+ buf->compare_buf = malloc(buf->uncompressed_size);
+ errcheck(buf->compare_buf);
+
+ ret = run_test_internal(uts, name, compress, uncompress, buf);
out:
printf(" %s: %s\n", name, ret == 0 ? "ok" : "FAILED");
- free(compare_buf);
- free(uncompressed_buf);
- free(compressed_buf);
+ free(buf->compare_buf);
+ free(buf->uncompressed_buf);
+ free(buf->compressed_buf);
return ret;
}
-static int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc,
- char *const argv[])
+static int compression_test_gzip(struct unit_test_state *uts)
{
- int err = 0;
+ return run_test(uts, "gzip", compress_using_gzip,
+ uncompress_using_gzip);
+}
+COMPRESSION_TEST(compression_test_gzip, 0);
+
+static int compression_test_bzip2(struct unit_test_state *uts)
+{
+ return run_test(uts, "bzip2", compress_using_bzip2,
+ uncompress_using_bzip2);
+}
+COMPRESSION_TEST(compression_test_bzip2, 0);
- err += run_test("gzip", compress_using_gzip, uncompress_using_gzip);
- err += run_test("bzip2", compress_using_bzip2, uncompress_using_bzip2);
- err += run_test("lzma", compress_using_lzma, uncompress_using_lzma);
- err += run_test("lzo", compress_using_lzo, uncompress_using_lzo);
- err += run_test("lz4", compress_using_lz4, uncompress_using_lz4);
+static int compression_test_lzma(struct unit_test_state *uts)
+{
+ return run_test(uts, "lzma", compress_using_lzma,
+ uncompress_using_lzma);
+}
+COMPRESSION_TEST(compression_test_lzma, 0);
- printf("ut_compression %s\n", err == 0 ? "ok" : "FAILED");
+static int compression_test_lzo(struct unit_test_state *uts)
+{
+ return run_test(uts, "lzo", compress_using_lzo, uncompress_using_lzo);
+}
+COMPRESSION_TEST(compression_test_lzo, 0);
- return err;
+static int compression_test_lz4(struct unit_test_state *uts)
+{
+ return run_test(uts, "lz4", compress_using_lz4, uncompress_using_lz4);
}
+COMPRESSION_TEST(compression_test_lz4, 0);
-static int compress_using_none(void *in, unsigned long in_size,
+static int compress_using_none(struct unit_test_state *uts,
+ void *in, unsigned long in_size,
void *out, unsigned long out_max,
unsigned long *out_size)
{
* @compress: Our function to compress data
* @return 0 if OK, non-zero on failure
*/
-static int run_bootm_test(int comp_type, mutate_func compress)
+static int run_bootm_test(struct unit_test_state *uts, int comp_type,
+ mutate_func compress)
{
ulong compress_size = 1024;
void *compress_buff;
printf("Testing: %s\n", genimg_get_comp_name(comp_type));
compress_buff = map_sysmem(image_start, 0);
unc_len = strlen(plain);
- compress((void *)plain, unc_len, compress_buff, compress_size,
+ compress(uts, (void *)plain, unc_len, compress_buff, compress_size,
&compress_size);
err = bootm_decomp_image(comp_type, load_addr, image_start,
IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
compress_buff, compress_size, unc_len,
&load_end);
- if (err)
- return err;
+ ut_assertok(err);
err = bootm_decomp_image(comp_type, load_addr, image_start,
IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
compress_buff, compress_size, unc_len - 1,
&load_end);
- if (!err)
- return -EINVAL;
+ ut_assert(err);
/* We can't detect corruption when not decompressing */
if (comp_type == IH_COMP_NONE)
IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
compress_buff, compress_size, 0x10000,
&load_end);
- if (!err)
- return -EINVAL;
+ ut_assert(err);
return 0;
}
-static int do_ut_image_decomp(cmd_tbl_t *cmdtp, int flag, int argc,
- char *const argv[])
+static int compression_test_bootm_gzip(struct unit_test_state *uts)
{
- int err = 0;
+ return run_bootm_test(uts, IH_COMP_GZIP, compress_using_gzip);
+}
+COMPRESSION_TEST(compression_test_bootm_gzip, 0);
+
+static int compression_test_bootm_bzip2(struct unit_test_state *uts)
+{
+ return run_bootm_test(uts, IH_COMP_BZIP2, compress_using_bzip2);
+}
+COMPRESSION_TEST(compression_test_bootm_bzip2, 0);
- err = run_bootm_test(IH_COMP_GZIP, compress_using_gzip);
- err |= run_bootm_test(IH_COMP_BZIP2, compress_using_bzip2);
- err |= run_bootm_test(IH_COMP_LZMA, compress_using_lzma);
- err |= run_bootm_test(IH_COMP_LZO, compress_using_lzo);
- err |= run_bootm_test(IH_COMP_LZ4, compress_using_lz4);
- err |= run_bootm_test(IH_COMP_NONE, compress_using_none);
+static int compression_test_bootm_lzma(struct unit_test_state *uts)
+{
+ return run_bootm_test(uts, IH_COMP_LZMA, compress_using_lzma);
+}
+COMPRESSION_TEST(compression_test_bootm_lzma, 0);
- printf("ut_image_decomp %s\n", err == 0 ? "ok" : "FAILED");
+static int compression_test_bootm_lzo(struct unit_test_state *uts)
+{
+ return run_bootm_test(uts, IH_COMP_LZO, compress_using_lzo);
+}
+COMPRESSION_TEST(compression_test_bootm_lzo, 0);
- return 0;
+static int compression_test_bootm_lz4(struct unit_test_state *uts)
+{
+ return run_bootm_test(uts, IH_COMP_LZ4, compress_using_lz4);
}
+COMPRESSION_TEST(compression_test_bootm_lz4, 0);
-U_BOOT_CMD(
- ut_compression, 5, 1, do_ut_compression,
- "Basic test of compressors: gzip bzip2 lzma lzo", ""
-);
+static int compression_test_bootm_none(struct unit_test_state *uts)
+{
+ return run_bootm_test(uts, IH_COMP_NONE, compress_using_none);
+}
+COMPRESSION_TEST(compression_test_bootm_none, 0);
-U_BOOT_CMD(
- ut_image_decomp, 5, 1, do_ut_image_decomp,
- "Basic test of bootm decompression", ""
-);
+int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ struct unit_test *tests = ll_entry_start(struct unit_test,
+ compression_test);
+ const int n_ents = ll_entry_count(struct unit_test, compression_test);
+
+ return cmd_ut_category("compression", tests, n_ents, argc, argv);
+}
{
struct unit_test *tests = ll_entry_start(struct unit_test, env_test);
const int n_ents = ll_entry_count(struct unit_test, env_test);
- struct unit_test_state uts = { .fail_count = 0 };
- struct unit_test *test;
- if (argc == 1)
- printf("Running %d environment tests\n", n_ents);
-
- for (test = tests; test < tests + n_ents; test++) {
- if (argc > 1 && strcmp(argv[1], test->name))
- continue;
- printf("Test: %s\n", test->name);
-
- uts.start = mallinfo();
-
- test->func(&uts);
- }
-
- printf("Failures: %d\n", uts.fail_count);
-
- return uts.fail_count ? CMD_RET_FAILURE : 0;
+ return cmd_ut_category("environment", tests, n_ents, argc, argv);
}
#include <test/ut.h>
#include <test/overlay.h>
+#include <test/suites.h>
/* 4k ought to be enough for anybody */
#define FDT_COPY_SIZE (4 * SZ_1K)
overlay_test);
const int n_ents = ll_entry_count(struct unit_test, overlay_test);
struct unit_test_state *uts;
- struct unit_test *test;
void *fdt_base = &__dtb_test_fdt_base_begin;
void *fdt_overlay = &__dtb_test_fdt_overlay_begin;
void *fdt_overlay_stacked = &__dtb_test_fdt_overlay_stacked_begin;
/* Apply the stacked overlay */
ut_assertok(fdt_overlay_apply(fdt_base_copy, fdt_overlay_stacked_copy));
- if (argc == 1)
- printf("Running %d environment tests\n", n_ents);
-
- for (test = tests; test < tests + n_ents; test++) {
- if (argc > 1 && strcmp(argv[1], test->name))
- continue;
- printf("Test: %s\n", test->name);
-
- uts->start = mallinfo();
-
- test->func(uts);
- }
-
- printf("Failures: %d\n", uts->fail_count);
- if (!uts->fail_count)
- ret = 0;
- else
- ret = CMD_RET_FAILURE;
+ ret = cmd_ut_category("overlay", tests, n_ents, argc, argv);
free(fdt_overlay_stacked_copy);
err3:
import u_boot_console_exec_attach
console = u_boot_console_exec_attach.ConsoleExecAttach(log, ubconfig)
-re_ut_test_list = re.compile(r'_u_boot_list_2_(dm|env)_test_2_\1_test_(.*)\s*$')
+re_ut_test_list = re.compile(r'_u_boot_list_2_(.*)_test_2_\1_test_(.*)\s*$')
def generate_ut_subtest(metafunc, fixture_name):
"""Provide parametrization for a ut_subtest fixture.
# The following files are synced with upstream DTC.
# Use synced versions from scripts/dtc/libfdt/.
-LIBFDT_SRCS_SYNCED := fdt.c fdt_sw.c fdt_strerror.c fdt_empty_tree.c \
+LIBFDT_SRCS_SYNCED := fdt.c fdt_wip.c fdt_sw.c fdt_strerror.c fdt_empty_tree.c \
fdt_addresses.c fdt_overlay.c
# The following files are locally modified for U-Boot (unfotunately).
# Use U-Boot own versions from lib/libfdt/.
-LIBFDT_SRCS_UNSYNCED := fdt_ro.c fdt_wip.c fdt_rw.c fdt_region.c
+LIBFDT_SRCS_UNSYNCED := fdt_ro.c fdt_rw.c fdt_region.c
LIBFDT_OBJS := $(addprefix libfdt/, $(patsubst %.c, %.o, $(LIBFDT_SRCS_SYNCED))) \
$(addprefix lib/libfdt/, $(patsubst %.c, %.o, $(LIBFDT_SRCS_UNSYNCED)))
--- /dev/null
+#include "fdt_host.h"
+#include "../scripts/dtc/libfdt/fdt_wip.c"