From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 10 Oct 2020 15:32:18 +0000 Subject: [PATCH] phy/rockchip: inno-hdmi: use correct vco_div_5 macro on rk3328 inno_hdmi_phy_rk3328_clk_set_rate() is using the RK3228 macro when configuring vco_div_5 on RK3328. Fix this by using correct vco_div_5 macro for RK3328. Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy") Signed-off-by: Jonas Karlman --- drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c index 80acca4e9e14..15339338aae3 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -790,8 +790,8 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, RK3328_PRE_PLL_POWER_DOWN); /* Configure pre-pll */ - inno_update_bits(inno, 0xa0, RK3228_PCLK_VCO_DIV_5_MASK, - RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); + inno_update_bits(inno, 0xa0, RK3328_PCLK_VCO_DIV_5_MASK, + RK3328_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); inno_write(inno, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv)); val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE; From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Zheng Yang Date: Sat, 10 Oct 2020 15:32:18 +0000 Subject: [PATCH] phy/rockchip: inno-hdmi: round fractal pixclock in rk3328 recalc_rate inno_hdmi_phy_rk3328_clk_recalc_rate() is returning a rate not found in the pre pll config table when the fractal divider is used. This can prevent proper power_on because a tmdsclock for the new rate is not found in the pre pll config table. Fix this by saving and returning a rounded pixel rate that exist in the pre pll config table. Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy") Signed-off-by: Zheng Yang Signed-off-by: Jonas Karlman --- drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c index 15339338aae3..15a008a1ac7b 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -745,10 +745,12 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2)); } - inno->pixclock = vco; - dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock); + inno->pixclock = DIV_ROUND_CLOSEST((unsigned long)vco, 1000) * 1000; - return vco; + dev_dbg(inno->dev, "%s rate %lu vco %llu\n", + __func__, inno->pixclock, vco); + + return inno->pixclock; } static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw, From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 10 Oct 2020 15:32:19 +0000 Subject: [PATCH] phy/rockchip: inno-hdmi: remove unused no_c from rk3328 recalc_rate no_c is not used in any calculation, lets remove it. Signed-off-by: Jonas Karlman --- drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c index 15a008a1ac7b..4b936ca19920 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -714,7 +714,7 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, { struct inno_hdmi_phy *inno = to_inno_hdmi_phy(hw); unsigned long frac; - u8 nd, no_a, no_b, no_c, no_d; + u8 nd, no_a, no_b, no_d; u64 vco; u16 nf; @@ -737,9 +737,6 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, no_b = inno_read(inno, 0xa5) & RK3328_PRE_PLL_PCLK_DIV_B_MASK; no_b >>= RK3328_PRE_PLL_PCLK_DIV_B_SHIFT; no_b += 2; - no_c = inno_read(inno, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_C_MASK; - no_c >>= RK3328_PRE_PLL_PCLK_DIV_C_SHIFT; - no_c = 1 << no_c; no_d = inno_read(inno, 0xa6) & RK3328_PRE_PLL_PCLK_DIV_D_MASK; do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2)); From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sat, 10 Oct 2020 15:32:19 +0000 Subject: [PATCH] phy/rockchip: inno-hdmi: do not power on rk3328 post pll on reg write inno_write is used to configure 0xaa reg, that also hold the POST_PLL_POWER_DOWN bit. When POST_PLL_REFCLK_SEL_TMDS is configured the power down bit is not taken into consideration. Fix this by keeping the power down bit until configuration is complete. Also reorder the reg write order for consistency. Fixes: 53706a116863 ("phy: add Rockchip Innosilicon hdmi phy") Signed-off-by: Jonas Karlman --- drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c index 4b936ca19920..620961fcfc1d 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -1020,9 +1020,10 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno, inno_write(inno, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv)); if (cfg->postdiv == 1) { - inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS); inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | RK3328_POST_PLL_PRE_DIV(cfg->prediv)); + inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS | + RK3328_POST_PLL_POWER_DOWN); } else { v = (cfg->postdiv / 2) - 1; v &= RK3328_POST_PLL_POST_DIV_MASK; @@ -1030,7 +1031,8 @@ inno_hdmi_phy_rk3328_power_on(struct inno_hdmi_phy *inno, inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | RK3328_POST_PLL_PRE_DIV(cfg->prediv)); inno_write(inno, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE | - RK3328_POST_PLL_REFCLK_SEL_TMDS); + RK3328_POST_PLL_REFCLK_SEL_TMDS | + RK3328_POST_PLL_POWER_DOWN); } for (v = 0; v < 14; v++) From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Huicong Xu Date: Sat, 10 Oct 2020 15:32:20 +0000 Subject: [PATCH] phy/rockchip: inno-hdmi: force set_rate on power_on Regular 8-bit and Deep Color video formats mainly differ in TMDS rate and not in pixel clock rate. When the hdmiphy clock is configured with the same pixel clock rate using clk_set_rate() the clock framework do not signal the hdmi phy driver to set_rate when switching between 8-bit and Deep Color. This result in pre/post pll not being re-configured when switching between regular 8-bit and Deep Color video formats. Fix this by calling set_rate in power_on to force pre pll re-configuration. Signed-off-by: Huicong Xu Signed-off-by: Jonas Karlman --- drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c index 620961fcfc1d..2f01259823ea 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -245,6 +245,7 @@ struct inno_hdmi_phy { struct clk_hw hw; struct clk *phyclk; unsigned long pixclock; + unsigned long tmdsclock; }; struct pre_pll_config { @@ -485,6 +486,8 @@ static int inno_hdmi_phy_power_on(struct phy *phy) dev_dbg(inno->dev, "Inno HDMI PHY Power On\n"); + inno->plat_data->clk_ops->set_rate(&inno->hw, inno->pixclock, 24000000); + ret = clk_prepare_enable(inno->phyclk); if (ret) return ret; @@ -509,6 +512,8 @@ static int inno_hdmi_phy_power_off(struct phy *phy) clk_disable_unprepare(inno->phyclk); + inno->tmdsclock = 0; + dev_dbg(inno->dev, "Inno HDMI PHY Power Off\n"); return 0; @@ -628,6 +633,9 @@ static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw, dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n", __func__, rate, tmdsclock); + if (inno->pixclock == rate && inno->tmdsclock == tmdsclock) + return 0; + cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate); if (IS_ERR(cfg)) return PTR_ERR(cfg); @@ -670,6 +678,7 @@ static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw, } inno->pixclock = rate; + inno->tmdsclock = tmdsclock; return 0; } @@ -781,6 +790,9 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n", __func__, rate, tmdsclock); + if (inno->pixclock == rate && inno->tmdsclock == tmdsclock) + return 0; + cfg = inno_hdmi_phy_get_pre_pll_cfg(inno, rate); if (IS_ERR(cfg)) return PTR_ERR(cfg); @@ -820,6 +832,7 @@ static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, } inno->pixclock = rate; + inno->tmdsclock = tmdsclock; return 0; } From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 17 Feb 2019 22:14:38 +0000 Subject: [PATCH] mmc: core: set initial signal voltage on power off Some boards have SD card connectors where the power rail cannot be switched off by the driver. If the card has not been power cycled, it may still be using 1.8V signaling after a warm re-boot. Bootroms expecting 3.3V signaling will fail to boot from a UHS card that continue to use 1.8V signaling. Set initial signal voltage in mmc_power_off() to allow re-boot to function. This fixes re-boot with UHS cards on Asus Tinker Board (Rockchip RK3288), same issue have been seen on some Rockchip RK3399 boards. I am sending this as a RFC because I have no insights into SD/MMC subsystem, this change fix a re-boot issue on my boards and does not break emmc/sdio. Is this an acceptable workaround? Any advice is appreciated. Signed-off-by: Jonas Karlman --- drivers/mmc/core/core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 95fedcf56e4a..38e75b275bb6 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1355,6 +1355,14 @@ void mmc_power_off(struct mmc_host *host) if (host->ios.power_mode == MMC_POWER_OFF) return; + mmc_set_initial_signal_voltage(host); + + /* + * This delay should be sufficient to allow the power supply + * to reach the minimum voltage. + */ + mmc_delay(host->ios.power_delay_ms); + mmc_pwrseq_power_off(host); host->ios.clock = 0; From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 23 Jun 2021 16:59:18 +0200 Subject: [PATCH] arm64: dts: rockchip: Add sdmmc_ext for RK3328 RK3328 SoC has a fourth mmc controller called SDMMC_EXT. Some boards have sdio wifi connected to it. In order to use it one would have to add the pinctrls from sdmmc0ext group which is done on board level. Signed-off-by: Alex Bee --- arch/arm64/boot/dts/rockchip/rk3328.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 5b2020590f53..df46edbec82c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -975,6 +975,20 @@ usb_host0_ohci: usb@ff5d0000 { status = "disabled"; }; + sdmmc_ext: mmc@ff5f0000 { + compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xff5f0000 0x0 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDMMC_EXT>, <&cru SCLK_SDMMC_EXT>, + <&cru SCLK_SDMMC_EXT_DRV>, <&cru SCLK_SDMMC_EXT_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; + resets = <&cru SRST_SDMMCEXT>; + reset-names = "reset"; + status = "disabled"; + }; + usbdrd3: usb@ff600000 { compatible = "rockchip,rk3328-dwc3", "snps,dwc3"; reg = <0x0 0xff600000 0x0 0x100000>; From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Wed, 23 Jun 2021 17:02:08 +0200 Subject: [PATCH] arm64: dts: rockchip: Add sdmmc/sdio/emmc reset controls for RK3328 The DW MCI controller driver will use them to reset the IP block before initialisation. Fixes: d717f7352ec6 ("arm64: dts: rockchip: add sdmmc/sdio/emmc nodes for RK3328 SoCs") Signed-off-by: Alex Bee --- arch/arm64/boot/dts/rockchip/rk3328.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index df46edbec82c..cfc57be009a6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -853,6 +853,8 @@ sdmmc: mmc@ff500000 { clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; max-frequency = <150000000>; + resets = <&cru SRST_MMC0>; + reset-names = "reset"; status = "disabled"; }; @@ -865,6 +867,8 @@ sdio: mmc@ff510000 { clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; max-frequency = <150000000>; + resets = <&cru SRST_SDIO>; + reset-names = "reset"; status = "disabled"; }; @@ -877,6 +881,8 @@ emmc: mmc@ff520000 { clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; max-frequency = <150000000>; + resets = <&cru SRST_EMMC>; + reset-names = "reset"; status = "disabled"; }; From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Sat, 21 Aug 2021 19:13:31 +0200 Subject: [PATCH] Commit a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes") intended to remove the interrupt-names property for the mmu nodes. It also removed them for the vpu node in rk3399.dtsi which currently results in a non-working driver. Fix this by re-adding them. Fixes: a728c10dd62a ("arm64: dts: rockchip: remove interrupt-names from iommu nodes") Signed-off-by: Alex Bee --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 9db9484ca38f..44def886b391 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -1240,6 +1240,7 @@ vpu: video-codec@ff650000 { reg = <0x0 0xff650000 0x0 0x800>; interrupts = , ; + interrupt-names = "vepu", "vdpu"; clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; clock-names = "aclk", "hclk"; iommus = <&vpu_mmu>;