ARC fixes for v2020.01-rc2

The main change is move to DM_MMC of yet 2 another ARC boards:
AXS101 & IoTDK.

Among that we improve handling of stock-formatted SD-cards of high volume
on EM SDP as well as introduction of reset driver for HSDK which is required
for prepser reinitialization of some peripherals like USB etc.
This commit is contained in:
Tom Rini 2019-11-01 17:49:40 -04:00
commit 61e8f2985b
13 changed files with 201 additions and 63 deletions

View file

@ -94,6 +94,13 @@ L: uboot-snps-arc@synopsys.com
F: doc/device-tree-bindings/gpio/snps,creg-gpio.txt
F: drivers/gpio/hsdk-creg-gpio.c
ARC HSDK RESET
M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
S: Maintained
L: uboot-snps-arc@synopsys.com
F: include/dt-bindings/reset/snps,hsdk-reset.h
F: drivers/reset/reset-hsdk.c
ARC SYNOPSYS DW MMC EXTENSIONS
M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
S: Maintained

View file

@ -32,4 +32,27 @@
reg-shift = <2>;
reg-io-width = <4>;
};
mmcclk_biu: mmcclk-biu {
compatible = "fixed-clock";
clock-frequency = <50000000>;
#clock-cells = <0>;
};
mmcclk_ciu: mmcclk-ciu {
compatible = "fixed-clock";
clock-frequency = <100000000>;
#clock-cells = <0>;
};
mmc: mmc0@f0010000 {
compatible = "snps,dw-mshc";
reg = <0xf0010000 0x400>;
bus-width = <4>;
fifo-depth = <256>;
clocks = <&mmcclk_biu>, <&mmcclk_ciu>;
clock-names = "biu", "ciu";
max-frequency = <25000000>;
};
};

View file

@ -42,4 +42,26 @@
compatible = "nop-phy";
#phy-cells = <0>;
};
mmcclk_biu: mmcclk-biu {
compatible = "fixed-clock";
clock-frequency = <50000000>;
#clock-cells = <0>;
};
mmcclk_ciu: mmcclk-ciu {
compatible = "fixed-clock";
clock-frequency = <50000000>;
#clock-cells = <0>;
};
mmc: mmc0@f000b000 {
compatible = "snps,dw-mshc";
reg = <0xf000b000 0x400>;
bus-width = <4>;
fifo-depth = <128>;
clocks = <&mmcclk_biu>, <&mmcclk_ciu>;
clock-names = "biu", "ciu";
max-frequency = <25000000>;
};
};

View file

@ -79,5 +79,5 @@ ARC EM Software Development Platform (AKA EMSDP)
2.1. In case of proprietary MetaWare debugger run:
------------------------->8----------------------
mdb -dll=opxdarc.so -OK -preloadexec="eval *(int*)0xf0001000=0" u-boot
mdb -digilent -OK -preloadexec="eval *(int*)0xf0001000=0" u-boot
------------------------->8----------------------

View file

@ -85,35 +85,6 @@ int board_early_init_r(void)
return 0;
}
int board_mmc_init(bd_t *bis)
{
struct dwmci_host *host = NULL;
host = malloc(sizeof(struct dwmci_host));
if (!host) {
printf("dwmci_host malloc fail!\n");
return 1;
}
memset(host, 0, sizeof(struct dwmci_host));
host->name = "Synopsys Mobile storage";
host->ioaddr = SDIO_BASE;
host->buswidth = 4;
host->dev_index = 0;
host->bus_hz = 50000000;
add_dwmci(host, host->bus_hz / 2, 400000);
return 0;
}
int board_mmc_getcd(struct mmc *mmc)
{
struct dwmci_host *host = mmc->priv;
return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
}
#define CREG_BASE 0xF0001000
#define CREG_BOOT (void *)(CREG_BASE + 0x0FF0)
#define CREG_IP_SW_RESET (void *)(CREG_BASE + 0x0FF0)

View file

@ -145,38 +145,6 @@ int mach_cpu_init(void)
return set_cpu_freq(gd->cpu_clk);
}
#define ARC_PERIPHERAL_BASE 0xF0000000
#define SDIO_BASE (ARC_PERIPHERAL_BASE + 0xB000)
int board_mmc_init(bd_t *bis)
{
struct dwmci_host *host = NULL;
host = malloc(sizeof(struct dwmci_host));
if (!host) {
printf("dwmci_host malloc fail!\n");
return -ENOMEM;
}
memset(host, 0, sizeof(struct dwmci_host));
host->name = "Synopsys Mobile storage";
host->ioaddr = (void *)SDIO_BASE;
host->buswidth = 4;
host->dev_index = 0;
host->bus_hz = 50000000;
add_dwmci(host, host->bus_hz / 2, 400000);
return 0;
}
int board_mmc_getcd(struct mmc *mmc)
{
struct dwmci_host *host = mmc->priv;
return !(dwmci_readl(host, DWMCI_CDETECT) & 1);
}
#define IOTDK_RESET_SEQ 0x55AA6699
void reset_cpu(ulong addr)

View file

@ -35,7 +35,9 @@ CONFIG_DM=y
CONFIG_DM_GPIO=y
CONFIG_HSDK_CREG_GPIO=y
CONFIG_MMC=y
CONFIG_DM_MMC=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_SNPS=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y

View file

@ -24,9 +24,11 @@ CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
# CONFIG_NET is not set
CONFIG_DM=y
CONFIG_MMC=y
CONFIG_DM_MMC=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_SNPS=y
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_FS_FAT_MAX_CLUSTSIZE=4096
CONFIG_FS_FAT_MAX_CLUSTSIZE=32768
CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_PANIC_HANG=y

