summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-03-02 16:46:16 -0500
committerTom Rini <trini@konsulko.com>2021-03-02 16:46:16 -0500
commit78af81c345430a9088235f48d302922955d2499f (patch)
tree8be493d09e9db97602f356b5d6fa0ae150b50fd5
parent20ecfbe93175e84dbf597d39a6ddeed29099dd73 (diff)
parentfae165b5a1991ca55acfb3dc78f3c473275b3faf (diff)
Merge tag 'rpi-next-2021.04.2' of https://source.denx.de/u-boot/custodians/u-boot-raspberrypi
- Disable Grub workaround for RPi2 - enable HS200 mode for iproc sdhci - add armv7 support for iproc_rng200
-rw-r--r--MAINTAINERS4
-rw-r--r--configs/rpi_2_defconfig1
-rw-r--r--configs/rpi_4_32b_defconfig2
-rw-r--r--drivers/mmc/iproc_sdhci.c92
-rw-r--r--drivers/rng/iproc_rng200.c8
5 files changed, 93 insertions, 14 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index c60f1953a4e..de499940e57 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -160,7 +160,7 @@ F: drivers/clk/aspeed/
F: drivers/pinctrl/aspeed/
N: aspeed
-ARM BROADCOM BCM283X
+ARM BROADCOM BCM283X / BCM27XX
M: Matthias Brugger <mbrugger@suse.com>
S: Maintained
F: arch/arm/dts/bcm283*
@@ -175,6 +175,8 @@ F: drivers/video/bcm2835.c
F: include/dm/platform_data/serial_bcm283x_mu.h
F: include/dt-bindings/pinctrl/bcm2835.h
F: drivers/pinctrl/broadcom/
+F: configs/rpi_*
+T: git https://source.denx.de/u-boot/custodians/u-boot-arm.git
ARM BROADCOM BCMSTB
M: Thomas Fitzsimmons <fitzsim@fitzsim.org>
diff --git a/configs/rpi_2_defconfig b/configs/rpi_2_defconfig
index 33f27cf09f6..a0f36e1a930 100644
--- a/configs/rpi_2_defconfig
+++ b/configs/rpi_2_defconfig
@@ -42,3 +42,4 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_CONSOLE_SCROLL_LINES=10
CONFIG_PHYS_TO_BUS=y
CONFIG_OF_LIBFDT_OVERLAY=y
+# CONFIG_EFI_GRUB_ARM32_WORKAROUND is not set
diff --git a/configs/rpi_4_32b_defconfig b/configs/rpi_4_32b_defconfig
index 0a5d3ff8cd7..91eeb3cd32b 100644
--- a/configs/rpi_4_32b_defconfig
+++ b/configs/rpi_4_32b_defconfig
@@ -37,6 +37,8 @@ CONFIG_PCI_BRCMSTB=y
CONFIG_PINCTRL=y
# CONFIG_PINCTRL_GENERIC is not set
CONFIG_DM_RESET=y
+CONFIG_DM_RNG=y
+CONFIG_RNG_IPROC200=y
# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
CONFIG_USB=y
CONFIG_DM_USB=y
diff --git a/drivers/mmc/iproc_sdhci.c b/drivers/mmc/iproc_sdhci.c
index 6e4f527e5d8..11d86ad658f 100644
--- a/drivers/mmc/iproc_sdhci.c
+++ b/drivers/mmc/iproc_sdhci.c
@@ -10,8 +10,11 @@
#include <malloc.h>
#include <sdhci.h>
#include <asm/global_data.h>
+#include "mmc_private.h"
#include <linux/delay.h>
+#define MAX_TUNING_LOOP 40
+
DECLARE_GLOBAL_DATA_PTR;
struct sdhci_iproc_host {
@@ -140,17 +143,89 @@ static void sdhci_iproc_writeb(struct sdhci_host *host, u8 val, int reg)
static int sdhci_iproc_set_ios_post(struct sdhci_host *host)
{
- u32 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ struct mmc *mmc = (struct mmc *)host->mmc;
+ u32 ctrl;
+
+ if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ ctrl |= SDHCI_CTRL_VDD_180;
+ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+ }
- /* Reset UHS mode bits */
- ctrl &= ~SDHCI_CTRL_UHS_MASK;
+ sdhci_set_uhs_timing(host);
+ return 0;
+}
- if (host->mmc->ddr_mode)
- ctrl |= UHS_DDR50_BUS_SPEED;
+static void sdhci_start_tuning(struct sdhci_host *host)
+{
+ u32 ctrl;
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ ctrl |= SDHCI_CTRL_EXEC_TUNING;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
- return 0;
+ sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
+ sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
+}
+
+static void sdhci_end_tuning(struct sdhci_host *host)
+{
+ /* Enable only interrupts served by the SD controller */
+ sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK,
+ SDHCI_INT_ENABLE);
+ /* Mask all sdhci interrupt sources */
+ sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE);
+}
+
+static int sdhci_iproc_execute_tuning(struct mmc *mmc, u8 opcode)
+{
+ struct mmc_cmd cmd;
+ u32 ctrl;
+ u32 blocksize = SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, 64);
+ struct sdhci_host *host = dev_get_priv(mmc->dev);
+ char tuning_loop_counter = MAX_TUNING_LOOP;
+ int ret = 0;
+
+ sdhci_start_tuning(host);
+
+ cmd.cmdidx = opcode;
+ cmd.resp_type = MMC_RSP_R1;
+ cmd.cmdarg = 0;
+
+ if (opcode == MMC_CMD_SEND_TUNING_BLOCK_HS200 && mmc->bus_width == 8)
+ blocksize = SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, 128);
+
+ sdhci_writew(host, blocksize, SDHCI_BLOCK_SIZE);
+ sdhci_writew(host, 1, SDHCI_BLOCK_COUNT);
+ sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
+
+ do {
+ mmc_send_cmd(mmc, &cmd, NULL);
+ if (opcode == MMC_CMD_SEND_TUNING_BLOCK)
+ /*
+ * For tuning command, do not do busy loop. As tuning
+ * is happening (CLK-DATA latching for setup/hold time
+ * requirements), give time to complete
+ */
+ udelay(1);
+
+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+ if (tuning_loop_counter-- == 0)
+ break;
+
+ } while (ctrl & SDHCI_CTRL_EXEC_TUNING);
+
+ if (tuning_loop_counter < 0 || (!(ctrl & SDHCI_CTRL_TUNED_CLK))) {
+ ctrl &= ~(SDHCI_CTRL_TUNED_CLK | SDHCI_CTRL_EXEC_TUNING);
+ sdhci_writel(host, ctrl, SDHCI_HOST_CONTROL2);
+ printf("%s:Tuning failed, opcode = 0x%02x\n", __func__, opcode);
+ ret = -EIO;
+ }
+
+ sdhci_end_tuning(host);
+
+ return ret;
}
static struct sdhci_ops sdhci_platform_ops = {
@@ -163,6 +238,7 @@ static struct sdhci_ops sdhci_platform_ops = {
.write_b = sdhci_iproc_writeb,
#endif
.set_ios_post = sdhci_iproc_set_ios_post,
+ .platform_execute_tuning = sdhci_iproc_execute_tuning,
};
struct iproc_sdhci_plat {
@@ -190,9 +266,7 @@ static int iproc_sdhci_probe(struct udevice *dev)
host->name = dev->name;
host->ioaddr = dev_read_addr_ptr(dev);
- host->voltages = MMC_VDD_165_195 |
- MMC_VDD_32_33 | MMC_VDD_33_34;
- host->quirks = SDHCI_QUIRK_BROKEN_VOLTAGE | SDHCI_QUIRK_BROKEN_R1B;
+ host->quirks = SDHCI_QUIRK_BROKEN_R1B;
host->host_caps = MMC_MODE_DDR_52MHz;
host->index = fdtdec_get_uint(gd->fdt_blob, node, "index", 0);
host->ops = &sdhci_platform_ops;
diff --git a/drivers/rng/iproc_rng200.c b/drivers/rng/iproc_rng200.c
index 1126bbd797e..85ac15bf9ca 100644
--- a/drivers/rng/iproc_rng200.c
+++ b/drivers/rng/iproc_rng200.c
@@ -34,12 +34,12 @@
#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK 0x000000FF
struct iproc_rng200_plat {
- fdt_addr_t base;
+ void __iomem *base;
};
static void iproc_rng200_enable(struct iproc_rng200_plat *pdata, bool enable)
{
- fdt_addr_t rng_base = pdata->base;
+ void __iomem *rng_base = pdata->base;
u32 val;
val = readl(rng_base + RNG_CTRL_OFFSET);
@@ -54,7 +54,7 @@ static void iproc_rng200_enable(struct iproc_rng200_plat *pdata, bool enable)
static void iproc_rng200_restart(struct iproc_rng200_plat *pdata)
{
- fdt_addr_t rng_base = pdata->base;
+ void __iomem *rng_base = pdata->base;
u32 val;
iproc_rng200_enable(pdata, false);
@@ -156,7 +156,7 @@ static int iproc_rng200_of_to_plat(struct udevice *dev)
{
struct iproc_rng200_plat *pdata = dev_get_plat(dev);
- pdata->base = dev_read_addr(dev);
+ pdata->base = devfdt_map_physmem(dev, sizeof(void *));
if (!pdata->base)
return -ENODEV;