Merge branch '2020-02-07-master-imports'

- 2 FAT fixes.
- MediaTek ethernet support improvement.
- Initial Cortina Access CAxxxx family support.
- Correct return value of do_gpio() and so gpio shell command.
This commit is contained in:
Tom Rini 2020-02-07 19:04:23 -05:00
commit e1dff2d69e
34 changed files with 1059 additions and 28 deletions

View File

@ -173,6 +173,14 @@ F: doc/README.bcm7xxx
F: drivers/mmc/bcmstb_sdhci.c
F: drivers/spi/bcmstb_spi.c
ARM CORTINA ACCESS CAxxxx
M: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
S: Supported
F: board/cortina/common/
F: drivers/gpio/cortina_gpio.c
F: drivers/watchdog/cortina_wdt.c
F: drivers/serial/serial_cortina.c
ARM/CZ.NIC TURRIS MOX SUPPORT
M: Marek Behun <marek.behun@nic.cz>
S: Maintained
@ -655,6 +663,14 @@ S: Maintained
T: git https://gitlab.denx.de/u-boot/custodians/u-boot-mips.git
F: arch/mips/
MIPS CORTINA ACCESS CAxxxx
M: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
S: Supported
F: board/cortina/common/
F: drivers/gpio/cortina_gpio.c
F: drivers/watchdog/cortina_wdt.c
F: drivers/serial/serial_cortina.c
MIPS MSCC
M: Gregory CLEMENT <gregory.clement@bootlin.com>
M: Lars Povlsen <lars.povlsen@microchip.com>

View File

@ -1675,6 +1675,10 @@ config TARGET_DURIAN
Support for durian platform.
It has 2GB Sdram, uart and pcie.
config TARGET_PRESIDIO_ASIC
bool "Support Cortina Presidio ASIC Platform"
select ARM64
endchoice
config ARCH_SUPPORT_TFABOOT
@ -1823,6 +1827,7 @@ source "board/Marvell/gplugd/Kconfig"
source "board/armadeus/apf27/Kconfig"
source "board/armltd/vexpress/Kconfig"
source "board/armltd/vexpress64/Kconfig"
source "board/cortina/presidio-asic/Kconfig"
source "board/broadcom/bcm23550_w1d/Kconfig"
source "board/broadcom/bcm28155_ap/Kconfig"
source "board/broadcom/bcm963158/Kconfig"

View File

@ -909,6 +909,8 @@ dtb-$(CONFIG_TARGET_VEXPRESS_CA15_TC2) += vexpress-v2p-ca15_a7.dtb
dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
targets += $(dtb-y)
# Add any required device tree compiler flags here

View File

@ -0,0 +1,69 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020, Cortina Access Inc.
*/
/dts-v1/;
/ {
#address-cells = <2>;
#size-cells = <1>;
mmc0: mmc@f4400000 {
compatible = "snps,dw-cortina";
reg = <0x0 0xf4400000 0x1000>;
bus-width = <4>;
io_ds = <0x77>;
fifo-mode;
sd_dll_ctrl = <0xf43200e8>;
io_drv_ctrl = <0xf432004c>;
};
gpio0: gpio-controller@0xf4329280 {
compatible = "cortina,ca-gpio";
reg = <0x0 0xf4329280 0x24>;
gpio-controller;
#gpio-cells = <2>;
status = "okay";
};
gpio1: gpio-controller@0xf43292a4 {
compatible = "cortina,ca-gpio";
reg = <0x0 0xf43292a4 0x24>;
gpio-controller;
#gpio-cells = <2>;
status = "disabled";
};
watchdog: watchdog@0xf432901c {
compatible = "cortina,ca-wdt";
reg = <0x0 0xf432901c 0x34>,
<0x0 0xf4320020 0x04>;
status = "okay";
};
uart0: serial@0xf4329148 {
u-boot,dm-pre-reloc;
compatible = "cortina,ca-uart";
reg = <0x0 0xf4329148 0x30>;
status = "okay";
};
i2c: i2c@f4329120 {
compatible = "cortina,ca-i2c";
reg = <0x0 0xf4329120 0x28>;
clock-frequency = <400000>;
};
sflash: sflash-controller@f4324000 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "cortina,ca-sflash";
reg = <0x0 0xf4324000 0x50>;
reg-names = "sflash-regs";
flash@0 {
compatible = "jedec,spi-nor";
spi-rx-bus-width = <1>;
spi-max-frequency = <108000000>;
};
};
};

View File

@ -178,3 +178,16 @@
pinctrl-0 = <&watchdog_pins>;
status = "okay";
};
&eth {
status = "okay";
mediatek,gmac-id = <0>;
phy-mode = "sgmii";
mediatek,switch = "mt7531";
reset-gpios = <&gpio 54 GPIO_ACTIVE_HIGH>;
fixed-link {
speed = <1000>;
full-duplex;
};
};

View File

