Merge git://git.denx.de/u-boot-sunxi

Signed-off-by: Tom Rini <trini@konsulko.com>
master
Tom Rini 6 years ago
commit e294ba0678
  1. 51
      arch/arm/dts/sun50i-a64-pine64-plus-u-boot.dtsi
  2. 7
      arch/arm/dts/sun50i-h5-orangepi-pc2.dts
  3. 17
      arch/arm/dts/sun8i-a23-a33.dtsi
  4. 6
      arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts
  5. 7
      arch/arm/dts/sun8i-h3-libretech-all-h3-cc.dts
  6. 6
      arch/arm/dts/sun8i-h3-nanopi-neo.dts
  7. 7
      arch/arm/dts/sun8i-h3-orangepi-2.dts
  8. 7
      arch/arm/dts/sun8i-h3-orangepi-one.dts
  9. 7
      arch/arm/dts/sun8i-h3-orangepi-pc.dts
  10. 8
      arch/arm/dts/sun8i-h3-orangepi-plus.dts
  11. 9
      arch/arm/dts/sun8i-h3-orangepi-plus2e.dts
  12. 69
      arch/arm/dts/sun8i-h3.dtsi
  13. 14
      arch/arm/dts/sun8i-r16-nintendo-nes-classic-edition.dts
  14. 6
      arch/arm/include/asm/arch-sunxi/clock_sun6i.h
  15. 6
      board/sunxi/README.sunxi64
  16. 7
      board/sunxi/board.c
  17. 5
      cmd/Kconfig
  18. 10
      common/spl/spl.c
  19. 6
      configs/CHIP_pro_defconfig
  20. 4
      configs/Nintendo_NES_Classic_Edition_defconfig
  21. 1
      configs/pine64_plus_defconfig
  22. 3
      drivers/gpio/sunxi_gpio.c
  23. 26
      drivers/mtd/nand/Kconfig
  24. 8
      drivers/mtd/nand/sunxi_nand.c
  25. 236
      drivers/mtd/nand/sunxi_nand_spl.c
  26. 89
      drivers/net/sun8i_emac.c
  27. 2
      drivers/video/Kconfig
  28. 1
      env/Kconfig
  29. 1
      lib/Kconfig

@ -4,25 +4,38 @@
};
soc {
emac: ethernet@01c30000 {
syscon: syscon@1c00000 {
compatible = "allwinner,sun50i-a64-system-controller",
"syscon";
reg = <0x01c00000 0x1000>;
};
emac: ethernet@1c30000 {
compatible = "allwinner,sun50i-a64-emac";
reg = <0x01c30000 0x2000>, <0x01c00030 0x4>;
reg-names = "emac", "syscon";
syscon = <&syscon>;
reg = <0x01c30000 0x10000>;
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
resets = <&ccu RST_BUS_EMAC>;
reset-names = "ahb";
reset-names = "stmmaceth";
clocks = <&ccu CLK_BUS_EMAC>;
clock-names = "ahb";
clock-names = "stmmaceth";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>;
phy-mode = "rgmii";
phy = <&phy1>;
phy-handle = <&ext_rgmii_phy>;
status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
mdio: mdio {
compatible = "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
ext_rgmii_phy: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
};
};
};
@ -30,21 +43,17 @@
&pio {
rmii_pins: rmii_pins {
allwinner,pins = "PD10", "PD11", "PD13", "PD14",
"PD17", "PD18", "PD19", "PD20",
"PD22", "PD23";
allwinner,function = "emac";
allwinner,drive = <3>;
allwinner,pull = <0>;
pins = "PD10", "PD11", "PD13", "PD14", "PD17",
"PD18", "PD19", "PD20", "PD22", "PD23";
function = "emac";
drive-strength = <40>;
};
rgmii_pins: rgmii_pins {
allwinner,pins = "PD8", "PD9", "PD10", "PD11",
"PD12", "PD13", "PD15",
"PD16", "PD17", "PD18", "PD19",
"PD20", "PD21", "PD22", "PD23";
allwinner,function = "emac";
allwinner,drive = <3>;
allwinner,pull = <0>;
pins = "PD8", "PD9", "PD10", "PD11", "PD12",
"PD13", "PD15", "PD16", "PD17", "PD18",
"PD19", "PD20", "PD21", "PD22", "PD23";
function = "emac";
drive-strength = <40>;
};
};

@ -108,10 +108,13 @@
pinctrl-names = "default";
pinctrl-0 = <&emac_rgmii_pins>;
phy-mode = "rgmii";
phy = <&phy1>;
phy-handle = <&ext_rgmii_phy>;
status = "okay";
};
phy1: ethernet-phy@1 {
&external_mdio {
ext_rgmii_phy: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
};

@ -289,6 +289,23 @@
function = "uart1";
};
nand_pins_a: nand-base0@0 {
pins = "PC0", "PC1", "PC2", "PC5",
"PC8", "PC9", "PC10", "PC11",
"PC12", "PC13", "PC14", "PC15";
function = "nand0";
};
nand_cs0_pins_a: nand-cs@0 {
pins = "PC4";
function = "nand0";
};
nand_rb0_pins_a: nand-rb@0 {
pins = "PC6";
function = "nand0";
};
mmc0_pins_a: mmc0@0 {
pins = "PF0", "PF1", "PF2",
"PF3", "PF4", "PF5";

@ -100,14 +100,10 @@
};
&emac {
phy = <&phy1>;
phy-handle = <&int_mii_phy>;
phy-mode = "mii";
allwinner,use-internal-phy;
allwinner,leds-active-low;
status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
};
};
&mmc0 {

@ -125,15 +125,10 @@
};
&emac {
phy = <&phy1>;
phy-handle = <&int_mii_phy>;
phy-mode = "mii";
allwinner,use-internal-phy;
allwinner,leds-active-low;
status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
};
};
&ir {

@ -48,12 +48,8 @@
};
&emac {
phy = <&phy1>;
phy-handle = <&int_mii_phy>;
phy-mode = "mii";
allwinner,use-internal-phy;
allwinner,leds-active-low;
status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
};
};

