Skip to content

Commit

Permalink
ipq807x: add various clock fixes
Browse files Browse the repository at this point in the history
Upstream IPQ8074 clock driver is lacking various resets and fixups
required for the networking and other subsystems to function properly.

So, port those from the downstream QCA 5.4 kernel.

Signed-off-by: Robert Marko <robimarko@gmail.com>
  • Loading branch information
robimarko committed Apr 4, 2022
1 parent db59dfd commit 7a6377c
Show file tree
Hide file tree
Showing 6 changed files with 357 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
From 2fc17ac5ce7a8c6c7564c4b91e06f2cde62d58be Mon Sep 17 00:00:00 2001
From: Rajkumar Ayyasamy <arajkuma@codeaurora.org>
Date: Wed, 18 Mar 2020 17:08:11 +0530
Subject: [PATCH] clk: ipq: support for resetting multiple bits

Current reset structure takes only one reset bit and
calculates the bitmask in its reset operation. Some of the
reset registers contains multiple bits in which each bit
will be associated with subsystem reset inside the block. To
reset properly the complete block, all the subsystem reset
should be triggered at same time i.e the register write
should go in one AHB write.

This patch adds the support for giving the complete bitmask
in reset structure and reset operation will use this bitmask
for all reset operations.

Change-Id: Ief49f8746624a0fc1e067d815725ae7c254c2c6f
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
(cherry picked from commit ef555fc1cffa6e823a9d929711cacae0821b35ec)
Signed-off-by: Rajkumar Ayyasamy <arajkuma@codeaurora.org>
---
drivers/clk/qcom/reset.c | 4 ++--
drivers/clk/qcom/reset.h | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c
index 819d194be8f7..8ad7b50dd534 100644
--- a/drivers/clk/qcom/reset.c
+++ b/drivers/clk/qcom/reset.c
@@ -28,7 +28,7 @@ qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)

rst = to_qcom_reset_controller(rcdev);
map = &rst->reset_map[id];
- mask = BIT(map->bit);
+ mask = map->bitmask ? map->bitmask : BIT(map->bit);

return regmap_update_bits(rst->regmap, map->reg, mask, mask);
}
@@ -42,7 +42,7 @@ qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)

rst = to_qcom_reset_controller(rcdev);
map = &rst->reset_map[id];
- mask = BIT(map->bit);
+ mask = map->bitmask ? map->bitmask : BIT(map->bit);

return regmap_update_bits(rst->regmap, map->reg, mask, 0);
}
diff --git a/drivers/clk/qcom/reset.h b/drivers/clk/qcom/reset.h
index 2a08b5e282c7..0410f83bf2bb 100644
--- a/drivers/clk/qcom/reset.h
+++ b/drivers/clk/qcom/reset.h
@@ -11,6 +11,7 @@
struct qcom_reset_map {
unsigned int reg;
u8 bit;
+ u32 bitmask;
};

struct regmap;
--
2.35.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
From 0981de6ff0a072fd25d919e661ac22890a7a1e34 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 1 Jan 2022 18:15:03 +0100
Subject: [PATCH] clk: qcom: ipq8074: add missing networking resets

Downstream QCA 5.4 kernel defines networking resets which are not present
in the mainline kernel but are required for the networking drivers.

So, port the downstream resets and avoid using magic values for mask,
construct mask for resets which require multiple bits to be set/cleared.

Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/clk/qcom/gcc-ipq8074.c | 14 ++++++++++++++
include/dt-bindings/clock/qcom,gcc-ipq8074.h | 14 ++++++++++++++
2 files changed, 28 insertions(+)

diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index 4d6e8c47515f..759e676d4110 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4745,6 +4745,20 @@ static const struct qcom_reset_map gcc_ipq8074_resets[] = {
[GCC_PCIE1_AHB_ARES] = { 0x76040, 5 },
[GCC_PCIE1_AXI_MASTER_STICKY_ARES] = { 0x76040, 6 },
[GCC_WCSSAON_RESET] = { 0x59010, 0 },
+ [GCC_PPE_FULL_RESET] = { 0x68014, 0, GENMASK(19, 16) },
+ [GCC_UNIPHY0_SOFT_RESET] = { 0x56004, 0, GENMASK(13, 4) | BIT(1) },
+ [GCC_UNIPHY0_XPCS_RESET] = { 0x56004, 2 },
+ [GCC_UNIPHY1_SOFT_RESET] = { 0x56104, 0, GENMASK(5, 4) | BIT(1) },
+ [GCC_UNIPHY1_XPCS_RESET] = { 0x56104, 2 },
+ [GCC_UNIPHY2_SOFT_RESET] = { 0x56204, 0, GENMASK(5, 4) | BIT(1) },
+ [GCC_UNIPHY2_XPCS_RESET] = { 0x56204, 2 },
+ [GCC_EDMA_HW_RESET] = { 0x68014, 0, GENMASK(21, 20) },
+ [GCC_NSSPORT1_RESET] = { 0x68014, 0, BIT(24) | GENMASK(1, 0) },
+ [GCC_NSSPORT2_RESET] = { 0x68014, 0, BIT(25) | GENMASK(3, 2) },
+ [GCC_NSSPORT3_RESET] = { 0x68014, 0, BIT(26) | GENMASK(5, 4) },
+ [GCC_NSSPORT4_RESET] = { 0x68014, 0, BIT(27) | GENMASK(9, 8) },
+ [GCC_NSSPORT5_RESET] = { 0x68014, 0, BIT(28) | GENMASK(11, 10) },
+ [GCC_NSSPORT6_RESET] = { 0x68014, 0, BIT(29) | GENMASK(13, 12) },
};

static const struct of_device_id gcc_ipq8074_match_table[] = {
diff --git a/include/dt-bindings/clock/qcom,gcc-ipq8074.h b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
index 9b1c42bc430c..07402d970959 100644
--- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
@@ -367,5 +367,19 @@
#define GCC_PCIE1_AXI_MASTER_STICKY_ARES 130
#define GCC_PCIE0_AXI_SLAVE_STICKY_ARES 131
#define GCC_WCSSAON_RESET 132
+#define GCC_PPE_FULL_RESET 133
+#define GCC_UNIPHY0_SOFT_RESET 134
+#define GCC_UNIPHY0_XPCS_RESET 135
+#define GCC_UNIPHY1_SOFT_RESET 136
+#define GCC_UNIPHY1_XPCS_RESET 137
+#define GCC_UNIPHY2_SOFT_RESET 138
+#define GCC_UNIPHY2_XPCS_RESET 139
+#define GCC_EDMA_HW_RESET 140
+#define GCC_NSSPORT1_RESET 141
+#define GCC_NSSPORT2_RESET 142
+#define GCC_NSSPORT3_RESET 143
+#define GCC_NSSPORT4_RESET 144
+#define GCC_NSSPORT5_RESET 145
+#define GCC_NSSPORT6_RESET 146

#endif
--
2.35.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
From 73344249026d524544e2f86c737759737c962e28 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 1 Jan 2022 18:48:56 +0100
Subject: [PATCH] clk: qcom: ipq8074: fix NSS core PLL-s
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Like in IPQ6018 the NSS related Alpha PLL-s require initial configuration
to work.

So, obtain the regmap that is required for the Alpha PLL configuration
and thus utilize the qcom_cc_really_probe() as we already have the regmap.
Then utilize the Alpha PLL configs from the downstream QCA 5.4 based
kernel to configure them.

This fixes the UBI32 and NSS crypto PLL-s failing to get enabled by the
kernel.

Fixes: b8e7e519625f ("clk: qcom: ipq8074: add remaining PLL’s")
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/clk/qcom/gcc-ipq8074.c | 39 +++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index 759e676d4110..244d1d8468e4 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4371,6 +4371,33 @@ static struct clk_branch gcc_pcie0_axi_s_bridge_clk = {
},
};