@ -7,6 +7,9 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/mt7622-clk.h>
#include <dt-bindings/power/mt7629-power.h>
#include <dt-bindings/reset/mt7629-reset.h>
#include <dt-bindings/gpio/gpio.h>
/ {
compatible = "mediatek,mt7622";
@ -182,4 +185,46 @@
clock-names = "source", "hclk";
status = "disabled";
};
ethsys: syscon@1b000000 {
compatible = "mediatek,mt7622-ethsys", "syscon";
reg = <0x1b000000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
eth: ethernet@1b100000 {
compatible = "mediatek,mt7622-eth", "syscon";
reg = <0x1b100000 0x20000>;
clocks = <&topckgen CLK_TOP_ETH_SEL>,
<&ethsys CLK_ETH_ESW_EN>,
<&ethsys CLK_ETH_GP0_EN>,
<&ethsys CLK_ETH_GP1_EN>,
<&ethsys CLK_ETH_GP2_EN>,
<&sgmiisys CLK_SGMII_TX250M_EN>,
<&sgmiisys CLK_SGMII_RX250M_EN>,
<&sgmiisys CLK_SGMII_CDR_REF>,
<&sgmiisys CLK_SGMII_CDR_FB>,
<&topckgen CLK_TOP_SGMIIPLL>,
<&apmixedsys CLK_APMIXED_ETH2PLL>;
clock-names = "ethif", "esw", "gp0", "gp1", "gp2",
"sgmii_tx250m", "sgmii_rx250m",
"sgmii_cdr_ref", "sgmii_cdr_fb", "sgmii_ck",
"eth2pll";
power-domains = <&scpsys MT7629_POWER_DOMAIN_ETHSYS>;
resets = <&ethsys ETHSYS_FE_RST>;
reset-names = "fe";
mediatek,ethsys = <&ethsys>;
mediatek,sgmiisys = <&sgmiisys>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
sgmiisys: sgmiisys@1b128000 {
compatible = "mediatek,mt7622-sgmiisys", "syscon";
reg = <0x1b128000 0x3000>;
#clock-cells = <1>;
};
};

View File

@ -4,8 +4,8 @@
!defined(CONFIG_ARCH_ROCKCHIP) && !defined(CONFIG_ARCH_LX2160A) && \
!defined(CONFIG_ARCH_LS1028A) && !defined(CONFIG_ARCH_LS2080A) && \
!defined(CONFIG_ARCH_LS1088A) && !defined(CONFIG_ARCH_ASPEED) && \
!defined(CONFIG_ARCH_LS1012A) && \
!defined(CONFIG_ARCH_U8500)
!defined(CONFIG_ARCH_LS1012A) && !defined(CONFIG_ARCH_U8500) && \
!defined(CONFIG_CORTINA_PLATFORM)
#include <asm/arch/gpio.h>
#endif
#include <asm-generic/gpio.h>

View File

@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2020 Cortina Access Inc.
#
obj-y += lowlevel_init.o

View File

@ -51,7 +51,7 @@ static void print_backtrace(unsigned long *sp)
printf("\n");
}
static void show_regs(struct pt_regs *regs)
void show_regs(struct pt_regs *regs)
{
int i;

View File

@ -0,0 +1,6 @@
config CORTINA_PLATFORM
bool "Cortina-Access Platform"
default y
help
Select this option for Cortina-Access platforms
to enables selection of CAxxxx drivers

View File

@ -0,0 +1,18 @@
if TARGET_PRESIDIO_ASIC
config BIT64
bool
default y
select SOC_CA7774
config SYS_BOARD
default "presidio-asic"
config SYS_VENDOR
default "cortina"
config SYS_CONFIG_NAME
default "presidio_asic"
source "board/cortina/common/Kconfig"
endif

View File

@ -0,0 +1,6 @@
Cortina Presidio ASIC G3 Engineering BOARD
M: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
S: Supported
F: board/cortina/presidio-asic/
F: include/configs/presidio_asic.h
F: configs/cortina_presidio-asic*defconfig

View File

@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2020 Cortina-Access.Inc.
#
#
obj-y := presidio.o
obj-y += lowlevel_init.o

View File

@ -0,0 +1,87 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2020 Cortina-Access
*
*/
#include <asm-offsets.h>
#include <config.h>
#include <linux/linkage.h>
#include <asm/macro.h>
#include <asm/armv8/mmu.h>
.globl lowlevel_init
lowlevel_init:
mov x29, lr /* Save LR */
#if defined(CONFIG_SOC_CA7774)
/* Enable SMPEN in CPUECTLR */
mrs x0, s3_1_c15_c2_1
tst x0, #0x40
b.ne skip_smp_setup
orr x0, x0, #0x40
msr s3_1_c15_c2_1, x0
skip_smp_setup:
#endif
#if defined(CONFIG_SOC_CA8277B)
/* Enable CPU Timer */
ldr x0, =CONFIG_SYS_TIMER_BASE
mov x1, #1
str w1, [x0]
#endif
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
branch_if_slave x0, 1f
#ifndef CONFIG_TARGET_VENUS
ldr x0, =GICD_BASE
bl gic_init_secure
#endif
1:
#if defined(CONFIG_GICV3)
ldr x0, =GICR_BASE
bl gic_init_secure_percpu
#elif defined(CONFIG_GICV2)
ldr x0, =GICD_BASE
ldr x1, =GICC_BASE
bl gic_init_secure_percpu
#endif
#endif
#ifdef CONFIG_ARMV8_MULTIENTRY
branch_if_master x0, x1, 2f
/*
* Slave should wait for master clearing spin table.
* This sync prevent salves observing incorrect
* value of spin table and jumping to wrong place.
*/
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
#ifdef CONFIG_GICV2
ldr x0, =GICC_BASE
#endif
bl gic_wait_for_interrupt
#endif
/*
* All slaves will enter EL2 and optionally EL1.
*/
adr x4, lowlevel_in_el2
ldr x5, =ES_TO_AARCH64
bl armv8_switch_to_el2
lowlevel_in_el2:
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
adr x4, lowlevel_in_el1
ldr x5, =ES_TO_AARCH64
bl armv8_switch_to_el1
lowlevel_in_el1:
#endif
#endif /* CONFIG_ARMV8_MULTIENTRY */
2:
mov lr, x29 /* Restore LR */
ret

View File

@ -0,0 +1,134 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2020 - Cortina Access Inc.
*
*/
#include <common.h>
#include <malloc.h>
#include <errno.h>
#include <netdev.h>
#include <asm/io.h>
#include <linux/compiler.h>
#include <configs/presidio_asic.h>
#include <linux/psci.h>
#include <asm/psci.h>
#include <cpu_func.h>
#include <asm/armv8/mmu.h>
DECLARE_GLOBAL_DATA_PTR;
#define CA_PERIPH_BASE 0xE0000000UL
#define CA_PERIPH_SIZE 0x20000000UL
#define CA_GLOBAL_BASE 0xf4320000
#define CA_GLOBAL_JTAG_ID 0xf4320000
#define CA_GLOBAL_BLOCK_RESET 0xf4320004
#define CA_GLOBAL_BLOCK_RESET_RESET_DMA BIT(16)
#define CA_DMA_SEC_SSP_BAUDRATE_CTRL 0xf7001b94
#define CA_DMA_SEC_SSP_ID 0xf7001b80
int print_cpuinfo(void)
{
printf("CPU: Cortina Presidio G3\n");
return 0;
}
static struct mm_region presidio_mem_map[] = {
{
.virt = DDR_BASE,
.phys = DDR_BASE,
.size = PHYS_SDRAM_1_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_OUTER_SHARE
},
{
.virt = CA_PERIPH_BASE,
.phys = CA_PERIPH_BASE,
.size = CA_PERIPH_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE
},
{
/* List terminator */
0,
}
};
struct mm_region *mem_map = presidio_mem_map;
static noinline int invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
u64 arg2)
{
asm volatile("mov x0, %0\n"
"mov x1, %1\n"
"mov x2, %2\n"
"mov x3, %3\n"
"smc #0\n"
: "+r" (function_id)
: "r" (arg0), "r" (arg1), "r" (arg2)
);
return function_id;
}
int board_early_init_r(void)
{
dcache_disable();
return 0;
}
int board_init(void)
{
unsigned int reg_data, jtag_id;
/* Enable timer */
writel(1, CONFIG_SYS_TIMER_BASE);
/* Enable snoop in CCI400 slave port#4 */
writel(3, 0xF5595000);
jtag_id = readl(CA_GLOBAL_JTAG_ID);
/* If this is HGU variant then do not use
* the Saturn daughter card ref. clk
*/
if (jtag_id == 0x1010D8F3) {
reg_data = readl(0xF3100064);
/* change multifunc. REF CLK pin to
* a simple GPIO pin
*/
reg_data |= (1 << 1);
writel(reg_data, 0xf3100064);
}
return 0;
}
int dram_init(void)
{
unsigned int ddr_size;
ddr_size = readl(0x111100c);
gd->ram_size = ddr_size * 0x100000;
return 0;
}
void reset_cpu(ulong addr)
{
invoke_psci_fn_smc(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
}
#ifdef CONFIG_LAST_STAGE_INIT
int last_stage_init(void)
{
u32 val;
val = readl(CA_GLOBAL_BLOCK_RESET);
val &= ~CA_GLOBAL_BLOCK_RESET_RESET_DMA;
writel(val, CA_GLOBAL_BLOCK_RESET);
/* reduce output pclk ~3.7Hz to save power consumption */
writel(0x000000FF, CA_DMA_SEC_SSP_BAUDRATE_CTRL);
return 0;
}
#endif

View File

@ -1,16 +1,7 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2001 William L. Pitts
* All rights reserved.
*
* Redistribution and use in source and binary forms are freely
* permitted provided that the above copyright notice and this
* paragraph and the following disclaimer are duplicated in all
* such forms.
*
* This software is provided "AS IS" and without any express or
* implied warranties, including, without limitation, the implied
* warranties of merchantability and fitness for a particular
* purpose.
*/
#include <common.h>

View File

@ -223,23 +223,35 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
gpio_direction_output(gpio, value);
}
printf("gpio: pin %s (gpio %u) value is ", str_gpio, gpio);
if (IS_ERR_VALUE(value))
if (IS_ERR_VALUE(value)) {
printf("unknown (ret=%d)\n", value);
else
goto err;
} else {
printf("%d\n", value);
}
if (sub_cmd != GPIOC_INPUT && !IS_ERR_VALUE(value)) {
int nval = gpio_get_value(gpio);
if (IS_ERR_VALUE(nval))
if (IS_ERR_VALUE(nval)) {
printf(" Warning: no access to GPIO output value\n");
else if (nval != value)
goto err;
} else if (nval != value) {
printf(" Warning: value of pin is still %d\n", nval);
goto err;
}
}
if (ret != -EBUSY)
gpio_free(gpio);
return value;
return CMD_RET_SUCCESS;
err:
if (ret != -EBUSY)
gpio_free(gpio);
return CMD_RET_FAILURE;
}
U_BOOT_CMD(gpio, 4, 0, do_gpio,

View File

@ -0,0 +1,29 @@
CONFIG_ARM=y
# CONFIG_SYS_ARCH_TIMER is not set
CONFIG_TARGET_PRESIDIO_ASIC=y
CONFIG_SYS_TEXT_BASE=0x04000000
CONFIG_DM_GPIO=y
CONFIG_ENV_SIZE=0x20000
CONFIG_NR_DRAM_BANKS=1
CONFIG_IDENT_STRING="Presidio-SoC"
CONFIG_SHOW_BOOT_PROGRESS=y
CONFIG_BOOTDELAY=3
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="earlycon=serial,0xf4329148 console=ttyS0,115200 root=/dev/ram0"
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SYS_PROMPT="G3#"
CONFIG_CMD_WDT=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIMER=y
CONFIG_CMD_SMC=y
CONFIG_OF_CONTROL=y
CONFIG_OF_LIVE=y
CONFIG_DEFAULT_DEVICE_TREE="ca-presidio-engboard"
# CONFIG_NET is not set
CONFIG_DM=y
CONFIG_CORTINA_GPIO=y
# CONFIG_MMC is not set
CONFIG_DM_SERIAL=y
CONFIG_CORTINA_UART=y
CONFIG_WDT=y
CONFIG_WDT_CORTINA=y

View File

@ -33,6 +33,10 @@ CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_DM_ETH=y
CONFIG_PHY_FIXED=y
CONFIG_MEDIATEK_ETH=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_CMD_PING=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_PINCTRL_MT7622=y

View File

@ -83,9 +83,9 @@ argv: Arguments.
Allowable return value are:
CMD_SUCCESS The command was successfully executed.
CMD_RET_SUCCESS The command was successfully executed.
CMD_FAILURE The command failed.
CMD_RET_FAILURE The command failed.
CMD_RET_USAGE The command was called with invalid parameters. This value
leads to the display of the usage string.

View File

@ -15,6 +15,7 @@ alias abrodkin Alexey Brodkin <alexey.brodkin@synopsys.com>
alias afleming Andy Fleming <afleming@gmail.com>
alias ag Anatolij Gustschin <agust@denx.de>
alias agraf Alexander Graf <agraf@csgraf.de>
alias alexnemirovsky Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
alias alisonwang Alison Wang <alison.wang@nxp.com>
alias angelo_ts Angelo Dureghello <angelo@sysam.it>
alias bmeng Bin Meng <bmeng.cn@gmail.com>
@ -57,6 +58,7 @@ alias arc uboot, abrodkin
alias arm uboot, trini
alias at91 uboot, abiessmann
alias cortina uboot, alexnemirovsky
alias davinci ti
alias imx uboot, sbabic
alias kirkwood uboot, stroese

View File

@ -60,6 +60,14 @@ config BCM6345_GPIO
help
This driver supports the GPIO banks on BCM6345 SoCs.
config CORTINA_GPIO
bool "Cortina-Access GPIO driver"
depends on DM_GPIO && CORTINA_PLATFORM
help
Enable support for the GPIO controller in Cortina CAxxxx SoCs.
This driver supports all CPU ISA variants supported by Cortina
Access CAxxxx SoCs.
config DWAPB_GPIO
bool "DWAPB GPIO driver"
depends on DM && DM_GPIO

View File

@ -17,6 +17,7 @@ endif
obj-$(CONFIG_AT91_GPIO) += at91_gpio.o
obj-$(CONFIG_ATMEL_PIO4) += atmel_pio4.o
obj-$(CONFIG_BCM6345_GPIO) += bcm6345_gpio.o
obj-$(CONFIG_CORTINA_GPIO) += cortina_gpio.o
obj-$(CONFIG_INTEL_GPIO) += intel_gpio.o
obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
obj-$(CONFIG_INTEL_BROADWELL_GPIO) += intel_broadwell_gpio.o

111
drivers/gpio/cortina_gpio.c Normal file
View File

@ -0,0 +1,111 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Cortina-Access
*
* GPIO Driver for Cortina Access CAxxxx Line of SoCs
*/
#include <common.h>
#include <dm.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <linux/compat.h>
#include <linux/compiler.h>
/* GPIO Register Map */
#define CORTINA_GPIO_CFG 0x00
#define CORTINA_GPIO_OUT 0x04
#define CORTINA_GPIO_IN 0x08
#define CORTINA_GPIO_LVL 0x0C
#define CORTINA_GPIO_EDGE 0x10
#define CORTINA_GPIO_BOTHEDGE 0x14
#define CORTINA_GPIO_IE 0x18
#define CORTINA_GPIO_INT 0x1C
#define CORTINA_GPIO_STAT 0x20
struct cortina_gpio_bank {
void __iomem *base;
};
#ifdef CONFIG_DM_GPIO
static int ca_gpio_direction_input(struct udevice *dev, unsigned int offset)
{
struct cortina_gpio_bank *priv = dev_get_priv(dev);
setbits_32(priv->base, BIT(offset));
return 0;
}
static int
ca_gpio_direction_output(struct udevice *dev, unsigned int offset, int value)
{
struct cortina_gpio_bank *priv = dev_get_priv(dev);
clrbits_32(priv->base, BIT(offset));
return 0;
}
static int ca_gpio_get_value(struct udevice *dev, unsigned int offset)
{
struct cortina_gpio_bank *priv = dev_get_priv(dev);
return readl(priv->base + CORTINA_GPIO_IN) & BIT(offset);
}
static int ca_gpio_set_value(struct udevice *dev, unsigned int offset,
int value)
{
struct cortina_gpio_bank *priv = dev_get_priv(dev);
setbits_32(priv->base + CORTINA_GPIO_OUT, BIT(offset));
return 0;
}
static int ca_gpio_get_function(struct udevice *dev, unsigned int offset)
{
struct cortina_gpio_bank *priv = dev_get_priv(dev);
if (readl(priv->base) & BIT(offset))
return GPIOF_INPUT;
else
return GPIOF_OUTPUT;
}
static const struct dm_gpio_ops gpio_cortina_ops = {
.direction_input = ca_gpio_direction_input,
.direction_output = ca_gpio_direction_output,
.get_value = ca_gpio_get_value,
.set_value = ca_gpio_set_value,
.get_function = ca_gpio_get_function,
};
static int ca_gpio_probe(struct udevice *dev)
{
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct cortina_gpio_bank *priv = dev_get_priv(dev);
priv->base = dev_remap_addr_index(dev, 0);
if (!priv->base)
return -EINVAL;
uc_priv->gpio_count = dev_read_u32_default(dev, "ngpios", 32);
uc_priv->bank_name = dev->name;
debug("Done Cortina GPIO init\n");
return 0;
}
static const struct udevice_id ca_gpio_ids[] = {
{.compatible = "cortina,ca-gpio"},
{}
};
U_BOOT_DRIVER(cortina_gpio) = {
.name = "cortina-gpio",
.id = UCLASS_GPIO,
.ops = &gpio_cortina_ops,
.probe = ca_gpio_probe,
.priv_auto_alloc_size = sizeof(struct cortina_gpio_bank),
.of_match = ca_gpio_ids,
};
#endif /* CONFIG_DM_GPIO */

View File

@ -136,7 +136,8 @@ enum mtk_switch {
enum mtk_soc {
SOC_MT7623,
SOC_MT7629
SOC_MT7629,
SOC_MT7622
};
struct mtk_eth_priv {
@ -151,6 +152,7 @@ struct mtk_eth_priv {
void __iomem *fe_base;
void __iomem *gmac_base;
void __iomem *ethsys_base;
void __iomem *sgmii_base;
struct mii_dev *mdio_bus;
int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg);
@ -750,6 +752,24 @@ static int mtk_phy_probe(struct udevice *dev)
return 0;
}
static void mtk_sgmii_init(struct mtk_eth_priv *priv)
{
/* Set SGMII GEN2 speed(2.5G) */
clrsetbits_le32(priv->sgmii_base + SGMSYS_GEN2_SPEED,
SGMSYS_SPEED_2500, SGMSYS_SPEED_2500);
/* Disable SGMII AN */
clrsetbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1,
SGMII_AN_ENABLE, 0);
/* SGMII force mode setting */
writel(SGMII_FORCE_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE);
/* Release PHYA power down state */
clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL,
SGMII_PHYA_PWD, 0);
}
static void mtk_mac_init(struct mtk_eth_priv *priv)
{
int i, ge_mode = 0;
@ -758,8 +778,13 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
switch (priv->phy_interface) {
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII:
ge_mode = GE_MODE_RGMII;
break;
case PHY_INTERFACE_MODE_SGMII:
ge_mode = GE_MODE_RGMII;
mtk_ethsys_rmw(priv, ETHSYS_SYSCFG0_REG, SYSCFG0_SGMII_SEL_M,
SYSCFG0_SGMII_SEL(priv->gmac_id));
mtk_sgmii_init(priv);
break;
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:
@ -828,7 +853,8 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
memset(priv->rx_ring_noc, 0, NUM_RX_DESC * sizeof(struct pdma_rxdesc));
memset(priv->pkt_pool, 0, TOTAL_PKT_BUF_SIZE);
flush_dcache_range((u32)pkt_base, (u32)(pkt_base + TOTAL_PKT_BUF_SIZE));
flush_dcache_range((ulong)pkt_base,
(ulong)(pkt_base + TOTAL_PKT_BUF_SIZE));
priv->rx_dma_owner_idx0 = 0;
priv->tx_cpu_owner_idx0 = 0;
@ -940,7 +966,7 @@ static int mtk_eth_send(struct udevice *dev, void *packet, int length)
pkt_base = (void *)phys_to_virt(priv->tx_ring_noc[idx].txd_info1.SDP0);
memcpy(pkt_base, packet, length);
flush_dcache_range((u32)pkt_base, (u32)pkt_base +
flush_dcache_range((ulong)pkt_base, (ulong)pkt_base +
roundup(length, ARCH_DMA_MINALIGN));
priv->tx_ring_noc[idx].txd_info2.SDL0 = length;
@ -966,7 +992,7 @@ static int mtk_eth_recv(struct udevice *dev, int flags, uchar **packetp)
length = priv->rx_ring_noc[idx].rxd_info2.PLEN0;
pkt_base = (void *)phys_to_virt(priv->rx_ring_noc[idx].rxd_info1.PDP0);
invalidate_dcache_range((u32)pkt_base, (u32)pkt_base +
invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base +
roundup(length, ARCH_DMA_MINALIGN));
if (packetp)
@ -994,7 +1020,7 @@ static int mtk_eth_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct mtk_eth_priv *priv = dev_get_priv(dev);
u32 iobase = pdata->iobase;
ulong iobase = pdata->iobase;
int ret;
/* Frame Engine Register Base */
@ -1104,6 +1130,26 @@ static int mtk_eth_ofdata_to_platdata(struct udevice *dev)
}
}
if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII) {
/* get corresponding sgmii phandle */
ret = dev_read_phandle_with_args(dev, "mediatek,sgmiisys",
NULL, 0, 0, &args);
if (ret)
return ret;
regmap = syscon_node_to_regmap(args.node);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
priv->sgmii_base = regmap_get_range(regmap, 0);
if (!priv->sgmii_base) {
dev_err(dev, "Unable to find sgmii\n");
return -ENODEV;
}
}
/* check for switch first, otherwise phy will be used */
priv->sw = SW_NONE;
priv->switch_init = NULL;
@ -1151,6 +1197,7 @@ static int mtk_eth_ofdata_to_platdata(struct udevice *dev)
static const struct udevice_id mtk_eth_ids[] = {
{ .compatible = "mediatek,mt7629-eth", .data = SOC_MT7629 },
{ .compatible = "mediatek,mt7623-eth", .data = SOC_MT7623 },
{ .compatible = "mediatek,mt7622-eth", .data = SOC_MT7622 },
{}
};

