- MVEBU Espressobin fixes and enhancements (fix switch security
  issue, enable MVNETA, enable SD-card, fix COMPHY nodes, default
  env variables, etc)
- MMC Xenon: Set signal voltage and max base clock
- a37xx PCI driver: Depend on DM_GPIO and remove #ifdef's
This commit is contained in:
Tom Rini 2020-08-31 09:43:13 -04:00
commit 123f4f84f8
10 changed files with 284 additions and 28 deletions

View file

@ -159,6 +159,6 @@
&pcie0 {
pinctrl-names = "default";
pinctrl-0 = <&pcie_pins>;
reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
status = "okay";
};

View file

@ -67,18 +67,29 @@
device_type = "memory";
reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
};
vcc_sd_reg0: regulator@0 {
compatible = "regulator-gpio";
regulator-name = "vcc_sd0";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-type = "voltage";
states = <1800000 0x1
3300000 0x0>;
gpios = <&gpionb 4 GPIO_ACTIVE_HIGH>;
};
};
&comphy {
max-lanes = <3>;
phy0 {
phy-type = <PHY_TYPE_PEX0>;
phy-speed = <PHY_SPEED_2_5G>;
phy-type = <PHY_TYPE_USB3_HOST0>;
phy-speed = <PHY_SPEED_5G>;
};
phy1 {
phy-type = <PHY_TYPE_USB3_HOST0>;
phy-speed = <PHY_SPEED_5G>;
phy-type = <PHY_TYPE_PEX0>;
phy-speed = <PHY_SPEED_2_5G>;
};
phy2 {
@ -110,6 +121,15 @@
status = "okay";
};
&sdhci0 {
pinctrl-names = "default";
pinctrl-0 = <&sdio_pins>;
bus-width = <4>;
cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>;
vqmmc-supply = <&vcc_sd_reg0>;
status = "okay";
};
&spi0 {
status = "okay";
pinctrl-names = "default";
@ -145,6 +165,6 @@
&pcie0 {
pinctrl-names = "default";
pinctrl-0 = <&pcie_pins>;
reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
status = "okay";
};

View file

@ -172,6 +172,6 @@
&pcie0 {
pinctrl-names = "default";
pinctrl-0 = <&pcie_pins>;
reset-gpio = <&gpiosb 3 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
status = "disabled";
};

View file

@ -44,6 +44,7 @@ DECLARE_GLOBAL_DATA_PTR;
/* Switch Port Registers */
#define MVEBU_SW_LINK_CTRL_REG (1)
#define MVEBU_SW_PORT_CTRL_REG (4)
#define MVEBU_SW_PORT_BASE_VLAN (6)
/* Global 2 Registers */
#define MVEBU_G2_SMI_PHY_CMD_REG (24)
@ -207,8 +208,16 @@ int board_network_enable(struct mii_dev *bus)
* FIXME: remove this code once Topaz driver gets available
* A3720 Community Board Only
* Configure Topaz switch (88E6341)
* Restrict output to ports 1,2,3 only from port 0 (CPU)
* Set port 0,1,2,3 to forwarding Mode (through Switch Port registers)
*/
mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(1),
MVEBU_SW_PORT_BASE_VLAN, BIT(0));
mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(2),
MVEBU_SW_PORT_BASE_VLAN, BIT(0));
mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(3),
MVEBU_SW_PORT_BASE_VLAN, BIT(0));
mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(0),
MVEBU_SW_PORT_CTRL_REG, 0x7f);
mii_multi_chip_mode_write(bus, 1, MVEBU_PORT_CTRL_SMI_ADDR(1),
@ -234,3 +243,103 @@ int board_network_enable(struct mii_dev *bus)
return 0;
}
#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_ENV_IS_IN_SPI_FLASH)
int ft_board_setup(void *blob, struct bd_info *bd)
{
int ret;
int spi_off;
int parts_off;
int part_off;
/* Fill SPI MTD partitions for Linux kernel on Espressobin */
if (!of_machine_is_compatible("marvell,armada-3720-espressobin"))
return 0;
spi_off = fdt_node_offset_by_compatible(blob, -1, "jedec,spi-nor");
if (spi_off < 0)
return 0;
/* Do not touch partitions if they are already defined */
if (fdt_subnode_offset(blob, spi_off, "partitions") >= 0)
return 0;
parts_off = fdt_add_subnode(blob, spi_off, "partitions");
if (parts_off < 0) {
printf("Can't add partitions node: %s\n", fdt_strerror(parts_off));
return 0;
}
ret = fdt_setprop_string(blob, parts_off, "compatible", "fixed-partitions");
if (ret < 0) {
printf("Can't set compatible property: %s\n", fdt_strerror(ret));
return 0;
}
ret = fdt_setprop_u32(blob, parts_off, "#address-cells", 1);
if (ret < 0) {
printf("Can't set #address-cells property: %s\n", fdt_strerror(ret));
return 0;
}
ret = fdt_setprop_u32(blob, parts_off, "#size-cells", 1);
if (ret < 0) {
printf("Can't set #size-cells property: %s\n", fdt_strerror(ret));
return 0;
}
/* Add u-boot-env partition */
part_off = fdt_add_subnode(blob, parts_off, "partition@u-boot-env");
if (part_off < 0) {
printf("Can't add partition@u-boot-env node: %s\n", fdt_strerror(part_off));
return 0;
}
ret = fdt_setprop_u32(blob, part_off, "reg", CONFIG_ENV_OFFSET);
if (ret < 0) {
printf("Can't set partition@u-boot-env reg property: %s\n", fdt_strerror(ret));
return 0;
}
ret = fdt_appendprop_u32(blob, part_off, "reg", CONFIG_ENV_SIZE);
if (ret < 0) {
printf("Can't set partition@u-boot-env reg property: %s\n", fdt_strerror(ret));
return 0;
}
ret = fdt_setprop_string(blob, part_off, "label", "u-boot-env");
if (ret < 0) {
printf("Can't set partition@u-boot-env label property: %s\n", fdt_strerror(ret));
return 0;
}
/* Add firmware partition */
part_off = fdt_add_subnode(blob, parts_off, "partition@firmware");
if (part_off < 0) {
printf("Can't add partition@firmware node: %s\n", fdt_strerror(part_off));
return 0;
}
ret = fdt_setprop_u32(blob, part_off, "reg", 0);
if (ret < 0) {
printf("Can't set partition@firmware reg property: %s\n", fdt_strerror(ret));
return 0;
}
ret = fdt_appendprop_u32(blob, part_off, "reg", CONFIG_ENV_OFFSET);
if (ret < 0) {
printf("Can't set partition@firmware reg property: %s\n", fdt_strerror(ret));
return 0;
}
ret = fdt_setprop_string(blob, part_off, "label", "firmware");
if (ret < 0) {
printf("Can't set partition@firmware label property: %s\n", fdt_strerror(ret));
return 0;
}
return 0;
}
#endif