+static const struct alpha_pll_config ubi32_pll_config = {
+ .l = 0x4e,
+ .config_ctl_val = 0x200d4aa8,
+ .config_ctl_hi_val = 0x3c2,
+ .main_output_mask = BIT(0),
+ .aux_output_mask = BIT(1),
+ .pre_div_val = 0x0,
+ .pre_div_mask = BIT(12),
+ .post_div_val = 0x0,
+ .post_div_mask = GENMASK(9, 8),
+};
+
+static const struct alpha_pll_config nss_crypto_pll_config = {
+ .l = 0x3e,
+ .alpha = 0x0,
+ .alpha_hi = 0x80,
+ .config_ctl_val = 0x4001055b,
+ .main_output_mask = BIT(0),
+ .pre_div_val = 0x0,
+ .pre_div_mask = GENMASK(14, 12),
+ .post_div_val = 0x1 << 8,
+ .post_div_mask = GENMASK(11, 8),
+ .vco_mask = GENMASK(21, 20),
+ .vco_val = 0x0,
+ .alpha_en_mask = BIT(24),
+};
+
static struct clk_hw *gcc_ipq8074_hws[] = {
&gpll0_out_main_div2.hw,
&gpll6_out_main_div2.hw,
@@ -4787,7 +4814,17 @@ static const struct qcom_cc_desc gcc_ipq8074_desc = {

static int gcc_ipq8074_probe(struct platform_device *pdev)
{
- return qcom_cc_probe(pdev, &gcc_ipq8074_desc);
+ struct regmap *regmap;
+
+ regmap = qcom_cc_map(pdev, &gcc_ipq8074_desc);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
+ clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
+ &nss_crypto_pll_config);
+
+ return qcom_cc_really_probe(pdev, &gcc_ipq8074_desc, regmap);
}

static struct platform_driver gcc_ipq8074_driver = {
--
2.35.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
From 1a33a943c643b43033af936f297898b540361c62 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 1 Jan 2022 19:11:55 +0100
Subject: [PATCH] clk: qcom: ipq8074: disable USB GDSC-s SW_COLLAPSE

Like in IPQ6018 Qualcomm intentionally disables the SW_COLLAPSE on the USB
GDSC-s.

This could potentially be better handled by utilizing the GDSC driver, but
I am not familiar with it nor do I have datasheets.

Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/clk/qcom/gcc-ipq8074.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index 244d1d8468e4..827c37787fa4 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4820,6 +4820,11 @@ static int gcc_ipq8074_probe(struct platform_device *pdev)
if (IS_ERR(regmap))
return PTR_ERR(regmap);

+ /* Disable SW_COLLAPSE for USB0 GDSCR */
+ regmap_update_bits(regmap, 0x3e078, BIT(0), 0x0);
+ /* Disable SW_COLLAPSE for USB1 GDSCR */
+ regmap_update_bits(regmap, 0x3f078, BIT(0), 0x0);
+
clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
&nss_crypto_pll_config);
--
2.35.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
From 124d46f0397daf0bc13270ee43cc7d8166170f04 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 1 Jan 2022 19:14:59 +0100
Subject: [PATCH] clk: qcom: ipq8074: SW workaround for UBI32 PLL lock

UBI32 Huayra PLL fails to lock in 5 us in some SoC silicon and thus it
will cause the wait_for_pll() to timeout and thus return the error
indicating that the PLL failed to lock.

This is bug in Huayra PLL HW for which SW workaround
is to set bit 26 of TEST_CTL register.

This is ported from the QCA 5.4 based downstream kernel.

Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/clk/qcom/gcc-ipq8074.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index 827c37787fa4..cef89ea761d6 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -4825,6 +4825,9 @@ static int gcc_ipq8074_probe(struct platform_device *pdev)
/* Disable SW_COLLAPSE for USB1 GDSCR */
regmap_update_bits(regmap, 0x3f078, BIT(0), 0x0);

+ /* SW Workaround for UBI32 Huayra PLL */
+ regmap_update_bits(regmap, 0x2501c, BIT(26), BIT(26));
+
clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
&nss_crypto_pll_config);
--
2.35.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
From 7cb389923931167cc772f36fabe5f140abb28053 Mon Sep 17 00:00:00 2001
From: Robert Marko <robimarko@gmail.com>
Date: Sat, 1 Jan 2022 19:29:48 +0100
Subject: [PATCH] clk: qcom: ipq8074: fix NSS port frequency tables

