ARM: renesas: Add R8A77970 V3MSK board and CPLD code

Add board code for the R8A77970 V3MSK board.
Add CPLD sysreset driver to the R-Car V3M SK board.
Extracted from a larger patch by Valentine Barshak.

Reviewed-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
Signed-off-by: Hai Pham <hai.pham.ud@renesas.com>
Signed-off-by: Tam Nguyen <tam.nguyen.xa@renesas.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
[Marek: Sync configs and board code with V3M Eagle, squash CPLD driver in]
This commit is contained in:
Valentine Barshak 2019-04-23 23:44:57 +03:00 committed by Marek Vasut
parent f2a21a8c24
commit 5f4e26964c
9 changed files with 564 additions and 0 deletions

View file

@ -1050,6 +1050,7 @@ dtb-$(CONFIG_RCAR_GEN3) += \
r8a77965-ulcb-u-boot.dtb \
r8a77965-salvator-x-u-boot.dtb \
r8a77970-eagle-u-boot.dtb \
r8a77970-v3msk-u-boot.dtb \
r8a77980-condor-u-boot.dtb \
r8a77990-ebisu-u-boot.dtb \
r8a77995-draak-u-boot.dtb

View file

@ -0,0 +1,65 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Device Tree Source extras for U-Boot for the V3MSK board
*
* Copyright (C) 2019 Cogent Embedded, Inc.
*/
#include "r8a77970-v3msk.dts"
#include "r8a77970-u-boot.dtsi"
#include <dt-bindings/gpio/gpio.h>
/ {
aliases {
spi0 = &rpc;
};
cpld {
compatible = "renesas,v3msk-cpld";
status = "okay";
gpio-mdc = <&gpio1 21 0>;
gpio-mosi = <&gpio1 22 0>;
gpio-miso = <&gpio1 23 0>;
gpio-enablez = <&gpio1 19 0>;
/* Disable V3MSK Videobox Mini CANFD PHY */
gpios = <&gpio0 12 0>, <&gpio0 14 0>;
};
};
&avb {
pinctrl-0 = <&avb0_pins>;
pinctrl-names = "default";
};
&phy0 {
reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
&pfc {
avb0_pins: avb {
mux {
groups = "avb0_link", "avb0_mdio", "avb0_rgmii", "avb0_txcrefclk";
function = "avb0";
};
};
};
&rpc {
num-cs = <1>;
status = "okay";
spi-max-frequency = <50000000>;
#address-cells = <1>;
#size-cells = <0>;
flash0: spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "s25fs512s", "spi-flash", "jedec,spi-nor";
spi-max-frequency = <50000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <1>;
reg = <0>;
status = "okay";
};
};

View file

@ -111,6 +111,11 @@ config TARGET_EAGLE
help
Support for Renesas R-Car Gen3 Eagle platform
config TARGET_V3MSK
bool "V3MSK board"
help
Support for Renesas R-Car Gen3 V3MSK platform
config TARGET_EBISU
bool "Ebisu board"
imply R8A77990
@ -166,6 +171,7 @@ source "board/renesas/eagle/Kconfig"
source "board/renesas/ebisu/Kconfig"
source "board/renesas/salvator-x/Kconfig"
source "board/renesas/ulcb/Kconfig"
source "board/renesas/v3msk/Kconfig"
source "board/beacon/beacon-rzg2m/Kconfig"
source "board/hoperun/hihope-rzg2/Kconfig"
source "board/silinux/ek874/Kconfig"

View file

@ -0,0 +1,15 @@
if TARGET_V3MSK
config SYS_SOC
default "rmobile"
config SYS_BOARD
default "v3msk"
config SYS_VENDOR
default "renesas"
config SYS_CONFIG_NAME
default "rcar-gen3-common"
endif

View file

@ -0,0 +1,6 @@
V3MSK BOARD
M: Cogent Embedded, Inc. <source@cogentembedded.com>
S: Maintained
F: board/renesas/v3msk/
F: include/configs/v3msk.h
F: configs/r8a77970_v3msk_defconfig

View file

@ -0,0 +1,15 @@
#
# board/renesas/v3msk/Makefile
#
# Copyright (C) 2019 Renesas Electronics Corporation
# Copyright (C) 2019 Cogent Embedded, Inc.
#
# SPDX-License-Identifier: GPL-2.0+
#
ifdef CONFIG_SPL_BUILD
obj-y := ../rcar-common/gen3-spl.o
else
obj-y := ../rcar-common/v3-common.o ../rcar-common/common.o
obj-$(CONFIG_SYSRESET) += cpld.o
endif

368
board/renesas/v3msk/cpld.c Normal file
View file

