diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/sunxi/board.c | 52 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/sunxi/usb_phy.c | 38 | ||||
-rw-r--r-- | arch/arm/dts/sun5i-a13-utoo-p66.dts | 14 | ||||
-rw-r--r-- | arch/arm/dts/sun8i-a23-a33.dtsi | 18 | ||||
-rw-r--r-- | arch/arm/dts/sun8i-a33-ga10h-v1.1.dts | 8 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-sunxi/mmc.h | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-sunxi/usb_phy.h | 8 |
8 files changed, 116 insertions, 29 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 506463c12c..3355b3bcaa 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -643,11 +643,17 @@ config ARCH_SOCFPGA config ARCH_SUNXI bool "Support sunxi (Allwinner) SoCs" + select CMD_USB select DM select DM_GPIO + select DM_ETH + select DM_SERIAL + select DM_USB select OF_CONTROL select OF_SEPARATE select SPL_DISABLE_OF_CONTROL + select USB + select USB_STORAGE config TARGET_SNOWBALL bool "Support snowball" diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 5f39aa07cf..f01846ef9a 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -11,6 +11,7 @@ */ #include <common.h> +#include <mmc.h> #include <i2c.h> #include <serial.h> #ifdef CONFIG_SPL_BUILD @@ -22,6 +23,7 @@ #include <asm/arch/gpio.h> #include <asm/arch/sys_proto.h> #include <asm/arch/timer.h> +#include <asm/arch/mmc.h> #include <linux/compiler.h> @@ -121,17 +123,18 @@ void s_init(void) } #ifdef CONFIG_SPL_BUILD +DECLARE_GLOBAL_DATA_PTR; + /* The sunxi internal brom will try to loader external bootloader * from mmc0, nand flash, mmc2. - * Unfortunately we can't check how SPL was loaded so assume - * it's always the first SD/MMC controller */ u32 spl_boot_device(void) { + struct mmc *mmc0, *mmc1; /* - * When booting from the SD card, the "eGON.BT0" signature is expected - * to be found in memory at the address 0x0004 (see the "mksunxiboot" - * tool, which generates this header). + * When booting from the SD card or NAND memory, the "eGON.BT0" + * signature is expected to be found in memory at the address 0x0004 + * (see the "mksunxiboot" tool, which generates this header). * * When booting in the FEL mode over USB, this signature is patched in * memory and replaced with something else by the 'fel' tool. This other @@ -139,15 +142,40 @@ u32 spl_boot_device(void) * valid bootable SD card image (because the BROM would refuse to * execute the SPL in this case). * - * This branch is just making a decision at runtime whether to load - * the main u-boot binary from the SD card (if the "eGON.BT0" signature - * is found) or return to the FEL code in the BROM to wait and receive - * the main u-boot binary over USB. + * This checks for the signature and if it is not found returns to + * the FEL code in the BROM to wait and receive the main u-boot + * binary over USB. If it is found, it determines where SPL was + * read from. */ - if (readl(4) == 0x4E4F4765 && readl(8) == 0x3054422E) /* eGON.BT0 */ - return BOOT_DEVICE_MMC1; - else + if (readl(4) != 0x4E4F4765 || readl(8) != 0x3054422E) /* eGON.BT0 */ return BOOT_DEVICE_BOARD; + + /* The BROM will try to boot from mmc0 first, so try that first. */ + mmc_initialize(gd->bd); + mmc0 = find_mmc_device(0); + if (sunxi_mmc_has_egon_boot_signature(mmc0)) + return BOOT_DEVICE_MMC1; + + /* Fallback to booting NAND if enabled. */ + if (IS_ENABLED(CONFIG_SPL_NAND_SUPPORT)) + return BOOT_DEVICE_NAND; + + if (CONFIG_MMC_SUNXI_SLOT_EXTRA == 2) { + mmc1 = find_mmc_device(1); + if (sunxi_mmc_has_egon_boot_signature(mmc1)) { + /* + * spl_mmc.c: spl_mmc_load_image() is hard-coded to + * use find_mmc_device(0), no matter what we + * return. Swap mmc0 and mmc2 to make this work. + */ + mmc0->block_dev.dev = 1; + mmc1->block_dev.dev = 0; + return BOOT_DEVICE_MMC2; + } + } + + panic("Could not determine boot source\n"); + return -1; /* Never reached */ } /* No confirmation data available in SPL yet. Hardcode bootmode */ diff --git a/arch/arm/cpu/armv7/sunxi/usb_phy.c b/arch/arm/cpu/armv7/sunxi/usb_phy.c index b07d67ff3f..4d63a7449d 100644 --- a/arch/arm/cpu/armv7/sunxi/usb_phy.c +++ b/arch/arm/cpu/armv7/sunxi/usb_phy.c @@ -44,6 +44,7 @@ static struct sunxi_usb_phy { int usb_rst_mask; int gpio_vbus; int gpio_vbus_det; + int gpio_id_det; int id; int init_count; int power_on_count; @@ -82,6 +83,14 @@ static int get_vbus_detect_gpio(int index) return -EINVAL; } +static int get_id_detect_gpio(int index) +{ + switch (index) { + case 0: return sunxi_name_to_gpio(CONFIG_USB0_ID_DET); + } + return -EINVAL; +} + static void usb_phy_write(struct sunxi_usb_phy *phy, int addr, int data, int len) { @@ -228,10 +237,8 @@ int sunxi_usb_phy_vbus_detect(int index) struct sunxi_usb_phy *phy = &sunxi_usb_phy[index]; int err, retries = 3; - if (phy->gpio_vbus_det < 0) { - eprintf("Error: invalid vbus detection pin\n"); + if (phy->gpio_vbus_det < 0) return phy->gpio_vbus_det; - } err = gpio_get_value(phy->gpio_vbus_det); /* @@ -247,6 +254,16 @@ int sunxi_usb_phy_vbus_detect(int index) return err; } +int sunxi_usb_phy_id_detect(int index) +{ + struct sunxi_usb_phy *phy = &sunxi_usb_phy[index]; + + if (phy->gpio_id_det < 0) + return phy->gpio_id_det; + + return gpio_get_value(phy->gpio_id_det); +} + int sunxi_usb_phy_probe(void) { struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; @@ -275,6 +292,18 @@ int sunxi_usb_phy_probe(void) if (ret) return ret; } + + phy->gpio_id_det = get_id_detect_gpio(i); + if (phy->gpio_id_det >= 0) { + ret = gpio_request(phy->gpio_id_det, "usb_id_det"); + if (ret) + return ret; + ret = gpio_direction_input(phy->gpio_id_det); + if (ret) + return ret; + sunxi_gpio_set_pull(phy->gpio_id_det, + SUNXI_GPIO_PULL_UP); + } } setbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE); @@ -298,6 +327,9 @@ int sunxi_usb_phy_remove(void) if (phy->gpio_vbus_det >= 0) gpio_free(phy->gpio_vbus_det); + + if (phy->gpio_id_det >= 0) + gpio_free(phy->gpio_id_det); } return 0; diff --git a/arch/arm/dts/sun5i-a13-utoo-p66.dts b/arch/arm/dts/sun5i-a13-utoo-p66.dts index 8c1bca7039..514f159a14 100644 --- a/arch/arm/dts/sun5i-a13-utoo-p66.dts +++ b/arch/arm/dts/sun5i-a13-utoo-p66.dts @@ -52,14 +52,6 @@ model = "Utoo P66"; compatible = "utoo,p66", "allwinner,sun5i-a13"; - aliases { - serial0 = &uart1; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - i2c_lcd: i2c@0 { /* The lcd panel i2c interface is hooked up via gpios */ compatible = "i2c-gpio"; @@ -227,12 +219,6 @@ status = "okay"; }; -&uart1 { - pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins_b>; - status = "okay"; -}; - &usbphy { usb0_vbus-supply = <®_usb0_vbus>; usb1_vbus-supply = <®_ldo3>; diff --git a/arch/arm/dts/sun8i-a23-a33.dtsi b/arch/arm/dts/sun8i-a23-a33.dtsi index 7abd0ae314..5cd2e92c19 100644 --- a/arch/arm/dts/sun8i-a23-a33.dtsi +++ b/arch/arm/dts/sun8i-a23-a33.dtsi @@ -332,6 +332,24 @@ #size-cells = <0>; }; + ehci0: usb@01c1a000 { + compatible = "allwinner,sun8i-a23-ehci", "generic-ehci"; + reg = <0x01c1a000 0x100>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ahb1_gates 26>; + resets = <&ahb1_rst 26>; + status = "disabled"; + }; + + ohci0: usb@01c1a400 { + compatible = "allwinner,sun8i-a23-ohci", "generic-ohci"; + reg = <0x01c1a400 0x100>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ahb1_gates 29>, <&usb_clk 16>; + resets = <&ahb1_rst 29>; + status = "disabled"; + }; + pio: pinctrl@01c20800 { /* compatible gets set in SoC specific dtsi file */ reg = <0x01c20800 0x400>; diff --git a/arch/arm/dts/sun8i-a33-ga10h-v1.1.dts b/arch/arm/dts/sun8i-a33-ga10h-v1.1.dts index 866703355b..da16343346 100644 --- a/arch/arm/dts/sun8i-a33-ga10h-v1.1.dts +++ b/arch/arm/dts/sun8i-a33-ga10h-v1.1.dts @@ -61,6 +61,10 @@ }; }; +&ehci0 { + status = "okay"; +}; + &i2c0 { pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins_a>; @@ -109,6 +113,10 @@ status = "okay"; }; +&ohci0 { + status = "okay"; +}; + &pio { mmc0_cd_pin_q8h: mmc0_cd_pin@0 { allwinner,pins = "PB4"; diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h index cb52e64873..3da360b177 100644 --- a/arch/arm/include/asm/arch-sunxi/mmc.h +++ b/arch/arm/include/asm/arch-sunxi/mmc.h @@ -127,4 +127,5 @@ struct sunxi_mmc { #define SUNXI_MMC_COMMON_RESET (1 << 18) struct mmc *sunxi_mmc_init(int sdc_no); +int sunxi_mmc_has_egon_boot_signature(struct mmc *mmc); #endif /* _SUNXI_MMC_H */ diff --git a/arch/arm/include/asm/arch-sunxi/usb_phy.h b/arch/arm/include/asm/arch-sunxi/usb_phy.h index b7b831e24a..17d31b8e31 100644 --- a/arch/arm/include/asm/arch-sunxi/usb_phy.h +++ b/arch/arm/include/asm/arch-sunxi/usb_phy.h @@ -17,4 +17,12 @@ void sunxi_usb_phy_exit(int index); void sunxi_usb_phy_power_on(int index); void sunxi_usb_phy_power_off(int index); int sunxi_usb_phy_vbus_detect(int index); +int sunxi_usb_phy_id_detect(int index); void sunxi_usb_phy_enable_squelch_detect(int index, int enable); + +/* Not really phy related, but we have to declare this somewhere ... */ +#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET) +void sunxi_musb_board_init(void); +#else +#define sunxi_musb_board_init() +#endif |