From a67e219d0ca1b4b45ddb0cfb0afa2d1781262f62 Mon Sep 17 00:00:00 2001 From: Peter Geis Date: Tue, 14 Mar 2023 00:38:26 +0000 Subject: clk: rockchip: rk3568: Fix reset handler The reset handler for rk3568 is missing its private data. This leads to an abort when a reset is triggered. => reset resetting ... "Synchronous Abort" handler, esr 0x96000045 elr: 0000000000a2bc04 lr : 0000000000a2bbd4 (reloc) elr: 00000000eff9bc04 lr : 00000000eff9bbd4 x0 : 00000000fdd20000 x1 : 0000000014000001 x2 : 000000000000fdb9 x3 : 00000000edf77e88 x4 : 00000000edf50e78 x5 : 00000000edf77530 x6 : 000000000000001d x7 : 00000000edf8a1d0 x8 : 00000000ffffffd8 x9 : 0000000000000008 x10: 000000000000000d x11: 0000000000000006 x12: 000000000001869f x13: 0000000086c290c5 x14: 000000009118e878 x15: 0000000000000000 x16: 00000000eff9bbb8 x17: 0000000012f8c119 x18: 00000000edf50dc0 x19: 0000000000000000 x20: 0000000000000001 x21: 0000000000000000 x22: 00000000edf85900 x23: 0000000000000001 x24: 00000000effe8bbc x25: 0000000000000000 x26: 00000000edf85940 x27: 0000000000000000 x28: 0000000000000000 x29: 00000000edf3c8e0 Code: d65f03c0 d5033fbf b9400661 529d9502 (b8216802) Resetting CPU ... Add the missing dev_set_priv to the rk3568 clk driver to fix this. Fixes: 4a262feba3a5 ("rockchip: rk3568: add clock driver") Signed-off-by: Peter Geis Reviewed-by: Kever Yang Reviewed-by: Jagan Teki Tested-by: Jagan Teki # radxa-cm3 Signed-off-by: Jonas Karlman --- drivers/clk/rockchip/clk_rk3568.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk_rk3568.c b/drivers/clk/rockchip/clk_rk3568.c index 99c195b3afe..253b69504f9 100644 --- a/drivers/clk/rockchip/clk_rk3568.c +++ b/drivers/clk/rockchip/clk_rk3568.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -2937,6 +2938,7 @@ static int rk3568_clk_bind(struct udevice *dev) glb_srst_fst); priv->glb_srst_snd_value = offsetof(struct rk3568_cru, glb_srsr_snd); + dev_set_priv(sys_child, priv); } #if CONFIG_IS_ENABLED(RESET_ROCKCHIP) -- cgit v1.2.3 From 67a1d773e7ed1bbfe05ff02d13e56558e7203af5 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Tue, 14 Mar 2023 00:38:27 +0000 Subject: clk: rockchip: rk3588: Fix clk_aux16m in clock driver The rate and error value is not returned for aux16m clocks, fix this. Fixes: 7a474df74023 ("clk: rockchip: Add rk3588 clk support") Signed-off-by: Jonas Karlman Reviewed-by: Kever Yang --- drivers/clk/rockchip/clk_rk3588.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk_rk3588.c b/drivers/clk/rockchip/clk_rk3588.c index 5271d943483..a7df553e875 100644 --- a/drivers/clk/rockchip/clk_rk3588.c +++ b/drivers/clk/rockchip/clk_rk3588.c @@ -1558,7 +1558,7 @@ static ulong rk3588_clk_get_rate(struct clk *clk) #ifndef CONFIG_SPL_BUILD case CLK_AUX16M_0: case CLK_AUX16M_1: - rk3588_aux16m_get_clk(priv, clk->id); + rate = rk3588_aux16m_get_clk(priv, clk->id); break; case ACLK_VOP_ROOT: case ACLK_VOP: @@ -1707,7 +1707,7 @@ static ulong rk3588_clk_set_rate(struct clk *clk, ulong rate) #ifndef CONFIG_SPL_BUILD case CLK_AUX16M_0: case CLK_AUX16M_1: - rk3588_aux16m_set_clk(priv, clk->id, rate); + ret = rk3588_aux16m_set_clk(priv, clk->id, rate); break; case ACLK_VOP_ROOT: case ACLK_VOP: -- cgit v1.2.3 From d11f0dac30215361aa046f593d003a7ea094e8a1 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Tue, 14 Mar 2023 00:38:32 +0000 Subject: mmc: rockchip_dw_mmc: Fix get_mmc_clk return value The get_mmc_clk ops is expected to set a clock rate and return the configured rate as an unsigned value. However, if clk_set_rate fails, e.g. using a fixed rate clock, a negative error value is returned. The mmc core will treat this as a valid unsigned rate and tries to configure a divider based on this bogus clock rate. Use 0 as the return value when setting clock rate fails, the mmc core will configure to use bypass mode instead of using a bogus divider. Signed-off-by: Jonas Karlman Reviewed-by: Kever Yang --- drivers/mmc/rockchip_dw_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c index 3661ce33143..72c820ee633 100644 --- a/drivers/mmc/rockchip_dw_mmc.c +++ b/drivers/mmc/rockchip_dw_mmc.c @@ -52,7 +52,7 @@ static uint rockchip_dwmmc_get_mmc_clk(struct dwmci_host *host, uint freq) ret = clk_set_rate(&priv->clk, freq); if (ret < 0) { debug("%s: err=%d\n", __func__, ret); - return ret; + return 0; } return freq; -- cgit v1.2.3 From 4340771323fc8cc9eee5508ffabbd48d0d83c27a Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 7 Mar 2023 21:16:10 -0800 Subject: clk: rockchip: rk3568: add stubs for CLK_PCIEPHY_REF clocks Device tree contains assigned-clock-rates property for these, but default value will work just fine Reviewed-by: Kever Yang Signed-off-by: Vasily Khoruzhick --- drivers/clk/rockchip/clk_rk3568.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/rockchip/clk_rk3568.c b/drivers/clk/rockchip/clk_rk3568.c index 253b69504f9..1c6adc56f91 100644 --- a/drivers/clk/rockchip/clk_rk3568.c +++ b/drivers/clk/rockchip/clk_rk3568.c @@ -425,6 +425,9 @@ static ulong rk3568_pmuclk_set_rate(struct clk *clk, ulong rate) case PCLK_PMU: ret = rk3568_pmu_set_pmuclk(priv, rate); break; + case CLK_PCIEPHY0_REF: + case CLK_PCIEPHY1_REF: + return 0; default: return -ENOENT; } -- cgit v1.2.3 From 2321a991bbb5f0de0781df09d332ee068426e264 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Wed, 8 Mar 2023 17:28:30 -0800 Subject: rockchip: sdhci: rk3568: bypass DLL when clk <= 52 MHz For Rockchip platform, DLL bypass bit and start bit need to be set if DLL is not locked. With this change applied eMMC in my NanoPi R5S can run at 52 MHz. Based on linux commit b75a52b0dda3 ("mmc: sdhci-of-dwcmshc: Update DLL and pre-change delay for rockchip platform") Signed-off-by: Vasily Khoruzhick Reviewed-by: Kever Yang --- drivers/mmc/rockchip_sdhci.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c index 9608770d4ec..e1409dd2c74 100644 --- a/drivers/mmc/rockchip_sdhci.c +++ b/drivers/mmc/rockchip_sdhci.c @@ -61,6 +61,7 @@ #define DWCMSHC_EMMC_DLL_RXCLK 0x804 #define DWCMSHC_EMMC_DLL_TXCLK 0x808 #define DWCMSHC_EMMC_DLL_STRBIN 0x80c +#define DECMSHC_EMMC_DLL_CMDOUT 0x810 #define DWCMSHC_EMMC_DLL_STATUS0 0x840 #define DWCMSHC_EMMC_DLL_STATUS1 0x844 #define DWCMSHC_EMMC_DLL_START BIT(0) @@ -69,6 +70,7 @@ #define DWCMSHC_EMMC_DLL_START_DEFAULT 5 #define DWCMSHC_EMMC_DLL_INC_VALUE 2 #define DWCMSHC_EMMC_DLL_INC 8 +#define DWCMSHC_EMMC_DLL_BYPASS BIT(24) #define DWCMSHC_EMMC_DLL_DLYENA BIT(27) #define DLL_TXCLK_TAPNUM_DEFAULT 0xA @@ -83,6 +85,7 @@ #define DWCMSHC_EMMC_DLL_TIMEOUT BIT(9) #define DLL_RXCLK_NO_INVERTER 1 #define DLL_RXCLK_INVERTER 0 +#define DLL_RXCLK_ORI_GATE BIT(31) #define DWCMSHC_ENHANCED_STROBE BIT(8) #define DLL_LOCK_WO_TMOUT(x) \ ((((x) & DWCMSHC_EMMC_DLL_LOCKED) == DWCMSHC_EMMC_DLL_LOCKED) && \ @@ -348,10 +351,14 @@ static int rk3568_sdhci_emmc_set_clock(struct sdhci_host *host, unsigned int clo DLL_STRBIN_TAPNUM_FROM_SW; sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN); } else { - /* reset the clock phase when the frequency is lower than 100MHz */ - sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL); - extra = DLL_RXCLK_NO_INVERTER << DWCMSHC_EMMC_DLL_RXCLK_SRCSEL; - sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK); + /* + * Disable DLL and reset both of sample and drive clock. + * The bypass bit and start bit need to be set if DLL is not locked. + */ + sdhci_writel(host, DWCMSHC_EMMC_DLL_BYPASS | DWCMSHC_EMMC_DLL_START, + DWCMSHC_EMMC_DLL_CTRL); + sdhci_writel(host, DLL_RXCLK_ORI_GATE, DWCMSHC_EMMC_DLL_RXCLK); + sdhci_writel(host, 0, DECMSHC_EMMC_DLL_CMDOUT); sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK); /* * Before switching to hs400es mode, the driver will enable -- cgit v1.2.3 From 791c7ac79274e2c3aa316da90fb3cc2411d5c5e8 Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Tue, 7 Mar 2023 16:30:58 +0100 Subject: rockchip: timer: rockchip_timer: fix compatible and driver name In the binding for the Rockchip timer the compatible string consists of a SoC orientated string and a fall back string "rockchip,rk3288-timer", so remove all unneeded ones and fix driver name. Signed-off-by: Johan Jonker Reviewed-by: Kever Yang --- drivers/timer/rockchip_timer.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/timer/rockchip_timer.c b/drivers/timer/rockchip_timer.c index 62eacb98689..e66c49aa6bb 100644 --- a/drivers/timer/rockchip_timer.c +++ b/drivers/timer/rockchip_timer.c @@ -20,7 +20,7 @@ DECLARE_GLOBAL_DATA_PTR; #if CONFIG_IS_ENABLED(OF_PLATDATA) struct rockchip_timer_plat { - struct dtd_rockchip_rk3368_timer dtd; + struct dtd_rockchip_rk3288_timer dtd; }; #endif @@ -152,14 +152,12 @@ static const struct timer_ops rockchip_timer_ops = { }; static const struct udevice_id rockchip_timer_ids[] = { - { .compatible = "rockchip,rk3188-timer" }, { .compatible = "rockchip,rk3288-timer" }, - { .compatible = "rockchip,rk3368-timer" }, {} }; -U_BOOT_DRIVER(rockchip_rk3368_timer) = { - .name = "rockchip_rk3368_timer", +U_BOOT_DRIVER(rockchip_rk3288_timer) = { + .name = "rockchip_rk3288_timer", .id = UCLASS_TIMER, .of_match = rockchip_timer_ids, .probe = rockchip_timer_probe, -- cgit v1.2.3 From afafaa2a8f3f0ef38fc55c5d830890adb508549f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 18 Mar 2023 12:30:53 +0100 Subject: clk: renesas: Pack reset identifier before look up The reset identifier must be processed via MOD_CLK_PACK() before it is used to look up register and bit within reset_regs or reset_clear_regs arrays, otherwise completely bogus register and bit is picked from the arrays, one which may even be out of range. Fixes: 326e05c5e21 ("clk: renesas: Add and enable CPG reset driver") Signed-off-by: Marek Vasut --- drivers/clk/renesas/clk-rcar-gen3.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/renesas/clk-rcar-gen3.c b/drivers/clk/renesas/clk-rcar-gen3.c index d778db6569d..c121d82de7e 100644 --- a/drivers/clk/renesas/clk-rcar-gen3.c +++ b/drivers/clk/renesas/clk-rcar-gen3.c @@ -479,8 +479,9 @@ static int gen3_reset_assert(struct reset_ctl *reset_ctl) { struct udevice *cdev = (struct udevice *)dev_get_driver_data(reset_ctl->dev); struct gen3_clk_priv *priv = dev_get_priv(cdev); - unsigned int reg = reset_ctl->id / 32; - unsigned int bit = reset_ctl->id % 32; + unsigned int packed_id = MOD_CLK_PACK(reset_ctl->id); + unsigned int reg = packed_id / 32; + unsigned int bit = packed_id % 32; u32 bitmask = BIT(bit); writel(bitmask, priv->base + priv->info->reset_regs[reg]); @@ -492,8 +493,9 @@ static int gen3_reset_deassert(struct reset_ctl *reset_ctl) { struct udevice *cdev = (struct udevice *)dev_get_driver_data(reset_ctl->dev); struct gen3_clk_priv *priv = dev_get_priv(cdev); - unsigned int reg = reset_ctl->id / 32; - unsigned int bit = reset_ctl->id % 32; + unsigned int packed_id = MOD_CLK_PACK(reset_ctl->id); + unsigned int reg = packed_id / 32; + unsigned int bit = packed_id % 32; u32 bitmask = BIT(bit); writel(bitmask, priv->base + priv->info->reset_clear_regs[reg]); -- cgit v1.2.3 From f8461352b84ea66ad03d3231a5056643ab73515d Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Wed, 8 Mar 2023 09:42:57 +0530 Subject: dma: ti: k3-udma: Fix channel hang on teardown Setting RX flow error handling will stall the channel until descriptors are available to move RX data. Setting this bit causes issues when tearing down ethernet DMA channel at the end of TFTP transfer as unrelated network packets can cause teardown to stall indefinitely waiting for driver to queue add more desc leading to channel hang with error logs: udma_stop_dev2mem TIMEOUT ! udma_stop_dev2mem: peer not stopped TIMEOUT ! udma_stop_dev2mem TIMEOUT ! Fix this by clearing rx_error_handling similar to how its done for UDMA as part of udma_alloc_rchan_sci_req() This fixes occasional TFTP Failures seen when downloading multiple files one after the other on AM64/AM62 SoCs. Fixes: 9a92851c33e8 ("dma: ti: k3-udma: Add BCDMA and PKTDMA support") Reported-by: Nishanth Menon Signed-off-by: Vignesh Raghavendra --- drivers/dma/ti/k3-udma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index d92b9644369..05c3a4311ce 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -2150,7 +2150,7 @@ static int pktdma_tisci_rx_channel_config(struct udma_chan *uc) flow_req.rx_psinfo_present = 1; else flow_req.rx_psinfo_present = 0; - flow_req.rx_error_handling = 1; + flow_req.rx_error_handling = 0; ret = tisci_ops->rx_flow_cfg(tisci_rm->tisci, &flow_req); -- cgit v1.2.3 From 85bdd28d2bb0827f311913e00e4e338f8e4e6565 Mon Sep 17 00:00:00 2001 From: Vincent Fazio Date: Tue, 14 Sep 2021 13:19:19 -0500 Subject: mmc: bcm2835-host: let firmware manage the clock divisor Newer firmware can manage the SDCDIV clock divisor register, allowing the divisor to scale with the core as necessary. Leverage this ability if the firmware supports it. Adapted from the following raspberrypi Linux kernel commit: bcm2835-sdhost: Firmware manages the clock divisor https://github.com/raspberrypi/linux/commit/08532d242d7702ae0add95096aa49c5e96e066e2 Signed-off-by: Vincent Fazio Signed-off-by: Peter Robinson --- drivers/mmc/bcm2835_sdhost.c | 53 ++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/bcm2835_sdhost.c b/drivers/mmc/bcm2835_sdhost.c index 894dbdd6861..5c23c03d10d 100644 --- a/drivers/mmc/bcm2835_sdhost.c +++ b/drivers/mmc/bcm2835_sdhost.c @@ -181,6 +181,7 @@ struct bcm2835_host { struct udevice *dev; struct mmc *mmc; struct bcm2835_plat *plat; + unsigned int firmware_sets_cdiv:1; }; static void bcm2835_dumpregs(struct bcm2835_host *host) @@ -233,7 +234,7 @@ static void bcm2835_reset_internal(struct bcm2835_host *host) msleep(20); host->clock = 0; writel(host->hcfg, host->ioaddr + SDHCFG); - writel(host->cdiv, host->ioaddr + SDCDIV); + writel(SDCDIV_MAX_CDIV, host->ioaddr + SDCDIV); } static int bcm2835_wait_transfer_complete(struct bcm2835_host *host) @@ -598,6 +599,7 @@ static int bcm2835_transmit(struct bcm2835_host *host) static void bcm2835_set_clock(struct bcm2835_host *host, unsigned int clock) { int div; + u32 clock_rate[2] = { 0 }; /* The SDCDIV register has 11 bits, and holds (div - 2). But * in data mode the max is 50MHz wihout a minimum, and only @@ -620,26 +622,34 @@ static void bcm2835_set_clock(struct bcm2835_host *host, unsigned int clock) * clock divisor at all times. */ - if (clock < 100000) { - /* Can't stop the clock, but make it as slow as possible - * to show willing - */ - host->cdiv = SDCDIV_MAX_CDIV; - writel(host->cdiv, host->ioaddr + SDCDIV); - return; - } + if (host->firmware_sets_cdiv) { + bcm2835_set_sdhost_clock(clock, &clock_rate[0], &clock_rate[1]); + clock = max(clock_rate[0], clock_rate[1]); + } else { + if (clock < 100000) { + /* Can't stop the clock, but make it as slow as possible + * to show willing + */ + host->cdiv = SDCDIV_MAX_CDIV; + writel(host->cdiv, host->ioaddr + SDCDIV); + return; + } - div = host->max_clk / clock; - if (div < 2) - div = 2; - if ((host->max_clk / div) > clock) - div++; - div -= 2; + div = host->max_clk / clock; + if (div < 2) + div = 2; + if ((host->max_clk / div) > clock) + div++; + div -= 2; - if (div > SDCDIV_MAX_CDIV) - div = SDCDIV_MAX_CDIV; + if (div > SDCDIV_MAX_CDIV) + div = SDCDIV_MAX_CDIV; + + clock = host->max_clk / (div + 2); + host->cdiv = div; + writel(host->cdiv, host->ioaddr + SDCDIV); + } - clock = host->max_clk / (div + 2); host->mmc->clock = clock; /* Calibrate some delays */ @@ -647,9 +657,6 @@ static void bcm2835_set_clock(struct bcm2835_host *host, unsigned int clock) host->ns_per_fifo_word = (1000000000 / clock) * ((host->mmc->card_caps & MMC_MODE_4BIT) ? 8 : 32); - host->cdiv = div; - writel(host->cdiv, host->ioaddr + SDCDIV); - /* Set the timeout to 500ms */ writel(host->mmc->clock / 2, host->ioaddr + SDTOUT); } @@ -759,6 +766,7 @@ static int bcm2835_probe(struct udevice *dev) struct bcm2835_host *host = dev_get_priv(dev); struct mmc *mmc = mmc_get_mmc_dev(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + u32 clock_rate[2] = { ~0 }; host->dev = dev; host->mmc = mmc; @@ -776,6 +784,9 @@ static int bcm2835_probe(struct udevice *dev) host->max_clk = bcm2835_get_mmc_clock(BCM2835_MBOX_CLOCK_ID_CORE); + bcm2835_set_sdhost_clock(0, &clock_rate[0], &clock_rate[1]); + host->firmware_sets_cdiv = (clock_rate[0] != ~0); + bcm2835_add_host(host); dev_dbg(dev, "%s -> OK\n", __func__); -- cgit v1.2.3