temp/u-boot-pinephone: upgrade to 2021.07 (MR 2315)

- switch sources to official repo https://source.denx.de/u-boot
- use tag v2021.07
- extract patches from pine64-org
- enable DMA transfers from eMMC and mSD (u-boot from Megi)

[ci:skip-build] already built successfully in CI
This commit is contained in:
Bobby The Builder 2021-06-08 17:36:42 -04:00 committed by Clayton Craft
parent cc6eb4d1f4
commit 63e2807916
No known key found for this signature in database
GPG key ID: 7A3461CA187CEA54
31 changed files with 4070 additions and 22 deletions

View file

@ -0,0 +1,73 @@
From af0ac30c08414e65f299149285dc81de664fc3f0 Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Fri, 18 Dec 2020 22:02:11 +0000
Subject: [PATCH 01/29] mmc: sunxi: Avoid #ifdefs in delay and width setup
The delay and bus-width setup are slightly different across the
Allwinner SoC generations, and we covered this so far with some
preprocessor conditionals.
Use the more readable IS_ENABLE() instead.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
drivers/mmc/sunxi_mmc.c | 33 +++++++++++++++------------------
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 3503ccdb2e..87b79fcf5e 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -156,23 +156,19 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
} else if (hz <= 25000000) {
oclk_dly = 0;
sclk_dly = 5;
-#ifdef CONFIG_MACH_SUN9I
- } else if (hz <= 52000000) {
- oclk_dly = 5;
- sclk_dly = 4;
- } else {
- /* hz > 52000000 */
- oclk_dly = 2;
- sclk_dly = 4;
-#else
- } else if (hz <= 52000000) {
- oclk_dly = 3;
- sclk_dly = 4;
} else {
- /* hz > 52000000 */
- oclk_dly = 1;
+ if (IS_ENABLED(CONFIG_MACH_SUN9I)) {
+ if (hz <= 52000000)
+ oclk_dly = 5;
+ else
+ oclk_dly = 2;
+ } else {
+ if (hz <= 52000000)
+ oclk_dly = 3;
+ else
+ oclk_dly = 1;
+ }
sclk_dly = 4;
-#endif
}
if (new_mode) {
@@ -521,10 +517,11 @@ struct mmc *sunxi_mmc_init(int sdc_no)
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
cfg->host_caps = MMC_MODE_4BIT;
-#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN8I) || defined(CONFIG_SUN50I_GEN_H6)
- if (sdc_no == 2)
+
+ if ((IS_ENABLED(CONFIG_MACH_SUN50I) || IS_ENABLED(CONFIG_MACH_SUN8I) ||
+ IS_ENABLED(CONFIG_SUN50I_GEN_H6)) && (sdc_no == 2))
cfg->host_caps = MMC_MODE_8BIT;
-#endif
+
cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
--
2.31.1

View file

@ -0,0 +1,41 @@
From 43e334d01e4ffb3d536bee35d8eeb57a2e0c497f Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Thu, 29 Apr 2021 09:31:58 +0100
Subject: [PATCH 02/29] mmc: sunxi: Fix warnings with CONFIG_PHYS_64BIT
When enabling PHYS_64BIT on 32-bit platforms, we get two warnings about
pointer casts in sunxi_mmc.c. Those are related to MMIO addresses, which
are always below 1GB on all Allwinner SoCs, so there is no problem with
anything having more than 32 bits.
Add the proper casts to make it compile cleanly.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
drivers/mmc/sunxi_mmc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 87b79fcf5e..869af993d3 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -631,14 +631,14 @@ static int sunxi_mmc_probe(struct udevice *dev)
cfg->f_min = 400000;
cfg->f_max = 52000000;
- priv->reg = (void *)dev_read_addr(dev);
+ priv->reg = dev_read_addr_ptr(dev);
/* We don't have a sunxi clock driver so find the clock address here */
ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
1, &args);
if (ret)
return ret;
- ccu_reg = (u32 *)ofnode_get_addr(args.node);
+ ccu_reg = (u32 *)(uintptr_t)ofnode_get_addr(args.node);
priv->mmc_no = ((uintptr_t)priv->reg - SUNXI_MMC0_BASE) / 0x1000;
priv->mclkreg = (void *)ccu_reg + get_mclk_offset() + priv->mmc_no * 4;
--
2.31.1

View file