@ -55,6 +55,7 @@
aliases {
serial0 = &uart0;
/* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */
ethernet0 = &emac;
ethernet1 = &rtl8189;
};
@ -110,14 +111,10 @@
};
&emac {
phy = <&phy1>;
phy-handle = <&int_mii_phy>;
phy-mode = "mii";
allwinner,use-internal-phy;
allwinner,leds-active-low;
status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
};
};
&ir {

@ -53,6 +53,7 @@
compatible = "xunlong,orangepi-one", "allwinner,sun8i-h3";
aliases {
ethernet0 = &emac;
serial0 = &uart0;
};
@ -95,14 +96,10 @@
};
&emac {
phy = <&phy1>;
phy-handle = <&int_mii_phy>;
phy-mode = "mii";
allwinner,use-internal-phy;
allwinner,leds-active-low;
status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
};
};
&mmc0 {

@ -53,6 +53,7 @@
compatible = "xunlong,orangepi-pc", "allwinner,sun8i-h3";
aliases {
ethernet0 = &emac;
serial0 = &uart0;
};
@ -167,12 +168,8 @@
};
&emac {
phy = <&phy1>;
phy-handle = <&int_mii_phy>;
phy-mode = "mii";
allwinner,use-internal-phy;
allwinner,leds-active-low;
status = "okay";
phy1: ethernet-phy@1 {
reg = <1>;
};
};

