diff --git a/MAINTAINERS b/MAINTAINERS index 42b5959d90..a310b8478f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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 +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 S: Maintained diff --git a/arch/arc/dts/emsdp.dts b/arch/arc/dts/emsdp.dts index d307b95d8e..dbebdb4e76 100644 --- a/arch/arc/dts/emsdp.dts +++ b/arch/arc/dts/emsdp.dts @@ -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>; + }; + }; diff --git a/arch/arc/dts/iot_devkit.dts b/arch/arc/dts/iot_devkit.dts index ebf5a950f0..c0173fa5ab 100644 --- a/arch/arc/dts/iot_devkit.dts +++ b/arch/arc/dts/iot_devkit.dts @@ -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>; + }; }; diff --git a/board/synopsys/emsdp/README b/board/synopsys/emsdp/README index 034062e397..036554c4d5 100644 --- a/board/synopsys/emsdp/README +++ b/board/synopsys/emsdp/README @@ -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---------------------- diff --git a/board/synopsys/emsdp/emsdp.c b/board/synopsys/emsdp/emsdp.c index 7a3fd5b7f2..5ba9f862e1 100644 --- a/board/synopsys/emsdp/emsdp.c +++ b/board/synopsys/emsdp/emsdp.c @@ -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) diff --git a/board/synopsys/iot_devkit/iot_devkit.c b/board/synopsys/iot_devkit/iot_devkit.c index 8424e09bd3..9dbdc128f8 100644 --- a/board/synopsys/iot_devkit/iot_devkit.c +++ b/board/synopsys/iot_devkit/iot_devkit.c @@ -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) diff --git a/configs/axs101_defconfig b/configs/axs101_defconfig index 0bfb532fc7..38c8ae998f 100644 --- a/configs/axs101_defconfig +++ b/configs/axs101_defconfig @@ -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 diff --git a/configs/emsdp_defconfig b/configs/emsdp_defconfig index 5e55e3e2b2..09fe388e58 100644 --- a/configs/emsdp_defconfig +++ b/configs/emsdp_defconfig @@ -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 diff --git a/configs/iot_devkit_defconfig b/configs/iot_devkit_defconfig index 24bbe3fc5d..42278d4fb1 100644 --- a/configs/iot_devkit_defconfig +++ b/configs/iot_devkit_defconfig @@ -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 diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index cff00820e4..75ccd65799 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -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 diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 8102d8db29..0a044d5d8c 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -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 diff --git a/drivers/reset/reset-hsdk.c b/drivers/reset/reset-hsdk.c new file mode 100644 index 0000000000..213d6c87be --- /dev/null +++ b/drivers/reset/reset-hsdk.c @@ -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 + */ + +#include +#include +#include +#include +#include + +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), +}; diff --git a/include/dt-bindings/reset/snps,hsdk-reset.h b/include/dt-bindings/reset/snps,hsdk-reset.h new file mode 100644 index 0000000000..e1a643e4bc --- /dev/null +++ b/include/dt-bindings/reset/snps,hsdk-reset.h @@ -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*/