View file

@ -6,7 +6,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_NR_DRAM_BANKS=1
CONFIG_TARGET_MVEBU_ARMADA_37XX=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x180000
CONFIG_ENV_OFFSET=0x3F0000
CONFIG_ENV_SECT_SIZE=0x10000
CONFIG_DM_GPIO=y
CONFIG_DEBUG_UART_BASE=0xd0012000
@ -80,3 +80,6 @@ CONFIG_USB_ETHER_RTL8152=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_SHA1=y
CONFIG_SHA256=y
CONFIG_MVNETA=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_OF_BOARD_SETUP=y

View file

@ -13,7 +13,8 @@ Build Procedure
2. Set the cross compiler:
# export CROSS_COMPILE=/path/to/toolchain/aarch64-marvell-linux-gnu-
# sudo apt-get install gcc-aarch64-linux-gnu
# export CROSS_COMPILE=aarch64-linux-gnu-
3. Clean-up old residuals:
@ -30,7 +31,7 @@ Build Procedure
5. Configure the device-tree and build the U-Boot image:
Compile u-boot and set the required device-tree using:
For the Armada-70x0/80x0 DB board compile u-boot and set the required device-tree using:
# make DEVICE_TREE=<name>
@ -42,12 +43,45 @@ Build Procedure
In order to prevent this, the required device-tree MUST be set during compilation.
All device-tree files are located in ./arch/arm/dts/ folder.
For other DB boards (MacchiatoBin, EspressoBin and 3700 DB board) compile u-boot with
just default device-tree from defconfig using:
# make
NOTE:
The u-boot.bin should not be used as a stand-alone image.
The ARM Trusted Firmware (ATF) build process uses this image to generate the
flash image.
flash image. See TF-A Build Instructions for Marvell Platforms for more details at:
https://trustedfirmware-a.readthedocs.io/en/latest/plat/marvell/armada/build.html
Configuration update
---------------------
To update the U-Boot configuration, please refer to doc/README.kconfig
Permanent ethernet MAC address
-------------------------------
Prior flashing new U-Boot version (as part of ATF image) it is suggested to backup
permanent ethernet MAC address as it is stored only in U-Boot env storage (SPI or eMMC).
Some boards like EspressoBin have MAC address printed on sticker. To print current MAC
address run:
# echo $ethaddr
MAC addresses 00:51:82:11:22:00, 00:51:82:11:22:01, 00:51:82:11:22:02, 00:51:82:11:22:03
and F0:AD:4E:03:64:7F are default hardcoded values found in Marvell's and Armbian U-Boot
forks and therefore *not* unique. Usage of static hardcoded MAC addresses should be avoided.
When original address is lost (e.g. erased by Armbian boot scripts for EspressoBin) it is
suggested to generate new random one.
After flashing new U-Boot version it is suggested to reset U-Boot env variables to default
and then set correct permanent ethernet MAC address.
# env default -a
# setenv ethaddr XX:XX:XX:XX:XX:XX
# saveenv
Where XX:XX:XX:XX:XX:XX is permanent ethernet MAC address.
Recent Linux kernel versions use correct permanent ethernet MAC address from U-Boot env as
U-Boot will inject it into kernel's device-tree.