@ -82,7 +82,13 @@
pinctrl-0 = <&emac_rgmii_pins>;
phy-supply = <&reg_gmac_3v3>;
phy-mode = "rgmii";
/delete-property/allwinner,use-internal-phy;
};
&external_mdio {
ext_rgmii_phy: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0>;
};
};
&mmc2 {

@ -69,8 +69,15 @@
pinctrl-names = "default";
pinctrl-0 = <&emac_rgmii_pins>;
phy-supply = <&reg_gmac_3v3>;
phy-handle = <&ext_rgmii_phy>;
phy-mode = "rgmii";
/delete-property/allwinner,use-internal-phy;
};
&external_mdio {
ext_rgmii_phy: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
};
&pio {

@ -144,9 +144,10 @@
#size-cells = <1>;
ranges;
syscon: syscon@01c00000 {
compatible = "allwinner,sun8i-h3-syscon","syscon";
reg = <0x01c00000 0x34>;
syscon: syscon@1c00000 {
compatible = "allwinner,sun8i-h3-system-controller",
"syscon";
reg = <0x01c00000 0x1000>;
};
dma: dma-controller@01c02000 {
@ -339,15 +340,12 @@
interrupt-controller;
#interrupt-cells = <3>;
emac_rgmii_pins: emac0@0 {
allwinner,pins = "PD0", "PD1", "PD2", "PD3",
"PD4", "PD5", "PD7",
"PD8", "PD9", "PD10",
"PD12", "PD13", "PD15",
"PD16", "PD17";
allwinner,function = "emac";
allwinner,drive = <SUN4I_PINCTRL_40_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
emac_rgmii_pins: emac0 {
pins = "PD0", "PD1", "PD2", "PD3", "PD4",
"PD5", "PD7", "PD8", "PD9", "PD10",
"PD12", "PD13", "PD15", "PD16", "PD17";
function = "emac";
drive-strength = <40>;
};
mmc0_pins_a: mmc0@0 {
@ -466,16 +464,51 @@
emac: ethernet@1c30000 {
compatible = "allwinner,sun8i-h3-emac";
reg = <0x01c30000 0x104>, <0x01c00030 0x4>;
reg-names = "emac", "syscon";
syscon = <&syscon>;
reg = <0x01c30000 0x10000>;
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
resets = <&ccu RST_BUS_EMAC>, <&ccu RST_BUS_EPHY>;
reset-names = "ahb", "ephy";
clocks = <&ccu CLK_BUS_EMAC>, <&ccu CLK_BUS_EPHY>;
clock-names = "ahb", "ephy";
interrupt-names = "macirq";
resets = <&ccu RST_BUS_EMAC>;
reset-names = "stmmaceth";
clocks = <&ccu CLK_BUS_EMAC>;
clock-names = "stmmaceth";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
mdio: mdio {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dwmac-mdio";
};
mdio-mux {
compatible = "allwinner,sun8i-h3-mdio-mux";
#address-cells = <1>;
#size-cells = <0>;
mdio-parent-bus = <&mdio>;
/* Only one MDIO is usable at the time */
internal_mdio: mdio@1 {
compatible = "allwinner,sun8i-h3-mdio-internal";
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
int_mii_phy: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
clocks = <&ccu CLK_BUS_EPHY>;
resets = <&ccu RST_BUS_EPHY>;
};
};
external_mdio: mdio@2 {
reg = <2>;
#address-cells = <1>;
#size-cells = <0>;
};
};
};
gic: interrupt-controller@01c81000 {

@ -61,3 +61,17 @@
pinctrl-0 = <&uart0_pins_a>;
status = "okay";
};
&nfc {
pinctrl-names = "default";
pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
status = "okay";
nand@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
allwinner,rb = <0>;
nand-ecc-mode = "hw";
};
};

@ -192,6 +192,7 @@ struct sunxi_ccm_reg {
#define ATB_DIV_1 0
#define ATB_DIV_2 1
#define ATB_DIV_4 2
#define AHB_DIV_1 0
#define CPU_CLK_SRC_OSC24M 1
#define CPU_CLK_SRC_PLL1 2
@ -317,6 +318,11 @@ struct sunxi_ccm_reg {
#define AHB_GATE_OFFSET_LCD0 3
#endif
#define CCM_NAND_CTRL_M(x) ((x) - 1)
#define CCM_NAND_CTRL_N(x) ((x) << 16)
#define CCM_NAND_CTRL_PLL6 (0x1 << 24)
#define CCM_NAND_CTRL_ENABLE (0x1 << 31)
#define CCM_MMC_CTRL_M(x) ((x) - 1)
#define CCM_MMC_CTRL_OCLK_DLY(x) ((x) << 8)
#define CCM_MMC_CTRL_N(x) ((x) << 16)

@ -38,6 +38,12 @@ the root of your U-Boot build directory (or create a symbolic link).
$ export BL31=/src/arm-trusted-firmware/build/sun50iw1p1/debug/bl31.bin
(adjust the actual path accordingly)
If you run into size issues with the resulting U-Boot image file, it might
help to use a release build, by using "DEBUG=0" when building bl31.bin.
As sometimes the ATF build process is a bit picky about the toolchain used,
or if you can't be bothered with building ATF, there are known working
binaries in the firmware repository[3], purely for convenience reasons.
SPL/U-Boot
------------
Both U-Boot proper and the SPL are using the 64-bit mode. As the boot ROM

@ -286,10 +286,9 @@ static void nand_clock_setup(void)
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
#ifdef CONFIG_MACH_SUN9I
setbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA));
#else
setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA));
#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I || \
defined CONFIG_MACH_SUN9I || defined CONFIG_MACH_SUN50I
setbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_GATE_OFFSET_NAND0));
#endif
setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
}

@ -426,7 +426,6 @@ menu "Memory commands"
config CMD_CRC32
bool "crc32"
select HASH
default n if ARCH_SUNXI
default y
help
Compute CRC32.
@ -568,7 +567,6 @@ config CMD_LZMADEC
config CMD_UNZIP
bool "unzip"
default n if ARCH_SUNXI
default y if CMD_BOOTI
help
Uncompress a zip-compressed memory region.
@ -780,14 +778,12 @@ config CMD_I2C
config CMD_LOADB
bool "loadb"
default n if ARCH_SUNXI
default y
help
Load a binary file over serial line.
config CMD_LOADS
bool "loads"
default n if ARCH_SUNXI
default y
help
Load an S-Record file over serial line
@ -1187,7 +1183,6 @@ config CMD_GETTIME
# TODO: rename to CMD_SLEEP
config CMD_MISC
bool "sleep"
default n if ARCH_SUNXI
default y
help
Delay execution for some time