View File

@ -20,6 +20,8 @@
#define ETHSYS_SYSCFG0_REG 0x14
#define SYSCFG0_GE_MODE_S(n) (12 + ((n) * 2))
#define SYSCFG0_GE_MODE_M 0x3
#define SYSCFG0_SGMII_SEL_M (0x3 << 8)
#define SYSCFG0_SGMII_SEL(gmac) ((!(gmac)) ? BIT(9) : BIT(8))
#define ETHSYS_CLKCFG0_REG 0x2c
#define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
@ -30,6 +32,19 @@
#define GE_MODE_MII_PHY 2
#define GE_MODE_RMII 3
/* SGMII subsystem config registers */
#define SGMSYS_PCS_CONTROL_1 0x0
#define SGMII_AN_ENABLE BIT(12)
#define SGMSYS_SGMII_MODE 0x20
#define SGMII_FORCE_MODE 0x31120019
#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
#define SGMII_PHYA_PWD BIT(4)
#define SGMSYS_GEN2_SPEED 0x2028
#define SGMSYS_SPEED_2500 BIT(2)
/* Frame Engine Registers */
/* PDMA */

View File

@ -553,6 +553,13 @@ config COREBOOT_SERIAL
a serial console on any platform without needing to change the
device tree, etc.
config CORTINA_UART
bool "Cortina UART support"
depends on DM_SERIAL
help
Select this to enable UART support for Cortina-Access UART devices
found on CAxxxx SoCs.
config FSL_LINFLEXUART
bool "Freescale Linflex UART support"
depends on DM_SERIAL