@ -0,0 +1,64 @@
From 8bd521470df1cb6324520babf9d3a2e96bc7b96e Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Wed, 5 May 2021 09:57:47 +0100
Subject: [PATCH 03/29] mmc: sunxi: Fix MMC clock parent selection
Most Allwinner SoCs which use the so called "new timing mode" in their
MMC controllers actually use the double-rate PLL6/PERIPH0 clock as their
parent input clock. This is interestingly enough compensated by a hidden
"by 2" post-divider in the mod clock, so the divider and actual output
rate stay the same.
Even though for the H6 and H616 (but only for them!) we use the doubled
input clock for the divider computation, we never accounted for the
implicit post-divider, so the clock was only half the speed on those SoCs.
Clean up the code around that selection, to always use the normal PLL6
(PERIPH0(1x)) clock as an input. As the rate and divider are the same,
that makes no difference.
Explain the hardware differences in a comment.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h | 2 +-
drivers/mmc/sunxi_mmc.c | 10 +++++++---
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
index 62abfc4ef6..e000f78ff4 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
@@ -326,7 +326,7 @@ struct sunxi_ccm_reg {
#define CCM_MMC_CTRL_M(x) ((x) - 1)
#define CCM_MMC_CTRL_N(x) ((x) << 8)
#define CCM_MMC_CTRL_OSCM24 (0x0 << 24)
-#define CCM_MMC_CTRL_PLL6X2 (0x1 << 24)
+#define CCM_MMC_CTRL_PLL6 (0x1 << 24)
#define CCM_MMC_CTRL_PLL_PERIPH2X2 (0x2 << 24)
#define CCM_MMC_CTRL_ENABLE (0x1 << 31)
/* H6 doesn't have these delays */
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 869af993d3..bc68debdad 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -124,10 +124,14 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
#ifdef CONFIG_MACH_SUN9I
pll = CCM_MMC_CTRL_PLL_PERIPH0;
pll_hz = clock_get_pll4_periph0();
-#elif defined(CONFIG_SUN50I_GEN_H6)
- pll = CCM_MMC_CTRL_PLL6X2;
- pll_hz = clock_get_pll6() * 2;
#else
+ /*
+ * SoCs since the A64 (H5, H6, H616) actually use the doubled
+ * rate of PLL6/PERIPH0 as an input clock, but compensate for
+ * that with a fixed post-divider of 2 in the mod clock.
+ * This cancels each other out, so for simplicity we just
+ * pretend it's always PLL6 without a post divider here.
+ */
pll = CCM_MMC_CTRL_PLL6;
pll_hz = clock_get_pll6();
#endif
--
2.31.1

View file

@ -0,0 +1,65 @@
From b8e83c3840068beb42ca821e20aaaa82369b84bc Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Wed, 5 May 2021 09:57:47 +0100
Subject: [PATCH 04/29] mmc: sunxi: Cleanup "new timing mode" selection
Among the SoCs using the "new timing mode", only the A83T needs to
explicitly switch to that mode.
By just defining the symbol for that one odd A83T bit to 0 for any other
SoCs, we can always OR that in, and save the confusing nested #ifdefs.
Clean up the also confusing new_mode setting on the way.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
drivers/mmc/sunxi_mmc.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index bc68debdad..33cedb4edb 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -23,6 +23,10 @@
#include <asm-generic/gpio.h>
#include <linux/delay.h>
+#ifndef CCM_MMC_CTRL_MODE_SEL_NEW
+#define CCM_MMC_CTRL_MODE_SEL_NEW 0
+#endif
+
struct sunxi_mmc_plat {
struct mmc_config cfg;
struct mmc mmc;
@@ -102,13 +106,10 @@ static int mmc_resource_init(int sdc_no)
static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
{
unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
- bool new_mode = true;
+ bool new_mode = IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE);
bool calibrate = false;
u32 val = 0;
- if (!IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE))
- new_mode = false;
-
/* A83T support new mode only on eMMC */
if (IS_ENABLED(CONFIG_MACH_SUN8I_A83T) && priv->mmc_no != 2)
new_mode = false;
@@ -176,12 +177,8 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
}
if (new_mode) {
-#ifdef CONFIG_MMC_SUNXI_HAS_NEW_MODE
-#ifdef CONFIG_MMC_SUNXI_HAS_MODE_SWITCH
- val = CCM_MMC_CTRL_MODE_SEL_NEW;
-#endif
+ val |= CCM_MMC_CTRL_MODE_SEL_NEW;
setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
-#endif
} else if (!calibrate) {
/*
* Use hardcoded delay values if controller doesn't support
--
2.31.1

View file

@ -0,0 +1,44 @@
From 5f2f7a0ed7346c3369cd22348c372892e903c60e Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Wed, 5 May 2021 10:04:41 +0100
Subject: [PATCH 05/29] mmc: sunxi: Enable "new timing mode" on all new SoCs
All SoCs since the Allwinner A64 (H5, H6, R40, H616) feature to so
called "new timing mode", so enable this in Kconfig for those SoCs.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm/mach-sunxi/Kconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 8e9012dbbf..e22a9c9103 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -152,6 +152,7 @@ config SUN50I_GEN_H6
bool
select FIT
select SPL_LOAD_FIT
+ select MMC_SUNXI_HAS_NEW_MODE
select SUPPORT_SPL
---help---
Select this for sunxi SoCs which have H6 like peripherals, clocks
@@ -297,6 +298,7 @@ config MACH_SUN8I_R40
select CPU_V7_HAS_VIRT
select ARCH_SUPPORT_PSCI
select SUNXI_GEN_SUN6I
+ select MMC_SUNXI_HAS_NEW_MODE
select SUPPORT_SPL
select SUNXI_DRAM_DW
select SUNXI_DRAM_DW_32BIT
@@ -346,6 +348,7 @@ config MACH_SUN50I_H5
bool "sun50i (Allwinner H5)"
select ARM64
select MACH_SUNXI_H3_H5
+ select MMC_SUNXI_HAS_NEW_MODE
select FIT
select SPL_LOAD_FIT
--
2.31.1

View file

@ -0,0 +1,87 @@
From 0c12222a222529e46589eb2ea147d0e62ee4b838 Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Wed, 5 May 2021 10:06:24 +0100
Subject: [PATCH 06/29] mmc: sunxi: Cleanup and fix self-calibration code
Newer SoCs have a self calibration feature, which avoids us writing hard
coded phase delay values into the controller.
Consolidate the code by avoiding unnecessary #ifdefs, and also enabling
the feature for all those newer SoCs.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
drivers/mmc/sunxi_mmc.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 33cedb4edb..a30fd8fbdb 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -103,21 +103,29 @@ static int mmc_resource_init(int sdc_no)
}
#endif
+/*
+ * All A64 and later MMC controllers feature auto-calibration. This would
+ * normally be detected via the compatible string, but we need something
+ * which works in the SPL as well.
+ */
+static bool sunxi_mmc_can_calibrate(void)
+{
+ return IS_ENABLED(CONFIG_MACH_SUN50I) ||
+ IS_ENABLED(CONFIG_MACH_SUN50I_H5) ||
+ IS_ENABLED(CONFIG_SUN50I_GEN_H6) ||
+ IS_ENABLED(CONFIG_MACH_SUN8I_R40);
+}
+
static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
{
unsigned int pll, pll_hz, div, n, oclk_dly, sclk_dly;
bool new_mode = IS_ENABLED(CONFIG_MMC_SUNXI_HAS_NEW_MODE);
- bool calibrate = false;
u32 val = 0;
/* A83T support new mode only on eMMC */
if (IS_ENABLED(CONFIG_MACH_SUN8I_A83T) && priv->mmc_no != 2)
new_mode = false;
-#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_SUN50I_GEN_H6)
- calibrate = true;
-#endif
-
if (hz <= 24000000) {
pll = CCM_MMC_CTRL_OSCM24;
pll_hz = 24000000;
@@ -179,7 +187,9 @@ static int mmc_set_mod_clk(struct sunxi_mmc_priv *priv, unsigned int hz)
if (new_mode) {
val |= CCM_MMC_CTRL_MODE_SEL_NEW;
setbits_le32(&priv->reg->ntsr, SUNXI_MMC_NTSR_MODE_SEL_NEW);
- } else if (!calibrate) {
+ }
+
+ if (!sunxi_mmc_can_calibrate()) {
/*
* Use hardcoded delay values if controller doesn't support
* calibration
@@ -237,14 +247,15 @@ static int mmc_config_clock(struct sunxi_mmc_priv *priv, struct mmc *mmc)
rval &= ~SUNXI_MMC_CLK_DIVIDER_MASK;
writel(rval, &priv->reg->clkcr);
-#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_SUN50I_GEN_H6)
+#if defined(CONFIG_SUNXI_GEN_SUN6I) || defined(CONFIG_SUN50I_GEN_H6)
/* A64 supports calibration of delays on MMC controller and we
* have to set delay of zero before starting calibration.
* Allwinner BSP driver sets a delay only in the case of
* using HS400 which is not supported by mainline U-Boot or
* Linux at the moment
*/
- writel(SUNXI_MMC_CAL_DL_SW_EN, &priv->reg->samp_dl);
+ if (sunxi_mmc_can_calibrate())
+ writel(SUNXI_MMC_CAL_DL_SW_EN, &priv->reg->samp_dl);
#endif
/* Re-enable Clock */
--
2.31.1

View file

@ -0,0 +1,114 @@
From 570ba1826f2962f63168e9b65aa5620956234901 Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Wed, 5 May 2021 11:33:40 +0100
Subject: [PATCH 07/29] mmc: sunxi: Increase MMIO FIFO read performance
To avoid the complexity of DMA operations (with chained descriptors), we
use repeated MMIO reads and writes to the SD_FIFO_REG, which allows us
to drain or fill the MMC data buffer FIFO very easily.
However those MMIO accesses are somewhat costly, so this limits our MMC
performance, to around 20MB/s on most SoCs, but down to 10MB/s on others
(H6, partly due to the lower AHB1 frequency).
As it turns out we read the FIFO status register after *every* word we
read or write, which effectively doubles the number of MMIO accesses,
thus effectively more than halving our performance.
To avoid this overhead, we can make use of the FIFO level bits, which are
in the very same FIFO status registers.
So for a read request, we now can collect as many words as the FIFO
level originally indicated, and only then need to update the status
register.
We don't know for sure the size of the FIFO (and it seems to differ
across SoCs anyway), so writing is more fragile, which is why we still
use the old method for that. If we find a minimum FIFO size available on
all SoCs, we could use that, in a later optimisation.
This patch increases the eMMC read speed on a Pine64-LTS from about
21MB/s to 43 MB/s. SD card reads increase slightly from about 20MB/s to
23MB/s, which is the practical limit for a 3.3V SD card anyway.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm/include/asm/arch-sunxi/mmc.h | 1 +
drivers/mmc/sunxi_mmc.c | 39 +++++++++++++++++++++------
2 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
index 340e25b04d..5daacf10eb 100644
--- a/arch/arm/include/asm/arch-sunxi/mmc.h
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -119,6 +119,7 @@ struct sunxi_mmc {
#define SUNXI_MMC_STATUS_CARD_PRESENT (0x1 << 8)
#define SUNXI_MMC_STATUS_CARD_DATA_BUSY (0x1 << 9)
#define SUNXI_MMC_STATUS_DATA_FSM_BUSY (0x1 << 10)
+#define SUNXI_MMC_STATUS_FIFO_LEVEL(reg) (((reg) >> 17) & 0x3fff)
#define SUNXI_MMC_NTSR_MODE_SEL_NEW (0x1 << 31)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index a30fd8fbdb..ce085c69f5 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -311,8 +311,9 @@ static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc,
SUNXI_MMC_STATUS_FIFO_FULL;
unsigned i;
unsigned *buff = (unsigned int *)(reading ? data->dest : data->src);
- unsigned byte_cnt = data->blocksize * data->blocks;
- unsigned timeout_msecs = byte_cnt >> 8;
+ unsigned word_cnt = (data->blocksize * data->blocks) >> 2;
+ unsigned timeout_msecs = word_cnt >> 6;
+ uint32_t status;
unsigned long start;
if (timeout_msecs < 2000)
@@ -323,16 +324,38 @@ static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc,
start = get_timer(0);
- for (i = 0; i < (byte_cnt >> 2); i++) {
- while (readl(&priv->reg->status) & status_bit) {
+ for (i = 0; i < word_cnt;) {
+ unsigned int in_fifo;
+
+ while ((status = readl(&priv->reg->status)) & status_bit) {
if (get_timer(start) > timeout_msecs)
return -1;
}
- if (reading)
- buff[i] = readl(&priv->reg->fifo);
- else
- writel(buff[i], &priv->reg->fifo);
+ /*
+ * For writing we do not easily know the FIFO size, so have
+ * to check the FIFO status after every word written.
+ * TODO: For optimisation we could work out a minimum FIFO
+ * size across all SoCs, and use that together with the current
+ * fill level to write chunks for words.
+ */
+ if (!reading) {
+ writel(buff[i++], &priv->reg->fifo);
+ continue;
+ }
+
+ /*
+ * The status register holds the current FIFO level, so we
+ * can be sure to collect as many words from the FIFO
+ * register without checking the status register after every
+ * read. That saves half of the costly MMIO reads, effectively
+ * doubling the read performance.
+ */
+ for (in_fifo = SUNXI_MMC_STATUS_FIFO_LEVEL(status);
+ in_fifo > 0;
+ in_fifo--)
+ buff[i++] = readl_relaxed(&priv->reg->fifo);
+ dmb();
}
return 0;
--
2.31.1

View file

@ -0,0 +1,107 @@
From 93962fbf1fe4ea4a53bffa035b991315b1af46a0 Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Wed, 21 Apr 2021 09:33:04 +0100
Subject: [PATCH 08/29] mmc: sunxi: Use mmc_of_parse()
At the moment the Allwinner MMC driver parses the bus-width and
non-removable DT properties itself, in the probe() routine.
There is actually a generic function provided by the MMC framework doing
this job, also it parses more generic properties like broken-cd and
advanced transfer modes.
Drop our own code and call mmc_of_parse() instead, to get all new
features for free.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
drivers/mmc/sunxi_mmc.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index ce085c69f5..28af8e6ac5 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -37,7 +37,6 @@ struct sunxi_mmc_priv {
uint32_t *mclkreg;
unsigned fatal_err;
struct gpio_desc cd_gpio; /* Change Detect GPIO */
- int cd_inverted; /* Inverted Card Detect */
struct sunxi_mmc *reg;
struct mmc_config cfg;
};
@@ -612,12 +611,21 @@ static int sunxi_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
static int sunxi_mmc_getcd(struct udevice *dev)
{
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
struct sunxi_mmc_priv *priv = dev_get_priv(dev);
+ /* If polling, assume that the card is always present. */
+ if ((mmc->cfg->host_caps & MMC_CAP_NONREMOVABLE) ||
+ (mmc->cfg->host_caps & MMC_CAP_NEEDS_POLL))
+ return 1;
+
if (dm_gpio_is_valid(&priv->cd_gpio)) {
int cd_state = dm_gpio_get_value(&priv->cd_gpio);
- return cd_state ^ priv->cd_inverted;
+ if (mmc->cfg->host_caps & MMC_CAP_CD_ACTIVE_HIGH)
+ return !cd_state;
+ else
+ return cd_state;
}
return 1;
}
@@ -649,23 +657,21 @@ static int sunxi_mmc_probe(struct udevice *dev)
struct mmc_config *cfg = &plat->cfg;
struct ofnode_phandle_args args;
u32 *ccu_reg;
- int bus_width, ret;
+ int ret;
cfg->name = dev->name;
- bus_width = dev_read_u32_default(dev, "bus-width", 1);
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
- cfg->host_caps = 0;
- if (bus_width == 8)
- cfg->host_caps |= MMC_MODE_8BIT;
- if (bus_width >= 4)
- cfg->host_caps |= MMC_MODE_4BIT;
- cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+ cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
cfg->f_min = 400000;
cfg->f_max = 52000000;
+ ret = mmc_of_parse(dev, cfg);
+ if (ret)
+ return ret;
+
priv->reg = dev_read_addr_ptr(dev);
/* We don't have a sunxi clock driver so find the clock address here */
@@ -691,17 +697,13 @@ static int sunxi_mmc_probe(struct udevice *dev)
return ret;
/* This GPIO is optional */
- if (!dev_read_bool(dev, "non-removable") &&
- !gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
+ if (!gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
GPIOD_IS_IN)) {
int cd_pin = gpio_get_number(&priv->cd_gpio);
sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP);
}
- /* Check if card detect is inverted */
- priv->cd_inverted = dev_read_bool(dev, "cd-inverted");
-
upriv->mmc = &plat->mmc;
/* Reset controller */
--
2.31.1

View file

@ -0,0 +1,334 @@
From 10aa9515a2b13ad865c1c134266fcfc7c4fa90ad Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Thu, 7 May 2020 18:50:28 -0500
Subject: [PATCH 09/29] sunxi: DT: H5: update device tree files
Import updated device trees from Linux v5.9.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
.../dts/sun50i-h5-bananapi-m2-plus-v1.2.dts | 1 +
arch/arm/dts/sun50i-h5-cpu-opp.dtsi | 79 +++++++++++++++++++
.../arm/dts/sun50i-h5-libretech-all-h3-cc.dts | 1 +
arch/arm/dts/sun50i-h5-orangepi-pc2.dts | 21 +++++
.../arm/dts/sun50i-h5-orangepi-zero-plus2.dts | 38 +++++++++
arch/arm/dts/sun50i-h5.dtsi | 41 +++++++++-
6 files changed, 179 insertions(+), 2 deletions(-)
create mode 100644 arch/arm/dts/sun50i-h5-cpu-opp.dtsi
diff --git a/arch/arm/dts/sun50i-h5-bananapi-m2-plus-v1.2.dts b/arch/arm/dts/sun50i-h5-bananapi-m2-plus-v1.2.dts
index 2e2b14c0ae..8857a37915 100644
--- a/arch/arm/dts/sun50i-h5-bananapi-m2-plus-v1.2.dts
+++ b/arch/arm/dts/sun50i-h5-bananapi-m2-plus-v1.2.dts
@@ -3,6 +3,7 @@
/dts-v1/;
#include "sun50i-h5.dtsi"
+#include "sun50i-h5-cpu-opp.dtsi"
#include <arm/sunxi-bananapi-m2-plus-v1.2.dtsi>
/ {
diff --git a/arch/arm/dts/sun50i-h5-cpu-opp.dtsi b/arch/arm/dts/sun50i-h5-cpu-opp.dtsi
new file mode 100644
index 0000000000..b265720195
--- /dev/null
+++ b/arch/arm/dts/sun50i-h5-cpu-opp.dtsi
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2020 Chen-Yu Tsai <wens@csie.org>
+
+/ {
+ cpu_opp_table: cpu-opp-table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-408000000 {
+ opp-hz = /bits/ 64 <408000000>;
+ opp-microvolt = <1000000 1000000 1310000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+
+ opp-648000000 {
+ opp-hz = /bits/ 64 <648000000>;
+ opp-microvolt = <1040000 1040000 1310000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+
+ opp-816000000 {
+ opp-hz = /bits/ 64 <816000000>;
+ opp-microvolt = <1080000 1080000 1310000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+
+ opp-912000000 {
+ opp-hz = /bits/ 64 <912000000>;
+ opp-microvolt = <1120000 1120000 1310000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+
+ opp-960000000 {
+ opp-hz = /bits/ 64 <960000000>;
+ opp-microvolt = <1160000 1160000 1310000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+
+ opp-1008000000 {
+ opp-hz = /bits/ 64 <1008000000>;
+ opp-microvolt = <1200000 1200000 1310000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+
+ opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-microvolt = <1240000 1240000 1310000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+
+ opp-1104000000 {
+ opp-hz = /bits/ 64 <1104000000>;
+ opp-microvolt = <1260000 1260000 1310000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+
+ opp-1152000000 {
+ opp-hz = /bits/ 64 <1152000000>;
+ opp-microvolt = <1300000 1300000 1310000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+ };
+};
+
+&cpu0 {
+ operating-points-v2 = <&cpu_opp_table>;
+};
+
+&cpu1 {
+ operating-points-v2 = <&cpu_opp_table>;
+};
+
+&cpu2 {
+ operating-points-v2 = <&cpu_opp_table>;
+};
+
+&cpu3 {
+ operating-points-v2 = <&cpu_opp_table>;
+};
diff --git a/arch/arm/dts/sun50i-h5-libretech-all-h3-cc.dts b/arch/arm/dts/sun50i-h5-libretech-all-h3-cc.dts
index a91806618e..016da3ec32 100644
--- a/arch/arm/dts/sun50i-h5-libretech-all-h3-cc.dts
+++ b/arch/arm/dts/sun50i-h5-libretech-all-h3-cc.dts
@@ -4,6 +4,7 @@
/dts-v1/;
#include "sun50i-h5.dtsi"
+#include "sun50i-h5-cpu-opp.dtsi"
#include <sunxi-libretech-all-h3-cc.dtsi>
/ {
diff --git a/arch/arm/dts/sun50i-h5-orangepi-pc2.dts b/arch/arm/dts/sun50i-h5-orangepi-pc2.dts
index 70b5f09984..7d7aad18f0 100644
--- a/arch/arm/dts/sun50i-h5-orangepi-pc2.dts
+++ b/arch/arm/dts/sun50i-h5-orangepi-pc2.dts
@@ -61,6 +61,7 @@
label = "sw4";
linux,code = <BTN_0>;
gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>;
+ wakeup-source;
};
};
@@ -93,6 +94,10 @@
status = "okay";
};
+&cpu0 {
+ cpu-supply = <&reg_vdd_cpux>;
+};
+
&de {
status = "okay";
};
@@ -168,6 +173,22 @@
status = "okay";
};
+&r_i2c {
+ status = "okay";
+
+ reg_vdd_cpux: regulator@65 {
+ compatible = "silergy,sy8106a";
+ reg = <0x65>;
+ regulator-name = "vdd-cpux";
+ silergy,fixed-microvolt = <1100000>;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-ramp-delay = <200>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
&spi0 {
status = "okay";
diff --git a/arch/arm/dts/sun50i-h5-orangepi-zero-plus2.dts b/arch/arm/dts/sun50i-h5-orangepi-zero-plus2.dts
index c95a685413..de19e68eb8 100644
--- a/arch/arm/dts/sun50i-h5-orangepi-zero-plus2.dts
+++ b/arch/arm/dts/sun50i-h5-orangepi-zero-plus2.dts
@@ -30,6 +30,21 @@
};
};
+ leds {
+ compatible = "gpio-leds";
+
+ pwr {
+ label = "orangepi:green:pwr";
+ gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+
+ status {
+ label = "orangepi:red:status";
+ gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
reg_vcc3v3: vcc3v3 {
compatible = "regulator-fixed";
regulator-name = "vcc3v3";
@@ -48,6 +63,10 @@
status = "okay";
};
+&ehci0 {
+ status = "okay";
+};
+
&hdmi {
status = "okay";
};
@@ -92,6 +111,10 @@
status = "okay";
};
+&ohci0 {
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pa_pins>;
@@ -103,3 +126,18 @@
pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
status = "okay";
};
+
+&usb_otg {
+ /*
+ * According to schematics CN1 MicroUSB port can be used to take
+ * external 5V to power up the board VBUS. On the contrary CN1 MicroUSB
+ * port cannot provide power externally even if the board is powered
+ * via GPIO pins. It thus makes sense to force peripheral mode.
+ */
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
diff --git a/arch/arm/dts/sun50i-h5.dtsi b/arch/arm/dts/sun50i-h5.dtsi
index 3a1c8b2efd..9c73c4e4c3 100644
--- a/arch/arm/dts/sun50i-h5.dtsi
+++ b/arch/arm/dts/sun50i-h5.dtsi
@@ -3,6 +3,8 @@
#include <sunxi-h3-h5.dtsi>
+#include <dt-bindings/thermal/thermal.h>
+
/ {
cpus {
#address-cells = <1>;
@@ -13,6 +15,9 @@
device_type = "cpu";
reg = <0>;
enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ #cooling-cells = <2>;
};
cpu1: cpu@1 {
@@ -20,6 +25,9 @@
device_type = "cpu";
reg = <1>;
enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ #cooling-cells = <2>;
};
cpu2: cpu@2 {
@@ -27,6 +35,9 @@
device_type = "cpu";
reg = <2>;
enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ #cooling-cells = <2>;
};
cpu3: cpu@3 {
@@ -34,12 +45,14 @@
device_type = "cpu";
reg = <3>;
enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ #cooling-cells = <2>;
};
};
pmu {
- compatible = "arm,cortex-a53-pmu",
- "arm,armv8-pmuv3";
+ compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
@@ -166,6 +179,30 @@
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = <&ths 0>;
+
+ trips {
+ cpu_hot_trip: cpu-hot {
+ temperature = <80000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_very_hot_trip: cpu-very-hot {
+ temperature = <100000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ cpu-hot-limit {
+ trip = <&cpu_hot_trip>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
};
gpu_thermal {
--
2.31.1

View file

@ -0,0 +1,56 @@
From 153c7e167201f9c17cee7ea919146a5168daa74e Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Thu, 7 May 2020 18:50:37 -0500
Subject: [PATCH 10/29] sunxi: DT: H6: update device tree files
Import updated device trees from Linux v5.9.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/Makefile | 1 +
arch/arm/dts/sun50i-h6-pine-h64-model-b.dts | 21 +++++++++++++++++++++
2 files changed, 22 insertions(+)
create mode 100644 arch/arm/dts/sun50i-h6-pine-h64-model-b.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 9fb38682e6..ec40983df2 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -633,6 +633,7 @@ dtb-$(CONFIG_MACH_SUN50I_H6) += \
sun50i-h6-orangepi-lite2.dtb \
sun50i-h6-orangepi-one-plus.dtb \
sun50i-h6-pine-h64.dtb \
+ sun50i-h6-pine-h64-model-b.dtb \
sun50i-h6-tanix-tx6.dtb
dtb-$(CONFIG_MACH_SUN50I_H616) += \
sun50i-h616-orangepi-zero2.dtb
diff --git a/arch/arm/dts/sun50i-h6-pine-h64-model-b.dts b/arch/arm/dts/sun50i-h6-pine-h64-model-b.dts
new file mode 100644
index 0000000000..f4c8966a64
--- /dev/null
+++ b/arch/arm/dts/sun50i-h6-pine-h64-model-b.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2019 Corentin LABBE <clabbe@baylibre.com>
+ */
+
+#include "sun50i-h6-pine-h64.dts"
+
+/ {
+ model = "Pine H64 model B";
+ compatible = "pine64,pine-h64-model-b", "allwinner,sun50i-h6";
+
+ /delete-node/ reg_gmac_3v3;
+};
+
+&hdmi_connector {
+ /delete-property/ ddc-en-gpios;
+};
+
+&emac {
+ phy-supply = <&reg_aldo2>;
+};
--
2.31.1

View file

@ -0,0 +1,222 @@
From a2fceed3e1d2ac4cce4a86274c57f2bb1e177646 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 30 May 2020 03:05:29 -0500
Subject: [PATCH 11/29] phy: sun50i-usb3: Add a driver for the H6 USB3 PHY
This driver is needed for XHCI to work on the Allwinner H6 SoC. The
driver is copied from Linux v5.10.
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/phy/allwinner/Kconfig | 8 ++
drivers/phy/allwinner/Makefile | 1 +
drivers/phy/allwinner/phy-sun50i-usb3.c | 171 ++++++++++++++++++++++++
3 files changed, 180 insertions(+)
create mode 100644 drivers/phy/allwinner/phy-sun50i-usb3.c
diff --git a/drivers/phy/allwinner/Kconfig b/drivers/phy/allwinner/Kconfig
index dba3bae61c..6bfb79cbca 100644
--- a/drivers/phy/allwinner/Kconfig
+++ b/drivers/phy/allwinner/Kconfig
@@ -11,3 +11,11 @@ config PHY_SUN4I_USB
This driver controls the entire USB PHY block, both the USB OTG
parts, as well as the 2 regular USB 2 host PHYs.
+
+config PHY_SUN50I_USB3
+ bool "Allwinner sun50i USB3 PHY driver"
+ depends on ARCH_SUNXI
+ select PHY
+ help
+ Enable this to support the USB3 transceiver that is part of
+ Allwinner sun50i SoCs.
diff --git a/drivers/phy/allwinner/Makefile b/drivers/phy/allwinner/Makefile
index e709fca643..f2b60ce1a6 100644
--- a/drivers/phy/allwinner/Makefile
+++ b/drivers/phy/allwinner/Makefile
@@ -4,3 +4,4 @@
#
obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
+obj-$(CONFIG_PHY_SUN50I_USB3) += phy-sun50i-usb3.o
diff --git a/drivers/phy/allwinner/phy-sun50i-usb3.c b/drivers/phy/allwinner/phy-sun50i-usb3.c
new file mode 100644
index 0000000000..e5a3d2d92e
--- /dev/null
+++ b/drivers/phy/allwinner/phy-sun50i-usb3.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Allwinner sun50i(H6) USB 3.0 phy driver
+ *
+ * Copyright (C) 2020 Samuel Holland <samuel@sholland.org>
+ *
+ * Based on the Linux driver, which is:
+ *
+ * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
+ *
+ * Based on phy-sun9i-usb.c, which is:
+ *
+ * Copyright (C) 2014-2015 Chen-Yu Tsai <wens@csie.org>
+ *
+ * Based on code from Allwinner BSP, which is:
+ *
+ * Copyright (c) 2010-2015 Allwinner Technology Co., Ltd.
+ */
+
+#include <asm/io.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <generic-phy.h>
+#include <linux/bitops.h>
+#include <reset.h>
+
+/* Interface Status and Control Registers */
+#define SUNXI_ISCR 0x00
+#define SUNXI_PIPE_CLOCK_CONTROL 0x14
+#define SUNXI_PHY_TUNE_LOW 0x18
+#define SUNXI_PHY_TUNE_HIGH 0x1c
+#define SUNXI_PHY_EXTERNAL_CONTROL 0x20
+
+/* USB2.0 Interface Status and Control Register */
+#define SUNXI_ISCR_FORCE_VBUS (3 << 12)
+
+/* PIPE Clock Control Register */
+#define SUNXI_PCC_PIPE_CLK_OPEN (1 << 6)
+
+/* PHY External Control Register */
+#define SUNXI_PEC_EXTERN_VBUS (3 << 1)
+#define SUNXI_PEC_SSC_EN (1 << 24)
+#define SUNXI_PEC_REF_SSP_EN (1 << 26)
+
+/* PHY Tune High Register */
+#define SUNXI_TX_DEEMPH_3P5DB(n) ((n) << 19)
+#define SUNXI_TX_DEEMPH_3P5DB_MASK GENMASK(24, 19)
+#define SUNXI_TX_DEEMPH_6DB(n) ((n) << 13)
+#define SUNXI_TX_DEEMPH_6GB_MASK GENMASK(18, 13)
+#define SUNXI_TX_SWING_FULL(n) ((n) << 6)
+#define SUNXI_TX_SWING_FULL_MASK GENMASK(12, 6)
+#define SUNXI_LOS_BIAS(n) ((n) << 3)
+#define SUNXI_LOS_BIAS_MASK GENMASK(5, 3)
+#define SUNXI_TXVBOOSTLVL(n) ((n) << 0)
+#define SUNXI_TXVBOOSTLVL_MASK GENMASK(2, 0)
+
+struct sun50i_usb3_phy_priv {
+ void __iomem *regs;
+ struct reset_ctl reset;
+ struct clk clk;
+};
+
+static void sun50i_usb3_phy_open(struct sun50i_usb3_phy_priv *phy)
+{
+ u32 val;
+
+ val = readl(phy->regs + SUNXI_PHY_EXTERNAL_CONTROL);
+ val |= SUNXI_PEC_EXTERN_VBUS;
+ val |= SUNXI_PEC_SSC_EN | SUNXI_PEC_REF_SSP_EN;
+ writel(val, phy->regs + SUNXI_PHY_EXTERNAL_CONTROL);
+
+ val = readl(phy->regs + SUNXI_PIPE_CLOCK_CONTROL);
+ val |= SUNXI_PCC_PIPE_CLK_OPEN;
+ writel(val, phy->regs + SUNXI_PIPE_CLOCK_CONTROL);
+
+ val = readl(phy->regs + SUNXI_ISCR);
+ val |= SUNXI_ISCR_FORCE_VBUS;
+ writel(val, phy->regs + SUNXI_ISCR);
+
+ /*
+ * All the magic numbers written to the PHY_TUNE_{LOW_HIGH}
+ * registers are directly taken from the BSP USB3 driver from
+ * Allwiner.
+ */
+ writel(0x0047fc87, phy->regs + SUNXI_PHY_TUNE_LOW);
+
+ val = readl(phy->regs + SUNXI_PHY_TUNE_HIGH);
+ val &= ~(SUNXI_TXVBOOSTLVL_MASK | SUNXI_LOS_BIAS_MASK |
+ SUNXI_TX_SWING_FULL_MASK | SUNXI_TX_DEEMPH_6GB_MASK |
+ SUNXI_TX_DEEMPH_3P5DB_MASK);
+ val |= SUNXI_TXVBOOSTLVL(0x7);
+ val |= SUNXI_LOS_BIAS(0x7);
+ val |= SUNXI_TX_SWING_FULL(0x55);
+ val |= SUNXI_TX_DEEMPH_6DB(0x20);
+ val |= SUNXI_TX_DEEMPH_3P5DB(0x15);
+ writel(val, phy->regs + SUNXI_PHY_TUNE_HIGH);
+}
+
+static int sun50i_usb3_phy_init(struct phy *phy)
+{
+ struct sun50i_usb3_phy_priv *priv = dev_get_priv(phy->dev);
+ int ret;
+
+ ret = clk_prepare_enable(&priv->clk);
+ if (ret)
+ return ret;
+
+ ret = reset_deassert(&priv->reset);
+ if (ret) {
+ clk_disable_unprepare(&priv->clk);
+ return ret;
+ }
+
+ sun50i_usb3_phy_open(priv);
+
+ return 0;
+}
+
+static int sun50i_usb3_phy_exit(struct phy *phy)
+{
+ struct sun50i_usb3_phy_priv *priv = dev_get_priv(phy->dev);
+
+ reset_assert(&priv->reset);
+ clk_disable_unprepare(&priv->clk);
+
+ return 0;
+}
+
+static const struct phy_ops sun50i_usb3_phy_ops = {
+ .init = sun50i_usb3_phy_init,
+ .exit = sun50i_usb3_phy_exit,
+};
+
+static int sun50i_usb3_phy_probe(struct udevice *dev)
+{
+ struct sun50i_usb3_phy_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = clk_get_by_index(dev, 0, &priv->clk);
+ if (ret) {
+ dev_err(dev, "failed to get phy clock\n");
+ return ret;
+ }
+
+ ret = reset_get_by_index(dev, 0, &priv->reset);
+ if (ret) {
+ dev_err(dev, "failed to get reset control\n");
+ return ret;
+ }
+
+ priv->regs = (void __iomem *)dev_read_addr(dev);
+ if (IS_ERR(priv->regs))
+ return PTR_ERR(priv->regs);
+
+ return 0;
+}
+
+static const struct udevice_id sun50i_usb3_phy_ids[] = {
+ { .compatible = "allwinner,sun50i-h6-usb3-phy" },
+ { },
+};
+
+U_BOOT_DRIVER(sun50i_usb3_phy) = {
+ .name = "sun50i-usb3-phy",
+ .id = UCLASS_PHY,
+ .of_match = sun50i_usb3_phy_ids,
+ .ops = &sun50i_usb3_phy_ops,
+ .probe = sun50i_usb3_phy_probe,
+ .priv_auto = sizeof(struct sun50i_usb3_phy_priv),
+};
--
2.31.1

View file

@ -0,0 +1,206 @@
From 1453bfc951cd05cfee6293b139f8bbefa7c42cb9 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 7 Feb 2021 23:21:26 -0600
Subject: [PATCH 12/29] usb: xhci-pci: Move reset logic out of XHCI core
Resetting an XHCI controller inside xhci_register undoes any register
setup performed by the platform driver. And at least on the Allwinner
H6, resetting the XHCI controller also resets the PHY, which prevents
the controller from working. That means the controller must be taken out
of reset before initializing the PHY, which must be done before calling
xhci_register.
The logic in the XHCI core was added to support the Raspberry Pi 4
(although this was not mentioned in the commit log!), which uses the
xhci-pci platform driver. Move the reset logic to the platform driver,
where it belongs, and where it cannot interfere with other platform
drivers.
This also fixes a failure to call reset_free if xhci_register failed.
Fixes: 0b80371b350e ("usb: xhci: Add reset controller support")
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/usb/host/xhci-mem.c | 2 --
drivers/usb/host/xhci-pci.c | 51 ++++++++++++++++++++++++++++++++++---
drivers/usb/host/xhci.c | 35 -------------------------
include/usb/xhci.h | 2 --
4 files changed, 47 insertions(+), 43 deletions(-)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 1c11c2e7e0..0d9da62bab 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -180,8 +180,6 @@ void xhci_cleanup(struct xhci_ctrl *ctrl)
xhci_free_virt_devices(ctrl);
free(ctrl->erst.entries);
free(ctrl->dcbaa);
- if (reset_valid(&ctrl->reset))
- reset_free(&ctrl->reset);
memset(ctrl, '\0', sizeof(struct xhci_ctrl));
}
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index aaa243f291..ea8e8f3211 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -10,9 +10,14 @@
#include <init.h>
#include <log.h>
#include <pci.h>
+#include <reset.h>
#include <usb.h>
#include <usb/xhci.h>
+struct xhci_pci_plat {
+ struct reset_ctl reset;
+};
+
static int xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr,
struct xhci_hcor **ret_hcor)
{
@@ -45,15 +50,53 @@ static int xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr,
static int xhci_pci_probe(struct udevice *dev)
{
+ struct xhci_pci_plat = dev_get_plat(dev);
struct xhci_hccr *hccr;
struct xhci_hcor *hcor;
int ret;
+ ret = reset_get_by_index(dev, 0, &plat->reset);
+ if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
+ dev_err(dev, "failed to get reset\n");
+ return ret;
+ }
+
+ if (reset_valid(&plat->reset)) {
+ ret = reset_assert(&plat->reset);
+ if (ret)
+ goto err_reset;
+
+ ret = reset_deassert(&plat->reset);
+ if (ret)
+ goto err_reset;
+ }
+
ret = xhci_pci_init(dev, &hccr, &hcor);
if (ret)
- return ret;
+ goto err_reset;
+
+ ret = xhci_register(dev, hccr, hcor);
+ if (ret)
+ goto err_reset;
+
+ return 0;
+
+err_reset:
+ if (reset_valid(&plat->reset))
+ reset_free(&plat->reset);
+
+ return ret;
+}
+
+static int xhci_pci_remove(struct udevice *dev)
+{
+ struct xhci_pci_plat = dev_get_plat(dev);
- return xhci_register(dev, hccr, hcor);
+ xhci_deregister(dev);
+ if (reset_valid(&plat->reset))
+ reset_free(&plat->reset);
+
+ return 0;
}
static const struct udevice_id xhci_pci_ids[] = {
@@ -65,10 +108,10 @@ U_BOOT_DRIVER(xhci_pci) = {
.name = "xhci_pci",
.id = UCLASS_USB,
.probe = xhci_pci_probe,
- .remove = xhci_deregister,
+ .remove = xhci_pci_remove,
.of_match = xhci_pci_ids,
.ops = &xhci_usb_ops,
- .plat_auto = sizeof(struct usb_plat),
+ .plat_auto = sizeof(struct xhci_pci_plat),
.priv_auto = sizeof(struct xhci_ctrl),
.flags = DM_FLAG_OS_PREPARE | DM_FLAG_ALLOC_PRIV_DMA,
};
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d27ac01c83..452dacc0af 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -188,37 +188,6 @@ static int xhci_start(struct xhci_hcor *hcor)
return ret;
}
-#if CONFIG_IS_ENABLED(DM_USB)
-/**
- * Resets XHCI Hardware
- *
- * @param ctrl pointer to host controller
- * @return 0 if OK, or a negative error code.
- */
-static int xhci_reset_hw(struct xhci_ctrl *ctrl)
-{
- int ret;
-
- ret = reset_get_by_index(ctrl->dev, 0, &ctrl->reset);
- if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
- dev_err(ctrl->dev, "failed to get reset\n");
- return ret;
- }
-
- if (reset_valid(&ctrl->reset)) {
- ret = reset_assert(&ctrl->reset);
- if (ret)
- return ret;
-
- ret = reset_deassert(&ctrl->reset);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-#endif
-
/**
* Resets the XHCI Controller
*
@@ -1534,10 +1503,6 @@ int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
ctrl->dev = dev;
- ret = xhci_reset_hw(ctrl);
- if (ret)
- goto err;
-
/*
* XHCI needs to issue a Address device command to setup
* proper device context structures, before it can interact
diff --git a/include/usb/xhci.h b/include/usb/xhci.h
index 8d95e213b0..01e63cf0fc 100644
--- a/include/usb/xhci.h
+++ b/include/usb/xhci.h
@@ -17,7 +17,6 @@
#define HOST_XHCI_H_
#include <phys2bus.h>
-#include <reset.h>
#include <asm/types.h>
#include <asm/cache.h>
#include <asm/io.h>
@@ -1200,7 +1199,6 @@ struct xhci_ctrl {
#if CONFIG_IS_ENABLED(DM_USB)
struct udevice *dev;
#endif
- struct reset_ctl reset;
struct xhci_hccr *hccr; /* R/O registers, not need for volatile */
struct xhci_hcor *hcor;
struct xhci_doorbell_array *dba;
--
2.31.1

View file

@ -0,0 +1,118 @@
From 03ea01cff249ec4204507e0252464de385fde4a0 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 30 May 2020 02:57:04 -0500
Subject: [PATCH 13/29] usb: xhci-dwc3: Add support for clocks/resets
Some platforms, like the Allwinner H6, do not have a separate glue layer
around the dwc3. Instead, they rely on the clocks/resets/phys referenced
from the dwc3 DT node itself. Add support for enabling the clocks/resets
referenced from the dwc3 DT node.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/usb/host/xhci-dwc3.c | 56 ++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
index 3e0ae80cec..5b12d1358e 100644
--- a/drivers/usb/host/xhci-dwc3.c
+++ b/drivers/usb/host/xhci-dwc3.c
@@ -7,10 +7,12 @@
* Author: Ramneek Mehresh<ramneek.mehresh@freescale.com>
*/
+#include <clk.h>
#include <common.h>
#include <dm.h>
#include <generic-phy.h>
#include <log.h>
+#include <reset.h>
#include <usb.h>
#include <dwc3-uboot.h>
#include <linux/delay.h>
@@ -21,7 +23,9 @@
#include <linux/usb/otg.h>
struct xhci_dwc3_plat {
+ struct clk_bulk clks;
struct phy_bulk phys;
+ struct reset_ctl_bulk resets;
};
void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
@@ -111,6 +115,46 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
}
#if CONFIG_IS_ENABLED(DM_USB)
+static int xhci_dwc3_reset_init(struct udevice *dev,
+ struct xhci_dwc3_plat *plat)
+{
+ int ret;
+
+ ret = reset_get_bulk(dev, &plat->resets);
+ if (ret == -ENOTSUPP || ret == -ENOENT)
+ return 0;
+ else if (ret)
+ return ret;
+
+ ret = reset_deassert_bulk(&plat->resets);
+ if (ret) {
+ reset_release_bulk(&plat->resets);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int xhci_dwc3_clk_init(struct udevice *dev,
+ struct xhci_dwc3_plat *plat)
+{
+ int ret;
+
+ ret = clk_get_bulk(dev, &plat->clks);
+ if (ret == -ENOSYS || ret == -ENOENT)
+ return 0;
+ if (ret)
+ return ret;
+
+ ret = clk_enable_bulk(&plat->clks);
+ if (ret) {
+ clk_release_bulk(&plat->clks);
+ return ret;
+ }
+
+ return 0;
+}
+
static int xhci_dwc3_probe(struct udevice *dev)
{
struct xhci_hcor *hcor;
@@ -122,6 +166,14 @@ static int xhci_dwc3_probe(struct udevice *dev)
u32 reg;
int ret;
+ ret = xhci_dwc3_reset_init(dev, plat);
+ if (ret)
+ return ret;
+
+ ret = xhci_dwc3_clk_init(dev, plat);
+ if (ret)
+ return ret;
+
hccr = (struct xhci_hccr *)((uintptr_t)dev_remap_addr(dev));
hcor = (struct xhci_hcor *)((uintptr_t)hccr +
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
@@ -171,6 +223,10 @@ static int xhci_dwc3_remove(struct udevice *dev)
dwc3_shutdown_phy(dev, &plat->phys);
+ clk_release_bulk(&plat->clks);
+
+ reset_release_bulk(&plat->resets);
+
return xhci_deregister(dev);
}
--
2.31.1

View file

@ -0,0 +1,47 @@
From 29867a32db349667947c32f966faf22a0f2b0369 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 30 May 2020 03:39:45 -0500
Subject: [PATCH 14/29] configs: Enable USB3 on Allwinner H6 boards
Pine H64 and Orange Pi 3 both provide a USB3 type A port.
Enable it in U-Boot.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
configs/orangepi_3_defconfig | 5 +++++
configs/pine_h64_defconfig | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/configs/orangepi_3_defconfig b/configs/orangepi_3_defconfig
index 82b9815205..eb25bd9f50 100644
--- a/configs/orangepi_3_defconfig
+++ b/configs/orangepi_3_defconfig
@@ -8,5 +8,10 @@ CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_BLUETOOTH_DT_DEVICE_FIXUP="brcm,bcm4345c5"
CONFIG_DEFAULT_DEVICE_TREE="sun50i-h6-orangepi-3"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_PHY_SUN50I_USB3=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_DWC3=y
+# CONFIG_USB_DWC3_GADGET is not set
diff --git a/configs/pine_h64_defconfig b/configs/pine_h64_defconfig
index 2fa66f3834..0095fb222e 100644
--- a/configs/pine_h64_defconfig
+++ b/configs/pine_h64_defconfig
@@ -12,5 +12,10 @@ CONFIG_SPL_SPI_SUNXI=y
CONFIG_DEFAULT_DEVICE_TREE="sun50i-h6-pine-h64"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SUN8I_EMAC=y
+CONFIG_PHY_SUN50I_USB3=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_DWC3=y
+# CONFIG_USB_DWC3_GADGET is not set
--
2.31.1

View file

@ -0,0 +1,181 @@
From 0aa9ea61cfbd9b4ddb9339ac1e0f4692bdc831da Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 20 Jun 2021 13:50:35 -0500
Subject: [PATCH 15/29] tools: Refactor mkimage linking with OpenSSL
Some mkimage features require linking with OpenSSL. Instead of linking
OpenSSL based on the individual platform symbols, create a single
Kconfig symbol which can be selected by platforms as necessary. Then,
all OpenSSL-dependent image types can be enabled at once.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/mach-imx/mxs/Kconfig | 2 ++
arch/arm/mach-mvebu/Kconfig | 1 +
common/Kconfig.boot | 2 ++
scripts/config_whitelist.txt | 1 -
tools/Kconfig | 3 +++
tools/Makefile | 22 +++++++---------------
tools/mxsimage.c | 3 ---
7 files changed, 15 insertions(+), 19 deletions(-)
diff --git a/arch/arm/mach-imx/mxs/Kconfig b/arch/arm/mach-imx/mxs/Kconfig
index 9f48ffda41..f067a9c38e 100644
--- a/arch/arm/mach-imx/mxs/Kconfig
+++ b/arch/arm/mach-imx/mxs/Kconfig
@@ -3,6 +3,7 @@ if ARCH_MX23
config MX23
bool
default y
+ select MKIMAGE_LINK_OPENSSL
choice
prompt "MX23 board select"
@@ -34,6 +35,7 @@ if ARCH_MX28
config MX28
bool
default y
+ select MKIMAGE_LINK_OPENSSL
choice
prompt "MX28 board select"
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index cda65f7478..2a4f861015 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -29,6 +29,7 @@ config ARMADA_38X
bool
select ARMADA_32BIT
select HAVE_MVEBU_EFUSE
+ select MKIMAGE_LINK_OPENSSL
config ARMADA_38X_HS_IMPEDANCE_THRESH
hex "Armada 38x USB 2.0 High-Speed Impedance Threshold (0x0 - 0x7)"
diff --git a/common/Kconfig.boot b/common/Kconfig.boot
index 89a3161f1f..7d022d1ccf 100644
--- a/common/Kconfig.boot
+++ b/common/Kconfig.boot
@@ -80,6 +80,7 @@ config FIT_SIGNATURE
select RSA_VERIFY
select IMAGE_SIGN_INFO
select FIT_FULL_CHECK
+ select MKIMAGE_LINK_OPENSSL
help
This option enables signature verification of FIT uImages,
using a hash signed and verified using RSA. If
@@ -115,6 +116,7 @@ config FIT_CIPHER
bool "Enable ciphering data in a FIT uImages"
depends on DM
select AES
+ select MKIMAGE_LINK_OPENSSL
help
Enable the feature of data ciphering/unciphering in the tool mkimage
and in the u-boot support of the FIT image.
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 3dbcc042a8..e013e1f26a 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -1066,7 +1066,6 @@ CONFIG_MXC_UART_BASE
CONFIG_MXC_USB_FLAGS
CONFIG_MXC_USB_PORT
CONFIG_MXC_USB_PORTSC
-CONFIG_MXS
CONFIG_MXS_AUART
CONFIG_MXS_AUART_BASE
CONFIG_MXS_OCOTP
diff --git a/tools/Kconfig b/tools/Kconfig
index b2f5012240..df3dffa9e1 100644
--- a/tools/Kconfig
+++ b/tools/Kconfig
@@ -9,4 +9,7 @@ config MKIMAGE_DTC_PATH
some cases the system dtc may not support all required features
and the path to a different version should be given here.
+config MKIMAGE_LINK_OPENSSL
+ bool
+
endmenu
diff --git a/tools/Makefile b/tools/Makefile
index d020c55d66..8843185703 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -75,9 +75,10 @@ ECDSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/ecdsa/, ecdsa-libcrypto.o)
AES_OBJS-$(CONFIG_FIT_CIPHER) := $(addprefix lib/aes/, \
aes-encrypt.o aes-decrypt.o)
-# Cryptographic helpers that depend on openssl/libcrypto
-LIBCRYPTO_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/, \
- fdt-libcrypto.o)
+# Cryptographic helpers and image types that depend on openssl/libcrypto
+OPENSSL_OBJS-$(CONFIG_MKIMAGE_LINK_OPENSSL) := \
+ lib/fdt-libcrypto.o \
+ mxsimage.o \
ROCKCHIP_OBS = lib/rc4.o rkcommon.o rkimage.o rksd.o rkspi.o
@@ -101,7 +102,6 @@ dumpimage-mkimage-objs := aisimage.o \
kwbimage.o \
lib/md5.o \
lpc32xximage.o \
- mxsimage.o \
omapimage.o \
os_support.o \
pblimage.o \
@@ -121,7 +121,7 @@ dumpimage-mkimage-objs := aisimage.o \
zynqimage.o \
zynqmpimage.o \
zynqmpbif.o \
- $(LIBCRYPTO_OBJS-y) \
+ $(OPENSSL_OBJS-y) \
$(LIBFDT_OBJS) \
gpimage.o \
gpimage-common.o \
@@ -136,12 +136,7 @@ fit_info-objs := $(dumpimage-mkimage-objs) fit_info.o
fit_check_sign-objs := $(dumpimage-mkimage-objs) fit_check_sign.o
file2include-objs := file2include.o
-ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_FIT_SIGNATURE),)
-# Add CONFIG_MXS into host CFLAGS, so we can check whether or not register
-# the mxsimage support within tools/mxsimage.c .
-HOSTCFLAGS_mxsimage.o += -DCONFIG_MXS
-endif
-
+ifneq ($(CONFIG_MKIMAGE_LINK_OPENSSL),)
ifdef CONFIG_FIT_SIGNATURE
# This affects include/image.h, but including the board config file
# is tricky, so manually define this options here.
@@ -159,12 +154,9 @@ ifdef CONFIG_SYS_U_BOOT_OFFS
HOSTCFLAGS_kwbimage.o += -DCONFIG_SYS_U_BOOT_OFFS=$(CONFIG_SYS_U_BOOT_OFFS)
endif
-ifneq ($(CONFIG_ARMADA_38X),)
+# Enable image features which depend on OpenSSL.
HOSTCFLAGS_kwbimage.o += -DCONFIG_KWB_SECURE
-endif
-# MXSImage needs LibSSL
-ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_ARMADA_38X)$(CONFIG_FIT_SIGNATURE)$(CONFIG_FIT_CIPHER),)
HOSTCFLAGS_kwbimage.o += \
$(shell pkg-config --cflags libssl libcrypto 2> /dev/null || echo "")
HOSTLDLIBS_mkimage += \
diff --git a/tools/mxsimage.c b/tools/mxsimage.c
index 002f4b525a..2bfbb421eb 100644
--- a/tools/mxsimage.c
+++ b/tools/mxsimage.c
@@ -5,8 +5,6 @@
* Copyright (C) 2012-2013 Marek Vasut <marex@denx.de>
*/
-#ifdef CONFIG_MXS
-
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@@ -2363,4 +2361,3 @@ U_BOOT_IMAGE_TYPE(
NULL,
mxsimage_generate
);
-#endif
--
2.31.1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,99 @@
From 4bb23c0a439a47e34c04ce4c117465e669918f26 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 20 Jun 2021 14:23:11 -0500
Subject: [PATCH 17/29] sunxi: Support both SPL image types
SPL uses the image header to detect the boot device and to find the
offset of U-Boot proper. Since this information is stored differently in
eGON and TOC0 image headers, add code to find the correct value based on
the image type currently in use.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/include/asm/arch-sunxi/spl.h | 2 --
arch/arm/mach-sunxi/board.c | 20 ++++++++++++++------
include/sunxi_image.h | 14 ++++++++++++++
3 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index 58cdf806d9..157b11e489 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -19,8 +19,6 @@
#define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10
#define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12
-#define is_boot0_magic(addr) (memcmp((void *)(addr), BOOT0_MAGIC, 8) == 0)
-
uint32_t sunxi_get_boot_device(void);
#endif
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 9b84132eda..8147f250f8 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -237,10 +237,13 @@ void s_init(void)
static int sunxi_get_boot_source(void)
{
- if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
- return SUNXI_INVALID_BOOT_SOURCE;
+ if (is_egon_image((void *)SPL_ADDR))
+ return ((struct boot_file_head *)SPL_ADDR)->boot_media;
+ if (is_toc0_image((void *)SPL_ADDR))
+ return ((struct toc0_main_info *)SPL_ADDR)->platform[0];
- return readb(SPL_ADDR + 0x28);
+ /* Not a valid BROM image, so we must have been booted via FEL. */
+ return SUNXI_INVALID_BOOT_SOURCE;
}
/* The sunxi internal brom will try to loader external bootloader
@@ -285,13 +288,18 @@ uint32_t sunxi_get_boot_device(void)
return -1; /* Never reached */
}
+#define is_toc0_magic(foo) true
+
#ifdef CONFIG_SPL_BUILD
static u32 sunxi_get_spl_size(void)
{
- if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
- return 0;
+ if (is_egon_image((void *)SPL_ADDR))
+ return ((struct boot_file_head *)SPL_ADDR)->length;
+ if (is_toc0_image((void *)SPL_ADDR))
+ return ((struct toc0_main_info *)SPL_ADDR)->length;
- return readl(SPL_ADDR + 0x10);
+ /* Unknown size, so fall back to the default offset. */
+ return 0;
}
/*
diff --git a/include/sunxi_image.h b/include/sunxi_image.h
index bdf80ec0e0..b0424b6b7f 100644
--- a/include/sunxi_image.h
+++ b/include/sunxi_image.h
@@ -270,4 +270,18 @@ struct toc0_key_item {
sizeof(struct toc0_key_item), \
32)
+static inline bool is_egon_image(void *addr)
+{
+ struct boot_file_head *head = addr;
+
+ return memcmp(head->magic, BOOT0_MAGIC, 8) == 0;
+}
+
+static inline bool is_toc0_image(void *addr)
+{
+ struct toc0_main_info *main = addr;
+
+ return memcmp(main->name, TOC0_MAIN_INFO_NAME, 8) == 0;
+}
+
#endif
--
2.31.1

View file

@ -0,0 +1,77 @@
From 84fbf777e029e28cf0cd182f8bf5e1c41c3b2c93 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 20 Jun 2021 14:24:29 -0500
Subject: [PATCH 18/29] sunxi: Support building a SPL as a TOC0 image
Now that mkimage can generate TOC0 images, and the SPL can interpret
them, hook up the build infrastructure so the user can choose which
image type to build.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/mach-sunxi/Kconfig | 2 ++
board/sunxi/Kconfig | 24 ++++++++++++++++++++++++
scripts/Makefile.spl | 3 ++-
3 files changed, 28 insertions(+), 1 deletion(-)
create mode 100644 board/sunxi/Kconfig
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index bc8509b72a..4c466325f3 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -1088,6 +1088,8 @@ config BLUETOOTH_DT_DEVICE_FIXUP
The used address is "bdaddr" if set, and "ethaddr" with the LSB
flipped elsewise.
+source "board/sunxi/Kconfig"
+
endif
config CHIP_DIP_SCAN
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
new file mode 100644
index 0000000000..c5c0929db5
--- /dev/null
+++ b/board/sunxi/Kconfig
@@ -0,0 +1,24 @@
+choice
+ prompt "SPL Image Type"
+ default SUNXI_SPL_IMAGE_EGON
+
+config SUNXI_SPL_IMAGE_EGON
+ bool "eGON (non-secure)"
+ help
+ Select this option to embed the SPL binary in an eGON.BT0 image,
+ which is compatible with the non-secure boot ROM (NBROM).
+
+ This is usually the correct option to choose.
+
+config SUNXI_SPL_IMAGE_TOC0
+ bool "TOC0 (secure)"
+ help
+ Select this option to embed the SPL binary in a TOC0 image,
+ which is compatible with the secure boot ROM (SBROM).
+
+endchoice
+
+config SUNXI_SPL_IMAGE_TYPE
+ string
+ default "sunxi_egon" if SUNXI_SPL_IMAGE_EGON
+ default "sunxi_toc0" if SUNXI_SPL_IMAGE_TOC0
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 5be1a9ba1b..7cc78bb318 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -414,7 +414,8 @@ endif
$(obj)/$(SPL_BIN).sfp: $(obj)/$(SPL_BIN).bin FORCE
$(call if_changed,mkimage)
-MKIMAGEFLAGS_sunxi-spl.bin = -T sunxi_egon \
+MKIMAGEFLAGS_sunxi-spl.bin = -T $(CONFIG_SUNXI_SPL_IMAGE_TYPE) \
+ -a $(CONFIG_SPL_TEXT_BASE) \
-n $(CONFIG_DEFAULT_DEVICE_TREE)
OBJCOPYFLAGS_u-boot-spl-dtb.hex := -I binary -O ihex --change-address=$(CONFIG_SPL_TEXT_BASE)
--
2.31.1

View file

@ -0,0 +1,55 @@
From 91ceaa78ab678743d5b998657160dc3f82a99944 Mon Sep 17 00:00:00 2001
From: Andre Przywara <andre.przywara@arm.com>
Date: Wed, 28 Apr 2021 23:53:04 +0100
Subject: [PATCH 19/29] sunxi: H616: Enable full 4GB of DRAM
The H616 is our first supported Allwinner SoC which goes beyond the 4GB
address space "barrier", by having more than 32 address bits.
Lift the preliminary 3GB DRAM limit for the H616, and update the page
table setup on the way, to actually map that last GB as well.
This will presumably break the EMAC, as the DMA descriptors only hold
32 bits worth of addresses, but this is no problem for now, as all
boards with 4GB of DRAM cannot use the EMAC at the moment (missing
PHY support).
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
arch/arm/mach-sunxi/Kconfig | 4 ++--
arch/arm/mach-sunxi/board.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index d409ab3051..b0191d0080 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -191,10 +191,10 @@ config MACH_SUNXI_H3_H5
select SUPPORT_SPL
# TODO: try out A80's 8GiB DRAM space
-# TODO: H616 supports 4 GiB DRAM space
config SUNXI_DRAM_MAX_SIZE
hex
- default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6 || MACH_SUN50I_H616
+ default 0x100000000 if MACH_SUN50I_H616
+ default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6
default 0x80000000
choice
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 8147f250f8..fe9d292e8e 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -56,7 +56,7 @@ static struct mm_region sunxi_mem_map[] = {
/* RAM */
.virt = 0x40000000UL,
.phys = 0x40000000UL,
- .size = 0xC0000000UL,
+ .size = CONFIG_SUNXI_DRAM_MAX_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
--
2.31.1

View file

@ -0,0 +1,36 @@
From 793378573dbb8a3ad041dfd769cd6c23ce61f45a Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 17 Apr 2021 14:21:45 -0500
Subject: [PATCH 20/29] sunxi: DT: H6: Add USB3 to Pine H64 DTS
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sun50i-h6-pine-h64.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/dts/sun50i-h6-pine-h64.dts b/arch/arm/dts/sun50i-h6-pine-h64.dts
index 961732c52a..76f84ad184 100644
--- a/arch/arm/dts/sun50i-h6-pine-h64.dts
+++ b/arch/arm/dts/sun50i-h6-pine-h64.dts
@@ -89,6 +89,10 @@
status = "okay";
};
+&dwc3 {
+ status = "okay";
+};
+
&ehci0 {
status = "okay";
};
@@ -331,3 +335,7 @@
usb3_vbus-supply = <&reg_usb_vbus>;
status = "okay";
};
+
+&usb3phy {
+ status = "okay";
+};
--
2.31.1

View file

@ -0,0 +1,63 @@
From 7342a9cb423ef2f58566387d7cfb9325fce92293 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 17 Apr 2021 14:08:31 -0500
Subject: [PATCH 21/29] sunxi: Select environment MMC based on boot device
Currently, the environment is always stored in eMMC if eMMC is enabled
in the config. This means images written to SD and eMMC will cross-
contaminate their environments unless the configuration is changed.
By dropping the device number from the environment location string and
implementing mmc_get_env_dev, we will always use the environment from
the boot device when booting from SD/eMMC.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
board/sunxi/board.c | 14 ++++++++++++++
env/Kconfig | 3 +--
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 21651a1bfc..b97ca578f7 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -623,6 +623,20 @@ int board_mmc_init(struct bd_info *bis)
return 0;
}
+
+#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
+int mmc_get_env_dev(void)
+{
+ switch (sunxi_get_boot_device()) {
+ case BOOT_DEVICE_MMC1:
+ return 0;
+ case BOOT_DEVICE_MMC2:
+ return 1;
+ default:
+ return CONFIG_SYS_MMC_ENV_DEV;
+ }
+}
+#endif
#endif
#ifdef CONFIG_SPL_BUILD
diff --git a/env/Kconfig b/env/Kconfig
index 1411f9e815..cccde2d855 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -444,10 +444,9 @@ config ENV_FAT_INTERFACE
config ENV_FAT_DEVICE_AND_PART
string "Device and partition for where to store the environemt in FAT"
depends on ENV_IS_IN_FAT
+ default ":auto" if ARCH_SUNXI
default "0:1" if TI_COMMON_CMD_OPTIONS
default "0:auto" if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
- default "0:auto" if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA = -1
- default "1:auto" if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA != -1
default "0" if ARCH_AT91
help
Define this to a string to specify the partition of the device. It can
--
2.31.1

View file

@ -0,0 +1,63 @@
From 8f57cff6cb93478f665564f7ef493b7d85053124 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 17 Apr 2021 10:43:58 -0500
Subject: [PATCH 22/29] sunxi: Load sun8i secure monitor to SRAM A2
Most sun6i-derived SoCs contain SRAM A2, a secure SRAM area for ARISC
SCP firmware. H3 has a smaller SRAM than other SoCs (A31/A33/A23/A83T).
On sun8i SoCs which do not have SRAM B, we can use part of this SRAM for
the secure monitor. Follow the design of 64-bit SoCs and use the first
part for the monitor, and the last 16 KiB for the SCP firmware. With
this change, the monitor no longer needs to reserve a region in DRAM.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 11 +++++++++++
include/configs/sun8i.h | 7 +++++++
2 files changed, 18 insertions(+)
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index 02ce73954d..d4c795d89c 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -11,7 +11,18 @@
#define SUNXI_SRAM_A1_BASE 0x00000000
#define SUNXI_SRAM_A1_SIZE (16 * 1024) /* 16 kiB */
+#if defined(CONFIG_SUNXI_GEN_SUN6I) && \
+ !defined(CONFIG_MACH_SUN8I_R40) && \
+ !defined(CONFIG_MACH_SUN8I_V3S)
+#define SUNXI_SRAM_A2_BASE 0x00040000
+#ifdef CONFIG_MACH_SUN8I_H3
+#define SUNXI_SRAM_A2_SIZE (48 * 1024) /* 16+32 kiB */
+#else
+#define SUNXI_SRAM_A2_SIZE (80 * 1024) /* 16+64 kiB */
+#endif
+#else
#define SUNXI_SRAM_A2_BASE 0x00004000 /* 16 kiB */
+#endif
#define SUNXI_SRAM_A3_BASE 0x00008000 /* 13 kiB */
#define SUNXI_SRAM_A4_BASE 0x0000b400 /* 3 kiB */
#define SUNXI_SRAM_D_BASE 0x00010000 /* 4 kiB */
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
index 9b4675e4c3..545d27996c 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.h
@@ -12,6 +12,13 @@
* A23 specific configuration
*/
+/*
+ * Skip the first 16 KiB of SRAM A2, which is not usable, as only certain bytes
+ * are writable. Reserve the last 17 KiB for the resume shim and SCP firmware.
+ */
+#define CONFIG_ARMV7_SECURE_BASE (SUNXI_SRAM_A2_BASE + 16 * 1024)
+#define CONFIG_ARMV7_SECURE_MAX_SIZE (SUNXI_SRAM_A2_SIZE - 33 * 1024)
+
/*
* Include common sunxi configuration where most the settings are
*/
--
2.31.1

View file

@ -0,0 +1,177 @@
From 0612580e68fa584d415f8080f65da2d4873664fe Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Tue, 11 Feb 2020 14:10:05 +0100
Subject: [PATCH 23/29] pinephone: Add volume_key environment variable
When the user has a volume key pressed volume_key variable will
contain either value 'down' or 'up', otherwise it will be empty.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
board/sunxi/Makefile | 1 +
board/sunxi/board.c | 18 ++++++++++
board/sunxi/lradc.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
board/sunxi/lradc.h | 11 ++++++
4 files changed, 111 insertions(+)
create mode 100644 board/sunxi/lradc.c
create mode 100644 board/sunxi/lradc.h
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index d96b7897b6..a096a5c771 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_MACH_SUN4I) += dram_sun4i_auto.o
obj-$(CONFIG_MACH_SUN5I) += dram_sun5i_auto.o
obj-$(CONFIG_MACH_SUN7I) += dram_sun5i_auto.o
obj-$(CONFIG_CHIP_DIP_SCAN) += chip.o
+obj-$(CONFIG_MACH_SUN50I) += lradc.o
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index b97ca578f7..2bc9883092 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -46,6 +46,7 @@
#include <spl.h>
#include <sy8106a.h>
#include <asm/setup.h>
+#include "lradc.h"
#if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
/* So that we can use pin names in Kconfig and sunxi_name_to_gpio() */
@@ -659,6 +660,12 @@ void sunxi_board_init(void)
{
int power_failed = 0;
+#ifdef CONFIG_MACH_SUN50I
+ // we init the lradc in SPL to get the ADC started early to have
+ // a valid sample when U-Boot main binary gets executed.
+ lradc_enable();
+#endif
+
#ifdef CONFIG_SY8106A_POWER
power_failed = sy8106a_set_vout1(CONFIG_SY8106A_VOUT1_VOLT);
#endif
@@ -933,6 +940,17 @@ int misc_init_r(void)
env_set("fdtfile", str);
}
+#ifdef CONFIG_MACH_SUN50I
+ int key = lradc_get_pressed_key();
+ if (key == KEY_VOLUMEDOWN)
+ env_set("volume_key", "down");
+ else if (key == KEY_VOLUMEUP)
+ env_set("volume_key", "up");
+
+ // no longer needed
+ lradc_disable();
+#endif
+
setup_environment(gd->fdt_blob);
return 0;
diff --git a/board/sunxi/lradc.c b/board/sunxi/lradc.c
new file mode 100644
index 0000000000..693b198e25
--- /dev/null
+++ b/board/sunxi/lradc.c
@@ -0,0 +1,81 @@
+#include <common.h>
+#include <asm/io.h>
+#include "lradc.h"
+
+#define LRADC_BASE 0x1c21800
+
+#define LRADC_CTRL (LRADC_BASE + 0x00)
+#define LRADC_INTC (LRADC_BASE + 0x04)
+#define LRADC_INTS (LRADC_BASE + 0x08)
+#define LRADC_DATA0 (LRADC_BASE + 0x0c)
+#define LRADC_DATA1 (LRADC_BASE + 0x10)
+
+/* LRADC_CTRL bits */
+#define FIRST_CONVERT_DLY(x) ((x) << 24) /* 8 bits */
+#define CHAN_SELECT(x) ((x) << 22) /* 2 bits */
+#define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */
+#define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */
+#define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */
+#define HOLD_KEY_EN(x) ((x) << 7)
+#define HOLD_EN(x) ((x) << 6)
+#define LEVELB_VOL(x) ((x) << 4) /* 2 bits */
+#define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */
+#define ENABLE(x) ((x) << 0)
+
+/* LRADC_INTC and LRADC_INTS bits */
+#define CHAN1_KEYUP_IRQ BIT(12)
+#define CHAN1_ALRDY_HOLD_IRQ BIT(11)
+#define CHAN1_HOLD_IRQ BIT(10)
+#define CHAN1_KEYDOWN_IRQ BIT(9)
+#define CHAN1_DATA_IRQ BIT(8)
+#define CHAN0_KEYUP_IRQ BIT(4)
+#define CHAN0_ALRDY_HOLD_IRQ BIT(3)
+#define CHAN0_HOLD_IRQ BIT(2)
+#define CHAN0_KEYDOWN_IRQ BIT(1)
+#define CHAN0_DATA_IRQ BIT(0)
+
+// this is for PinePhone only
+
+int lradc_get_pressed_key(void)
+{
+ uint32_t val;
+ uint32_t vref = 3000000 * 2 / 3;
+
+ val = readl(LRADC_DATA0) & 0x3f;
+ val = val * vref / 63;
+
+// printf("lradc=%u\n", val);
+
+ if (val < 200000) // 158730
+ return KEY_VOLUMEUP;
+ else if (val < 400000) // 349206
+ return KEY_VOLUMEDOWN;
+
+ return 0;
+}
+
+void lradc_enable(void)
+{
+ // aldo3 is always on and defaults to 3V
+
+ writel(0xffffffff, LRADC_INTS);
+ writel(0, LRADC_INTC);
+
+ /*
+ * Set sample time to 4 ms / 250 Hz. Wait 2 * 4 ms for key to
+ * stabilize on press, wait (1 + 1) * 4 ms for key release
+ */
+ writel(FIRST_CONVERT_DLY(0) | LEVELA_B_CNT(0) | HOLD_EN(0) |
+ SAMPLE_RATE(0) | ENABLE(1), LRADC_CTRL);
+
+}
+
+void lradc_disable(void)
+{
+ writel(0xffffffff, LRADC_INTS);
+ writel(0, LRADC_INTC);
+
+ /* Disable lradc, leave other settings unchanged */
+ writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) |
+ SAMPLE_RATE(2), LRADC_CTRL);
+}
diff --git a/board/sunxi/lradc.h b/board/sunxi/lradc.h
new file mode 100644
index 0000000000..c908401b5b
--- /dev/null
+++ b/board/sunxi/lradc.h
@@ -0,0 +1,11 @@
+#pragma once
+
+enum {
+ KEY_NONE = 0,
+ KEY_VOLUMEDOWN = 1,
+ KEY_VOLUMEUP = 2,
+};
+
+int lradc_get_pressed_key(void);
+void lradc_enable(void);
+void lradc_disable(void);
--
2.31.1

View file

@ -0,0 +1,58 @@
From bbb3d10356bcbf931a63a70610f1e7869eeebd21 Mon Sep 17 00:00:00 2001
From: Marius Gripsgard <marius@ubports.com>
Date: Tue, 5 May 2020 16:51:13 +0200
Subject: [PATCH 24/29] Enable led on boot to notify user of boot status
---
arch/arm/mach-sunxi/Kconfig | 5 +++++
board/sunxi/board.c | 6 ++++++
configs/pinephone_defconfig | 1 +
3 files changed, 12 insertions(+)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index b0191d0080..7a46bb4481 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -1,5 +1,10 @@
if ARCH_SUNXI
+config PINEPHONE_LEDS
+ bool "Notify boot status via LEDs on PinePhone"
+ ---help---
+ LED boot notification.
+
config SPL_LDSCRIPT
default "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds" if !ARM64
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 2bc9883092..59f7c2c5f1 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -666,6 +666,12 @@ void sunxi_board_init(void)
lradc_enable();
#endif
+#ifdef CONFIG_PINEPHONE_LEDS
+ /* PD18:G PD19:R PD20:B */
+ gpio_request(SUNXI_GPD(19), "led:red");
+ gpio_direction_output(SUNXI_GPD(19), 1);
+#endif
+
#ifdef CONFIG_SY8106A_POWER
power_failed = sy8106a_set_vout1(CONFIG_SY8106A_VOUT1_VOLT);
#endif
diff --git a/configs/pinephone_defconfig b/configs/pinephone_defconfig
index 64ecef59c9..623265d719 100644
--- a/configs/pinephone_defconfig
+++ b/configs/pinephone_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_SUNXI=y
CONFIG_SPL=y
+CONFIG_PINEPHONE_LEDS=y
CONFIG_MACH_SUN50I=y
CONFIG_SUNXI_DRAM_LPDDR3_STOCK=y
CONFIG_DRAM_CLK=552
--
2.31.1

View file

@ -0,0 +1,21 @@
From 89cb280f35abc0f2b0b66ddec035d1ebf1674e64 Mon Sep 17 00:00:00 2001
From: Marius Gripsgard <marius@ubports.com>
Date: Mon, 4 May 2020 22:28:42 +0200
Subject: [PATCH 25/29] disable bootdelay
---
configs/pinephone_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/configs/pinephone_defconfig b/configs/pinephone_defconfig
index 623265d719..d8ee930a69 100644
--- a/configs/pinephone_defconfig
+++ b/configs/pinephone_defconfig
@@ -11,3 +11,4 @@ CONFIG_PINEPHONE_DT_SELECTION=y
CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-pinephone-1.2"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_OF_LIST="sun50i-a64-pinephone-1.1 sun50i-a64-pinephone-1.2"
+CONFIG_BOOTDELAY=0
--
2.31.1

View file

@ -0,0 +1,26 @@
From 880f5035decae44a5be943875f35ed9d9efc011d Mon Sep 17 00:00:00 2001
From: Dalton Durst <dalton@ubports.com>
Date: Wed, 10 Mar 2021 11:44:07 -0600
Subject: [PATCH 26/29] Reduce DRAM speed to 528 for better compatibility with
all PinePhones
---
configs/pinephone_defconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configs/pinephone_defconfig b/configs/pinephone_defconfig
index d8ee930a69..702e2bdc14 100644
--- a/configs/pinephone_defconfig
+++ b/configs/pinephone_defconfig
@@ -4,7 +4,7 @@ CONFIG_SPL=y
CONFIG_PINEPHONE_LEDS=y
CONFIG_MACH_SUN50I=y
CONFIG_SUNXI_DRAM_LPDDR3_STOCK=y
-CONFIG_DRAM_CLK=552
+CONFIG_DRAM_CLK=528
CONFIG_DRAM_ZQ=3881949
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_PINEPHONE_DT_SELECTION=y
--
2.31.1

View file

@ -0,0 +1,354 @@
From b0950e4696b391578f7428337e41fa8ca14b225d Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Wed, 11 Sep 2019 20:45:28 +0200
Subject: [PATCH 27/29] mmc: sunxi: Add support for DMA transfers
Allwinner MMC controller supports DMA via internal DMA controller,
use it.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
arch/arm/include/asm/arch-sunxi/mmc.h | 7 +
drivers/mmc/sunxi_mmc.c | 204 +++++++++++++++++++++++---
2 files changed, 192 insertions(+), 19 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
index 5daacf10eb..dc8ea6f43a 100644
--- a/arch/arm/include/asm/arch-sunxi/mmc.h
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -112,6 +112,10 @@ struct sunxi_mmc {
SUNXI_MMC_RINT_COMMAND_DONE | \
SUNXI_MMC_RINT_VOLTAGE_CHANGE_DONE)
+#define SUNXI_MMC_FTRGLEVEL_BURST_SIZE(v) (((v) & 0x7) << 28)
+#define SUNXI_MMC_FTRGLEVEL_RX_TL(v) (((v) & 0xfff) << 16)
+#define SUNXI_MMC_FTRGLEVEL_TX_TL(v) (((v) & 0xffff) << 0)
+
#define SUNXI_MMC_STATUS_RXWL_FLAG (0x1 << 0)
#define SUNXI_MMC_STATUS_TXWL_FLAG (0x1 << 1)
#define SUNXI_MMC_STATUS_FIFO_EMPTY (0x1 << 2)
@@ -130,6 +134,9 @@ struct sunxi_mmc {
#define SUNXI_MMC_IDIE_TXIRQ (0x1 << 0)
#define SUNXI_MMC_IDIE_RXIRQ (0x1 << 1)
+#define SUNXI_MMC_IDST_TXIRQ (0x1 << 0)
+#define SUNXI_MMC_IDST_RXIRQ (0x1 << 1)
+
#define SUNXI_MMC_COMMON_CLK_GATE (1 << 16)
#define SUNXI_MMC_COMMON_RESET (1 << 18)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 28af8e6ac5..47c947cdb8 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -9,6 +9,7 @@
#include <common.h>
#include <dm.h>
+#include <cpu_func.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
@@ -27,6 +28,27 @@
#define CCM_MMC_CTRL_MODE_SEL_NEW 0
#endif
+#define DMA_CONFIG_DIC BIT(1) // flag: disable interrupt after this descriptor's buffer is processed
+#define DMA_CONFIG_LAST BIT(2) // flag: last descriptor
+#define DMA_CONFIG_FIRST BIT(3) // flag: first descriptor
+#define DMA_CONFIG_CHAIN BIT(4) // flag: buf_addr_ptr2 points to next descriptor
+#define DMA_CONFIG_ERROR BIT(30) // flag: out: error happened
+#define DMA_CONFIG_HOLD BIT(31) // flag: desc owned by IDMAC (set to 1)
+
+#if defined(CONFIG_MACH_SUN50I)
+// mmc2 on A64 only allows for 8k
+#define DMA_BUF_MAX_SIZE (1 << 13)
+#else
+#define DMA_BUF_MAX_SIZE (1 << 16)
+#endif
+
+struct sunxi_idma_desc {
+ u32 config;
+ u32 buf_size;
+ u32 buf_addr_ptr1;
+ u32 buf_addr_ptr2;
+};
+
struct sunxi_mmc_plat {
struct mmc_config cfg;
struct mmc mmc;
@@ -39,6 +61,8 @@ struct sunxi_mmc_priv {
struct gpio_desc cd_gpio; /* Change Detect GPIO */
struct sunxi_mmc *reg;
struct mmc_config cfg;
+ unsigned n_dma_descs;
+ struct sunxi_idma_desc* dma_descs;
};
#if !CONFIG_IS_ENABLED(DM_MMC)
@@ -318,7 +342,7 @@ static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc,
if (timeout_msecs < 2000)
timeout_msecs = 2000;
- /* Always read / write data through the CPU */
+ /* Read / write data through the CPU */
setbits_le32(&priv->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
start = get_timer(0);
@@ -328,7 +352,7 @@ static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc,
while ((status = readl(&priv->reg->status)) & status_bit) {
if (get_timer(start) > timeout_msecs)
- return -1;
+ return -ETIMEDOUT;
}
/*
@@ -360,21 +384,142 @@ static int mmc_trans_data_by_cpu(struct sunxi_mmc_priv *priv, struct mmc *mmc,
return 0;
}
+static void flush_cache_auto_align(void* buf, size_t len)
+{
+ uintptr_t mask = ~((uintptr_t)CONFIG_SYS_CACHELINE_SIZE - 1);
+ uintptr_t start = (uintptr_t)buf & mask;
+
+ len = (len + 2 * CONFIG_SYS_CACHELINE_SIZE) & mask;
+
+ flush_cache(start, len);
+}
+
+static int mmc_trans_data_by_dma(struct sunxi_mmc_priv *priv, struct mmc *mmc,
+ struct mmc_data *data)
+{
+ const int reading = !!(data->flags & MMC_DATA_READ);
+ uint8_t *buff = (uint8_t*)(reading ? data->dest : data->src);
+ unsigned byte_cnt = data->blocksize * data->blocks;
+ unsigned i, n_desc, last_block_size;
+ u32 rval;
+
+ /* data pointer and transfer size needs to be aligned to 4 bytes */
+
+ /* Read / write data through IDMAC */
+ clrbits_le32(&priv->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB);
+
+ n_desc = byte_cnt / DMA_BUF_MAX_SIZE;
+ last_block_size = byte_cnt % DMA_BUF_MAX_SIZE;
+ if (last_block_size)
+ n_desc++;
+
+ if (n_desc > priv->n_dma_descs)
+ return -ENOMEM;
+
+ memset(priv->dma_descs, 0, sizeof(struct sunxi_idma_desc) * n_desc);
+
+ for (i = 0; i < n_desc; i++) {
+ struct sunxi_idma_desc* desc = &priv->dma_descs[i];
+ bool is_last = i == n_desc - 1;
+ bool is_first = i == 0;
+
+ desc->config = DMA_CONFIG_CHAIN | DMA_CONFIG_HOLD
+ | (is_last ? DMA_CONFIG_LAST : DMA_CONFIG_DIC)
+ | (is_first ? DMA_CONFIG_FIRST : 0);
+
+ if (is_last && last_block_size)
+ desc->buf_size = last_block_size;
+ else
+ desc->buf_size = DMA_BUF_MAX_SIZE;
+
+ desc->buf_addr_ptr1 = (uintptr_t)buff + i * DMA_BUF_MAX_SIZE;
+ if (!is_last)
+ desc->buf_addr_ptr2 = (uintptr_t)(desc + 1);
+ }
+
+ /*
+ * Make sure everyhting needed for a transfer is in DRAM.
+ */
+
+ flush_cache_auto_align(buff, byte_cnt);
+ flush_cache_auto_align(priv->dma_descs,
+ sizeof(struct sunxi_idma_desc) * n_desc);
+
+ dsb();
+ isb();
+
+ /* dma enable */
+ setbits_le32(&priv->reg->gctrl, SUNXI_MMC_GCTRL_DMA_RESET
+ | SUNXI_MMC_GCTRL_DMA_ENABLE);
+
+ /* idma reset */
+ writel(SUNXI_MMC_IDMAC_RESET, &priv->reg->dmac);
+
+ /* wait idma reset done */
+ while (readl(&priv->reg->dmac) & SUNXI_MMC_IDMAC_RESET);
+
+ /* idma on */
+ writel(SUNXI_MMC_IDMAC_ENABLE | SUNXI_MMC_IDMAC_FIXBURST,
+ &priv->reg->dmac);
+
+ /* enable interrupt flags */
+ rval = readl(&priv->reg->idie)
+ & ~(SUNXI_MMC_IDIE_RXIRQ | SUNXI_MMC_IDIE_TXIRQ);
+ rval |= reading ? SUNXI_MMC_IDIE_RXIRQ : SUNXI_MMC_IDIE_TXIRQ;
+ writel(rval, &priv->reg->idie);
+
+ /* set address of the first descriptor */
+ writel((uintptr_t)priv->dma_descs, &priv->reg->dlba);
+
+ /* set fifo fill tresholds for issuing dma */
+
+#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H6)
+ if (priv->mmc_no == 2) {
+ // for mmc 2 we need to set this differently
+ writel(SUNXI_MMC_FTRGLEVEL_BURST_SIZE(3) // burst-16
+ | SUNXI_MMC_FTRGLEVEL_RX_TL(15)
+ | SUNXI_MMC_FTRGLEVEL_TX_TL(240),
+ &priv->reg->ftrglevel);
+ } else {
+ writel(SUNXI_MMC_FTRGLEVEL_BURST_SIZE(2) // burst-8
+ | SUNXI_MMC_FTRGLEVEL_RX_TL(7)
+ | SUNXI_MMC_FTRGLEVEL_TX_TL(248),
+ &priv->reg->ftrglevel);
+ }
+#else
+ writel(SUNXI_MMC_FTRGLEVEL_BURST_SIZE(2) // burst-8
+ | SUNXI_MMC_FTRGLEVEL_RX_TL(7)
+ | SUNXI_MMC_FTRGLEVEL_TX_TL(8),
+ &priv->reg->ftrglevel);
+#endif
+
+ writel(0xffffffff, &priv->reg->idst);
+
+ return 0;
+}
+
static int mmc_rint_wait(struct sunxi_mmc_priv *priv, struct mmc *mmc,
- uint timeout_msecs, uint done_bit, const char *what)
+ uint timeout_msecs, uint done_bit, bool wait_dma,
+ const char *what)
{
unsigned int status;
unsigned long start = get_timer(0);
+ bool dma_done = true;
do {
status = readl(&priv->reg->rint);
+
if ((get_timer(start) > timeout_msecs) ||
(status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT)) {
debug("%s timeout %x\n", what,
status & SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT);
return -ETIMEDOUT;
}
- } while (!(status & done_bit));
+
+ if (wait_dma)
+ dma_done = readl(&priv->reg->idst)
+ & (SUNXI_MMC_IDST_TXIRQ | SUNXI_MMC_IDST_RXIRQ);
+ } while (!(status & done_bit) || !dma_done);
return 0;
}
@@ -388,6 +533,7 @@ static int sunxi_mmc_send_cmd_common(struct sunxi_mmc_priv *priv,
int error = 0;
unsigned int status = 0;
unsigned int bytecnt = 0;
+ bool usedma = false;
if (priv->fatal_err)
return -1;
@@ -424,42 +570,45 @@ static int sunxi_mmc_send_cmd_common(struct sunxi_mmc_priv *priv,
cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg);
writel(cmd->cmdarg, &priv->reg->arg);
- if (!data)
- writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
-
/*
* transfer data and check status
* STATREG[2] : FIFO empty
* STATREG[3] : FIFO full
*/
if (data) {
- int ret = 0;
-
bytecnt = data->blocksize * data->blocks;
debug("trans data %d bytes\n", bytecnt);
- writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
- ret = mmc_trans_data_by_cpu(priv, mmc, data);
- if (ret) {
- error = readl(&priv->reg->rint) &
- SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT;
- error = -ETIMEDOUT;
- goto out;
+
+ if (bytecnt > 64 && !IS_ENABLED(SPL_BUILD)) {
+ debug(" using dma %d\n", bytecnt);
+ error = mmc_trans_data_by_dma(priv, mmc, data);
+ writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
+ usedma = true;
+ } else {
+ debug(" using pio\n");
+ writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
+ error = mmc_trans_data_by_cpu(priv, mmc, data);
}
+
+ if (error)
+ goto out;
+ } else {
+ writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
}
error = mmc_rint_wait(priv, mmc, 1000, SUNXI_MMC_RINT_COMMAND_DONE,
- "cmd");
+ false, "cmd");
if (error)
goto out;
if (data) {
- timeout_msecs = 120;
+ timeout_msecs = 10000;
debug("cacl timeout %x msec\n", timeout_msecs);
error = mmc_rint_wait(priv, mmc, timeout_msecs,
data->blocks > 1 ?
SUNXI_MMC_RINT_AUTO_COMMAND_DONE :
SUNXI_MMC_RINT_DATA_OVER,
- "data");
+ usedma, "data");
if (error)
goto out;
}
@@ -491,6 +640,14 @@ static int sunxi_mmc_send_cmd_common(struct sunxi_mmc_priv *priv,
debug("mmc resp 0x%08x\n", cmd->response[0]);
}
out:
+ if (data && usedma) {
+ //status = readl(&reg->idst);
+ writel(0, &priv->reg->idie);
+ writel(0xffffffff, &priv->reg->idst);
+ writel(0, &priv->reg->dmac);
+ clrbits_le32(&priv->reg->gctrl, SUNXI_MMC_GCTRL_DMA_ENABLE);
+ }
+
if (error < 0) {
writel(SUNXI_MMC_GCTRL_RESET, &priv->reg->gctrl);
mmc_update_clk(priv);
@@ -674,6 +831,15 @@ static int sunxi_mmc_probe(struct udevice *dev)
priv->reg = dev_read_addr_ptr(dev);
+ // make sure we have enough space for descritors for BLK_SIZE * b_max
+ priv->n_dma_descs = 512 * 65536 / DMA_BUF_MAX_SIZE;
+ priv->dma_descs = malloc(sizeof(struct sunxi_idma_desc)
+ * priv->n_dma_descs);
+ if (priv->dma_descs == NULL) {
+ debug("init mmc alloc failed\n");
+ return -ENOMEM;
+ }
+
/* We don't have a sunxi clock driver so find the clock address here */
ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
1, &args);
--
2.31.1

View file

@ -0,0 +1,50 @@
From 1af4c86329397bc553122c650226bd5c7acb1ed0 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Fri, 13 Sep 2019 22:14:43 +0200
Subject: [PATCH 28/29] mmc: sunxi: DDR/DMA support for SPL
---
drivers/mmc/sunxi_mmc.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
index 47c947cdb8..855dfd35d9 100644
--- a/drivers/mmc/sunxi_mmc.c
+++ b/drivers/mmc/sunxi_mmc.c
@@ -579,7 +579,12 @@ static int sunxi_mmc_send_cmd_common(struct sunxi_mmc_priv *priv,
bytecnt = data->blocksize * data->blocks;
debug("trans data %d bytes\n", bytecnt);
- if (bytecnt > 64 && !IS_ENABLED(SPL_BUILD)) {
+ // DMA doesn't work when the target is SRAM for some reason.
+ int reading = !!(data->flags & MMC_DATA_READ);
+ uint8_t* buf = (uint8_t*)(reading ? data->dest : data->src);
+ bool is_dram = (uintptr_t)buf >= 0x4000000;
+
+ if (bytecnt > 64 && is_dram) {
debug(" using dma %d\n", bytecnt);
error = mmc_trans_data_by_dma(priv, mmc, data);
writel(cmdval | cmd->cmdidx, &priv->reg->cmd);
@@ -715,10 +720,19 @@ struct mmc *sunxi_mmc_init(int sdc_no)
cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+ if (sdc_no == 2)
+ cfg->host_caps |= MMC_MODE_DDR_52MHz;
cfg->f_min = 400000;
cfg->f_max = 52000000;
+ // enough descs for a realy big u-boot (4MiB)
+ priv->n_dma_descs = 4*1024*1024 / DMA_BUF_MAX_SIZE;
+ priv->dma_descs = malloc(sizeof(struct sunxi_idma_desc)
+ * priv->n_dma_descs);
+ if (priv->dma_descs == NULL)
+ return NULL;
+
if (mmc_resource_init(sdc_no) != 0)
return NULL;
--
2.31.1

View file

@ -0,0 +1,148 @@
From 6ad822cb4d64beda76cade8761c49b55620a8b5b Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Tue, 14 Jan 2020 03:56:32 +0100
Subject: [PATCH 29/29] spl: ARM: Enable CPU caches
http://u-boot.10912.n7.nabble.com/RFC-PATCH-0-3-spl-Add-D-cache-support-td274750.html
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
arch/arm/lib/cache-cp15.c | 29 ++++++++++++++++++++++++
common/spl/spl.c | 46 +++++++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index aab1bf4360..c2fe0acdc4 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -116,6 +116,25 @@ __weak void dram_bank_mmu_setup(int bank)
set_section_dcache(i, DCACHE_DEFAULT_OPTION);
}
+#if defined(CONFIG_SPL_BUILD) && (defined(CONFIG_SPL_MAX_SIZE) || \
+ defined(CONFIG_SPL_MAX_FOOTPRINT))
+__weak void sram_bank_mmu_setup(phys_addr_t start, phys_addr_t size)
+{
+ int i;
+
+ for (i = start >> MMU_SECTION_SHIFT;
+ i < (start >> MMU_SECTION_SHIFT) + (size >> MMU_SECTION_SHIFT);
+ i++)
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+ set_section_dcache(i, DCACHE_WRITETHROUGH);
+#elif defined(CONFIG_SYS_ARM_CACHE_WRITEALLOC)
+ set_section_dcache(i, DCACHE_WRITEALLOC);
+#else
+ set_section_dcache(i, DCACHE_WRITEBACK);
+#endif
+}
+#endif
+
/* to activate the MMU we need to set up virtual memory: use 1M areas */
static inline void mmu_setup(void)
{
@@ -131,6 +150,16 @@ static inline void mmu_setup(void)
dram_bank_mmu_setup(i);
}
+#if defined(CONFIG_SPL_BUILD)
+#if defined(CONFIG_SPL_MAX_SIZE)
+ sram_bank_mmu_setup(CONFIG_SPL_TEXT_BASE,
+ ALIGN(CONFIG_SPL_MAX_SIZE, MMU_SECTION_SIZE));
+#elif defined(CONFIG_SPL_MAX_FOOTPRINT)
+ sram_bank_mmu_setup(CONFIG_SPL_TEXT_BASE,
+ ALIGN(CONFIG_SPL_MAX_FOOTPRINT, MMU_SECTION_SIZE));
+#endif
+#endif
+
#if defined(CONFIG_ARMV7_LPAE) && __LINUX_ARM_ARCH__ != 4
/* Set up 4 PTE entries pointing to our 4 1GB page tables */
for (i = 0; i < 4; i++) {
diff --git a/common/spl/spl.c b/common/spl/spl.c
index a0a608fd77..40c9022928 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -10,6 +10,7 @@
#include <bloblist.h>
#include <binman_sym.h>
#include <bootstage.h>
+#include <cpu_func.h>
#include <dm.h>
#include <handoff.h>
#include <hang.h>
@@ -636,6 +637,35 @@ void board_init_f(ulong dummy)
}
#endif
+#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
+ defined(CONFIG_ARM)
+int reserve_mmu(void)
+{
+ phys_addr_t ram_top = 0;
+ /* reserve TLB table */
+ gd->arch.tlb_size = PGTABLE_SIZE;
+
+#ifdef CONFIG_SYS_SDRAM_BASE
+ ram_top = CONFIG_SYS_SDRAM_BASE;
+#endif
+ ram_top += get_effective_memsize();
+ gd->arch.tlb_addr = ram_top - gd->arch.tlb_size;
+ debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr,
+ gd->arch.tlb_addr + gd->arch.tlb_size);
+ return 0;
+}
+
+__weak int dram_init_banksize(void)
+{
+#if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE)
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ gd->bd->bi_dram[0].size = get_effective_memsize();
+#endif
+ return 0;
+}
+
+#endif
+
void board_init_r(gd_t *dummy1, ulong dummy2)
{
u32 spl_boot_list[] = {
@@ -651,6 +681,12 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
debug(">>" SPL_TPL_PROMPT "board_init_r()\n");
spl_set_bd();
+#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
+ defined(CONFIG_ARM)
+ dram_init_banksize();
+ reserve_mmu();
+ enable_caches();
+#endif
#if defined(CONFIG_SYS_SPL_MALLOC_START)
mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
@@ -661,6 +697,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
if (spl_init())
hang();
}
+ if (IS_ENABLED(CONFIG_SPL_ALLOC_BD) && spl_alloc_bd()) {
+ puts("Cannot alloc bd\n");
+ hang();
+ }
+
#if !defined(CONFIG_PPC) && !defined(CONFIG_ARCH_MX6)
/*
* timer_init() does not exist on PPC systems. The timer is initialized
@@ -728,6 +769,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
ret);
}
+#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
+ defined(CONFIG_ARM)
+ cleanup_before_linux();
+#endif
+
#ifdef CONFIG_CPU_V7M
spl_image.entry_point |= 0x1;
#endif
--
2.31.1

View file

@ -1,18 +1,19 @@
From b94ee51a5d818e55b3288d2fa3cbc27837981307 Mon Sep 17 00:00:00 2001
From a568d5efe609fec974d44fec4cba31288ab0f621 Mon Sep 17 00:00:00 2001
From: Bobby The Builder <bob@najdan.com>
Date: Mon, 29 Mar 2021 16:42:07 -0400
Subject: [PATCH] expose DRAM clock speed
Subject: [PATCH 4/5] common: expose DRAM clock speed
add memory/ram_freq
---
common/board_f.c | 6 ++++--
common/main.c | 7 +++++++
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c
index 9f441c44f1..8e005337e6 100644
index 0cddf0359d..e481c70ef0 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -226,12 +226,14 @@ static int show_dram_config(void)
@@ -227,12 +227,14 @@ static int show_dram_config(void)
print_size(gd->bd->bi_dram[i].size, "\n");
#endif
}
@ -30,17 +31,17 @@ index 9f441c44f1..8e005337e6 100644
}
diff --git a/common/main.c b/common/main.c
index 4b3cd302c3..1dbb44060d 100644
index ae5bcdb32f..85adcc6c13 100644
--- a/common/main.c
+++ b/common/main.c
@@ -45,6 +45,13 @@ void main_loop(void)
@@ -46,6 +46,13 @@ void main_loop(void)
if (IS_ENABLED(CONFIG_VERSION_VARIABLE))
env_set("ver", version_string); /* set version variable */
+#if defined(CONFIG_DRAM_CLK)
+ char ram_clk_string[11];
+ sprintf(ram_clk_string, "%d", CONFIG_DRAM_CLK);
+ int ret = env_set("ram_freq", ram_clk_string);
+ env_set("ram_freq", ram_clk_string);
+ printf("Set ram_freq : %s\n", ram_clk_string);
+#endif
+
@ -48,5 +49,5 @@ index 4b3cd302c3..1dbb44060d 100644
if (IS_ENABLED(CONFIG_USE_PREBOOT))
--
2.30.2
2.31.1

View file

@ -1,23 +1,49 @@
# U-boot with patches to make the PinePhone boot faster and have control over the ddr clock speed
pkgname=u-boot-pinephone
pkgver=2021.01_git20201228
pkgrel=4
# Last commit from "crust" branch, as used in "crust-meta":
# https://gitlab.com/pine64-org/crust-meta/-/blob/8886bcc829179bf77216fade71f0ede9bd014e67/Makefile#L78
_commit="7492749fec31b1086bc8933bf113a766aea021aa"
pkgdesc="u-boot bootloader for the PINE64 PinePhone"
url="https://gitlab.com/pine64-org/u-boot"
pkgver=2021.07
pkgrel=0
pkgdesc="U-Boot bootloader for the PINE64 PinePhone"
url="https://source.denx.de/u-boot"
arch="aarch64"
license="GPL-2.0-or-later OFL-1.1 BSD-2-Clause BSD-3-Clause eCos-2.0 IBM-pibs
ISC LGPL-2.0-only LGPL-2.1-only X11"
depends="linux-postmarketos-allwinner>=5.12"
makedepends="$depends_dev bc dtc python3-dev py3-setuptools swig bison flex openssl-dev arm-trusted-firmware-sun50i crust"
makedepends="$depends_dev bc dtc python3-dev py3-setuptools swig bison flex openssl-dev arm-trusted-firmware crust"
options="!check"
source="https://gitlab.com/pine64-org/u-boot/-/archive/$_commit/u-boot-$_commit.tar.gz
0001-expose-DRAM-clock-speed.patch
source="https://source.denx.de/u-boot/u-boot/-/archive/v$pkgver/u-boot-v$pkgver.tar.gz
update-u-boot
0001-mmc-sunxi-Avoid-ifdefs-in-delay-and-width-setup.patch
0002-mmc-sunxi-Fix-warnings-with-CONFIG_PHYS_64BIT.patch
0003-mmc-sunxi-Fix-MMC-clock-parent-selection.patch
0004-mmc-sunxi-Cleanup-new-timing-mode-selection.patch
0005-mmc-sunxi-Enable-new-timing-mode-on-all-new-SoCs.patch
0006-mmc-sunxi-Cleanup-and-fix-self-calibration-code.patch
0007-mmc-sunxi-Increase-MMIO-FIFO-read-performance.patch
0008-mmc-sunxi-Use-mmc_of_parse.patch
0009-sunxi-DT-H5-update-device-tree-files.patch
0010-sunxi-DT-H6-update-device-tree-files.patch
0011-phy-sun50i-usb3-Add-a-driver-for-the-H6-USB3-PHY.patch
0012-usb-xhci-pci-Move-reset-logic-out-of-XHCI-core.patch
0013-usb-xhci-dwc3-Add-support-for-clocks-resets.patch
0014-configs-Enable-USB3-on-Allwinner-H6-boards.patch
0015-tools-Refactor-mkimage-linking-with-OpenSSL.patch
0016-tools-mkimage-Add-Allwinner-TOC0-support.patch
0017-sunxi-Support-both-SPL-image-types.patch
0018-sunxi-Support-building-a-SPL-as-a-TOC0-image.patch
0019-sunxi-H616-Enable-full-4GB-of-DRAM.patch
0020-sunxi-DT-H6-Add-USB3-to-Pine-H64-DTS.patch
0021-sunxi-Select-environment-MMC-based-on-boot-device.patch
0022-sunxi-Load-sun8i-secure-monitor-to-SRAM-A2.patch
0023-pinephone-Add-volume_key-environment-variable.patch
0024-Enable-led-on-boot-to-notify-user-of-boot-status.patch
0025-disable-bootdelay.patch
0026-Reduce-DRAM-speed-to-528-for-better-compatibility-wi.patch
0027-mmc-sunxi-Add-support-for-DMA-transfers.patch
0028-mmc-sunxi-DDR-DMA-support-for-SPL.patch
0029-spl-ARM-Enable-CPU-caches.patch
0030-common-expose-DRAM-clock-speed.patch
"
builddir="$srcdir/u-boot-$_commit"
builddir="$srcdir/u-boot-v$pkgver"
install="$pkgname.post-upgrade"
frequencies='528 552 624'
@ -26,7 +52,7 @@ build() {
LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"' > include/timestamp_autogenerated.h
LC_ALL=C date +'#define U_BOOT_TIME "%T"' >> include/timestamp_autogenerated.h
export BL31="/usr/share/arm-trusted-firmware/sun50i/bl31.bin"
export BL31="/usr/share/arm-trusted-firmware/sun50i_a64/bl31.bin"
export SCP="/usr/share/crust/pinephone/scp.bin"
export BUILD_DIR="$builddir"/build
@ -51,7 +77,36 @@ package() {
}
sha512sums="
73b132cdc26113a83d060f0d243320ca989b4efa98fe95a2205526a42f615ced7046bb9d4878c67a9a550b04c2519d90be3c2272be97c878d759bf5d027cf536 u-boot-7492749fec31b1086bc8933bf113a766aea021aa.tar.gz
3cba8a0e899be8cb0b9260b7a86d4115f74c279a1bac8c1403ee669adf91dca8215d8d2d6395ebb3cd67ce000f37a51d6e033b62a8d616b346a9072fa58a4b70 0001-expose-DRAM-clock-speed.patch
bbfc92bda2d9229787f507d2e3c120a8536788b198b910fb018f851e6990f73de4a57bc9686664f777c1665573c2f9015e1e7bbfcec5773dc957dbb71f2aa56b u-boot-v2021.07.tar.gz
4857d5f6e4f591f97b8842cc9fb7d1131d71af63d05f6bd8457f4323886fb2334614a00699a3efc8d1b32d149d130c3cca0205150eedb40e9da60e4508281e36 update-u-boot
05ae2fa9ce48567f91589b6bbf69f0849b37ef11b2cc98c400e3d08fd5d52d02ad4bc30111cbf2e9bfe75a2b2b68606193110019bfc8e2e451c8ab0a2d6153ca 0001-mmc-sunxi-Avoid-ifdefs-in-delay-and-width-setup.patch
57ff8c7bbd697e183cce079e6d4fb272909aa1d00aa4d6a0fabb2cfd395c1e051be11846aad8aafdf92b4fe98760742e0a1a3d7ecd763e8b8a4e0b656fe53d1e 0002-mmc-sunxi-Fix-warnings-with-CONFIG_PHYS_64BIT.patch
bb10dabb6b66d38ca406fd8be656be9fc5582e5224e54d2fd4cd33dd7ee20a1c976fa1b5807a3c740534ddc22782330fbd5e4b436917416acc05a63dd3e9d181 0003-mmc-sunxi-Fix-MMC-clock-parent-selection.patch
6fe63a013a3716c962647f166c085cbb3edd0ed18511a97e51f5c32aff752c3a3581f6b68ff7bf482e91ebf29cb098b3f6bd5f11f491aff65f999120b3520267 0004-mmc-sunxi-Cleanup-new-timing-mode-selection.patch
1eb21c9f5af6580937d7e107f742a226d3b95d49adf4ea77b7812c76d9102506adbc219a49476d0e8f84a536bc43fb53a288eec0708f41454327f85a7e7ab59d 0005-mmc-sunxi-Enable-new-timing-mode-on-all-new-SoCs.patch
e794d989d31672d7ad05730dd469ad91e3ed1c1cb40bff25f2df6bdb364417ad288b79700ca7223d0f82ce750cfa158a72d19191d7b5e8fa549efc59b0cf902f 0006-mmc-sunxi-Cleanup-and-fix-self-calibration-code.patch
1b5c17632f4a680727c2548940bcccca6615f6847fed121ddef03dcadc5b9eceb1de8e03dcc71abc0cc496a73068c40cfb50ad98aa051b3e9af090e959e23cca 0007-mmc-sunxi-Increase-MMIO-FIFO-read-performance.patch
752d8831c348c019c67593a6d8c23ce238ab96957fda0f56f2dc2831afc8a5367bff33627c8002a9ead55e9a878440ffee5da2d9a73d2c0733895cf2f4f076a8 0008-mmc-sunxi-Use-mmc_of_parse.patch
4076ee3fcf746e7b3ca1519646af5a9cc5befb8dedbd32b6737cbe4e422e0a0e7100da265f2feac2d77fa1fd5d510c5251c9d3672b006cd290c9f906d8af673c 0009-sunxi-DT-H5-update-device-tree-files.patch
aa951994ccd7cfdfa6e5f34cf87229d6cf5d87c4c7eaeab38904f3fa704c17dd8cfe9c67b9f1e123a80dbed9e7724314bb9914630a7df4d3bff55d11a10b3241 0010-sunxi-DT-H6-update-device-tree-files.patch
c59a36a6dfc0313076baaa3ada2ffd17710d816b0590aa4970354ccf60e503df1b23c7701c2abf6c9625df7b76e0b0ff81079bd6b7c8c7c68cabf56b26c2b25f 0011-phy-sun50i-usb3-Add-a-driver-for-the-H6-USB3-PHY.patch
1f1f5394ef2699d011ba89fe8161f6b792b3862a26c112d9085404db4ccbe090376e9f7487268aeb492bc7bc72d6217e3e29612b30d8e687af3990d781786fe8 0012-usb-xhci-pci-Move-reset-logic-out-of-XHCI-core.patch
d93307d1d0d583cd041b54bd17e0b60ff6cd886435f528898495bdfaa9e19ab578ee7d8edcd6523757bfe6a2f70305e4633a082a994cdc5850deba3ff4720d89 0013-usb-xhci-dwc3-Add-support-for-clocks-resets.patch
c426c2145654d5ad34980ee2255155f63d7e6aa374a21f7d4d3a9ff7cc96ceec6a6267beef9ca2024d1f8c82285d6e0c76e5f9dc0b4af12c1316fd7a0e483936 0014-configs-Enable-USB3-on-Allwinner-H6-boards.patch
c32c8a8760239350408d3c78dcad0226cf8576ca7b75cbe52cb4eee7d0a9f8d824b022c5767d703aae89a811c8ac6b953620cb5ec69166e3d8b31bad8a501c25 0015-tools-Refactor-mkimage-linking-with-OpenSSL.patch
607a86a2f76fc8338da083ccb068bc140ff8513d2a48c479a4f4c2e3307853485db708cbe381cd36498240d7752c83b6667d696251fd27ac96b41a2dec9f8911 0016-tools-mkimage-Add-Allwinner-TOC0-support.patch
9eaf3a854250df8863eec109912f5351e3a3a165677770c016b0c3b60e66e9dd8370cf6e6bd4b3f0ba00e777c1a3a1e05e4fc69a1e709e6e784f71b306ba6e13 0017-sunxi-Support-both-SPL-image-types.patch
07c1cad4b3e6ff2a220c2e1f7b613bb0265e58b203016e523d3c1055e465c2a4b697b1761cf8823b80fa8ad056beb7a4169aa551c76a2814675f841f15adab28 0018-sunxi-Support-building-a-SPL-as-a-TOC0-image.patch
19f7f99e0649780226915f97b22c30fb1963aa5267d7f07bef727cbae4c6a4750ba31a4f807601d53f53fd605c16f1c462b4b255783220fe91faa297db6de3c1 0019-sunxi-H616-Enable-full-4GB-of-DRAM.patch
44ce977b41a07b64f61328e17a5b7bb19b8ff2cfc0664946a869b22b2e03ecbfab8a64bec41adafcce7c6351d570882246020fcdaa81b43c1af512d41a239d62 0020-sunxi-DT-H6-Add-USB3-to-Pine-H64-DTS.patch
5d77c5c253c31b47c41f159d3c0f0954ce84bd8cde39c39a5894e40ff5e89439ea6e133c66e254a39aab621cb6f3b252ab36ea91a3beff122cdb2e023b9599f1 0021-sunxi-Select-environment-MMC-based-on-boot-device.patch
299be54d9cc6bc5190ae28d020db1d0e91cdc2ff15c28a5779972c5b77cc80dd9cf8209f1a380971118356963efea0b5afcbd49753b8f192d8667f65eaa87825 0022-sunxi-Load-sun8i-secure-monitor-to-SRAM-A2.patch
95a1f9277b92b4dfeac8dd2ebd00425ef266d5dd1f3874d3d283b88421a84698df09513f4b6d317de983b3ce4351deba660c5d6c0ef9fa4abcd3e0030dc53ada 0023-pinephone-Add-volume_key-environment-variable.patch
4e2f803f287fde9874a3e49f7a1ba07bce8760270bffa5d204915eaf8fd26be2ca7575bb3e4fc997e05321e93ecea14eba7f733ad78f78075e42b63239c76f67 0024-Enable-led-on-boot-to-notify-user-of-boot-status.patch
c9b0e640fe021c33be3e60defbef6a784cd482566ca0cfc54d05a63fe9bd4bc4c9e87eed4262eb531ac47e8af69660baf29906130542704d23a51f4a680690cc 0025-disable-bootdelay.patch
f982f87bb34544d3dca38bfda3157a355d48a058315a80fe525acefa14a03698857e14ed40c40d36b78db9158d2e158af88a000c239b0470a6ca70c5ad74847b 0026-Reduce-DRAM-speed-to-528-for-better-compatibility-wi.patch
ae2d0baf7c2048e142230741368db1d0520b1764d62e798098d2548b0ba9622f098f64edc0988db10963543ca0169ae6f3db609f436e1fd090d785274cf30283 0027-mmc-sunxi-Add-support-for-DMA-transfers.patch
eff2901ac5e14949f326a9d8b553f6f32d7e89502929090595b360d1b76d0d3335c94d0c4960b25603f9786524baf2386251bd4a18582ed1012a6db3e5e84618 0028-mmc-sunxi-DDR-DMA-support-for-SPL.patch
f2ee73c774758bd13872d370bc7990474adc453531dacf15664609ca0fdc2a4844d4769376c370b7d18896ac734a7080ee709066659647a4cf0368928bf5e198 0029-spl-ARM-Enable-CPU-caches.patch
86d9587cb2b0ca99fb4090bd0daacd47c0043858654f6f7114c8d0ed6c660eb2b8bc0b37de6723e738df9b1137d62482f00764c284f4aa0a6054db9efe754db9 0030-common-expose-DRAM-clock-speed.patch
"