View file

@ -22,6 +22,7 @@
#include <linux/libfdt.h>
#include <malloc.h>
#include <sdhci.h>
#include <power/regulator.h>
DECLARE_GLOBAL_DATA_PTR;
@ -42,6 +43,14 @@ DECLARE_GLOBAL_DATA_PTR;
#define SDHC_SYS_EXT_OP_CTRL 0x010C
#define MASK_CMD_CONFLICT_ERROR BIT(8)
#define SDHC_SLOT_EMMC_CTRL 0x0130
#define ENABLE_DATA_STROBE_SHIFT 24
#define SET_EMMC_RSTN_SHIFT 16
#define EMMC_VCCQ_MASK 0x3
#define EMMC_VCCQ_1_8V 0x1
#define EMMC_VCCQ_1_2V 0x2
#define EMMC_VCCQ_3_3V 0x3
#define SDHC_SLOT_RETUNING_REQ_CTRL 0x0144
/* retuning compatible */
#define RETUNING_COMPATIBLE 0x1
@ -108,6 +117,8 @@ DECLARE_GLOBAL_DATA_PTR;
#define MMC_TIMING_MMC_HS400 10
#define XENON_MMC_MAX_CLK 400000000
#define XENON_MMC_3V3_UV 3300000
#define XENON_MMC_1V8_UV 1800000
enum soc_pad_ctrl_type {
SOC_PAD_SD,
@ -128,6 +139,8 @@ struct xenon_sdhci_priv {
void *pad_ctrl_reg;
int pad_type;
struct udevice *vqmmc;
};
static int xenon_mmc_phy_init(struct sdhci_host *host)
@ -208,6 +221,51 @@ static void armada_3700_soc_pad_voltage_set(struct sdhci_host *host)
writel(ARMADA_3700_SOC_PAD_3_3V, priv->pad_ctrl_reg);
}
static int xenon_mmc_start_signal_voltage_switch(struct sdhci_host *host)
{
struct xenon_sdhci_priv *priv = host->mmc->priv;
u8 voltage;
u32 ctrl;
int ret = 0;
/* If there is no vqmmc regulator, return */
if (!priv->vqmmc)
return 0;
if (priv->pad_type == SOC_PAD_FIXED_1_8V) {
/* Switch to 1.8v */
ret = regulator_set_value(priv->vqmmc,
XENON_MMC_1V8_UV);
} else if (priv->pad_type == SOC_PAD_SD) {
/* Get voltage info */
voltage = sdhci_readb(host, SDHCI_POWER_CONTROL);
voltage &= ~SDHCI_POWER_ON;
if (voltage == SDHCI_POWER_330) {
/* Switch to 3.3v */
ret = regulator_set_value(priv->vqmmc,
XENON_MMC_3V3_UV);
} else {
/* Switch to 1.8v */
ret = regulator_set_value(priv->vqmmc,
XENON_MMC_1V8_UV);
}
}
/* Set VCCQ, eMMC mode: 1.8V; SD/SDIO mode: 3.3V */
ctrl = sdhci_readl(host, SDHC_SLOT_EMMC_CTRL);
if (IS_SD(host->mmc))
ctrl |= EMMC_VCCQ_3_3V;
else
ctrl |= EMMC_VCCQ_1_8V;
sdhci_writel(host, ctrl, SDHC_SLOT_EMMC_CTRL);
if (ret)
printf("Signal voltage switch fail\n");
return ret;
}
static void xenon_mmc_phy_set(struct sdhci_host *host)
{
struct xenon_sdhci_priv *priv = host->mmc->priv;
@ -334,6 +392,13 @@ static int xenon_sdhci_set_ios_post(struct sdhci_host *host)
uint speed = host->mmc->tran_speed;
int pwr_18v = 0;
/*
* Signal Voltage Switching is only applicable for Host Controllers
* v3.00 and above.
*/
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
xenon_mmc_start_signal_voltage_switch(host);
if ((sdhci_readb(host, SDHCI_POWER_CONTROL) & ~SDHCI_POWER_ON) ==
SDHCI_POWER_180)
pwr_18v = 1;
@ -394,6 +459,18 @@ static int xenon_sdhci_probe(struct udevice *dev)
/* Set default timing */
priv->timing = MMC_TIMING_LEGACY;
/* Get the vqmmc regulator if there is */
device_get_supply_regulator(dev, "vqmmc-supply", &priv->vqmmc);
/* Set the initial voltage value to 3.3V if there is regulator */
if (priv->vqmmc) {
ret = regulator_set_value(priv->vqmmc,
XENON_MMC_3V3_UV);
if (ret) {
printf("Failed to set VQMMC regulator to 3.3V\n");
return ret;
}
}
/* Disable auto clock gating during init */
xenon_mmc_set_acg(host, false);
@ -426,7 +503,7 @@ static int xenon_sdhci_probe(struct udevice *dev)
host->ops = &xenon_sdhci_ops;
host->max_clk = XENON_MMC_MAX_CLK;
ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
ret = sdhci_setup_cfg(&plat->cfg, host, XENON_MMC_MAX_CLK, 0);
if (ret)
return ret;

View file

@ -30,6 +30,7 @@ config PCI_AARDVARK
bool "Enable Aardvark PCIe driver"
default n
depends on DM_PCI
depends on DM_GPIO
depends on ARMADA_3700
help
Say Y here if you want to enable PCIe controller support on

View file

@ -148,6 +148,7 @@ struct pcie_advk {
void *base;
int first_busno;
struct udevice *dev;
struct gpio_desc reset_gpio;
};
static inline void advk_writel(struct pcie_advk *pcie, uint val, uint reg)
@ -613,10 +614,7 @@ static int pcie_advk_probe(struct udevice *dev)
{
struct pcie_advk *pcie = dev_get_priv(dev);
#if CONFIG_IS_ENABLED(DM_GPIO)
struct gpio_desc reset_gpio;
gpio_request_by_name(dev, "reset-gpio", 0, &reset_gpio,
gpio_request_by_name(dev, "reset-gpios", 0, &pcie->reset_gpio,
GPIOD_IS_OUT);
/*
* Issue reset to add-in card through the dedicated GPIO.
@ -631,15 +629,14 @@ static int pcie_advk_probe(struct udevice *dev)
* possible before PCIe PHY initialization. Moreover, the PCIe
* clock should be gated as well.
*/
if (dm_gpio_is_valid(&reset_gpio)) {
if (dm_gpio_is_valid(&pcie->reset_gpio)) {
dev_dbg(pcie->dev, "Toggle PCIE Reset GPIO ...\n");
dm_gpio_set_value(&reset_gpio, 0);
dm_gpio_set_value(&pcie->reset_gpio, 1);
mdelay(200);
dm_gpio_set_value(&reset_gpio, 1);
dm_gpio_set_value(&pcie->reset_gpio, 0);
} else {
dev_warn(pcie->dev, "PCIE Reset on GPIO support is missing\n");
}
#else
dev_dbg(pcie->dev, "PCIE Reset on GPIO support is missing\n");
#endif /* DM_GPIO */
pcie->first_busno = dev->seq;
pcie->dev = pci_get_controller(dev);
@ -647,6 +644,16 @@ static int pcie_advk_probe(struct udevice *dev)
return pcie_advk_setup_hw(pcie);
}
static int pcie_advk_remove(struct udevice *dev)
{
struct pcie_advk *pcie = dev_get_priv(dev);
if (dm_gpio_is_valid(&pcie->reset_gpio))
dm_gpio_set_value(&pcie->reset_gpio, 1);
return 0;
}
/**
* pcie_advk_ofdata_to_platdata() - Translate from DT to device state
*
@ -687,5 +694,7 @@ U_BOOT_DRIVER(pcie_advk) = {
.ops = &pcie_advk_ops,
.ofdata_to_platdata = pcie_advk_ofdata_to_platdata,
.probe = pcie_advk_probe,
.remove = pcie_advk_remove,
.flags = DM_FLAG_OS_PREPARE,
.priv_auto_alloc_size = sizeof(struct pcie_advk),
};

View file

@ -37,7 +37,7 @@
/*
* Other required minimal configurations
*/
#define CONFIG_SYS_LOAD_ADDR 0x00800000 /* default load adr- 8M */
#define CONFIG_SYS_LOAD_ADDR 0x06000000 /* default load adr */
#define CONFIG_SYS_RESET_ADDRESS 0xffff0000 /* Rst Vector Adr */
#define CONFIG_SYS_MAXARGS 32 /* max number of command args */
@ -90,12 +90,15 @@
#include <config_distro_bootcmd.h>
/* fdt_addr and kernel_addr are needed for existing distribution boot scripts */
#define CONFIG_EXTRA_ENV_SETTINGS \
"scriptaddr=0x4d00000\0" \
"pxefile_addr_r=0x4e00000\0" \
"fdt_addr_r=0x4f00000\0" \
"kernel_addr_r=0x5000000\0" \
"ramdisk_addr_r=0x8000000\0" \
"scriptaddr=0x6d00000\0" \
"pxefile_addr_r=0x6e00000\0" \
"fdt_addr=0x6f00000\0" \
"fdt_addr_r=0x6f00000\0" \
"kernel_addr=0x7000000\0" \
"kernel_addr_r=0x7000000\0" \
"ramdisk_addr_r=0xa000000\0" \
BOOTENV
#endif /* _CONFIG_MVEBU_ARMADA_37XX_H */