View File

@ -36,6 +36,7 @@ obj-$(CONFIG_ARM_DCC) += arm_dcc.o
obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
obj-$(CONFIG_BCM6345_SERIAL) += serial_bcm6345.o
obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o
obj-$(CONFIG_CORTINA_UART) += serial_cortina.o
obj-$(CONFIG_EFI_APP) += serial_efi.o
obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
obj-$(CONFIG_MCFUART) += mcfuart.o

View File

@ -0,0 +1,164 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2020 Cortina-Access Ltd.
* Common UART Driver for Cortina Access CAxxxx line of SoCs
*
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <watchdog.h>
#include <asm/io.h>
#include <serial.h>
#include <linux/compiler.h>
/* Register definitions */
#define UCFG 0x00 /* UART config register */
#define UFC 0x04 /* Flow Control */
#define URX_SAMPLE 0x08 /* UART RX Sample register */
#define URT_TUNE 0x0C /* Fine tune of UART clk */
#define UTX_DATA 0x10 /* UART TX Character data */
#define URX_DATA 0x14 /* UART RX Character data */
#define UINFO 0x18 /* UART Info */
#define UINT_EN0 0x1C /* UART Interrupt enable 0 */
#define UINT_EN1 0x20 /* UART Interrupt enable 1 */
#define UINT0 0x24 /* UART Interrupt 0 setting/clearing */
#define UINT1 0x28 /* UART Interrupt 1 setting/clearing */
#define UINT_STAT 0x2C /* UART Interrupt Status */
/* UART Control Register Bit Fields */
#define UCFG_BAUD_COUNT_MASK 0xFFFFFF00
#define UCFG_BAUD_COUNT(x) ((x << 8) & UCFG_BAUD_COUNT_MASK)
#define UCFG_EN BIT(7)
#define UCFG_RX_EN BIT(6)
#define UCFG_TX_EN BIT(5)
#define UCFG_PARITY_EN BIT(4)
#define UCFG_PARITY_SEL BIT(3)
#define UCFG_2STOP_BIT BIT(2)
#define UCFG_CNT1 BIT(1)
#define UCFG_CNT0 BIT(0)
#define UCFG_CHAR_5 0
#define UCFG_CHAR_6 1
#define UCFG_CHAR_7 2
#define UCFG_CHAR_8 3
#define UINFO_TX_FIFO_EMPTY BIT(3)
#define UINFO_TX_FIFO_FULL BIT(2)
#define UINFO_RX_FIFO_EMPTY BIT(1)
#define UINFO_RX_FIFO_FULL BIT(0)
#define UINT_RX_NON_EMPTY BIT(6)
#define UINT_TX_EMPTY BIT(5)
#define UINT_RX_UNDERRUN BIT(4)
#define UINT_RX_OVERRUN BIT(3)
#define UINT_RX_PARITY_ERR BIT(2)
#define UINT_RX_STOP_ERR BIT(1)
#define UINT_TX_OVERRUN BIT(0)
#define UINT_MASK_ALL 0x7F
struct ca_uart_priv {
void __iomem *base;
};
int ca_serial_setbrg(struct udevice *dev, int baudrate)
{
struct ca_uart_priv *priv = dev_get_priv(dev);
unsigned int uart_ctrl, baud, sample;
baud = CORTINA_UART_CLOCK / baudrate;
uart_ctrl = readl(priv->base + UCFG);
uart_ctrl &= ~UCFG_BAUD_COUNT_MASK;
uart_ctrl |= UCFG_BAUD_COUNT(baud);
writel(uart_ctrl, priv->base + UCFG);
sample = baud / 2;
sample = (sample < 7) ? 7 : sample;
writel(sample, priv->base + URX_SAMPLE);
return 0;
}
static int ca_serial_getc(struct udevice *dev)
{
struct ca_uart_priv *priv = dev_get_priv(dev);
int ch;
ch = readl(priv->base + URX_DATA) & 0xFF;
return (int)ch;
}
static int ca_serial_putc(struct udevice *dev, const char ch)
{
struct ca_uart_priv *priv = dev_get_priv(dev);
unsigned int status;
/* Retry if TX FIFO full */
status = readl(priv->base + UINFO);
if (status & UINFO_TX_FIFO_FULL)
return -EAGAIN;
writel(ch, priv->base + UTX_DATA);
return 0;
}
static int ca_serial_pending(struct udevice *dev, bool input)
{
struct ca_uart_priv *priv = dev_get_priv(dev);
unsigned int status;
status = readl(priv->base + UINFO);
if (input)
return (status & UINFO_RX_FIFO_EMPTY) ? 0 : 1;
else
return (status & UINFO_TX_FIFO_FULL) ? 1 : 0;
}
static int ca_serial_probe(struct udevice *dev)
{
struct ca_uart_priv *priv = dev_get_priv(dev);
u32 uart_ctrl;
/* Set data, parity and stop bits */
uart_ctrl = UCFG_EN | UCFG_TX_EN | UCFG_RX_EN | UCFG_CHAR_8;
writel(uart_ctrl, priv->base + UCFG);
return 0;
}
static int ca_serial_ofdata_to_platdata(struct udevice *dev)
{
struct ca_uart_priv *priv = dev_get_priv(dev);
priv->base = dev_remap_addr_index(dev, 0);
if (!priv->base)
return -ENOENT;
return 0;
}
static const struct dm_serial_ops ca_serial_ops = {
.putc = ca_serial_putc,
.pending = ca_serial_pending,
.getc = ca_serial_getc,
.setbrg = ca_serial_setbrg,
};
static const struct udevice_id ca_serial_ids[] = {
{.compatible = "cortina,ca-uart"},
{}
};
U_BOOT_DRIVER(serial_cortina) = {
.name = "serial_cortina",
.id = UCLASS_SERIAL,
.of_match = ca_serial_ids,
.ofdata_to_platdata = ca_serial_ofdata_to_platdata,
.priv_auto_alloc_size = sizeof(struct ca_uart_priv),
.probe = ca_serial_probe,
.ops = &ca_serial_ops
};

