summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2024-04-26 07:28:57 -0600
committerTom Rini <[email protected]>2024-04-26 07:28:57 -0600
commit689f52491d4722bd70eda3256c6e75654ecf00ed (patch)
treeb6477b472c8fae3f6d001cd2af0e46368bcaa839 /drivers
parent8c855106213d12ef7363745c985019979a70c648 (diff)
parentf6114fb871108eb2bad7393191c9983f0b125dc1 (diff)
Merge tag 'u-boot-rockchip-20240426' of https://source.denx.de/u-boot/custodians/u-boot-rockchip
Please pull the updates for rockchip platform: - dts sync for rk3308; - sdram: Support getting banks from TPL for rk3568 and rk3588; - dts and config clean and sync up for rk3568/rk3588; - Other misc fixes; CI: https://source.denx.de/u-boot/custodians/u-boot-rockchip/-/pipelines/20543
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/rockchip/clk_rk3308.c101
-rw-r--r--drivers/clk/rockchip/clk_rk3568.c36
-rw-r--r--drivers/clk/rockchip/clk_rk3588.c6
-rw-r--r--drivers/misc/Kconfig2
-rw-r--r--drivers/misc/rockchip-io-domain.c38
-rw-r--r--drivers/mmc/rockchip_sdhci.c26
-rw-r--r--drivers/net/gmac_rockchip.c4
-rw-r--r--drivers/phy/rockchip/phy-rockchip-inno-usb2.c20
-rw-r--r--drivers/ram/rockchip/sdram_rk3308.c2
9 files changed, 200 insertions, 35 deletions
diff --git a/drivers/clk/rockchip/clk_rk3308.c b/drivers/clk/rockchip/clk_rk3308.c
index 7755b016111..861648321d4 100644
--- a/drivers/clk/rockchip/clk_rk3308.c
+++ b/drivers/clk/rockchip/clk_rk3308.c
@@ -12,8 +12,8 @@
#include <malloc.h>
#include <syscon.h>
#include <asm/global_data.h>
-#include <asm/arch/cru_rk3308.h>
#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3308.h>
#include <asm/arch-rockchip/hardware.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
@@ -65,6 +65,57 @@ static struct rockchip_pll_clock rk3308_pll_clks[] = {
RK3308_MODE_CON, 6, 10, 0, NULL),
};
+/*
+ *
+ * rational_best_approximation(31415, 10000,
+ * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look at given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * http://en.wikipedia.org/wiki/Continued_fraction
+ */
+static void rational_best_approximation(unsigned long given_numerator,
+ unsigned long given_denominator,
+ unsigned long max_numerator,
+ unsigned long max_denominator,
+ unsigned long *best_numerator,
+ unsigned long *best_denominator)
+{
+ unsigned long n, d, n0, d0, n1, d1;
+
+ n = given_numerator;
+ d = given_denominator;
+ n0 = 0;
+ d1 = 0;
+ n1 = 1;
+ d0 = 1;
+ for (;;) {
+ unsigned long t, a;
+
+ if (n1 > max_numerator || d1 > max_denominator) {
+ n1 = n0;
+ d1 = d0;
+ break;
+ }
+ if (d == 0)
+ break;
+ t = d;
+ a = n / d;
+ d = n % d;
+ n = t;
+ t = n0 + a * n1;
+ n0 = n1;
+ n1 = t;
+ t = d0 + a * d1;
+ d0 = d1;
+ d1 = t;
+ }
+ *best_numerator = n1;
+ *best_denominator = d1;
+}
+
static ulong rk3308_armclk_set_clk(struct rk3308_clk_priv *priv, ulong hz)
{
struct rk3308_cru *cru = priv->cru;
@@ -832,6 +883,44 @@ static ulong rk3308_crypto_set_clk(struct rk3308_clk_priv *priv, ulong clk_id,
return rk3308_crypto_get_clk(priv, clk_id);
}
+static ulong rk3308_rtc32k_get_clk(struct rk3308_clk_priv *priv, ulong clk_id)
+{
+ struct rk3308_cru *cru = priv->cru;
+ unsigned long m, n;
+ u32 con, fracdiv;
+
+ con = readl(&cru->clksel_con[2]);
+ if ((con & CLK_RTC32K_SEL_MASK) >> CLK_RTC32K_SEL_SHIFT !=
+ CLK_RTC32K_FRAC_DIV)
+ return -EINVAL;
+
+ fracdiv = readl(&cru->clksel_con[3]);
+ m = fracdiv & CLK_RTC32K_FRAC_NUMERATOR_MASK;
+ m >>= CLK_RTC32K_FRAC_NUMERATOR_SHIFT;
+ n = fracdiv & CLK_RTC32K_FRAC_DENOMINATOR_MASK;
+ n >>= CLK_RTC32K_FRAC_DENOMINATOR_SHIFT;
+
+ return OSC_HZ * m / n;
+}
+
+static ulong rk3308_rtc32k_set_clk(struct rk3308_clk_priv *priv, ulong clk_id,
+ ulong hz)
+{
+ struct rk3308_cru *cru = priv->cru;
+ unsigned long m, n, val;
+
+ rational_best_approximation(hz, OSC_HZ,
+ GENMASK(16 - 1, 0),
+ GENMASK(16 - 1, 0),
+ &m, &n);
+ val = m << CLK_RTC32K_FRAC_NUMERATOR_SHIFT | n;
+ writel(val, &cru->clksel_con[3]);
+ rk_clrsetreg(&cru->clksel_con[2], CLK_RTC32K_SEL_MASK,
+ CLK_RTC32K_FRAC_DIV << CLK_RTC32K_SEL_SHIFT);
+
+ return rk3308_rtc32k_get_clk(priv, clk_id);
+}
+
static ulong rk3308_clk_get_rate(struct clk *clk)
{
struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
@@ -912,6 +1001,9 @@ static ulong rk3308_clk_get_rate(struct clk *clk)
case SCLK_CRYPTO_APK:
rate = rk3308_crypto_get_clk(priv, clk->id);
break;
+ case SCLK_RTC32K:
+ rate = rk3308_rtc32k_get_clk(priv, clk->id);
+ break;
default:
return -ENOENT;
}
@@ -990,6 +1082,11 @@ static ulong rk3308_clk_set_rate(struct clk *clk, ulong rate)
case SCLK_CRYPTO_APK:
ret = rk3308_crypto_set_clk(priv, clk->id, rate);
break;
+ case SCLK_RTC32K:
+ ret = rk3308_rtc32k_set_clk(priv, clk->id, rate);
+ break;
+ case USB480M:
+ return 0;
default:
return -ENOENT;
}
@@ -1022,6 +1119,8 @@ static int __maybe_unused rk3308_clk_set_parent(struct clk *clk, struct clk *par
switch (clk->id) {
case SCLK_MAC:
return rk3308_mac_set_parent(clk, parent);
+ case USB480M:
+ return 0;
default:
break;
}
diff --git a/drivers/clk/rockchip/clk_rk3568.c b/drivers/clk/rockchip/clk_rk3568.c
index 57ef27dda89..24eeca8bf26 100644
--- a/drivers/clk/rockchip/clk_rk3568.c
+++ b/drivers/clk/rockchip/clk_rk3568.c
@@ -1527,28 +1527,20 @@ static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
struct rk3568_cru *cru = priv->cru;
int src_clk;
- switch (rate) {
- case OSC_HZ:
- src_clk = SCLK_SFC_SEL_24M;
- break;
- case 50 * MHz:
- src_clk = SCLK_SFC_SEL_50M;
- break;
- case 75 * MHz:
- src_clk = SCLK_SFC_SEL_75M;
- break;
- case 100 * MHz:
- src_clk = SCLK_SFC_SEL_100M;
- break;
- case 125 * MHz:
- src_clk = SCLK_SFC_SEL_125M;
- break;
- case 150 * MHz:
+ if (rate >= 150 * MHz)
src_clk = SCLK_SFC_SEL_150M;
- break;
- default:
+ else if (rate >= 125 * MHz)
+ src_clk = SCLK_SFC_SEL_125M;
+ else if (rate >= 100 * MHz)
+ src_clk = SCLK_SFC_SEL_100M;
+ else if (rate >= 75 * MHz)
+ src_clk = SCLK_SFC_SEL_75M;
+ else if (rate >= 50 * MHz)
+ src_clk = SCLK_SFC_SEL_50M;
+ else if (rate >= OSC_HZ)
+ src_clk = SCLK_SFC_SEL_24M;
+ else
return -ENOENT;
- }
rk_clrsetreg(&cru->clksel_con[28],
SCLK_SFC_SEL_MASK,
@@ -2417,6 +2409,8 @@ static ulong rk3568_clk_get_rate(struct clk *clk)
case BCLK_EMMC:
rate = rk3568_emmc_get_bclk(priv);
break;
+ case CLK_USB3OTG0_REF:
+ case CLK_USB3OTG1_REF:
case TCLK_EMMC:
rate = OSC_HZ;
break;
@@ -2596,6 +2590,8 @@ static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)
case BCLK_EMMC:
ret = rk3568_emmc_set_bclk(priv, rate);
break;
+ case CLK_USB3OTG0_REF:
+ case CLK_USB3OTG1_REF:
case TCLK_EMMC:
ret = OSC_HZ;
break;
diff --git a/drivers/clk/rockchip/clk_rk3588.c b/drivers/clk/rockchip/clk_rk3588.c
index 8f33843179b..4c611a39049 100644
--- a/drivers/clk/rockchip/clk_rk3588.c
+++ b/drivers/clk/rockchip/clk_rk3588.c
@@ -1569,6 +1569,9 @@ static ulong rk3588_clk_get_rate(struct clk *clk)
case DCLK_DECOM:
rate = rk3588_mmc_get_clk(priv, clk->id);
break;
+ case REF_CLK_USB3OTG0:
+ case REF_CLK_USB3OTG1:
+ case REF_CLK_USB3OTG2:
case TMCLK_EMMC:
case TCLK_WDT0:
rate = OSC_HZ;
@@ -1734,6 +1737,9 @@ static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate)
case DCLK_DECOM:
ret = rk3588_mmc_set_clk(priv, clk->id, rate);
break;
+ case REF_CLK_USB3OTG0:
+ case REF_CLK_USB3OTG1:
+ case REF_CLK_USB3OTG2:
case TMCLK_EMMC:
case TCLK_WDT0:
ret = OSC_HZ;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 6b06888454f..6009d55f400 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -104,7 +104,7 @@ config ROCKCHIP_OTP
config ROCKCHIP_IODOMAIN
bool "Rockchip IO-domain driver support"
depends on DM_REGULATOR && ARCH_ROCKCHIP
- default y if ROCKCHIP_RK3568
+ default y if ROCKCHIP_RK3328 || ROCKCHIP_RK3568
help
Enable support for IO-domains in Rockchip SoCs. It is necessary
for the IO-domain setting of the SoC to match the voltage supplied
diff --git a/drivers/misc/rockchip-io-domain.c b/drivers/misc/rockchip-io-domain.c
index 0ffea32ef07..04d4d07c412 100644
--- a/drivers/misc/rockchip-io-domain.c
+++ b/drivers/misc/rockchip-io-domain.c
@@ -27,6 +27,10 @@
#define MAX_VOLTAGE_1_8 1980000
#define MAX_VOLTAGE_3_3 3600000
+#define RK3328_SOC_CON4 0x410
+#define RK3328_SOC_CON4_VCCIO2 BIT(7)
+#define RK3328_SOC_VCCIO2_SUPPLY_NUM 1
+
#define RK3399_PMUGRF_CON0 0x180
#define RK3399_PMUGRF_CON0_VSEL BIT(8)
#define RK3399_PMUGRF_VSEL_SUPPLY_NUM 9
@@ -95,6 +99,22 @@ static int rockchip_iodomain_write(struct regmap *grf, uint offset, int idx, int
return regmap_write(grf, offset, val);
}
+static int rk3328_iodomain_write(struct regmap *grf, uint offset, int idx, int uV)
+{
+ int ret = rockchip_iodomain_write(grf, offset, idx, uV);
+
+ if (!ret && idx == RK3328_SOC_VCCIO2_SUPPLY_NUM) {
+ /*
+ * set vccio2 iodomain to also use this framework
+ * instead of a special gpio.
+ */
+ u32 val = RK3328_SOC_CON4_VCCIO2 | (RK3328_SOC_CON4_VCCIO2 << 16);
+ ret = regmap_write(grf, RK3328_SOC_CON4, val);
+ }
+
+ return ret;
+}
+
static int rk3399_pmu_iodomain_write(struct regmap *grf, uint offset, int idx, int uV)
{
int ret = rockchip_iodomain_write(grf, offset, idx, uV);
@@ -111,6 +131,20 @@ static int rk3399_pmu_iodomain_write(struct regmap *grf, uint offset, int idx, i
return ret;
}
+static const struct rockchip_iodomain_soc_data soc_data_rk3328 = {
+ .grf_offset = 0x410,
+ .supply_names = {
+ "vccio1-supply",
+ "vccio2-supply",
+ "vccio3-supply",
+ "vccio4-supply",
+ "vccio5-supply",
+ "vccio6-supply",
+ "pmuio-supply",
+ },
+ .write = rk3328_iodomain_write,
+};
+
static const struct rockchip_iodomain_soc_data soc_data_rk3399 = {
.grf_offset = 0xe640,
.supply_names = {
@@ -157,6 +191,10 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
static const struct udevice_id rockchip_iodomain_ids[] = {
{
+ .compatible = "rockchip,rk3328-io-voltage-domain",
+ .data = (ulong)&soc_data_rk3328,
+ },
+ {
.compatible = "rockchip,rk3399-io-voltage-domain",
.data = (ulong)&soc_data_rk3399,
},
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index 706fb123579..c889c7bc985 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -391,6 +391,8 @@ static int rk3568_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enab
static int rk3568_sdhci_set_ios_post(struct sdhci_host *host)
{
struct mmc *mmc = host->mmc;
+ struct rockchip_sdhc_plat *plat = dev_get_plat(mmc->dev);
+ struct mmc_config *cfg = &plat->cfg;
u32 reg;
reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
@@ -437,6 +439,20 @@ static int rk3568_sdhci_set_ios_post(struct sdhci_host *host)
sdhci_writew(host, reg, DWCMSHC_EMMC_EMMC_CTRL);
+ /*
+ * Reading more than 4 blocks with a single CMD18 command in PIO mode
+ * triggers Data End Bit Error using a slower mode than HS200. Limit to
+ * reading max 4 blocks in one command when using PIO mode.
+ */
+ if (!(host->flags & USE_DMA)) {
+ if (mmc->selected_mode == MMC_HS_200 ||
+ mmc->selected_mode == MMC_HS_400 ||
+ mmc->selected_mode == MMC_HS_400_ES)
+ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+ else
+ cfg->b_max = 4;
+ }
+
return 0;
}
@@ -598,16 +614,6 @@ static int rockchip_sdhci_probe(struct udevice *dev)
dev_read_bool(dev, "u-boot,spl-fifo-mode"))
host->flags &= ~USE_DMA;
- /*
- * Reading more than 4 blocks with a single CMD18 command in PIO mode
- * triggers Data End Bit Error on RK3568 and RK3588. Limit to reading
- * max 4 blocks in one command when using PIO mode.
- */
- if (!(host->flags & USE_DMA) &&
- (device_is_compatible(dev, "rockchip,rk3568-dwcmshc") ||
- device_is_compatible(dev, "rockchip,rk3588-dwcmshc")))
- cfg->b_max = 4;
-
return sdhci_probe(dev);
}
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
index c1bae3f68bd..51f835adabc 100644
--- a/drivers/net/gmac_rockchip.c
+++ b/drivers/net/gmac_rockchip.c
@@ -19,7 +19,7 @@
#include <asm/arch-rockchip/grf_px30.h>
#include <asm/arch-rockchip/grf_rk322x.h>
#include <asm/arch-rockchip/grf_rk3288.h>
-#include <asm/arch-rk3308/grf_rk3308.h>
+#include <asm/arch-rockchip/grf_rk3308.h>
#include <asm/arch-rockchip/grf_rk3328.h>
#include <asm/arch-rockchip/grf_rk3368.h>
#include <asm/arch-rockchip/grf_rk3399.h>
@@ -739,7 +739,7 @@ static const struct udevice_id rockchip_gmac_ids[] = {
.data = (ulong)&rk3228_gmac_ops },
{ .compatible = "rockchip,rk3288-gmac",
.data = (ulong)&rk3288_gmac_ops },
- { .compatible = "rockchip,rk3308-mac",
+ { .compatible = "rockchip,rk3308-gmac",
.data = (ulong)&rk3308_gmac_ops },
{ .compatible = "rockchip,rk3328-gmac",
.data = (ulong)&rk3328_gmac_ops },
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index d392aed2d4d..43f6e020a6a 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -329,6 +329,22 @@ bind_fail:
return ret;
}
+static const struct rockchip_usb2phy_cfg rk3308_phy_cfgs[] = {
+ {
+ .reg = 0x100,
+ .clkout_ctl = { 0x0108, 4, 4, 1, 0 },
+ .port_cfgs = {
+ [USB2PHY_PORT_OTG] = {
+ .phy_sus = { 0x0100, 1, 0, 2, 1 },
+ },
+ [USB2PHY_PORT_HOST] = {
+ .phy_sus = { 0x0104, 1, 0, 2, 1 },
+ }
+ },
+ },
+ { /* sentinel */ }
+};
+
static const struct rockchip_usb2phy_cfg rk3328_usb2phy_cfgs[] = {
{
.reg = 0x100,
@@ -443,6 +459,10 @@ static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
static const struct udevice_id rockchip_usb2phy_ids[] = {
{
+ .compatible = "rockchip,rk3308-usb2phy",
+ .data = (ulong)&rk3308_phy_cfgs,
+ },
+ {
.compatible = "rockchip,rk3328-usb2phy",
.data = (ulong)&rk3328_usb2phy_cfgs,
},
diff --git a/drivers/ram/rockchip/sdram_rk3308.c b/drivers/ram/rockchip/sdram_rk3308.c
index 10828e80822..264366291cf 100644
--- a/drivers/ram/rockchip/sdram_rk3308.c
+++ b/drivers/ram/rockchip/sdram_rk3308.c
@@ -7,8 +7,8 @@
#include <dm.h>
#include <ram.h>
#include <syscon.h>
-#include <asm/arch/grf_rk3308.h>
#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_rk3308.h>
#include <asm/arch-rockchip/sdram.h>
struct dram_info {