mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-29 16:10:58 +00:00
Merge tag 'arc-fixes-for-2020.01-rc2' of https://gitlab.denx.de/u-boot/custodians/u-boot-arc
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:
commit
61e8f2985b
13 changed files with 201 additions and 63 deletions
|
@ -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
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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----------------------
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
116
drivers/reset/reset-hsdk.c
Normal 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),
|
||||
};
|
17
include/dt-bindings/reset/snps,hsdk-reset.h
Normal file
17
include/dt-bindings/reset/snps,hsdk-reset.h
Normal 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*/
|
Loading…
Reference in a new issue