View File

@ -107,6 +107,14 @@ config WDT_CDNS
Select this to enable Cadence watchdog timer, which can be found on some
Xilinx Microzed Platform.
config WDT_CORTINA
bool "Cortina Access CAxxxx watchdog timer support"
depends on WDT
help
Cortina Access CAxxxx watchdog timer support.
This driver support all CPU ISAs supported by Cortina
Access CAxxxx SoCs.
config WDT_MPC8xx
bool "MPC8xx watchdog timer support"
depends on WDT && MPC8xx

View File

@ -20,6 +20,7 @@ obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o
obj-$(CONFIG_WDT_ARMADA_37XX) += armada-37xx-wdt.o
obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o
obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o
obj-$(CONFIG_WDT_ORION) += orion_wdt.o
obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o

View File

@ -0,0 +1,139 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Cortina-Access
*
*/
#include <common.h>
#include <dm.h>
#include <hang.h>
#include <asm/io.h>
#include <wdt.h>
#include <linux/bitops.h>
#define CA_WDT_CTRL 0x00
#define CA_WDT_PS 0x04
#define CA_WDT_DIV 0x08
#define CA_WDT_LD 0x0C
#define CA_WDT_LOADE 0x10
#define CA_WDT_CNT 0x14
#define CA_WDT_IE 0x18
#define CA_WDT_INT 0x1C
#define CA_WDT_STAT 0x20
/* CA_WDT_CTRL */
#define CTL_WDT_EN BIT(0)
#define CTL_WDT_RSTEN BIT(1)
#define CTL_WDT_CLK_SEL BIT(2)
/* CA_WDT_LOADE */
#define WDT_UPD BIT(0)
#define WDT_UPD_PS BIT(1)
/* Global config */
#define WDT_RESET_SUB BIT(4)
#define WDT_RESET_ALL_BLOCK BIT(6)
#define WDT_RESET_REMAP BIT(7)
#define WDT_EXT_RESET BIT(8)
#define WDT_RESET_DEFAULT (WDT_EXT_RESET | WDT_RESET_REMAP | \
WDT_RESET_ALL_BLOCK | WDT_RESET_SUB)
struct ca_wdt_priv {
void __iomem *base;
void __iomem *global_config;
};
static void cortina_wdt_set_timeout(struct udevice *dev, u64 timeout_ms)
{
struct ca_wdt_priv *priv = dev_get_priv(dev);
/* Prescale using millisecond unit */
writel(CORTINA_PER_IO_FREQ / 1000, priv->base + CA_WDT_PS);
/* Millisecond */
writel(1, priv->base + CA_WDT_DIV);
writel(timeout_ms, priv->base + CA_WDT_LD);
writel(WDT_UPD | WDT_UPD_PS, priv->base + CA_WDT_LOADE);
}
static int cortina_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
{
struct ca_wdt_priv *priv = dev_get_priv(dev);
cortina_wdt_set_timeout(dev, timeout);
/* WDT Reset option */
setbits_32(priv->global_config, WDT_RESET_DEFAULT);
/* Enable WDT */
setbits_32(priv->base, CTL_WDT_EN | CTL_WDT_RSTEN | CTL_WDT_CLK_SEL);
return 0;
}
static int cortina_wdt_stop(struct udevice *dev)
{
struct ca_wdt_priv *priv = dev_get_priv(dev);
/* Disable WDT */
writel(0, priv->base);
return 0;
}
static int cortina_wdt_reset(struct udevice *dev)
{
struct ca_wdt_priv *priv = dev_get_priv(dev);
/* Reload WDT counter */
writel(WDT_UPD, priv->base + CA_WDT_LOADE);
return 0;
}
static int cortina_wdt_expire_now(struct udevice *dev, ulong flags)
{
/* Set 1ms timeout to reset system */
cortina_wdt_set_timeout(dev, 1);
hang();
return 0;
}
static int cortina_wdt_probe(struct udevice *dev)
{
struct ca_wdt_priv *priv = dev_get_priv(dev);
priv->base = dev_remap_addr_index(dev, 0);
if (!priv->base)
return -ENOENT;
priv->global_config = dev_remap_addr_index(dev, 1);
if (!priv->global_config)
return -ENOENT;
/* Stop WDT */
cortina_wdt_stop(dev);
return 0;
}
static const struct wdt_ops cortina_wdt_ops = {
.start = cortina_wdt_start,
.reset = cortina_wdt_reset,
.stop = cortina_wdt_stop,
.expire_now = cortina_wdt_expire_now,
};
static const struct udevice_id cortina_wdt_ids[] = {
{.compatible = "cortina,ca-wdt"},
{}
};
U_BOOT_DRIVER(cortina_wdt) = {
.name = "cortina_wdt",
.id = UCLASS_WDT,
.probe = cortina_wdt_probe,
.of_match = cortina_wdt_ids,
.ops = &cortina_wdt_ops,
};