NSS port 5 and 6 frequency tables are currently broken and are causing a
wide ranges of issue like 1G not working at all on port 6 or port 5 being
clocked with 312 instead of 125 MHz as UNIPHY1 gets selected.

So, update the frequency tables with the ones from the downstream QCA 5.4
based kernel which has already fixed this.

Fixes: 7117a51ed303 ("clk: qcom: ipq8074: add NSS ethernet port clocks")
Signed-off-by: Robert Marko <robimarko@gmail.com>
---
drivers/clk/qcom/gcc-ipq8074.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
index cef89ea761d6..1e493f19fa44 100644
--- a/drivers/clk/qcom/gcc-ipq8074.c
+++ b/drivers/clk/qcom/gcc-ipq8074.c
@@ -1788,8 +1788,10 @@ static struct clk_regmap_div nss_port4_tx_div_clk_src = {
static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(25000000, P_UNIPHY1_RX, 12.5, 0, 0),
+ F(25000000, P_UNIPHY0_RX, 5, 0, 0),
F(78125000, P_UNIPHY1_RX, 4, 0, 0),
F(125000000, P_UNIPHY1_RX, 2.5, 0, 0),
+ F(125000000, P_UNIPHY0_RX, 1, 0, 0),
F(156250000, P_UNIPHY1_RX, 2, 0, 0),
F(312500000, P_UNIPHY1_RX, 1, 0, 0),
{ }
@@ -1828,8 +1830,10 @@ static struct clk_regmap_div nss_port5_rx_div_clk_src = {
static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(25000000, P_UNIPHY1_TX, 12.5, 0, 0),
+ F(25000000, P_UNIPHY0_TX, 5, 0, 0),
F(78125000, P_UNIPHY1_TX, 4, 0, 0),
F(125000000, P_UNIPHY1_TX, 2.5, 0, 0),
+ F(125000000, P_UNIPHY0_TX, 1, 0, 0),
F(156250000, P_UNIPHY1_TX, 2, 0, 0),
F(312500000, P_UNIPHY1_TX, 1, 0, 0),
{ }
@@ -1867,8 +1871,10 @@ static struct clk_regmap_div nss_port5_tx_div_clk_src = {

static const struct freq_tbl ftbl_nss_port6_rx_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
+ F(25000000, P_UNIPHY2_RX, 5, 0, 0),
F(25000000, P_UNIPHY2_RX, 12.5, 0, 0),
F(78125000, P_UNIPHY2_RX, 4, 0, 0),
+ F(125000000, P_UNIPHY2_RX, 1, 0, 0),
F(125000000, P_UNIPHY2_RX, 2.5, 0, 0),
F(156250000, P_UNIPHY2_RX, 2, 0, 0),
F(312500000, P_UNIPHY2_RX, 1, 0, 0),
@@ -1907,8 +1913,10 @@ static struct clk_regmap_div nss_port6_rx_div_clk_src = {

static const struct freq_tbl ftbl_nss_port6_tx_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
+ F(25000000, P_UNIPHY2_TX, 5, 0, 0),
F(25000000, P_UNIPHY2_TX, 12.5, 0, 0),
F(78125000, P_UNIPHY2_TX, 4, 0, 0),
+ F(125000000, P_UNIPHY2_TX, 1, 0, 0),
F(125000000, P_UNIPHY2_TX, 2.5, 0, 0),
F(156250000, P_UNIPHY2_TX, 2, 0, 0),
F(312500000, P_UNIPHY2_TX, 1, 0, 0),
--
2.35.1

0 comments on commit 7a6377c

Please sign in to comment.