Compare commits
37 Commits
master
...
imi415_t11
Author | SHA1 | Date |
---|---|---|
Yilin Sun | 85e7731ec8 | |
Yilin Sun | 373439ec6e | |
Yilin Sun | 7983de7e9d | |
Yilin Sun | f40e65a1fa | |
Yilin Sun | 36e82a0265 | |
Yilin Sun | 738ce1e4fd | |
Yilin Sun | 9aa63a2ab5 | |
Yilin Sun | 4eb8e11576 | |
Yilin Sun | ffb7ad153e | |
Yilin Sun | a5ec3a143d | |
Yilin Sun | 0afbe90ad2 | |
Yilin Sun | aca390cb24 | |
Jookia | 89e8047f7a | |
Jookia | e27886d3c4 | |
Jookia | 0fe6f1a12f | |
Jookia | 25cc03547d | |
Jookia | 1cd3de2337 | |
Jookia | c9c4031f35 | |
Jookia | a2b04d91d2 | |
Jookia | 701910350f | |
Jookia | 0d323b1397 | |
Jookia | 50b08adeeb | |
Jookia | c09732de8d | |
Jookia | 6a39611c35 | |
Jookia | 9a65cadec8 | |
Jookia | c680e9576e | |
Jookia | 2c97cf9958 | |
Jookia | cd95fd413d | |
Jookia | bea38baf59 | |
Jookia | dcac3831d4 | |
Jookia | 401df2d803 | |
Jookia | 3a3b1e3889 | |
Icenowy Zheng | cc0b1dc927 | |
Icenowy Zheng | 002d9e9a4c | |
Icenowy Zheng | 34f631f0dc | |
Icenowy Zheng | 453ff2fb10 | |
Icenowy Zheng | 6ecb0cba2a |
|
@ -810,6 +810,7 @@ dtb-$(CONFIG_MACH_SUN8I_V3S) += \
|
|||
sun8i-v3-sl631-imx179.dtb \
|
||||
sun8i-v3s-licheepi-zero.dtb
|
||||
dtb-$(CONFIG_MACH_SUN8I_R528) += \
|
||||
sun8i-t113i-tronlong-tlt113-minievm.dtb \
|
||||
sun8i-t113s-mangopi-mq-r-t113.dtb
|
||||
dtb-$(CONFIG_MACH_SUN50I_H5) += \
|
||||
sun50i-h5-bananapi-m2-plus.dtb \
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
// Copyright (C) 2022 Arm Ltd.
|
||||
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "sun8i-t113i.dtsi"
|
||||
#include "sunxi-t113i-tronlong-tlt113.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Tronlong TLT113-MiniEVM";
|
||||
compatible = "tronlong,tlt113-minievm", "allwinner,sun8i-t113i";
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu-supply = <®_vcc_core>;
|
||||
};
|
||||
|
||||
&cpu1 {
|
||||
cpu-supply = <®_vcc_core>;
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
bootph-all;
|
||||
pinctrl-0 = <&mmc0_pins>;
|
||||
pinctrl-names = "default";
|
||||
vmmc-supply = <®_3v3>;
|
||||
cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
|
||||
disable-wp;
|
||||
bus-width = <4>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
// Copyright (C) 2022 Arm Ltd.
|
||||
|
||||
#define SOC_PERIPHERAL_IRQ(nr) GIC_SPI nr
|
||||
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <../../riscv/dts/sunxi-d1s-t113.dtsi>
|
||||
#include <../../riscv/dts/sunxi-d1-t113.dtsi>
|
||||
|
||||
/ {
|
||||
interrupt-parent = <&gic>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu0: cpu@0 {
|
||||
compatible = "arm,cortex-a7";
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
clocks = <&ccu CLK_CPUX>;
|
||||
clock-names = "cpu";
|
||||
};
|
||||
|
||||
cpu1: cpu@1 {
|
||||
compatible = "arm,cortex-a7";
|
||||
device_type = "cpu";
|
||||
reg = <1>;
|
||||
clocks = <&ccu CLK_CPUX>;
|
||||
clock-names = "cpu";
|
||||
};
|
||||
};
|
||||
|
||||
gic: interrupt-controller@1c81000 {
|
||||
compatible = "arm,gic-400";
|
||||
reg = <0x03021000 0x1000>,
|
||||
<0x03022000 0x2000>,
|
||||
<0x03024000 0x2000>,
|
||||
<0x03026000 0x2000>;
|
||||
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv7-timer";
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
|
||||
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
|
||||
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
|
||||
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
|
||||
};
|
||||
|
||||
pmu {
|
||||
compatible = "arm,cortex-a7-pmu";
|
||||
interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-affinity = <&cpu0>, <&cpu1>;
|
||||
};
|
||||
};
|
|
@ -33,3 +33,56 @@
|
|||
interrupt-names = "host-wake";
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
pinctrl-0 = <&spi0_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
flash@0 {
|
||||
compatible = "spi-nand";
|
||||
reg = <0>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "uboot";
|
||||
reg = <0x00000000 0x00080000>;
|
||||
};
|
||||
|
||||
partition@80000 {
|
||||
label = "ubi";
|
||||
reg = <0x00080000 0x0fb00000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&usb_otg {
|
||||
status = "okay";
|
||||
dr_mode = "peripheral";
|
||||
};
|
||||
|
||||
&usbphy {
|
||||
usb1_vbus-supply = <®_vcc5v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ohci0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ohci1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ehci0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ehci1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -9,11 +9,13 @@
|
|||
|
||||
/ {
|
||||
aliases {
|
||||
serial1 = &uart1;
|
||||
serial2 = &uart2;
|
||||
serial3 = &uart3;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial3:115200n8";
|
||||
stdout-path = "serial1:115200n8";
|
||||
};
|
||||
|
||||
leds {
|
||||
|
@ -108,10 +110,22 @@
|
|||
vcc-pg-supply = <®_3v3>;
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart1_pg6_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart2_pe_pins>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&uart3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart3_pb_pins>;
|
||||
status = "okay";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
/* The USB-C socket has its CC pins pulled to GND, so is hardwired as a UFP. */
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
// Copyright (C) 2022 Arm Ltd.
|
||||
/*
|
||||
* Common peripherals and configurations for MangoPi MQ-R boards.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
serial2 = &uart2;
|
||||
mmc0 = &mmc0;
|
||||
mmc2 = &mmc2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial2:115200n8";
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led-0 {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
gpios = <&pio 2 0 GPIO_ACTIVE_HIGH>; /* PC0 */
|
||||
};
|
||||
|
||||
led-1 {
|
||||
color = <LED_COLOR_ID_RED>;
|
||||
function = LED_FUNCTION_STATUS;
|
||||
gpios = <&pio 2 1 GPIO_ACTIVE_HIGH>; /* PC1 */
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/* EC2232E DC/DC regulator on SoM */
|
||||
reg_vcc5v: regulator-5v {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc-5v";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
/* EC2232E DC/DC regulator on SoM */
|
||||
reg_3v3: regulator-3v3 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc-3v3";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
vin-supply = <®_vcc5v>;
|
||||
};
|
||||
|
||||
/* EC2232E DC/DC regulator on SoM, also supplying VDD-SYS */
|
||||
reg_vcc_core: regulator-core {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc-core";
|
||||
regulator-min-microvolt = <880000>;
|
||||
regulator-max-microvolt = <880000>;
|
||||
vin-supply = <®_vcc5v>;
|
||||
};
|
||||
};
|
||||
|
||||
&dcxo {
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
|
||||
&ehci1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ohci1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pio {
|
||||
vcc-pb-supply = <®_3v3>;
|
||||
vcc-pd-supply = <®_3v3>;
|
||||
vcc-pe-supply = <®_3v3>;
|
||||
vcc-pf-supply = <®_3v3>;
|
||||
vcc-pg-supply = <®_3v3>;
|
||||
|
||||
uart2_pg_pins: uart2_pg_pins {
|
||||
pins = "PG17", "PG18";
|
||||
function = "uart2";
|
||||
};
|
||||
};
|
||||
|
||||
&uart2 {
|
||||
bootph-all;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart2_pg_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mmc2 {
|
||||
bootph-all;
|
||||
pinctrl-0 = <&mmc2_pins>;
|
||||
pinctrl-names = "default";
|
||||
vmmc-supply = <®_3v3>;
|
||||
non-removable;
|
||||
disable-wp;
|
||||
bus-width = <4>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
bootph-all;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi0_pins>;
|
||||
status = "okay";
|
||||
|
||||
spi_nand@0 {
|
||||
bootph-all;
|
||||
compatible = "spi-nand";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <50000000>;
|
||||
partitions {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
compatible = "fixed-partitions";
|
||||
partition@0 {
|
||||
label = "u-boot";
|
||||
reg = <0x0 0x100000>; /* 1MB */
|
||||
};
|
||||
|
||||
partition@100000 {
|
||||
label = "env";
|
||||
reg = <0x100000 0x400000>; /* 4MB */
|
||||
};
|
||||
|
||||
partition@500000 {
|
||||
label = "rootfs";
|
||||
reg = <0x500000 0xfb00000>; /* 251MB */
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* The USB-C socket has its CC pins pulled to GND, so is hardwired as a UFP. */
|
||||
&usb_otg {
|
||||
dr_mode = "peripheral";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usbphy {
|
||||
usb1_vbus-supply = <®_vcc5v>;
|
||||
status = "okay";
|
||||
};
|
|
@ -16,8 +16,7 @@
|
|||
#define SUNXI_BOOTED_FROM_NAND 1
|
||||
#define SUNXI_BOOTED_FROM_MMC2 2
|
||||
#define SUNXI_BOOTED_FROM_SPI 3
|
||||
#define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10
|
||||
#define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12
|
||||
#define SUNXI_BOOTED_FROM_SPINAND 4
|
||||
|
||||
/*
|
||||
* Values taken from the F1C200s BootROM stack
|
||||
|
|
|
@ -22,6 +22,7 @@ enum {
|
|||
BOOT_DEVICE_NOR,
|
||||
BOOT_DEVICE_UART,
|
||||
BOOT_DEVICE_SPI,
|
||||
BOOT_DEVICE_SPINAND,
|
||||
BOOT_DEVICE_USB,
|
||||
BOOT_DEVICE_SATA,
|
||||
BOOT_DEVICE_I2C,
|
||||
|
|
|
@ -729,6 +729,17 @@ config UART0_PORT_F
|
|||
at the same time, the system can be only booted in the FEL mode.
|
||||
Only enable this if you really know what you are doing.
|
||||
|
||||
config UART2_PORT_G
|
||||
bool "UART2 on Port G"
|
||||
---help---
|
||||
Select this option for boards where UART2 uses the Port G pinmux.
|
||||
|
||||
config UART2_PORT_E
|
||||
bool "UART2 on PE2 and PE3 pins"
|
||||
---help---
|
||||
UART2 may used pins PE2 and PE3 on the Allwinner T113 board.
|
||||
Enable this if you are using these pins for UART2.
|
||||
|
||||
config OLD_SUNXI_KERNEL_COMPAT
|
||||
bool "Enable workarounds for booting old kernels"
|
||||
---help---
|
||||
|
@ -1061,7 +1072,7 @@ config SPL_STACK_R_ADDR
|
|||
|
||||
config SPL_SPI_SUNXI
|
||||
bool "Support for SPI Flash on Allwinner SoCs in SPL"
|
||||
depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || SUN50I_GEN_H6 || MACH_SUNIV
|
||||
depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || SUN50I_GEN_H6 || MACH_SUN8I_R528 || MACH_SUNIV
|
||||
help
|
||||
Enable support for SPI Flash. This option allows SPL to read from
|
||||
sunxi SPI Flash. It uses the same method as the boot ROM, so does
|
||||
|
|
|
@ -167,6 +167,20 @@ static int gpio_init(void)
|
|||
sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_GPB_UART2);
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_GPB_UART2);
|
||||
sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
|
||||
#elif CONFIG_CONS_INDEX == 3 && defined(CONFIG_MACH_SUN8I_R528)
|
||||
#if IS_ENABLED(CONFIG_UART2_PORT_E)
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPE(2), 3);
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPE(3), 3);
|
||||
sunxi_gpio_set_pull(SUNXI_GPE(2), SUNXI_GPIO_PULL_UP);
|
||||
#elif IS_ENABLED(CONFIG_UART2_PORT_G)
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPG(17), SUN8I_R528_GPG_UART2);
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPG(18), SUN8I_R528_GPG_UART2);
|
||||
sunxi_gpio_set_pull(SUNXI_GPG(18), SUNXI_GPIO_PULL_UP);
|
||||
#else
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPB(0), 7);
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPB(1), 7);
|
||||
sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP);
|
||||
#endif
|
||||
#elif CONFIG_CONS_INDEX == 4 && defined(CONFIG_MACH_SUN8I_R528)
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPB(6), 7);
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPB(7), 7);
|
||||
|
@ -175,8 +189,9 @@ static int gpio_init(void)
|
|||
sunxi_gpio_set_cfgpin(SUNXI_GPL(2), SUN8I_GPL_R_UART);
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPL(3), SUN8I_GPL_R_UART);
|
||||
sunxi_gpio_set_pull(SUNXI_GPL(3), SUNXI_GPIO_PULL_UP);
|
||||
#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_MACH_SUN8I) && \
|
||||
!defined(CONFIG_MACH_SUN8I_R40)
|
||||
#elif CONFIG_CONS_INDEX == 2 && (defined(CONFIG_MACH_SUN8I) && \
|
||||
!defined(CONFIG_MACH_SUN8I_R40)) \
|
||||
|| defined(CONFIG_MACH_SUN8I_R528)
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPG(6), SUN8I_GPG_UART1);
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPG(7), SUN8I_GPG_UART1);
|
||||
sunxi_gpio_set_pull(SUNXI_GPG(7), SUNXI_GPIO_PULL_UP);
|
||||
|
@ -223,13 +238,12 @@ static int suniv_get_boot_source(void)
|
|||
switch (brom_call) {
|
||||
case SUNIV_BOOTED_FROM_MMC0:
|
||||
return SUNXI_BOOTED_FROM_MMC0;
|
||||
case SUNIV_BOOTED_FROM_SPI:
|
||||
case SUNIV_BOOTED_FROM_NAND:
|
||||
return SUNXI_BOOTED_FROM_SPI;
|
||||
case SUNIV_BOOTED_FROM_MMC1:
|
||||
return SUNXI_BOOTED_FROM_MMC2;
|
||||
/* SPI NAND is not supported yet. */
|
||||
case SUNIV_BOOTED_FROM_NAND:
|
||||
return SUNXI_INVALID_BOOT_SOURCE;
|
||||
case SUNIV_BOOTED_FROM_SPI:
|
||||
return SUNXI_BOOTED_FROM_SPINAND;
|
||||
}
|
||||
/* If we get here something went wrong try to boot from FEL.*/
|
||||
printf("Unknown boot source from BROM: 0x%x\n", brom_call);
|
||||
|
@ -279,6 +293,7 @@ static int sunxi_get_boot_source(void)
|
|||
uint32_t sunxi_get_boot_device(void)
|
||||
{
|
||||
int boot_source = sunxi_get_boot_source();
|
||||
int boot_dev = (boot_source & 0xF); /* Low nibble is device */
|
||||
|
||||
/*
|
||||
* When booting from the SD card or NAND memory, the "eGON.BT0"
|
||||
|
@ -296,25 +311,34 @@ uint32_t sunxi_get_boot_device(void)
|
|||
* binary over USB. If it is found, it determines where SPL was
|
||||
* read from.
|
||||
*/
|
||||
switch (boot_source) {
|
||||
case SUNXI_INVALID_BOOT_SOURCE:
|
||||
if (boot_source == SUNXI_INVALID_BOOT_SOURCE)
|
||||
return BOOT_DEVICE_BOARD;
|
||||
|
||||
switch (boot_dev) {
|
||||
case SUNXI_BOOTED_FROM_MMC0:
|
||||
case SUNXI_BOOTED_FROM_MMC0_HIGH:
|
||||
return BOOT_DEVICE_MMC1;
|
||||
case SUNXI_BOOTED_FROM_NAND:
|
||||
return BOOT_DEVICE_NAND;
|
||||
case SUNXI_BOOTED_FROM_MMC2:
|
||||
case SUNXI_BOOTED_FROM_MMC2_HIGH:
|
||||
return BOOT_DEVICE_MMC2;
|
||||
case SUNXI_BOOTED_FROM_SPI:
|
||||
return BOOT_DEVICE_SPI;
|
||||
case SUNXI_BOOTED_FROM_SPINAND:
|
||||
return BOOT_DEVICE_SPINAND;
|
||||
}
|
||||
|
||||
panic("Unknown boot source %d\n", boot_source);
|
||||
return -1; /* Never reached */
|
||||
}
|
||||
|
||||
uint32_t sunxi_get_boot_position(void)
|
||||
{
|
||||
int boot_source = sunxi_get_boot_source();
|
||||
int boot_pos = ((boot_source >> 8) & 0xF); /* High nibble is position */
|
||||
|
||||
return boot_pos;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
uint32_t sunxi_get_spl_size(void)
|
||||
{
|
||||
|
@ -346,11 +370,8 @@ unsigned long board_spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
|
|||
|
||||
sector = max(raw_sect, spl_size / 512);
|
||||
|
||||
switch (sunxi_get_boot_source()) {
|
||||
case SUNXI_BOOTED_FROM_MMC0_HIGH:
|
||||
case SUNXI_BOOTED_FROM_MMC2_HIGH:
|
||||
if (sunxi_get_boot_position() == 1) {
|
||||
sector += (128 - 8) * 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return sector;
|
||||
|
@ -459,6 +480,8 @@ void board_init_f(ulong dummy)
|
|||
{
|
||||
sunxi_sram_init();
|
||||
|
||||
spl_early_init();
|
||||
|
||||
#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I_H3
|
||||
/* Enable non-secure access to some peripherals */
|
||||
tzpc_init();
|
||||
|
|
|
@ -78,13 +78,17 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#define CCM_AHB_GATING0 (0x01C20000 + 0x60)
|
||||
#define SUN6I_BUS_SOFT_RST_REG0 (0x01C20000 + 0x2C0)
|
||||
|
||||
#if defined(CONFIG_MACH_SUN8I_R528)
|
||||
#define CCM_H6_SPI_BGR_REG (0x02001000 + 0x96c)
|
||||
#define CCM_SPI0_CLK (0x02001000 + 0x940)
|
||||
#elif defined(CONFIG_SUN50I_GEN_H6)
|
||||
#define CCM_H6_SPI_BGR_REG (0x03001000 + 0x96c)
|
||||
#ifdef CONFIG_SUN50I_GEN_H6
|
||||
#define CCM_SPI0_CLK (0x03001000 + 0x940)
|
||||
#else
|
||||
#define CCM_SPI0_CLK (0x01C20000 + 0xA0)
|
||||
#endif
|
||||
#define SUN6I_BUS_SOFT_RST_REG0 (0x01C20000 + 0x2C0)
|
||||
|
||||
#define AHB_RESET_SPI0_SHIFT 20
|
||||
#define AHB_GATE_OFFSET_SPI0 20
|
||||
|
@ -99,20 +103,24 @@
|
|||
* Allwinner A10/A20 SoCs were using pins PC0,PC1,PC2,PC23 for booting
|
||||
* from SPI Flash, everything else is using pins PC0,PC1,PC2,PC3.
|
||||
* The H6 uses PC0, PC2, PC3, PC5, the H616 PC0, PC2, PC3, PC4.
|
||||
* The R528 uses PC2, PC3, PC4, PC5, PC6, PC7.
|
||||
*/
|
||||
static void spi0_pinmux_setup(unsigned int pin_function)
|
||||
{
|
||||
/* All chips use PC0 and PC2. */
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function);
|
||||
/* All chips use PC2. */
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPC(2), pin_function);
|
||||
|
||||
/* All chips except R528 use PC0. */
|
||||
if (!IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPC(0), pin_function);
|
||||
|
||||
/* All chips except H6 and H616 use PC1. */
|
||||
if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6))
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPC(1), pin_function);
|
||||
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN50I_H6) || IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPC(5), pin_function);
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN50I_H616))
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) || IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPC(4), pin_function);
|
||||
|
||||
/* Older generations use PC23 for CS, newer ones use PC3. */
|
||||
|
@ -121,12 +129,19 @@ static void spi0_pinmux_setup(unsigned int pin_function)
|
|||
sunxi_gpio_set_cfgpin(SUNXI_GPC(23), pin_function);
|
||||
else
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPC(3), pin_function);
|
||||
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPC(6), pin_function);
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
sunxi_gpio_set_cfgpin(SUNXI_GPC(7), pin_function);
|
||||
}
|
||||
|
||||
static bool is_sun6i_gen_spi(void)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_SUNXI_GEN_SUN6I) ||
|
||||
IS_ENABLED(CONFIG_SUN50I_GEN_H6);
|
||||
IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
|
||||
IS_ENABLED(CONFIG_MACH_SUN8I_R528)
|
||||
;
|
||||
}
|
||||
|
||||
static uintptr_t spi0_base_address(void)
|
||||
|
@ -137,6 +152,9 @@ static uintptr_t spi0_base_address(void)
|
|||
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
|
||||
return 0x05010000;
|
||||
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
return 0x04025000;
|
||||
|
||||
if (!is_sun6i_gen_spi() ||
|
||||
IS_ENABLED(CONFIG_MACH_SUNIV))
|
||||
return 0x01C05000;
|
||||
|
@ -152,19 +170,22 @@ static void spi0_enable_clock(void)
|
|||
uintptr_t base = spi0_base_address();
|
||||
|
||||
/* Deassert SPI0 reset on SUN6I */
|
||||
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
|
||||
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
setbits_le32(CCM_H6_SPI_BGR_REG, (1U << 16) | 0x1);
|
||||
else if (is_sun6i_gen_spi())
|
||||
setbits_le32(SUN6I_BUS_SOFT_RST_REG0,
|
||||
(1 << AHB_RESET_SPI0_SHIFT));
|
||||
|
||||
/* Open the SPI0 gate */
|
||||
if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6))
|
||||
if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) && !IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
|
||||
|
||||
if (IS_ENABLED(CONFIG_MACH_SUNIV)) {
|
||||
/* Divide by 32, clock source is AHB clock 200MHz */
|
||||
writel(SPI0_CLK_DIV_BY_32, base + SUN6I_SPI0_CCTL);
|
||||
} else if (IS_ENABLED(CONFIG_MACH_SUN8I_R528)) {
|
||||
/* 24MHz from OSC24M */
|
||||
writel((1 << 31), CCM_SPI0_CLK);
|
||||
} else {
|
||||
/* Divide by 4 */
|
||||
writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ?
|
||||
|
@ -206,11 +227,11 @@ static void spi0_disable_clock(void)
|
|||
writel(0, CCM_SPI0_CLK);
|
||||
|
||||
/* Close the SPI0 gate */
|
||||
if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6))
|
||||
if (!IS_ENABLED(CONFIG_SUN50I_GEN_H6) && !IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
clrbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
|
||||
|
||||
/* Assert SPI0 reset on SUN6I */
|
||||
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6))
|
||||
if (IS_ENABLED(CONFIG_SUN50I_GEN_H6) || IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
clrbits_le32(CCM_H6_SPI_BGR_REG, (1U << 16) | 0x1);
|
||||
else if (is_sun6i_gen_spi())
|
||||
clrbits_le32(SUN6I_BUS_SOFT_RST_REG0,
|
||||
|
@ -221,7 +242,9 @@ static void spi0_init(void)
|
|||
{
|
||||
unsigned int pin_function = SUNXI_GPC_SPI0;
|
||||
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN50I) ||
|
||||
if (IS_ENABLED(CONFIG_MACH_SUN8I_R528))
|
||||
pin_function = SUNIV_GPC_SPI0;
|
||||
else if (IS_ENABLED(CONFIG_MACH_SUN50I) ||
|
||||
IS_ENABLED(CONFIG_SUN50I_GEN_H6))
|
||||
pin_function = SUN50I_GPC_SPI0;
|
||||
else if (IS_ENABLED(CONFIG_MACH_SUNIV))
|
||||
|
@ -247,77 +270,139 @@ static void spi0_deinit(void)
|
|||
|
||||
#define SPI_READ_MAX_SIZE 60 /* FIFO size, minus 4 bytes of the header */
|
||||
|
||||
static void sunxi_spi0_read_data(u8 *buf, u32 addr, u32 bufsize,
|
||||
ulong spi_ctl_reg,
|
||||
ulong spi_ctl_xch_bitmask,
|
||||
ulong spi_fifo_reg,
|
||||
ulong spi_tx_reg,
|
||||
ulong spi_rx_reg,
|
||||
ulong spi_bc_reg,
|
||||
ulong spi_tc_reg,
|
||||
ulong spi_bcc_reg)
|
||||
static void sunxi_spi0_xfer(const u8 *txbuf, u32 txlen,
|
||||
u8 *rxbuf, u32 rxlen,
|
||||
ulong spi_ctl_reg,
|
||||
ulong spi_ctl_xch_bitmask,
|
||||
ulong spi_fifo_reg,
|
||||
ulong spi_tx_reg,
|
||||
ulong spi_rx_reg,
|
||||
ulong spi_bc_reg,
|
||||
ulong spi_tc_reg,
|
||||
ulong spi_bcc_reg)
|
||||
{
|
||||
writel(4 + bufsize, spi_bc_reg); /* Burst counter (total bytes) */
|
||||
writel(4, spi_tc_reg); /* Transfer counter (bytes to send) */
|
||||
writel(txlen + rxlen, spi_bc_reg); /* Burst counter (total bytes) */
|
||||
writel(txlen, spi_tc_reg); /* Transfer counter (bytes to send) */
|
||||
if (spi_bcc_reg)
|
||||
writel(4, spi_bcc_reg); /* SUN6I also needs this */
|
||||
writel(txlen, spi_bcc_reg); /* SUN6I also needs this */
|
||||
|
||||
/* Send the Read Data Bytes (03h) command header */
|
||||
writeb(0x03, spi_tx_reg);
|
||||
writeb((u8)(addr >> 16), spi_tx_reg);
|
||||
writeb((u8)(addr >> 8), spi_tx_reg);
|
||||
writeb((u8)(addr), spi_tx_reg);
|
||||
for (u32 i = 0; i < txlen; i++)
|
||||
writeb(*(txbuf++), spi_tx_reg);
|
||||
|
||||
/* Start the data transfer */
|
||||
setbits_le32(spi_ctl_reg, spi_ctl_xch_bitmask);
|
||||
|
||||
/* Wait until everything is received in the RX FIFO */
|
||||
while ((readl(spi_fifo_reg) & 0x7F) < 4 + bufsize)
|
||||
while ((readl(spi_fifo_reg) & 0x7F) < txlen + rxlen)
|
||||
;
|
||||
|
||||
/* Skip 4 bytes */
|
||||
readl(spi_rx_reg);
|
||||
/* Skip txlen bytes */
|
||||
for (u32 i = 0; i < txlen; i++)
|
||||
readb(spi_rx_reg);
|
||||
|
||||
/* Read the data */
|
||||
while (bufsize-- > 0)
|
||||
*buf++ = readb(spi_rx_reg);
|
||||
|
||||
/* tSHSL time is up to 100 ns in various SPI flash datasheets */
|
||||
udelay(1);
|
||||
while (rxlen-- > 0)
|
||||
*rxbuf++ = readb(spi_rx_reg);
|
||||
}
|
||||
|
||||
static void spi0_read_data(void *buf, u32 addr, u32 len)
|
||||
static void spi0_xfer(const u8 *txbuf, u32 txlen, u8 *rxbuf, u32 rxlen)
|
||||
{
|
||||
uintptr_t base = spi0_base_address();
|
||||
|
||||
if (is_sun6i_gen_spi()) {
|
||||
sunxi_spi0_xfer(txbuf, txlen, rxbuf, rxlen,
|
||||
base + SUN6I_SPI0_TCR,
|
||||
SUN6I_TCR_XCH,
|
||||
base + SUN6I_SPI0_FIFO_STA,
|
||||
base + SUN6I_SPI0_TXD,
|
||||
base + SUN6I_SPI0_RXD,
|
||||
base + SUN6I_SPI0_MBC,
|
||||
base + SUN6I_SPI0_MTC,
|
||||
base + SUN6I_SPI0_BCC);
|
||||
} else {
|
||||
sunxi_spi0_xfer(txbuf, txlen, rxbuf, rxlen,
|
||||
base + SUN4I_SPI0_CTL,
|
||||
SUN4I_CTL_XCH,
|
||||
base + SUN4I_SPI0_FIFO_STA,
|
||||
base + SUN4I_SPI0_TX,
|
||||
base + SUN4I_SPI0_RX,
|
||||
base + SUN4I_SPI0_BC,
|
||||
base + SUN4I_SPI0_TC,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SPL_SPINAND_SUPPORT)
|
||||
static int spi0_nand_switch_page(u32 page)
|
||||
{
|
||||
unsigned count;
|
||||
u8 buf[4];
|
||||
|
||||
/* Configure the Page Data Read (13h) command header */
|
||||
buf[0] = 0x13;
|
||||
buf[1] = (u8)(page >> 16);
|
||||
buf[2] = (u8)(page >> 8);
|
||||
buf[3] = (u8)(page);
|
||||
|
||||
spi0_xfer(buf, 4, NULL, 0);
|
||||
|
||||
/* Wait for NAND chip to exit busy state */
|
||||
buf[0] = 0x0f;
|
||||
buf[1] = 0xc0;
|
||||
|
||||
/* Load a NAND page can take up to 2-decimal-digit microseconds */
|
||||
for (count = 0; count < 100; count ++) {
|
||||
udelay(1);
|
||||
spi0_xfer(buf, 2, buf+2, 1);
|
||||
if (!(buf[2] & 0x1))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static void spi0_nand_reset(void)
|
||||
{
|
||||
u8 buf[1];
|
||||
|
||||
/* Configure the Device RESET (ffh) command */
|
||||
buf[0] = 0xff;
|
||||
|
||||
spi0_xfer(buf, 1, NULL, 0);
|
||||
|
||||
/* Wait for the NAND to finish resetting */
|
||||
udelay(10);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
|
||||
{
|
||||
u8 *buf8 = buf;
|
||||
u32 chunk_len;
|
||||
uintptr_t base = spi0_base_address();
|
||||
u8 txbuf[4];
|
||||
|
||||
while (len > 0) {
|
||||
chunk_len = len;
|
||||
|
||||
/* Configure the Read Data Bytes (03h) command header */
|
||||
txbuf[0] = 0x03;
|
||||
if (addr_len == 3) {
|
||||
txbuf[1] = (u8)(addr >> 16);
|
||||
txbuf[2] = (u8)(addr >> 8);
|
||||
txbuf[3] = (u8)(addr);
|
||||
} else if (addr_len == 2) {
|
||||
txbuf[1] = (u8)(addr >> 8);
|
||||
txbuf[2] = (u8)(addr);
|
||||
txbuf[3] = 0; /* dummy */
|
||||
}
|
||||
|
||||
if (chunk_len > SPI_READ_MAX_SIZE)
|
||||
chunk_len = SPI_READ_MAX_SIZE;
|
||||
|
||||
if (is_sun6i_gen_spi()) {
|
||||
sunxi_spi0_read_data(buf8, addr, chunk_len,
|
||||
base + SUN6I_SPI0_TCR,
|
||||
SUN6I_TCR_XCH,
|
||||
base + SUN6I_SPI0_FIFO_STA,
|
||||
base + SUN6I_SPI0_TXD,
|
||||
base + SUN6I_SPI0_RXD,
|
||||
base + SUN6I_SPI0_MBC,
|
||||
base + SUN6I_SPI0_MTC,
|
||||
base + SUN6I_SPI0_BCC);
|
||||
} else {
|
||||
sunxi_spi0_read_data(buf8, addr, chunk_len,
|
||||
base + SUN4I_SPI0_CTL,
|
||||
SUN4I_CTL_XCH,
|
||||
base + SUN4I_SPI0_FIFO_STA,
|
||||
base + SUN4I_SPI0_TX,
|
||||
base + SUN4I_SPI0_RX,
|
||||
base + SUN4I_SPI0_BC,
|
||||
base + SUN4I_SPI0_TC,
|
||||
0);
|
||||
}
|
||||
spi0_xfer(txbuf, 4, buf8, chunk_len);
|
||||
|
||||
/* tSHSL time is up to 100 ns in various SPI flash datasheets */
|
||||
udelay(1);
|
||||
|
||||
len -= chunk_len;
|
||||
buf8 += chunk_len;
|
||||
|
@ -325,54 +410,130 @@ static void spi0_read_data(void *buf, u32 addr, u32 len)
|
|||
}
|
||||
}
|
||||
|
||||
static ulong spi_load_read(struct spl_load_info *load, ulong sector,
|
||||
ulong count, void *buf)
|
||||
static ulong spi_load_read_nor(struct spl_load_info *load, ulong sector,
|
||||
ulong count, void *buf)
|
||||
{
|
||||
spi0_read_data(buf, sector, count);
|
||||
spi0_read_data(buf, sector, count, 3);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SPL_SPINAND_SUPPORT)
|
||||
static ulong spi_load_read_nand(struct spl_load_info *load, ulong sector,
|
||||
ulong count, void *buf)
|
||||
{
|
||||
const ulong pagesize = CONFIG_SPL_SPINAND_PAGE_SIZE;
|
||||
ulong remain = count;
|
||||
|
||||
while (remain) {
|
||||
ulong count_in_page = min(remain, pagesize - (sector % pagesize));
|
||||
ulong current_page = sector / pagesize;
|
||||
if (spi0_nand_switch_page(current_page) != 0)
|
||||
return 0;
|
||||
spi0_read_data(buf, sector % pagesize, count_in_page, 2);
|
||||
remain -= count_in_page;
|
||||
sector += count_in_page;
|
||||
buf += count_in_page;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void spinand_init(void)
|
||||
{
|
||||
spi0_init();
|
||||
spi0_nand_reset();
|
||||
}
|
||||
|
||||
void spinand_deinit(void)
|
||||
{
|
||||
spi0_deinit();
|
||||
}
|
||||
|
||||
int spinand_spl_read_block(int block, int offset, int len, void *dst)
|
||||
{
|
||||
ulong byte_offset = (block * CONFIG_SPL_SPINAND_BLOCK_SIZE) + offset;
|
||||
spi_load_read_nand(NULL, byte_offset, len, dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int spl_spi_try_load(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev,
|
||||
struct spl_load_info *load, u32 offset,
|
||||
bool allow_raw)
|
||||
{
|
||||
int ret = 0;
|
||||
struct legacy_img_hdr *header;
|
||||
header = (struct legacy_img_hdr *)CONFIG_TEXT_BASE;
|
||||
|
||||
if (load->read(load, offset, 0x40, (void *)header) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
|
||||
image_get_magic(header) == FDT_MAGIC) {
|
||||
|
||||
debug("Found FIT image\n");
|
||||
ret = spl_load_simple_fit(spl_image, load,
|
||||
offset, header);
|
||||
} else {
|
||||
if (!allow_raw && image_get_magic(header) != IH_MAGIC)
|
||||
return -EINVAL;
|
||||
|
||||
ret = spl_parse_image_header(spl_image, bootdev, header);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (load->read(load, offset, spl_image->size,
|
||||
(void *)spl_image->load_addr) == 0)
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spl_spi_load_image(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct legacy_img_hdr *header;
|
||||
uint32_t load_offset = sunxi_get_spl_size();
|
||||
struct spl_load_info load;
|
||||
bool allow_raw = false;
|
||||
|
||||
header = (struct legacy_img_hdr *)CONFIG_TEXT_BASE;
|
||||
load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
|
||||
|
||||
load.dev = NULL;
|
||||
load.priv = NULL;
|
||||
load.filename = NULL;
|
||||
load.bl_len = 1;
|
||||
|
||||
spi0_init();
|
||||
|
||||
spi0_read_data((void *)header, load_offset, 0x40);
|
||||
|
||||
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
|
||||
image_get_magic(header) == FDT_MAGIC) {
|
||||
struct spl_load_info load;
|
||||
|
||||
debug("Found FIT image\n");
|
||||
load.dev = NULL;
|
||||
load.priv = NULL;
|
||||
load.filename = NULL;
|
||||
load.bl_len = 1;
|
||||
load.read = spi_load_read;
|
||||
ret = spl_load_simple_fit(spl_image, &load,
|
||||
load_offset, header);
|
||||
} else {
|
||||
ret = spl_parse_image_header(spl_image, bootdev, header);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spi0_read_data((void *)spl_image->load_addr,
|
||||
load_offset, spl_image->size);
|
||||
switch (bootdev->boot_device) {
|
||||
#if defined(CONFIG_SPL_SPINAND_SUPPORT)
|
||||
case BOOT_DEVICE_SPINAND:
|
||||
spi0_nand_reset();
|
||||
load.read = spi_load_read_nand;
|
||||
break;
|
||||
#endif
|
||||
case BOOT_DEVICE_SPI:
|
||||
load.read = spi_load_read_nor;
|
||||
allow_raw = true;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, allow_raw);
|
||||
|
||||
spi0_deinit();
|
||||
|
||||
return ret;
|
||||
}
|
||||
/* Use priorty 0 to override the default if it happens to be linked in */
|
||||
SPL_LOAD_IMAGE_METHOD("sunxi SPI", 0, BOOT_DEVICE_SPI, spl_spi_load_image);
|
||||
|
||||
#if defined(CONFIG_SPL_SPINAND_SUPPORT)
|
||||
SPL_LOAD_IMAGE_METHOD("sunxi SPI NAND", 0, BOOT_DEVICE_SPINAND, spl_spi_load_image);
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,7 @@ enum {
|
|||
BOOT_DEVICE_NOR,
|
||||
BOOT_DEVICE_UART,
|
||||
BOOT_DEVICE_SPI,
|
||||
BOOT_DEVICE_SPINAND,
|
||||
BOOT_DEVICE_USB,
|
||||
BOOT_DEVICE_SATA,
|
||||
BOOT_DEVICE_I2C,
|
||||
|
|
|
@ -138,6 +138,12 @@
|
|||
function = "uart1";
|
||||
};
|
||||
|
||||
/omit-if-no-ref/
|
||||
uart2_pe_pins: uart2-pe-pins {
|
||||
pins = "PE2", "PE3";
|
||||
function = "uart2";
|
||||
};
|
||||
|
||||
/omit-if-no-ref/
|
||||
uart3_pb_pins: uart3-pb-pins {
|
||||
pins = "PB6", "PB7";
|
||||
|
|
|
@ -18,6 +18,7 @@ enum {
|
|||
BOOT_DEVICE_NOR,
|
||||
BOOT_DEVICE_UART,
|
||||
BOOT_DEVICE_SPI,
|
||||
BOOT_DEVICE_SPINAND,
|
||||
BOOT_DEVICE_USB,
|
||||
BOOT_DEVICE_SATA,
|
||||
BOOT_DEVICE_NVME,
|
||||
|
|
|
@ -15,6 +15,7 @@ enum {
|
|||
BOOT_DEVICE_CPGMAC,
|
||||
BOOT_DEVICE_NOR,
|
||||
BOOT_DEVICE_SPI,
|
||||
BOOT_DEVICE_SPINAND,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -874,6 +874,27 @@ config SPL_MUSB_NEW
|
|||
the drivers in drivers/usb/musb-new as part of an SPL build. The
|
||||
old drivers are in drivers/usb/musb.
|
||||
|
||||
config SPL_SPINAND_SUPPORT
|
||||
bool "Support SPINAND flash"
|
||||
help
|
||||
Enable support for SPINAND (Negative AND) flash in SPL. SPINAND flash
|
||||
can be used to allow SPL to load U-Boot from supported devices.
|
||||
|
||||
config SPL_SPINAND_PAGE_SIZE
|
||||
hex "SPINAND chip page size"
|
||||
depends on SPL_SPINAND_SUPPORT
|
||||
help
|
||||
Number of data bytes in one page for the SPINAND chip on the
|
||||
board, not including the OOB area.
|
||||
|
||||
config SPL_SPINAND_BLOCK_SIZE
|
||||
hex "SPINAND chip eraseblock size"
|
||||
depends on SPL_SPINAND_SUPPORT
|
||||
help
|
||||
Number of data bytes in one eraseblock for the SPINAND chip on the
|
||||
board. This is the multiple of SPINAND_PAGE_SIZE and the number of
|
||||
pages.
|
||||
|
||||
config SPL_NAND_SUPPORT
|
||||
bool "Support NAND flash"
|
||||
help
|
||||
|
|
|
@ -12,6 +12,14 @@
|
|||
#include <ubispl.h>
|
||||
#include <spl.h>
|
||||
|
||||
static ulong ram_spl_load_read(struct spl_load_info *load, ulong sector,
|
||||
ulong count, void *buf)
|
||||
{
|
||||
char* ubi_contents = load->priv;
|
||||
memcpy(buf, ubi_contents + sector, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
int spl_ubi_load_image(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev)
|
||||
{
|
||||
|
@ -21,6 +29,13 @@ int spl_ubi_load_image(struct spl_image_info *spl_image,
|
|||
int ret = 1;
|
||||
|
||||
switch (bootdev->boot_device) {
|
||||
#ifdef CONFIG_SPL_SPINAND_SUPPORT
|
||||
case BOOT_DEVICE_SPINAND:
|
||||
spinand_init();
|
||||
info.read = spinand_spl_read_block;
|
||||
info.peb_size = CONFIG_SPL_SPINAND_BLOCK_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_SPL_NAND_SUPPORT
|
||||
case BOOT_DEVICE_NAND:
|
||||
nand_init();
|
||||
|
@ -62,7 +77,8 @@ int spl_ubi_load_image(struct spl_image_info *spl_image,
|
|||
puts("Loading Linux failed, falling back to U-Boot.\n");
|
||||
}
|
||||
#endif
|
||||
header = spl_get_load_buffer(-sizeof(*header), sizeof(header));
|
||||
/* Ensure there's enough room for the full UBI volume! */
|
||||
header = (void*)CONFIG_SYS_LOAD_ADDR;
|
||||
#ifdef CONFIG_SPL_UBI_LOAD_BY_VOLNAME
|
||||
volumes[0].vol_id = -1;
|
||||
strncpy(volumes[0].name,
|
||||
|
@ -74,15 +90,35 @@ int spl_ubi_load_image(struct spl_image_info *spl_image,
|
|||
volumes[0].load_addr = (void *)header;
|
||||
|
||||
ret = ubispl_load_volumes(&info, volumes, 1);
|
||||
if (!ret)
|
||||
spl_parse_image_header(spl_image, bootdev, header);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
spl_parse_image_header(spl_image, bootdev, header);
|
||||
|
||||
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
|
||||
image_get_magic(header) == FDT_MAGIC) {
|
||||
struct spl_load_info load;
|
||||
printf("Found FIT\n");
|
||||
load.dev = NULL;
|
||||
load.priv = (char*)header;
|
||||
load.filename = NULL;
|
||||
load.bl_len = 1;
|
||||
load.read = ram_spl_load_read;
|
||||
ret = spl_load_simple_fit(spl_image, &load, 0, header);
|
||||
}
|
||||
|
||||
out:
|
||||
#ifdef CONFIG_SPL_SPI_NAND_SUPPORT
|
||||
if (bootdev->boot_device == BOOT_DEVICE_SPINAND)
|
||||
spinand_deselect();
|
||||
#endif
|
||||
#ifdef CONFIG_SPL_NAND_SUPPORT
|
||||
if (bootdev->boot_device == BOOT_DEVICE_NAND)
|
||||
nand_deselect();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
/* Use priorty 0 so that Ubi will override NAND and ONENAND methods */
|
||||
/* Use priority 0 so that UBI will override all NAND methods */
|
||||
SPL_LOAD_IMAGE_METHOD("NAND", 0, BOOT_DEVICE_NAND, spl_ubi_load_image);
|
||||
SPL_LOAD_IMAGE_METHOD("OneNAND", 0, BOOT_DEVICE_ONENAND, spl_ubi_load_image);
|
||||
SPL_LOAD_IMAGE_METHOD("SPINAND", 0, BOOT_DEVICE_SPINAND, spl_ubi_load_image);
|
||||
|
|
|
@ -6,10 +6,38 @@ CONFIG_MACH_SUN8I_R528=y
|
|||
CONFIG_DRAM_CLK=792
|
||||
CONFIG_DRAM_ZQ=8092667
|
||||
CONFIG_SUNXI_MINIMUM_DRAM_MB=128
|
||||
CONFIG_UART2_PORT_E=y
|
||||
CONFIG_SPL_SPI_SUNXI=y
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_SPL_LOAD_FIT=y
|
||||
CONFIG_SPL_LEGACY_IMAGE_FORMAT=y
|
||||
CONFIG_SPL_FIT_IMAGE_TINY=y
|
||||
CONFIG_SPL_SPINAND_SUPPORT=y
|
||||
CONFIG_SPL_SPINAND_PAGE_SIZE=0x800
|
||||
CONFIG_SPL_SPINAND_BLOCK_SIZE=0x20000
|
||||
CONFIG_SPL_UBI=y
|
||||
CONFIG_SPL_UBI_MAX_VOL_LEBS=2048
|
||||
CONFIG_SPL_UBI_MAX_PEB_SIZE=131072
|
||||
CONFIG_SPL_UBI_MAX_PEBS=2048
|
||||
CONFIG_SPL_UBI_PEB_OFFSET=4
|
||||
CONFIG_SPL_UBI_VID_OFFSET=2048
|
||||
CONFIG_SPL_UBI_LEB_START=4096
|
||||
CONFIG_SPL_UBI_INFO_ADDR=0x41000000
|
||||
CONFIG_SPL_UBI_VOL_IDS=256
|
||||
CONFIG_SPL_UBI_LOAD_MONITOR_ID=0
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_UBI=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_MTD=y
|
||||
CONFIG_MTD_SPI_NAND=y
|
||||
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
||||
CONFIG_SPI_FLASH_MTD=y
|
||||
CONFIG_MTD_UBI_FASTMAP=y
|
||||
CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT=1
|
||||
CONFIG_DRAM_SUNXI_ODT_EN=0
|
||||
CONFIG_DRAM_SUNXI_TPR0=0x004a2195
|
||||
CONFIG_DRAM_SUNXI_TPR11=0x340000
|
||||
CONFIG_DRAM_SUNXI_TPR12=0x46
|
||||
CONFIG_DRAM_SUNXI_TPR13=0x34000100
|
||||
CONFIG_CONS_INDEX=4
|
||||
CONFIG_CONS_INDEX=2
|
||||
CONFIG_SPI=y
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_SUNXI=y
|
||||
CONFIG_ENV_SIZE=0x20000
|
||||
CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113i-tronlong-tlt113-minievm"
|
||||
CONFIG_SPL=y
|
||||
CONFIG_MACH_SUN8I_R528=y
|
||||
CONFIG_DRAM_CLK=792
|
||||
CONFIG_DRAM_ZQ=8092667
|
||||
CONFIG_UART2_PORT_G=y
|
||||
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
|
||||
CONFIG_SPL_SPI_SUNXI=y
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_SPL_SPINAND_SUPPORT=y
|
||||
CONFIG_SPL_SPINAND_PAGE_SIZE=0x800
|
||||
CONFIG_SPL_SPINAND_BLOCK_SIZE=0x20000
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_UBI=y
|
||||
CONFIG_SPL_OF_CONTROL=y
|
||||
CONFIG_OF_LIVE=y
|
||||
# CONFIG_ENV_IS_IN_SPI_FLASH is not set
|
||||
CONFIG_ENV_FAT_DEVICE_AND_PART="0:auto"
|
||||
CONFIG_SPL_DM=y
|
||||
# CONFIG_SPL_BLK is not set
|
||||
# CONFIG_SPL_DM_MMC is not set
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_MTD=y
|
||||
CONFIG_MTD_SPI_NAND=y
|
||||
CONFIG_UBI_SILENCE_MSG=y
|
||||
CONFIG_DRAM_SUNXI_ODT_EN=1
|
||||
CONFIG_DRAM_SUNXI_TPR0=0x004a2195
|
||||
CONFIG_DRAM_SUNXI_TPR11=0x770000
|
||||
CONFIG_DRAM_SUNXI_TPR12=0x2
|
||||
CONFIG_DRAM_SUNXI_TPR13=0x34050100
|
||||
CONFIG_CONS_INDEX=3
|
||||
CONFIG_SPI=y
|
||||
CONFIG_UBIFS_SILENCE_MSG=y
|
|
@ -0,0 +1,37 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_SUNXI=y
|
||||
CONFIG_SYS_BOARD="tlt113-minievm"
|
||||
CONFIG_DEFAULT_DEVICE_TREE="sun8i-t113i-tronlong-tlt113-minievm"
|
||||
CONFIG_MACH_SUN8I_R528=y
|
||||
CONFIG_OF_LIVE=y
|
||||
# CONFIG_ENV_IS_IN_FAT is not set
|
||||
# CONFIG_ENV_IS_IN_SPI_FLASH is not set
|
||||
CONFIG_ENV_IS_IN_UBI=y
|
||||
CONFIG_ENV_UBI_PART="env"
|
||||
CONFIG_ENV_UBI_VOLUME="env"
|
||||
CONFIG_ENV_UBI_VID_OFFSET=2048
|
||||
CONFIG_SPL=y
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_SPL_OF_CONTROL=y
|
||||
CONFIG_SPL_SPINAND_SUPPORT=y
|
||||
CONFIG_SPL_SPINAND_PAGE_SIZE=0x800
|
||||
CONFIG_SPL_SPINAND_BLOCK_SIZE=0x20000
|
||||
CONFIG_SPL_SPI_SUNXI=y
|
||||
CONFIG_SUNXI_MINIMUM_DRAM_MB=256
|
||||
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
|
||||
CONFIG_DRAM_CLK=792
|
||||
CONFIG_DRAM_ZQ=8092667
|
||||
CONFIG_DRAM_SUNXI_ODT_EN=1
|
||||
CONFIG_DRAM_SUNXI_TPR0=0x004a2195
|
||||
CONFIG_DRAM_SUNXI_TPR11=0x770000
|
||||
CONFIG_DRAM_SUNXI_TPR12=0x2
|
||||
CONFIG_DRAM_SUNXI_TPR13=0x34050100
|
||||
CONFIG_CONS_INDEX=3
|
||||
CONFIG_UART2_PORT_G=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_DM_MTD=y
|
||||
CONFIG_MTD_SPI_NAND=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_CMD_MTD=y
|
||||
CONFIG_CMD_UBI=y
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
|
||||
spinand-objs := core.o foresee.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
|
||||
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
|
||||
|
|
|
@ -822,6 +822,7 @@ static const struct nand_ops spinand_ops = {
|
|||
};
|
||||
|
||||
static const struct spinand_manufacturer *spinand_manufacturers[] = {
|
||||
&foresee_spinand_manufacturer,
|
||||
&gigadevice_spinand_manufacturer,
|
||||
¯onix_spinand_manufacturer,
|
||||
µn_spinand_manufacturer,
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2017 exceet electronics GmbH
|
||||
* Copyright (c) 2024 Yilin Sun
|
||||
*
|
||||
* Authors:
|
||||
* Frieder Schrempf <frieder.schrempf@exceet.de>
|
||||
* Boris Brezillon <boris.brezillon@bootlin.com>
|
||||
* Yilin Sun <imi415@imi.moe>
|
||||
*/
|
||||
|
||||
#ifndef __UBOOT__
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#endif
|
||||
#include <linux/bug.h>
|
||||
#include <linux/mtd/spinand.h>
|
||||
|
||||
#define SPINAND_MFR_FORESEE 0xCD
|
||||
|
||||
static SPINAND_OP_VARIANTS(read_cache_variants,
|
||||
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
|
||||
|
||||
static SPINAND_OP_VARIANTS(write_cache_variants,
|
||||
SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
|
||||
SPINAND_PROG_LOAD(true, 0, NULL, 0));
|
||||
|
||||
static SPINAND_OP_VARIANTS(update_cache_variants,
|
||||
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
|
||||
SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
||||
|
||||
static int f35sqa001g_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section > 3)
|
||||
return -ERANGE;
|
||||
|
||||
region->offset = (16 * section) + 8;
|
||||
region->length = 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int f35sqa001g_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section > 3)
|
||||
return -ERANGE;
|
||||
|
||||
region->offset = (16 * section) + 2;
|
||||
region->length = 6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct mtd_ooblayout_ops f35sqa001g_ooblayout = {
|
||||
.ecc = f35sqa001g_ooblayout_ecc,
|
||||
.rfree = f35sqa001g_ooblayout_free,
|
||||
};
|
||||
|
||||
static const struct spinand_info foresee_spinand_table[] = {
|
||||
SPINAND_INFO("F35SQA001G",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71, 0x71),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&f35sqa001g_ooblayout, NULL)),
|
||||
SPINAND_INFO("F35SQA002G",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x72, 0x72),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&f35sqa001g_ooblayout, NULL)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops foresee_spinand_manuf_ops = {
|
||||
};
|
||||
|
||||
const struct spinand_manufacturer foresee_spinand_manufacturer = {
|
||||
.id = SPINAND_MFR_FORESEE,
|
||||
.name = "FORESEE",
|
||||
.chips = foresee_spinand_table,
|
||||
.nchips = ARRAY_SIZE(foresee_spinand_table),
|
||||
.ops = &foresee_spinand_manuf_ops,
|
||||
};
|
|
@ -9,6 +9,7 @@ config UBI_SILENCE_MSG
|
|||
|
||||
config MTD_UBI
|
||||
bool "Enable UBI - Unsorted block images"
|
||||
depends on MTD
|
||||
select RBTREE
|
||||
select MTD_PARTITIONS
|
||||
help
|
||||
|
|
|
@ -613,7 +613,13 @@ static const struct sunxi_pinctrl_function sun20i_d1_pinctrl_functions[] = {
|
|||
{ "uart0", 6 }, /* PB0-PB1, PB8-PB9, PE2-PE3 */
|
||||
#endif
|
||||
{ "uart1", 2 }, /* PG6-PG7 */
|
||||
#if IS_ENABLED(CONFIG_UART2_PORT_E)
|
||||
{ "uart2", 3 }, /* PE2-PE3 */
|
||||
#elif IS_ENABLED(CONFIG_UART2_PORT_G)
|
||||
{ "uart2", 2 }, /* PG17-PG18 */
|
||||
#else
|
||||
{ "uart2", 7 }, /* PB0-PB1 */
|
||||
#endif
|
||||
{ "uart3", 7 }, /* PB6-PB7 */
|
||||
};
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ struct sun4i_spi_variant {
|
|||
u32 fifo_depth;
|
||||
bool has_soft_reset;
|
||||
bool has_burst_ctl;
|
||||
bool clock_d1;
|
||||
};
|
||||
|
||||
struct sun4i_spi_plat {
|
||||
|
@ -229,7 +230,7 @@ err_ahb:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void sun4i_spi_set_speed_mode(struct udevice *dev)
|
||||
static void sun4i_spi_adjust_clock(struct udevice *dev)
|
||||
{
|
||||
struct sun4i_spi_priv *priv = dev_get_priv(dev);
|
||||
unsigned int div;
|
||||
|
@ -270,6 +271,22 @@ static void sun4i_spi_set_speed_mode(struct udevice *dev)
|
|||
}
|
||||
|
||||
writel(reg, SPI_REG(priv, SPI_CCR));
|
||||
}
|
||||
|
||||
static void sun4i_spi_adjust_clock_d1(struct udevice *dev)
|
||||
{
|
||||
/* Do nothing for now: We run at HOSC 24MHz by default */
|
||||
}
|
||||
|
||||
static void sun4i_spi_set_speed_mode(struct udevice *dev)
|
||||
{
|
||||
struct sun4i_spi_priv *priv = dev_get_priv(dev);
|
||||
u32 reg;
|
||||
|
||||
if (priv->variant->clock_d1)
|
||||
sun4i_spi_adjust_clock_d1(dev->parent);
|
||||
else
|
||||
sun4i_spi_adjust_clock(dev->parent);
|
||||
|
||||
reg = readl(SPI_REG(priv, SPI_TCR));
|
||||
reg &= ~(SPI_BIT(priv, SPI_TCR_CPOL) | SPI_BIT(priv, SPI_TCR_CPHA));
|
||||
|
@ -544,6 +561,15 @@ static const struct sun4i_spi_variant sun8i_h3_spi_variant = {
|
|||
.has_burst_ctl = true,
|
||||
};
|
||||
|
||||
static const struct sun4i_spi_variant sun50i_r329_spi_variant = {
|
||||
.regs = sun6i_spi_regs,
|
||||
.bits = sun6i_spi_bits,
|
||||
.fifo_depth = 64,
|
||||
.has_soft_reset = true,
|
||||
.has_burst_ctl = true,
|
||||
.clock_d1 = true,
|
||||
};
|
||||
|
||||
static const struct udevice_id sun4i_spi_ids[] = {
|
||||
{
|
||||
.compatible = "allwinner,sun4i-a10-spi",
|
||||
|
@ -557,6 +583,10 @@ static const struct udevice_id sun4i_spi_ids[] = {
|
|||
.compatible = "allwinner,sun8i-h3-spi",
|
||||
.data = (ulong)&sun8i_h3_spi_variant,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun50i-r329-spi",
|
||||
.data = (ulong)&sun50i_r329_spi_variant,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
|
|
|
@ -283,6 +283,17 @@ static void sunxi_musb_disable(struct musb *musb)
|
|||
enabled = false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_USB_GADGET
|
||||
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
|
||||
{
|
||||
struct sunxi_glue *glue = dev_get_priv(dev);
|
||||
struct musb_host_data *host = &glue->mdata;
|
||||
|
||||
host->host->isr(0, host->host);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sunxi_musb_init(struct musb *musb)
|
||||
{
|
||||
struct sunxi_glue *glue = to_sunxi_glue(musb->controller);
|
||||
|
@ -431,16 +442,13 @@ static struct musb_hdrc_config musb_config_h3 = {
|
|||
|
||||
static int musb_usb_probe(struct udevice *dev)
|
||||
{
|
||||
struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
|
||||
struct sunxi_glue *glue = dev_get_priv(dev);
|
||||
struct musb_host_data *host = &glue->mdata;
|
||||
struct musb_hdrc_platform_data pdata;
|
||||
void *base = dev_read_addr_ptr(dev);
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_USB_MUSB_HOST
|
||||
struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
|
||||
#endif
|
||||
|
||||
if (!base)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -471,26 +479,30 @@ static int musb_usb_probe(struct udevice *dev)
|
|||
pdata.platform_ops = &sunxi_musb_ops;
|
||||
pdata.config = glue->cfg->config;
|
||||
|
||||
#ifdef CONFIG_USB_MUSB_HOST
|
||||
priv->desc_before_addr = true;
|
||||
if (IS_ENABLED(CONFIG_USB_MUSB_HOST)) {
|
||||
priv->desc_before_addr = true;
|
||||
|
||||
pdata.mode = MUSB_HOST;
|
||||
host->host = musb_init_controller(&pdata, &glue->dev, base);
|
||||
if (!host->host)
|
||||
return -EIO;
|
||||
pdata.mode = MUSB_HOST;
|
||||
host->host = musb_init_controller(&pdata, &glue->dev, base);
|
||||
if (!host->host)
|
||||
return -EIO;
|
||||
|
||||
return musb_lowlevel_init(host);
|
||||
} else if (CONFIG_IS_ENABLED(DM_USB_GADGET)) {
|
||||
pdata.mode = MUSB_PERIPHERAL;
|
||||
host->host = musb_init_controller(&pdata, &glue->dev, base);
|
||||
if (!host->host)
|
||||
return -EIO;
|
||||
|
||||
printf("Allwinner mUSB OTG (Peripheral)\n");
|
||||
musb_gadget_setup(host->host);
|
||||
return usb_add_gadget_udc(&glue->dev, &host->host->g);
|
||||
}
|
||||
|
||||
ret = musb_lowlevel_init(host);
|
||||
if (!ret)
|
||||
printf("Allwinner mUSB OTG (Host)\n");
|
||||
#else
|
||||
pdata.mode = MUSB_PERIPHERAL;
|
||||
host->host = musb_register(&pdata, &glue->dev, base);
|
||||
if (IS_ERR_OR_NULL(host->host))
|
||||
return -EIO;
|
||||
|
||||
printf("Allwinner mUSB OTG (Peripheral)\n");
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -245,6 +245,7 @@ struct spinand_manufacturer {
|
|||
};
|
||||
|
||||
/* SPI NAND manufacturers */
|
||||
extern const struct spinand_manufacturer foresee_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer micron_spinand_manufacturer;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <config.h>
|
||||
|
||||
extern void spinand_init(void);
|
||||
extern void nand_init(void);
|
||||
unsigned long nand_size(void);
|
||||
|
||||
|
@ -107,7 +108,9 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset);
|
|||
u32 nand_spl_adjust_offset(u32 sector, u32 offs);
|
||||
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst);
|
||||
int nand_spl_read_block(int block, int offset, int len, void *dst);
|
||||
int spinand_spl_read_block(int block, int offset, int len, void *dst);
|
||||
void nand_deselect(void);
|
||||
void spinand_deselect(void);
|
||||
|
||||
#ifdef CONFIG_SYS_NAND_SELECT_DEVICE
|
||||
void board_nand_select_device(struct nand_chip *nand, int chip);
|
||||
|
|
|
@ -142,6 +142,7 @@ enum sunxi_gpio_number {
|
|||
#define SUN6I_GPG_SDC1 2
|
||||
#define SUN8I_GPG_SDC1 2
|
||||
#define SUN8I_GPG_UART1 2
|
||||
#define SUN8I_R528_GPG_UART2 2
|
||||
#define SUN5I_GPG_UART1 4
|
||||
|
||||
#define SUN6I_GPH_PWM 2
|
||||
|
|
Loading…
Reference in New Issue