View file

@ -29,7 +29,9 @@ CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
# CONFIG_NET is not set
CONFIG_DM=y
CONFIG_MMC=y
CONFIG_DM_MMC=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_SNPS=y
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_USB=y

View file

@ -91,6 +91,13 @@ config RESET_ROCKCHIP
though is that some reset signals, like I2C or MISC reset multiple
devices.
config RESET_HSDK
bool "Synopsys HSDK Reset Driver"
depends on DM_RESET && TARGET_HSDK
default y
help
This enables the reset controller driver for HSDK board.
config RESET_MESON
bool "Reset controller driver for Amlogic Meson SoCs"
depends on DM_RESET && ARCH_MESON

View file

@ -11,6 +11,7 @@ obj-$(CONFIG_STM32_RESET) += stm32-reset.o
obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o
obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o

116
drivers/reset/reset-hsdk.c Normal file
View file

@ -0,0 +1,116 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* HSDK SoC Reset Controller driver
*
* Copyright (C) 2019 Synopsys, Inc. All rights reserved.
* Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
*/
#include <asm/io.h>
#include <common.h>
#include <dm.h>
#include <linux/iopoll.h>
#include <reset-uclass.h>
struct hsdk_rst {
void __iomem *regs_ctl;
void __iomem *regs_rst;
};
static const u32 rst_map[] = {
BIT(16), /* APB_RST */
BIT(17), /* AXI_RST */
BIT(18), /* ETH_RST */
BIT(19), /* USB_RST */
BIT(20), /* SDIO_RST */
BIT(21), /* HDMI_RST */
BIT(22), /* GFX_RST */
BIT(25), /* DMAC_RST */
BIT(31), /* EBI_RST */
};
#define HSDK_MAX_RESETS ARRAY_SIZE(rst_map)
#define CGU_SYS_RST_CTRL 0x0
#define CGU_IP_SW_RESET 0x0
#define CGU_IP_SW_RESET_DELAY_SHIFT 16
#define CGU_IP_SW_RESET_DELAY_MASK GENMASK(31, CGU_IP_SW_RESET_DELAY_SHIFT)
#define CGU_IP_SW_RESET_DELAY 0
#define CGU_IP_SW_RESET_RESET BIT(0)
#define SW_RESET_TIMEOUT 10000
static void hsdk_reset_config(struct hsdk_rst *rst, unsigned long id)
{
writel(rst_map[id], rst->regs_ctl + CGU_SYS_RST_CTRL);
}
static int hsdk_reset_do(struct hsdk_rst *rst)
{
u32 reg;
reg = readl(rst->regs_rst + CGU_IP_SW_RESET);
reg &= ~CGU_IP_SW_RESET_DELAY_MASK;
reg |= CGU_IP_SW_RESET_DELAY << CGU_IP_SW_RESET_DELAY_SHIFT;
reg |= CGU_IP_SW_RESET_RESET;
writel(reg, rst->regs_rst + CGU_IP_SW_RESET);
/* wait till reset bit is back to 0 */
return readl_poll_timeout(rst->regs_rst + CGU_IP_SW_RESET, reg,
!(reg & CGU_IP_SW_RESET_RESET), SW_RESET_TIMEOUT);
}
static int hsdk_reset_reset(struct reset_ctl *rst_ctl)
{
struct udevice *dev = rst_ctl->dev;
struct hsdk_rst *rst = dev_get_priv(dev);
if (rst_ctl->id >= HSDK_MAX_RESETS)
return -EINVAL;
debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, rst_ctl,
rst_ctl->dev, rst_ctl->id);
hsdk_reset_config(rst, rst_ctl->id);
return hsdk_reset_do(rst);
}
static int hsdk_reset_noop(struct reset_ctl *rst_ctl)
{
return 0;
}
static const struct reset_ops hsdk_reset_ops = {
.request = hsdk_reset_noop,
.free = hsdk_reset_noop,
.rst_assert = hsdk_reset_noop,
.rst_deassert = hsdk_reset_reset,
};
static const struct udevice_id hsdk_reset_dt_match[] = {
{ .compatible = "snps,hsdk-reset" },
{ },
};
static int hsdk_reset_probe(struct udevice *dev)
{
struct hsdk_rst *rst = dev_get_priv(dev);
rst->regs_ctl = dev_remap_addr_index(dev, 0);
if (!rst->regs_ctl)
return -EINVAL;
rst->regs_rst = dev_remap_addr_index(dev, 1);
if (!rst->regs_rst)
return -EINVAL;
return 0;
}
U_BOOT_DRIVER(hsdk_reset) = {
.name = "hsdk-reset",
.id = UCLASS_RESET,
.of_match = hsdk_reset_dt_match,
.ops = &hsdk_reset_ops,
.probe = hsdk_reset_probe,
.priv_auto_alloc_size = sizeof(struct hsdk_rst),
};

View file

@ -0,0 +1,17 @@
/**
* This header provides index for the HSDK reset controller.
*/
#ifndef _DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK
#define _DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK
#define HSDK_APB_RESET 0
#define HSDK_AXI_RESET 1
#define HSDK_ETH_RESET 2
#define HSDK_USB_RESET 3
#define HSDK_SDIO_RESET 4
#define HSDK_HDMI_RESET 5
#define HSDK_GFX_RESET 6
#define HSDK_DMAC_RESET 7
#define HSDK_EBI_RESET 8
#endif /*_DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK*/