View File

@ -794,6 +794,8 @@ set_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos, __u8 *buffer,
newclust = get_fatent(mydata, endclust);
if (newclust != endclust + 1)
break;
if (IS_LAST_CLUST(newclust, mydata->fatsize))
break;
if (CHECK_CLUST(newclust, mydata->fatsize)) {
@ -811,7 +813,9 @@ set_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos, __u8 *buffer,
offset = 0;
else
offset = pos - cur_pos;
wsize = min(cur_pos + actsize, filesize) - pos;
wsize = min_t(unsigned long long, actsize, filesize - cur_pos);
wsize -= offset;
if (get_set_cluster(mydata, curclust, offset,
buffer, wsize, &actsize)) {
printf("Error get-and-setting cluster\n");
@ -824,8 +828,6 @@ set_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos, __u8 *buffer,
if (filesize <= cur_pos)
break;
/* CHECK: newclust = get_fatent(mydata, endclust); */
if (IS_LAST_CLUST(newclust, mydata->fatsize))
/* no more clusters */
break;

View File

@ -0,0 +1,75 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2020 Cortina Access Inc.
*
* Configuration for Cortina-Access Presidio board.
*/
#ifndef __PRESIDIO_ASIC_H
#define __PRESIDIO_ASIC_H
#define CONFIG_REMAKE_ELF
#define CONFIG_SUPPORT_RAW_INITRD
#define CONFIG_SYS_INIT_SP_ADDR 0x00100000
#define CONFIG_SYS_BOOTM_LEN 0x00c00000
/* Generic Timer Definitions */
#define COUNTER_FREQUENCY 25000000
#define CONFIG_SYS_TIMER_RATE COUNTER_FREQUENCY
#define CONFIG_SYS_TIMER_COUNTER 0xf4321008
/* note: arch/arm/cpu/armv8/start.S which references GICD_BASE/GICC_BASE
* does not yet support DT. Thus define it here.
*/
#define CONFIG_GICV2
#define GICD_BASE 0xf7011000
#define GICC_BASE 0xf7012000
#define CONFIG_SYS_MEMTEST_SCRATCH 0x00100000
#define CONFIG_SYS_MEMTEST_START 0x05000000
#define CONFIG_SYS_MEMTEST_END 0x0D000000
/* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (8 << 20))
#define CONFIG_SYS_TIMER_BASE 0xf4321000
/* Use external clock source */
#define PRESIDIO_APB_CLK 125000000
#define CORTINA_PER_IO_FREQ PRESIDIO_APB_CLK
/* Cortina Serial Configuration */
#define CORTINA_UART_CLOCK (PRESIDIO_APB_CLK)
#define CORTINA_SERIAL_PORTS {(void *)CONFIG_SYS_SERIAL0, \
(void *)CONFIG_SYS_SERIAL1}
#define CONFIG_BAUDRATE 115200
#define CONFIG_SYS_SERIAL0 PER_UART0_CFG
#define CONFIG_SYS_SERIAL1 PER_UART1_CFG
/* BOOTP options */
#define CONFIG_BOOTP_BOOTFILESIZE
/* Miscellaneous configurable options */
#define CONFIG_SYS_LOAD_ADDR (DDR_BASE + 0x10000000)
#define CONFIG_LAST_STAGE_INIT
/* SDRAM Bank #1 */
#define DDR_BASE 0x00000000
#define PHYS_SDRAM_1 DDR_BASE
#define PHYS_SDRAM_1_SIZE 0x80000000 /* 2GB */
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
/* Console I/O Buffer Size */
#define CONFIG_SYS_CBSIZE 256
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
sizeof(CONFIG_SYS_PROMPT) + 16)
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
/* max command args */
#define CONFIG_SYS_MAXARGS 64
#define CONFIG_EXTRA_ENV_SETTINGS "silent=y\0"
#endif /* __PRESIDIO_ASIC_H */