@ -0,0 +1,368 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* V3MSK board CPLD access support
*
* Copyright (C) 2019 Renesas Electronics Corporation
* Copyright (C) 2019 Cogent Embedded, Inc.
*
*/
#include <common.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <dm.h>
#include <errno.h>
#include <linux/err.h>
#include <sysreset.h>
#include <linux/delay.h>
#include <command.h>
#define CPLD_ADDR_PRODUCT_L 0x000 /* R */
#define CPLD_ADDR_PRODUCT_H 0x001 /* R */
#define CPLD_ADDR_CPLD_VERSION_D 0x002 /* R */
#define CPLD_ADDR_CPLD_VERSION_Y 0x003 /* R */
#define CPLD_ADDR_MODE_SET_L 0x004 /* R/W */
#define CPLD_ADDR_MODE_SET_H 0x005 /* R/W */
#define CPLD_ADDR_MODE_APPLIED_L 0x006 /* R */
#define CPLD_ADDR_MODE_APPLIED_H 0x007 /* R */
#define CPLD_ADDR_DIPSW 0x008 /* R */
#define CPLD_ADDR_RESET 0x00A /* R/W */
#define CPLD_ADDR_POWER_CFG 0x00B /* R/W */
#define CPLD_ADDR_PERI_CFG1 0x00C /* R/W */
#define CPLD_ADDR_PERI_CFG2 0x00D /* R/W */
#define CPLD_ADDR_LEDS 0x00E /* R/W */
#define CPLD_ADDR_PCB_VERSION 0x300 /* R */
#define CPLD_ADDR_SOC_VERSION 0x301 /* R */
#define CPLD_ADDR_PCB_SN_L 0x302 /* R */
#define CPLD_ADDR_PCB_SN_H 0x303 /* R */
#define MDIO_DELAY 10 /* microseconds */
#define CPLD_MAX_GPIOS 2
struct renesas_v3msk_sysreset_priv {
struct gpio_desc miso;
struct gpio_desc mosi;
struct gpio_desc mdc;
struct gpio_desc enablez;
/*
* V3MSK Videobox Mini board has CANFD PHY connected
* we must shutdown this chip to use bb pins
*/
struct gpio_desc gpios[CPLD_MAX_GPIOS];
};
static void mdio_bb_active_mdio(struct renesas_v3msk_sysreset_priv *priv)
{
dm_gpio_set_dir_flags(&priv->mosi, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
}
static void mdio_bb_tristate_mdio(struct renesas_v3msk_sysreset_priv *priv)
{
dm_gpio_set_dir_flags(&priv->mosi, GPIOD_IS_IN);
}
static void mdio_bb_set_mdio(struct renesas_v3msk_sysreset_priv *priv, int val)
{
dm_gpio_set_value(&priv->mosi, val);
}
static int mdio_bb_get_mdio(struct renesas_v3msk_sysreset_priv *priv)
{
return dm_gpio_get_value(&priv->miso);
}
static void mdio_bb_set_mdc(struct renesas_v3msk_sysreset_priv *priv, int val)
{
dm_gpio_set_value(&priv->mdc, val);
}
static void mdio_bb_delay(void)
{
udelay(MDIO_DELAY);
}
/* Send the preamble, address, and register (common to read and write) */
static void mdio_bb_pre(struct renesas_v3msk_sysreset_priv *priv,
u8 op, u8 addr, u8 reg)
{
int i;
/* 32-bit preamble */
mdio_bb_active_mdio(priv);
mdio_bb_set_mdio(priv, 1);
for (i = 0; i < 32; i++) {
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
}
/* send the ST (2-bits of '01') */
mdio_bb_set_mdio(priv, 0);
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
mdio_bb_set_mdio(priv, 1);
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
/* send the OP (2-bits of Opcode: '10'-read, '01'-write) */
mdio_bb_set_mdio(priv, op >> 1);
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
mdio_bb_set_mdio(priv, op & 1);
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
/* send the PA5 (5-bits of PHY address) */
for (i = 0; i < 5; i++) {
mdio_bb_set_mdio(priv, addr & 0x10); /* MSB first */
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
addr <<= 1;
}
/* send the RA5 (5-bits of register address) */
for (i = 0; i < 5; i++) {
mdio_bb_set_mdio(priv, reg & 0x10); /* MSB first */
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
reg <<= 1;
}
}
static int mdio_bb_read(struct renesas_v3msk_sysreset_priv *priv,
u8 addr, u8 reg)
{
int i;
u16 data = 0;
mdio_bb_pre(priv, 2, addr, reg);
/* tri-state MDIO */
mdio_bb_tristate_mdio(priv);
/* read TA (2-bits of turn-around, last bit must be '0') */
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
/* check the turnaround bit: the PHY should drive line to zero */
if (mdio_bb_get_mdio(priv) != 0) {
printf("PHY didn't drive TA low\n");
for (i = 0; i < 32; i++) {
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
}
/* There is no PHY, set value to 0xFFFF */
return 0xFFFF;
}
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
/* read 16-bits of data */
for (i = 0; i < 16; i++) {
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
data <<= 1;
data |= mdio_bb_get_mdio(priv);
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
}
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
debug("cpld_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, data);
return data;
}
static void mdio_bb_write(struct renesas_v3msk_sysreset_priv *priv,
u8 addr, u8 reg, u16 val)
{
int i;
mdio_bb_pre(priv, 1, addr, reg);
/* send the TA (2-bits of turn-around '10') */
mdio_bb_set_mdio(priv, 1);
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
mdio_bb_set_mdio(priv, 0);
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
/* write 16-bits of data */
for (i = 0; i < 16; i++) {
mdio_bb_set_mdio(priv, val & 0x8000); /* MSB first */
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
val <<= 1;
}
/* tri-state MDIO */
mdio_bb_tristate_mdio(priv);
mdio_bb_set_mdc(priv, 0);
mdio_bb_delay();
mdio_bb_set_mdc(priv, 1);
mdio_bb_delay();
}
static u16 cpld_read(struct udevice *dev, u16 addr)
{
struct renesas_v3msk_sysreset_priv *priv = dev_get_priv(dev);
/* random flash reads require 2 reads: first read is unreliable */
if (addr >= CPLD_ADDR_PCB_VERSION)
mdio_bb_read(priv, addr >> 5, addr & 0x1f);
return mdio_bb_read(priv, addr >> 5, addr & 0x1f);
}
static void cpld_write(struct udevice *dev, u16 addr, u16 data)
{
struct renesas_v3msk_sysreset_priv *priv = dev_get_priv(dev);
mdio_bb_write(priv, addr >> 5, addr & 0x1f, data);
}
static int do_cpld(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
{
struct udevice *dev;
u16 addr, val;
int ret;
ret = uclass_get_device_by_driver(UCLASS_SYSRESET,
DM_DRIVER_GET(sysreset_renesas_v3msk),
&dev);
if (ret)
return ret;
if (argc == 2 && strcmp(argv[1], "info") == 0) {
printf("Product: 0x%08x\n",
(cpld_read(dev, CPLD_ADDR_PRODUCT_H) << 16) |
cpld_read(dev, CPLD_ADDR_PRODUCT_L));
printf("CPLD version: 0x%08x\n",
(cpld_read(dev, CPLD_ADDR_CPLD_VERSION_Y) << 16) |
cpld_read(dev, CPLD_ADDR_CPLD_VERSION_D));
printf("Mode setting (MD0..26): 0x%08x\n",
(cpld_read(dev, CPLD_ADDR_MODE_APPLIED_H) << 16) |
cpld_read(dev, CPLD_ADDR_MODE_APPLIED_L));
printf("DIPSW (SW4, SW5): 0x%02x, 0x%x\n",
(cpld_read(dev, CPLD_ADDR_DIPSW) & 0xff) ^ 0xff,
(cpld_read(dev, CPLD_ADDR_DIPSW) >> 8) ^ 0xf);
printf("Power config: 0x%08x\n",
cpld_read(dev, CPLD_ADDR_POWER_CFG));
printf("Periferals config: 0x%08x\n",
(cpld_read(dev, CPLD_ADDR_PERI_CFG2) << 16) |
cpld_read(dev, CPLD_ADDR_PERI_CFG1));
printf("PCB version: %d.%d\n",
cpld_read(dev, CPLD_ADDR_PCB_VERSION) >> 8,
cpld_read(dev, CPLD_ADDR_PCB_VERSION) & 0xff);
printf("SOC version: %d.%d\n",
cpld_read(dev, CPLD_ADDR_SOC_VERSION) >> 8,
cpld_read(dev, CPLD_ADDR_SOC_VERSION) & 0xff);
printf("PCB S/N: %d\n",
(cpld_read(dev, CPLD_ADDR_PCB_SN_H) << 16) |
cpld_read(dev, CPLD_ADDR_PCB_SN_L));
return 0;
}
if (argc < 3)
return CMD_RET_USAGE;
addr = simple_strtoul(argv[2], NULL, 16);
if (!(addr >= CPLD_ADDR_PRODUCT_L && addr <= CPLD_ADDR_LEDS)) {
printf("cpld invalid addr\n");
return CMD_RET_USAGE;
}
if (argc == 3 && strcmp(argv[1], "read") == 0) {
printf("0x%x\n", cpld_read(dev, addr));
} else if (argc == 4 && strcmp(argv[1], "write") == 0) {
val = simple_strtoul(argv[3], NULL, 16);
cpld_write(dev, addr, val);
}
return 0;
}
U_BOOT_CMD(cpld, 4, 1, do_cpld,
"CPLD access",
"info\n"
"cpld read addr\n"
"cpld write addr val\n"
);
static int renesas_v3msk_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
cpld_write(dev, CPLD_ADDR_RESET, 1);
return -EINPROGRESS;
}
static int renesas_v3msk_sysreset_probe(struct udevice *dev)
{
struct renesas_v3msk_sysreset_priv *priv = dev_get_priv(dev);
if (gpio_request_by_name(dev, "gpio-miso", 0, &priv->miso,
GPIOD_IS_IN))
return -EINVAL;
if (gpio_request_by_name(dev, "gpio-mosi", 0, &priv->mosi,
GPIOD_IS_OUT))
return -EINVAL;
if (gpio_request_by_name(dev, "gpio-mdc", 0, &priv->mdc,
GPIOD_IS_OUT))
return -EINVAL;
if (gpio_request_by_name(dev, "gpio-enablez", 0, &priv->enablez,
GPIOD_IS_OUT))
return -EINVAL;
/* V3MSK Videobox Mini board has CANFD PHY connected
* we must shutdown this chip to use bb pins
*/
gpio_request_list_by_name(dev, "gpios", priv->gpios, CPLD_MAX_GPIOS,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
return 0;
}
static struct sysreset_ops renesas_v3msk_sysreset = {
.request = renesas_v3msk_sysreset_request,
};
static const struct udevice_id renesas_v3msk_sysreset_ids[] = {
{ .compatible = "renesas,v3msk-cpld" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(sysreset_renesas_v3msk) = {
.name = "renesas_v3msk_sysreset",
.id = UCLASS_SYSRESET,
.ops = &renesas_v3msk_sysreset,
.probe = renesas_v3msk_sysreset_probe,
.of_match = renesas_v3msk_sysreset_ids,
.priv_auto = sizeof(struct renesas_v3msk_sysreset_priv),
};

View file

@ -0,0 +1,87 @@
CONFIG_ARM=y
CONFIG_COUNTER_FREQUENCY=16666666
CONFIG_ARCH_CPU_INIT=y
CONFIG_ARCH_RMOBILE=y
CONFIG_TEXT_BASE=0x50000000
CONFIG_SYS_MALLOC_LEN=0x4000000
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_ENV_SIZE=0x40000
CONFIG_ENV_OFFSET=0x700000
CONFIG_ENV_SECT_SIZE=0x40000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="r8a77970-v3msk-u-boot"
CONFIG_SPL_TEXT_BASE=0xe6318000
CONFIG_RCAR_GEN3=y
CONFIG_R8A77970=y
CONFIG_TARGET_V3MSK=y
CONFIG_SPL_STACK=0xe6304000
CONFIG_SYS_LOAD_ADDR=0x58000000
CONFIG_LTO=y
CONFIG_REMAKE_ELF=y
CONFIG_SYS_MONITOR_LEN=1048576
CONFIG_FIT=y
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_USE_BOOTARGS=y
CONFIG_DEFAULT_FDT_FILE="r8a77970-v3msk.dtb"
CONFIG_SYS_MALLOC_BOOTPARAMS=y
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0xe631f000
CONFIG_SPL_BSS_MAX_SIZE=0x1000
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
CONFIG_HUSH_PARSER=y
CONFIG_SYS_MAXARGS=64
CONFIG_SYS_PBSIZE=2068
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_DFU=y
CONFIG_CMD_ASKENV=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SPI=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_OF_CONTROL=y
CONFIG_OF_DTB_PROPS_REMOVE=y
CONFIG_OF_REMOVE_PROPS="dmas dma-names interrupt-parent interrupts interrupts-extended interrupt-names interrupt-map interrupt-map-mask iommus"
CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_VERSION_VARIABLE=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
CONFIG_CLK_RENESAS=y
CONFIG_DFU_TFTP=y
CONFIG_DFU_RAM=y
CONFIG_DFU_SF=y
CONFIG_RCAR_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_RCAR_I2C=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
CONFIG_MMC_HS200_SUPPORT=y
CONFIG_RENESAS_SDHI=y
CONFIG_MTD=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_SPANSION=y
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
CONFIG_BITBANGMII=y
CONFIG_BITBANGMII_MULTI=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_RENESAS_RAVB=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_SCIF_CONSOLE=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_RENESAS_RPC_SPI=y
CONFIG_SYSRESET=y

View file

@ -35,6 +35,7 @@ Currently the following boards are supported:
| R8A77965 M3-N | Renesas Electronics ULCB | r8a77965_ulcb
|---------------+----------------------------------------+-------------------
| R8A77970 V3M | Renesas Electronics Eagle | r8a77970_eagle_defconfig
| R8A77970 V3M | Renesas Electronics V3MSK | r8a77970_v3msk_defconfig
|---------------+----------------------------------------+-------------------
| R8A77995 D3 | Renesas Electronics Draak | r8a77995_draak_defconfig
'===============+========================================+===================