@ -127,8 +127,14 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
ulong u_boot_pos = binman_sym(ulong, u_boot_any, pos);
spl_image->size = CONFIG_SYS_MONITOR_LEN;
if (u_boot_pos != BINMAN_SYM_MISSING) {
/* biman does not support separate entry addresses at present */
/*
* Binman error cases: address of the end of the previous region or the
* start of the image's entry area (usually 0) if there is no previous
* region.
*/
if (u_boot_pos && u_boot_pos != BINMAN_SYM_MISSING) {
/* Binman does not support separated entry addresses */
spl_image->entry_point = u_boot_pos;
spl_image->load_addr = u_boot_pos;
} else {

@ -1,11 +1,12 @@
CONFIG_ARM=y
CONFIG_ARCH_SUNXI=y
CONFIG_SPL_NAND_SUPPORT=y
CONFIG_MACH_SUN5I=y
CONFIG_DRAM_TIMINGS_DDR3_800E_1066G_1333J=y
CONFIG_USB0_VBUS_PIN="PB10"
CONFIG_DEFAULT_DEVICE_TREE="sun5i-gr8-chip-pro"
CONFIG_SYS_EXTRA_OPTIONS="SYS_NAND_BLOCK_SIZE=0x40000,SYS_NAND_PAGE_SIZE=4096,SYS_NAND_OOBSIZE=256"
CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
CONFIG_SYS_NAND_PAGE_SIZE=0x1000
CONFIG_SYS_NAND_OOBSIZE=0x100
CONFIG_SPL=y
CONFIG_SPL_I2C_SUPPORT=y
# CONFIG_CMD_FLASH is not set
@ -16,7 +17,6 @@ CONFIG_ENV_UBI_PART="UBI"
CONFIG_ENV_UBI_VOLUME="uboot-env"
# CONFIG_MMC is not set
CONFIG_NAND=y
CONFIG_NAND_SUNXI=y
CONFIG_AXP_ALDO3_VOLT=3300
CONFIG_AXP_ALDO4_VOLT=3300
CONFIG_CONS_INDEX=2

@ -9,6 +9,10 @@ CONFIG_AXP_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="sun8i-r16-nintendo-nes-classic-edition"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
CONFIG_NAND=y
CONFIG_SYS_NAND_BLOCK_SIZE=0x20000
CONFIG_SYS_NAND_PAGE_SIZE=0x800
CONFIG_SYS_NAND_OOBSIZE=0x40
# CONFIG_CMD_FLASH is not set
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_ISO_PARTITION is not set

@ -9,6 +9,7 @@ CONFIG_SPL=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_ISO_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_OF_LIST="sun50i-a64-pine64 sun50i-a64-pine64-plus"
CONFIG_SUN8I_EMAC=y
CONFIG_USB_EHCI_HCD=y
CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y

@ -354,12 +354,15 @@ static const struct udevice_id sunxi_gpio_ids[] = {
ID("allwinner,sun8i-a83t-pinctrl", a_all),
ID("allwinner,sun8i-h3-pinctrl", a_all),
ID("allwinner,sun8i-r40-pinctrl", a_all),
ID("allwinner,sun8i-v3s-pinctrl", a_all),
ID("allwinner,sun9i-a80-pinctrl", a_all),
ID("allwinner,sun50i-a64-pinctrl", a_all),
ID("allwinner,sun6i-a31-r-pinctrl", l_2),
ID("allwinner,sun8i-a23-r-pinctrl", l_1),
ID("allwinner,sun8i-a83t-r-pinctrl", l_1),
ID("allwinner,sun8i-h3-r-pinctrl", l_1),
ID("allwinner,sun9i-a80-r-pinctrl", l_3),
ID("allwinner,sun50i-a64-r-pinctrl", l_1),
{ }
};

@ -95,9 +95,11 @@ config NAND_PXA3XX
config NAND_SUNXI
bool "Support for NAND on Allwinner SoCs"
depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I
default ARCH_SUNXI
depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUN8I
select SYS_NAND_SELF_INIT
select SYS_NAND_U_BOOT_LOCATIONS
select SPL_NAND_SUPPORT
imply CMD_NAND
---help---
Enable support for NAND. This option enables the standard and
@ -166,6 +168,28 @@ config NAND_ZYNQ_USE_BOOTLOADER1_TIMINGS
comment "Generic NAND options"
config SYS_NAND_BLOCK_SIZE
hex "NAND chip eraseblock size"
depends on ARCH_SUNXI
help
Number of data bytes in one eraseblock for the NAND chip on the
board. This is the multiple of NAND_PAGE_SIZE and the number of
pages.
config SYS_NAND_PAGE_SIZE
hex "NAND chip page size"
depends on ARCH_SUNXI
help
Number of data bytes in one page for the NAND chip on the
board, not including the OOB area.
config SYS_NAND_OOBSIZE
hex "NAND chip OOB size"
depends on ARCH_SUNXI
help
Number of bytes in the Out-Of-Band area for the NAND chip on
the board.
# Enhance depends when converting drivers to Kconfig which use this config
# option (mxc_nand, ndfc, omap_gpmc).
config SYS_NAND_BUSWIDTH_16BIT

@ -1407,8 +1407,14 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
/* Add ECC info retrieval from DT */
for (i = 0; i < ARRAY_SIZE(strengths); i++) {
if (ecc->strength <= strengths[i])
if (ecc->strength <= strengths[i]) {
/*
* Update ecc->strength value with the actual strength
* that will be used by the ECC engine.
*/
ecc->strength = strengths[i];
break;
}
}
if (i >= ARRAY_SIZE(strengths)) {

@ -10,6 +10,7 @@
#include <common.h>
#include <config.h>
#include <nand.h>
#include <linux/ctype.h>
/* registers */
#define NFC_CTL 0x00000000
@ -55,7 +56,7 @@
#define NFC_ADDR_NUM_OFFSET 16
#define NFC_SEND_ADR (1 << 19)
#define NFC_SEND_ADDR (1 << 19)
#define NFC_ACCESS_DIR (1 << 20)
#define NFC_DATA_TRANS (1 << 21)
#define NFC_SEND_CMD1 (1 << 22)
@ -67,10 +68,12 @@
#define NFC_SEND_CMD3 (1 << 28)
#define NFC_SEND_CMD4 (1 << 29)
#define NFC_RAW_CMD (0 << 30)
#define NFC_ECC_CMD (1 << 30)
#define NFC_PAGE_CMD (2 << 30)
#define NFC_ST_CMD_INT_FLAG (1 << 1)
#define NFC_ST_DMA_INT_FLAG (1 << 2)
#define NFC_ST_CMD_FIFO_STAT (1 << 3)
#define NFC_READ_CMD_OFFSET 0
#define NFC_RANDOM_READ_CMD0_OFFSET 8
@ -80,22 +83,6 @@
#define NFC_CMD_RNDOUT 0x05
#define NFC_CMD_READSTART 0x30
#define SUNXI_DMA_CFG_REG0 0x300
#define SUNXI_DMA_SRC_START_ADDR_REG0 0x304
#define SUNXI_DMA_DEST_START_ADDRR_REG0 0x308
#define SUNXI_DMA_DDMA_BC_REG0 0x30C
#define SUNXI_DMA_DDMA_PARA_REG0 0x318
#define SUNXI_DMA_DDMA_CFG_REG_LOADING (1 << 31)
#define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25)
#define SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM (1 << 16)
#define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9)
#define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5)
#define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0)
#define SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC (0x0F << 0)
#define SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE (0x7F << 8)
struct nfc_config {
int page_size;
int ecc_strength;
@ -155,6 +142,42 @@ static inline int check_value_negated(int offset, int unexpected_bits,
return check_value_inner(offset, unexpected_bits, timeout_us, 1);
}
static int nand_wait_cmd_fifo_empty(void)
{
if (!check_value_negated(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_FIFO_STAT,
DEFAULT_TIMEOUT_US)) {
printf("nand: timeout waiting for empty cmd FIFO\n");
return -ETIMEDOUT;
}
return 0;
}
static int nand_wait_int(void)
{
if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
DEFAULT_TIMEOUT_US)) {
printf("nand: timeout waiting for interruption\n");
return -ETIMEDOUT;
}
return 0;
}
static int nand_exec_cmd(u32 cmd)
{
int ret;
ret = nand_wait_cmd_fifo_empty();
if (ret)
return ret;
writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
writel(cmd, SUNXI_NFC_BASE + NFC_CMD);
return nand_wait_int();
}
void nand_init(void)
{
uint32_t val;
@ -172,22 +195,15 @@ void nand_init(void)
}
/* reset NAND */
writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET,
SUNXI_NFC_BASE + NFC_CMD);
if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
DEFAULT_TIMEOUT_US)) {
printf("Error timeout waiting for nand reset\n");
return;
}
writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
nand_exec_cmd(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET);
}
static void nand_apply_config(const struct nfc_config *conf)
{
u32 val;
nand_wait_cmd_fifo_empty();
val = readl(SUNXI_NFC_BASE + NFC_CTL);
val &= ~NFC_CTL_PAGE_SIZE_MASK;
writel(val | NFC_CTL_RAM_METHOD | NFC_CTL_PAGE_SIZE(conf->page_size),
@ -206,128 +222,111 @@ static int nand_load_page(const struct nfc_config *conf, u32 offs)
SUNXI_NFC_BASE + NFC_RCMD_SET);
writel(((page & 0xFFFF) << 16), SUNXI_NFC_BASE + NFC_ADDR_LOW);
writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH);
writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD | NFC_WAIT_FLAG |
((conf->addr_cycles - 1) << NFC_ADDR_NUM_OFFSET) | NFC_SEND_ADR,
SUNXI_NFC_BASE + NFC_CMD);
if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
DEFAULT_TIMEOUT_US)) {
printf("Error while initializing dma interrupt\n");
return -EIO;
}
return 0;
return nand_exec_cmd(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD |
NFC_SEND_ADDR | NFC_WAIT_FLAG |
((conf->addr_cycles - 1) << NFC_ADDR_NUM_OFFSET));
}
static int nand_reset_column(void)
static int nand_change_column(u16 column)
{
int ret;
writel((NFC_CMD_RNDOUTSTART << NFC_RANDOM_READ_CMD1_OFFSET) |
(NFC_CMD_RNDOUT << NFC_RANDOM_READ_CMD0_OFFSET) |
(NFC_CMD_RNDOUTSTART << NFC_READ_CMD_OFFSET),
SUNXI_NFC_BASE + NFC_RCMD_SET);
writel(0, SUNXI_NFC_BASE + NFC_ADDR_LOW);
writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD |
(1 << NFC_ADDR_NUM_OFFSET) | NFC_SEND_ADR | NFC_CMD_RNDOUT,
SUNXI_NFC_BASE + NFC_CMD);
writel(column, SUNXI_NFC_BASE + NFC_ADDR_LOW);
if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG,
DEFAULT_TIMEOUT_US)) {
printf("Error while initializing dma interrupt\n");
return -1;
}
ret = nand_exec_cmd(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_RAW_CMD |
(1 << NFC_ADDR_NUM_OFFSET) | NFC_SEND_ADDR |
NFC_CMD_RNDOUT);
if (ret)
return ret;
/* Ensure tCCS has passed before reading data */
udelay(1);
return 0;
}
static const int ecc_bytes[] = {32, 46, 54, 60, 74, 88, 102, 110, 116};
static int nand_read_page(const struct nfc_config *conf, u32 offs,
void *dest, int len)
{
dma_addr_t dst = (dma_addr_t)dest;
int nsectors = len / conf->ecc_size;
u16 rand_seed = 0;
u32 val;
int page;
page = offs / conf->page_size;
int oob_chunk_sz = ecc_bytes[conf->ecc_strength];
int page = offs / conf->page_size;
u32 ecc_st;
int i;
if (offs % conf->page_size || len % conf->ecc_size ||
len > conf->page_size || len < 0)
return -EINVAL;
/* clear ecc status */
writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
/* Choose correct seed if randomized */
if (conf->randomize)
rand_seed = random_seed[page % conf->nseeds];
writel((rand_seed << 16) | (conf->ecc_strength << 12) |
(conf->randomize ? NFC_ECC_RANDOM_EN : 0) |
(conf->ecc_size == 512 ? NFC_ECC_BLOCK_SIZE : 0) |
NFC_ECC_EN | NFC_ECC_PIPELINE | NFC_ECC_EXCEPTION,
SUNXI_NFC_BASE + NFC_ECC_CTL);
flush_dcache_range(dst, ALIGN(dst + conf->ecc_size, ARCH_DMA_MINALIGN));
/* SUNXI_DMA */
writel(0x0, SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0); /* clr dma cmd */
/* read from REG_IO_DATA */
writel(SUNXI_NFC_BASE + NFC_IO_DATA,
SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0);
/* read to RAM */
writel(dst, SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0);
writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC |
SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE,
SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0);
writel(len, SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0);
writel(SUNXI_DMA_DDMA_CFG_REG_LOADING |
SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 |
SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM |
SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 |
SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO |
SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC,
SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0);
writel(nsectors, SUNXI_NFC_BASE + NFC_SECTOR_NUM);
writel(NFC_ST_DMA_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
writel(NFC_DATA_TRANS | NFC_PAGE_CMD | NFC_DATA_SWAP_METHOD,
SUNXI_NFC_BASE + NFC_CMD);
if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_DMA_INT_FLAG,
DEFAULT_TIMEOUT_US)) {
printf("Error while initializing dma interrupt\n");
return -EIO;
}
writel(NFC_ST_DMA_INT_FLAG, SUNXI_NFC_BASE + NFC_ST);
/* Retrieve data from SRAM (PIO) */
for (i = 0; i < nsectors; i++) {
int data_off = i * conf->ecc_size;
int oob_off = conf->page_size + (i * oob_chunk_sz);
u8 *data = dest + data_off;
/* Clear ECC status and restart ECC engine */
writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
writel((rand_seed << 16) | (conf->ecc_strength << 12) |
(conf->randomize ? NFC_ECC_RANDOM_EN : 0) |
(conf->ecc_size == 512 ? NFC_ECC_BLOCK_SIZE : 0) |
NFC_ECC_EN | NFC_ECC_EXCEPTION,
SUNXI_NFC_BASE + NFC_ECC_CTL);
/* Move the data in SRAM */
nand_change_column(data_off);
writel(conf->ecc_size, SUNXI_NFC_BASE + NFC_CNT);
nand_exec_cmd(NFC_DATA_TRANS);
if (!check_value_negated(SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0,
SUNXI_DMA_DDMA_CFG_REG_LOADING,
DEFAULT_TIMEOUT_US)) {
printf("Error while waiting for dma transfer to finish\n");
return -EIO;
}
/*
* Let the ECC engine consume the ECC bytes and possibly correct
* the data.
*/
nand_change_column(oob_off);
nand_exec_cmd(NFC_DATA_TRANS | NFC_ECC_CMD);
/* Get the ECC status */
ecc_st = readl(SUNXI_NFC_BASE + NFC_ECC_ST);
/* ECC error detected. */
if (ecc_st & 0xffff)
return -EIO;
/*
* Return 1 if the first chunk is empty (needed for
* configuration detection).
*/
if (!i && (ecc_st & 0x10000))
return 1;
invalidate_dcache_range(dst,
ALIGN(dst + conf->ecc_size, ARCH_DMA_MINALIGN));
/* Retrieve the data from SRAM */
memcpy_fromio(data, SUNXI_NFC_BASE + NFC_RAM0_BASE,
conf->ecc_size);
val = readl(SUNXI_NFC_BASE + NFC_ECC_ST);
/* Stop the ECC engine */
writel(readl(SUNXI_NFC_BASE + NFC_ECC_CTL) & ~NFC_ECC_EN,
SUNXI_NFC_BASE + NFC_ECC_CTL);
/* ECC error detected. */
if (val & 0xffff)
return -EIO;
if (data_off + conf->ecc_size >= len)
break;
}
/*
* Return 1 if the page is empty.
* We consider the page as empty if the first ECC block is marked
* empty.
*/
return (val & 0x10000) ? 1 : 0;
return 0;
}
static int nand_max_ecc_strength(struct nfc_config *conf)
{
static const int ecc_bytes[] = { 32, 46, 54, 60, 74, 88, 102, 110, 116 };
int max_oobsize, max_ecc_bytes;
int nsectors = conf->page_size / conf->ecc_size;
int i;
@ -393,7 +392,7 @@ static int nand_detect_ecc_config(struct nfc_config *conf, u32 offs,
conf->ecc_strength >= 0;
conf->ecc_strength--) {
conf->randomize = false;
if (nand_reset_column())
if (nand_change_column(0))
return -EIO;
/*
@ -413,7 +412,7 @@ static int nand_detect_ecc_config(struct nfc_config *conf, u32 offs,
conf->randomize = true;
conf->nseeds = ARRAY_SIZE(random_seed);
do {
if (nand_reset_column())
if (nand_change_column(0))
return -EIO;
if (!nand_read_page(conf, offs, dest,
@ -475,11 +474,12 @@ static int nand_detect_config(struct nfc_config *conf, u32 offs, void *dest)
static int nand_read_buffer(struct nfc_config *conf, uint32_t offs,
unsigned int size, void *dest)
{
int first_seed, page, ret;
int first_seed = 0, page, ret;
size = ALIGN(size, conf->page_size);
page = offs / conf->page_size;
first_seed = page % conf->nseeds;
if (conf->randomize)
first_seed = page % conf->nseeds;
for (; size; size -= conf->page_size) {
if (nand_load_page(conf, offs))
@ -504,7 +504,7 @@ static int nand_read_buffer(struct nfc_config *conf, uint32_t offs,
/* Try to adjust ->nseeds and read the page again... */
conf->nseeds = cur_seed;
if (nand_reset_column())
if (nand_change_column(0))
return -EIO;
/* ... it still fails => it's a real corruption. */

@ -21,6 +21,7 @@
#include <malloc.h>
#include <miiphy.h>
#include <net.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
#ifdef CONFIG_DM_GPIO
#include <asm-generic/gpio.h>
#endif
@ -278,7 +279,7 @@ static int sun8i_emac_set_syscon(struct emac_eth_dev *priv)
int ret;
u32 reg;
reg = readl(priv->sysctl_reg);
reg = readl(priv->sysctl_reg + 0x30);
if (priv->variant == H3_EMAC) {
ret = sun8i_emac_set_syscon_ephy(priv, &reg);
@ -309,7 +310,7 @@ static int sun8i_emac_set_syscon(struct emac_eth_dev *priv)
return -EINVAL;
}
writel(reg, priv->sysctl_reg);
writel(reg, priv->sysctl_reg + 0x30);
return 0;
}
@ -455,7 +456,7 @@ static int parse_phy_pins(struct udevice *dev)
{
int offset;
const char *pin_name;
int drive, pull, i;
int drive, pull = SUN4I_PINCTRL_NO_PULL, i;
offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev),
"pinctrl-0");
@ -465,30 +466,44 @@ static int parse_phy_pins(struct udevice *dev)
}
drive = fdt_getprop_u32_default_node(gd->fdt_blob, offset, 0,
"allwinner,drive", 4);
pull = fdt_getprop_u32_default_node(gd->fdt_blob, offset, 0,
"allwinner,pull", 0);
"drive-strength", ~0);
if (drive != ~0) {
if (drive <= 10)
drive = SUN4I_PINCTRL_10_MA;
else if (drive <= 20)
drive = SUN4I_PINCTRL_20_MA;
else if (drive <= 30)
drive = SUN4I_PINCTRL_30_MA;
else
drive = SUN4I_PINCTRL_40_MA;
}
if (fdt_get_property(gd->fdt_blob, offset, "bias-pull-up", NULL))
pull = SUN4I_PINCTRL_PULL_UP;
else if (fdt_get_property(gd->fdt_blob, offset, "bias-pull-down", NULL))
pull = SUN4I_PINCTRL_PULL_DOWN;
for (i = 0; ; i++) {
int pin;
pin_name = fdt_stringlist_get(gd->fdt_blob, offset,
"allwinner,pins", i, NULL);
"pins", i, NULL);
if (!pin_name)
break;
if (pin_name[0] != 'P')
continue;
pin = (pin_name[1] - 'A') << 5;
if (pin >= 26 << 5)
pin = sunxi_name_to_gpio(pin_name);
if (pin < 0)
continue;
pin += simple_strtol(&pin_name[2], NULL, 10);
sunxi_gpio_set_cfgpin(pin, SUN8I_GPD8_GMAC);
sunxi_gpio_set_drv(pin, drive);
sunxi_gpio_set_pull(pin, pull);
if (drive != ~0)
sunxi_gpio_set_drv(pin, drive);
if (pull != ~0)
sunxi_gpio_set_pull(pin, pull);
}
if (!i) {
printf("WARNING: emac: cannot find allwinner,pins property\n");
printf("WARNING: emac: cannot find pins property\n");
return -2;
}
@ -772,6 +787,7 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
struct eth_pdata *pdata = &sun8i_pdata->eth_pdata;
struct emac_eth_dev *priv = dev_get_priv(dev);
const char *phy_mode;
const fdt32_t *reg;
int node = dev_of_offset(dev);
int offset = 0;
#ifdef CONFIG_DM_GPIO
@ -779,18 +795,40 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
int ret = 0;
#endif
pdata->iobase = devfdt_get_addr_name(dev, "emac");
priv->sysctl_reg = devfdt_get_addr_name(dev, "syscon");
pdata->iobase = devfdt_get_addr(dev);
if (pdata->iobase == FDT_ADDR_T_NONE) {
debug("%s: Cannot find MAC base address\n", __func__);
return -EINVAL;
}
offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "syscon");
if (offset < 0) {
debug("%s: cannot find syscon node\n", __func__);
return -EINVAL;
}
reg = fdt_getprop(gd->fdt_blob, offset, "reg", NULL);
if (!reg) {
debug("%s: cannot find reg property in syscon node\n",
__func__);
return -EINVAL;
}
priv->sysctl_reg = fdt_translate_address((void *)gd->fdt_blob,
offset, reg);
if (priv->sysctl_reg == FDT_ADDR_T_NONE) {
debug("%s: Cannot find syscon base address\n", __func__);
return -EINVAL;
}
pdata->phy_interface = -1;
priv->phyaddr = -1;
priv->use_internal_phy = false;
offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
"phy");
if (offset > 0)
priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg",
-1);
offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "phy-handle");
if (offset < 0) {
debug("%s: Cannot find PHY address\n", __func__);
return -EINVAL;
}
priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL);
@ -812,8 +850,11 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev)
}
if (priv->variant == H3_EMAC) {
if (fdt_getprop(gd->fdt_blob, node,
"allwinner,use-internal-phy", NULL))
int parent = fdt_parent_offset(gd->fdt_blob, offset);
if (parent >= 0 &&
!fdt_node_check_compatible(gd->fdt_blob, parent,
"allwinner,sun8i-h3-mdio-internal"))
priv->use_internal_phy = true;
}

@ -38,7 +38,6 @@ config BACKLIGHT_GPIO
config VIDEO_BPP8
bool "Support 8-bit-per-pixel displays"
depends on DM_VIDEO
default n if ARCH_SUNXI
default y if DM_VIDEO
help
Support drawing text and bitmaps onto a 8-bit-per-pixel display.
@ -49,7 +48,6 @@ config VIDEO_BPP8
config VIDEO_BPP16
bool "Support 16-bit-per-pixel displays"
depends on DM_VIDEO
default n if ARCH_SUNXI
default y if DM_VIDEO
help
Support drawing text and bitmaps onto a 16-bit-per-pixel display.

1
env/Kconfig vendored

@ -152,7 +152,6 @@ config ENV_IS_IN_MMC
bool "Environment in an MMC device"
depends on !CHAIN_OF_TRUST
depends on MMC
default y if ARCH_SUNXI
default y if ARCH_EXYNOS4
default y if MX6SX || MX7D
default y if TEGRA30 || TEGRA124

@ -66,7 +66,6 @@ config PANIC_HANG
config REGEX
bool "Enable regular expression support"
default n if ARCH_SUNXI
default y if NET
help
If this variable is defined, U-Boot is linked against the

Loading…
Cancel
Save