Update On Fri Apr 25 20:35:40 CEST 2025

This commit is contained in:
github-action[bot]
2025-04-25 20:35:40 +02:00
parent 05a86235e7
commit 5ddea2b00c
49 changed files with 2687 additions and 128 deletions
+1
View File
@@ -979,3 +979,4 @@ Update On Thu Apr 17 20:38:25 CEST 2025
Update On Fri Apr 18 20:35:44 CEST 2025
Update On Sat Apr 19 20:35:13 CEST 2025
Update On Fri Apr 25 14:32:58 CEST 2025
Update On Fri Apr 25 20:35:32 CEST 2025
+1
View File
@@ -396,6 +396,7 @@ CONFIG_QCOM_BAM_DMA=y
# CONFIG_QCOM_GSBI is not set
# CONFIG_QCOM_HFPLL is not set
# CONFIG_QCOM_ICC_BWMON is not set
# CONFIG_QCOM_IPA is not set
# CONFIG_QCOM_IPCC is not set
# CONFIG_QCOM_LLCC is not set
CONFIG_QCOM_MDT_LOADER=y
@@ -44,7 +44,6 @@ CONFIG_IPQ_CMN_PLL=y
CONFIG_IPQ_NSSCC_9574=y
CONFIG_IPQ_NSSCC_QCA8K=y
CONFIG_QCOM_PPE=y
CONFIG_QCOM_IPA=y
CONFIG_INTERCONNECT_QCOM=y
CONFIG_INTERCONNECT_QCOM_OSM_L3=y
CONFIG_MTD_SPI_NAND=y
@@ -320,7 +320,7 @@ Signed-off-by: Bjorn Andersson <andersson@kernel.org>
static struct platform_driver disp_cc_sm6125_driver = {
--- a/drivers/clk/qcom/dispcc-sm6350.c
+++ b/drivers/clk/qcom/dispcc-sm6350.c
@@ -761,7 +761,7 @@ static int disp_cc_sm6350_probe(struct p
@@ -760,7 +760,7 @@ static int disp_cc_sm6350_probe(struct p
clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
@@ -661,7 +661,7 @@ Signed-off-by: Bjorn Andersson <andersson@kernel.org>
static struct platform_driver gcc_sm6125_driver = {
--- a/drivers/clk/qcom/gcc-sm6350.c
+++ b/drivers/clk/qcom/gcc-sm6350.c
@@ -2559,7 +2559,7 @@ static int gcc_sm6350_probe(struct platf
@@ -2565,7 +2565,7 @@ static int gcc_sm6350_probe(struct platf
if (ret)
return ret;
@@ -0,0 +1,388 @@
From 652935ba05860eadaa19ac9efe7aea61fb7a3aef Mon Sep 17 00:00:00 2001
From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Date: Wed, 17 Apr 2024 12:32:53 +0530
Subject: [PATCH] PCI: qcom: Use devm_clk_bulk_get_all() API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There is no need for the device drivers to validate the clocks defined in
Devicetree. The validation should be performed by the DT schema and the
drivers should just get all the clocks from DT. Right now the driver
hardcodes the clock info and validates them against DT which is redundant.
So use devm_clk_bulk_get_all() that just gets all the clocks defined in DT
and get rid of all static clocks info from the driver. This simplifies the
driver.
Link: https://lore.kernel.org/linux-pci/20240417-pci-qcom-clk-bulk-v1-1-52ca19b3d6b2@linaro.org
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/controller/dwc/pcie-qcom.c | 177 ++++++++-----------------
1 file changed, 58 insertions(+), 119 deletions(-)
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -151,58 +151,56 @@
#define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0))
-#define QCOM_PCIE_1_0_0_MAX_CLOCKS 4
struct qcom_pcie_resources_1_0_0 {
- struct clk_bulk_data clks[QCOM_PCIE_1_0_0_MAX_CLOCKS];
+ struct clk_bulk_data *clks;
+ int num_clks;
struct reset_control *core;
struct regulator *vdda;
};
-#define QCOM_PCIE_2_1_0_MAX_CLOCKS 5
#define QCOM_PCIE_2_1_0_MAX_RESETS 6
#define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
struct qcom_pcie_resources_2_1_0 {
- struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];
+ struct clk_bulk_data *clks;
+ int num_clks;
struct reset_control_bulk_data resets[QCOM_PCIE_2_1_0_MAX_RESETS];
int num_resets;
struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY];
};
-#define QCOM_PCIE_2_3_2_MAX_CLOCKS 4
#define QCOM_PCIE_2_3_2_MAX_SUPPLY 2
struct qcom_pcie_resources_2_3_2 {
- struct clk_bulk_data clks[QCOM_PCIE_2_3_2_MAX_CLOCKS];
+ struct clk_bulk_data *clks;
+ int num_clks;
struct regulator_bulk_data supplies[QCOM_PCIE_2_3_2_MAX_SUPPLY];
};
-#define QCOM_PCIE_2_3_3_MAX_CLOCKS 5
#define QCOM_PCIE_2_3_3_MAX_RESETS 7
struct qcom_pcie_resources_2_3_3 {
- struct clk_bulk_data clks[QCOM_PCIE_2_3_3_MAX_CLOCKS];
+ struct clk_bulk_data *clks;
+ int num_clks;
struct reset_control_bulk_data rst[QCOM_PCIE_2_3_3_MAX_RESETS];
};
-#define QCOM_PCIE_2_4_0_MAX_CLOCKS 4
#define QCOM_PCIE_2_4_0_MAX_RESETS 12
struct qcom_pcie_resources_2_4_0 {
- struct clk_bulk_data clks[QCOM_PCIE_2_4_0_MAX_CLOCKS];
+ struct clk_bulk_data *clks;
int num_clks;
struct reset_control_bulk_data resets[QCOM_PCIE_2_4_0_MAX_RESETS];
int num_resets;
};
-#define QCOM_PCIE_2_7_0_MAX_CLOCKS 15
#define QCOM_PCIE_2_7_0_MAX_SUPPLIES 2
struct qcom_pcie_resources_2_7_0 {
- struct clk_bulk_data clks[QCOM_PCIE_2_7_0_MAX_CLOCKS];
+ struct clk_bulk_data *clks;
int num_clks;
struct regulator_bulk_data supplies[QCOM_PCIE_2_7_0_MAX_SUPPLIES];
struct reset_control *rst;
};
-#define QCOM_PCIE_2_9_0_MAX_CLOCKS 5
struct qcom_pcie_resources_2_9_0 {
- struct clk_bulk_data clks[QCOM_PCIE_2_9_0_MAX_CLOCKS];
+ struct clk_bulk_data *clks;
+ int num_clks;
struct reset_control *rst;
};
@@ -313,21 +311,11 @@ static int qcom_pcie_get_resources_2_1_0
if (ret)
return ret;
- res->clks[0].id = "iface";
- res->clks[1].id = "core";
- res->clks[2].id = "phy";
- res->clks[3].id = "aux";
- res->clks[4].id = "ref";
-
- /* iface, core, phy are required */
- ret = devm_clk_bulk_get(dev, 3, res->clks);
- if (ret < 0)
- return ret;
-
- /* aux, ref are optional */
- ret = devm_clk_bulk_get_optional(dev, 2, res->clks + 3);
- if (ret < 0)
- return ret;
+ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
+ if (res->num_clks < 0) {
+ dev_err(dev, "Failed to get clocks\n");
+ return res->num_clks;
+ }
res->resets[0].id = "pci";
res->resets[1].id = "axi";
@@ -349,7 +337,7 @@ static void qcom_pcie_deinit_2_1_0(struc
{
struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+ clk_bulk_disable_unprepare(res->num_clks, res->clks);
reset_control_bulk_assert(res->num_resets, res->resets);
writel(1, pcie->parf + PARF_PHY_CTRL);
@@ -401,7 +389,7 @@ static int qcom_pcie_post_init_2_1_0(str
val &= ~PHY_TEST_PWR_DOWN;
writel(val, pcie->parf + PARF_PHY_CTRL);
- ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+ ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
if (ret)
return ret;
@@ -452,20 +440,16 @@ static int qcom_pcie_get_resources_1_0_0
struct qcom_pcie_resources_1_0_0 *res = &pcie->res.v1_0_0;
struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev;
- int ret;
res->vdda = devm_regulator_get(dev, "vdda");
if (IS_ERR(res->vdda))
return PTR_ERR(res->vdda);
- res->clks[0].id = "iface";
- res->clks[1].id = "aux";
- res->clks[2].id = "master_bus";
- res->clks[3].id = "slave_bus";
-
- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
- if (ret < 0)
- return ret;
+ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
+ if (res->num_clks < 0) {
+ dev_err(dev, "Failed to get clocks\n");
+ return res->num_clks;
+ }
res->core = devm_reset_control_get_exclusive(dev, "core");
return PTR_ERR_OR_ZERO(res->core);
@@ -476,7 +460,7 @@ static void qcom_pcie_deinit_1_0_0(struc
struct qcom_pcie_resources_1_0_0 *res = &pcie->res.v1_0_0;
reset_control_assert(res->core);
- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+ clk_bulk_disable_unprepare(res->num_clks, res->clks);
regulator_disable(res->vdda);
}
@@ -493,7 +477,7 @@ static int qcom_pcie_init_1_0_0(struct q
return ret;
}
- ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+ ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
if (ret) {
dev_err(dev, "cannot prepare/enable clocks\n");
goto err_assert_reset;
@@ -508,7 +492,7 @@ static int qcom_pcie_init_1_0_0(struct q
return 0;
err_disable_clks:
- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+ clk_bulk_disable_unprepare(res->num_clks, res->clks);
err_assert_reset:
reset_control_assert(res->core);
@@ -556,14 +540,11 @@ static int qcom_pcie_get_resources_2_3_2
if (ret)
return ret;
- res->clks[0].id = "aux";
- res->clks[1].id = "cfg";
- res->clks[2].id = "bus_master";
- res->clks[3].id = "bus_slave";
-
- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
- if (ret < 0)
- return ret;
+ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
+ if (res->num_clks < 0) {
+ dev_err(dev, "Failed to get clocks\n");
+ return res->num_clks;
+ }
return 0;
}
@@ -572,7 +553,7 @@ static void qcom_pcie_deinit_2_3_2(struc
{
struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2;
- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+ clk_bulk_disable_unprepare(res->num_clks, res->clks);
regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
}
@@ -589,7 +570,7 @@ static int qcom_pcie_init_2_3_2(struct q
return ret;
}
- ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+ ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
if (ret) {
dev_err(dev, "cannot prepare/enable clocks\n");
regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
@@ -637,17 +618,11 @@ static int qcom_pcie_get_resources_2_4_0
bool is_ipq = of_device_is_compatible(dev->of_node, "qcom,pcie-ipq4019");
int ret;
- res->clks[0].id = "aux";
- res->clks[1].id = "master_bus";
- res->clks[2].id = "slave_bus";
- res->clks[3].id = "iface";
-
- /* qcom,pcie-ipq4019 is defined without "iface" */
- res->num_clks = is_ipq ? 3 : 4;
-
- ret = devm_clk_bulk_get(dev, res->num_clks, res->clks);
- if (ret < 0)
- return ret;
+ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
+ if (res->num_clks < 0) {
+ dev_err(dev, "Failed to get clocks\n");
+ return res->num_clks;
+ }
res->resets[0].id = "axi_m";
res->resets[1].id = "axi_s";
@@ -718,15 +693,11 @@ static int qcom_pcie_get_resources_2_3_3
struct device *dev = pci->dev;
int ret;
- res->clks[0].id = "iface";
- res->clks[1].id = "axi_m";
- res->clks[2].id = "axi_s";
- res->clks[3].id = "ahb";
- res->clks[4].id = "aux";
-
- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
- if (ret < 0)
- return ret;
+ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
+ if (res->num_clks < 0) {
+ dev_err(dev, "Failed to get clocks\n");
+ return res->num_clks;
+ }
res->rst[0].id = "axi_m";
res->rst[1].id = "axi_s";
@@ -747,7 +718,7 @@ static void qcom_pcie_deinit_2_3_3(struc
{
struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3;
- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+ clk_bulk_disable_unprepare(res->num_clks, res->clks);
}
static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)
@@ -777,7 +748,7 @@ static int qcom_pcie_init_2_3_3(struct q
*/
usleep_range(2000, 2500);
- ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+ ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
if (ret) {
dev_err(dev, "cannot prepare/enable clocks\n");
goto err_assert_resets;
@@ -838,8 +809,6 @@ static int qcom_pcie_get_resources_2_7_0
struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev;
- unsigned int num_clks, num_opt_clks;
- unsigned int idx;
int ret;
res->rst = devm_reset_control_array_get_exclusive(dev);
@@ -853,36 +822,11 @@ static int qcom_pcie_get_resources_2_7_0
if (ret)
return ret;
- idx = 0;
- res->clks[idx++].id = "aux";
- res->clks[idx++].id = "cfg";
- res->clks[idx++].id = "bus_master";
- res->clks[idx++].id = "bus_slave";
- res->clks[idx++].id = "slave_q2a";
-
- num_clks = idx;
-
- ret = devm_clk_bulk_get(dev, num_clks, res->clks);
- if (ret < 0)
- return ret;
-
- res->clks[idx++].id = "tbu";
- res->clks[idx++].id = "ddrss_sf_tbu";
- res->clks[idx++].id = "aggre0";
- res->clks[idx++].id = "aggre1";
- res->clks[idx++].id = "noc_aggr";
- res->clks[idx++].id = "noc_aggr_4";
- res->clks[idx++].id = "noc_aggr_south_sf";
- res->clks[idx++].id = "cnoc_qx";
- res->clks[idx++].id = "sleep";
- res->clks[idx++].id = "cnoc_sf_axi";
-
- num_opt_clks = idx - num_clks;
- res->num_clks = idx;
-
- ret = devm_clk_bulk_get_optional(dev, num_opt_clks, res->clks + num_clks);
- if (ret < 0)
- return ret;
+ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
+ if (res->num_clks < 0) {
+ dev_err(dev, "Failed to get clocks\n");
+ return res->num_clks;
+ }
return 0;
}
@@ -1073,17 +1017,12 @@ static int qcom_pcie_get_resources_2_9_0
struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev;
- int ret;
-
- res->clks[0].id = "iface";
- res->clks[1].id = "axi_m";
- res->clks[2].id = "axi_s";
- res->clks[3].id = "axi_bridge";
- res->clks[4].id = "rchng";
- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
- if (ret < 0)
- return ret;
+ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
+ if (res->num_clks < 0) {
+ dev_err(dev, "Failed to get clocks\n");
+ return res->num_clks;
+ }
res->rst = devm_reset_control_array_get_exclusive(dev);
if (IS_ERR(res->rst))
@@ -1096,7 +1035,7 @@ static void qcom_pcie_deinit_2_9_0(struc
{
struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+ clk_bulk_disable_unprepare(res->num_clks, res->clks);
}
static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
@@ -1125,7 +1064,7 @@ static int qcom_pcie_init_2_9_0(struct q
usleep_range(2000, 2500);
- return clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+ return clk_bulk_prepare_enable(res->num_clks, res->clks);
}
static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
@@ -0,0 +1,277 @@
From 10ba0854c5e6165b58e17bda5fb671e729fecf9e Mon Sep 17 00:00:00 2001
From: Prudhvi Yarlagadda <quic_pyarlaga@quicinc.com>
Date: Wed, 14 Aug 2024 15:03:38 -0700
Subject: [PATCH] PCI: qcom: Disable mirroring of DBI and iATU register space
in BAR region
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PARF hardware block which is a wrapper on top of DWC PCIe controller
mirrors the DBI and ATU register space. It uses PARF_SLV_ADDR_SPACE_SIZE
register to get the size of the memory block to be mirrored and uses
PARF_DBI_BASE_ADDR, PARF_ATU_BASE_ADDR registers to determine the base
address of DBI and ATU space inside the memory block that is being
mirrored.
When a memory region which is located above the SLV_ADDR_SPACE_SIZE
boundary is used for BAR region then there could be an overlap of DBI and
ATU address space that is getting mirrored and the BAR region. This
results in DBI and ATU address space contents getting updated when a PCIe
function driver tries updating the BAR/MMIO memory region. Reference
memory map of the PCIe memory region with DBI and ATU address space
overlapping BAR region is as below.
|---------------|
| |
| |
------- --------|---------------|
| | |---------------|
| | | DBI |
| | |---------------|---->DBI_BASE_ADDR
| | | |
| | | |
| PCIe | |---->2*SLV_ADDR_SPACE_SIZE
| BAR/MMIO|---------------|
| Region | ATU |
| | |---------------|---->ATU_BASE_ADDR
| | | |
PCIe | |---------------|
Memory | | DBI |
Region | |---------------|---->DBI_BASE_ADDR
| | | |
| --------| |
| | |---->SLV_ADDR_SPACE_SIZE
| |---------------|
| | ATU |
| |---------------|---->ATU_BASE_ADDR
| | |
| |---------------|
| | DBI |
| |---------------|---->DBI_BASE_ADDR
| | |
| | |
----------------|---------------|
| |
| |
| |
|---------------|
Currently memory region beyond the SLV_ADDR_SPACE_SIZE boundary is not
used for BAR region which is why the above mentioned issue is not
encountered. This issue is discovered as part of internal testing when we
tried moving the BAR region beyond the SLV_ADDR_SPACE_SIZE boundary. Hence
we are trying to fix this.
As PARF hardware block mirrors DBI and ATU register space after every
PARF_SLV_ADDR_SPACE_SIZE (default 0x1000000) boundary multiple, program
maximum possible size to this register by writing 0x80000000 to it(it
considers only powers of 2 as values) to avoid mirroring DBI and ATU to
BAR/MMIO region. Write the physical base address of DBI and ATU register
blocks to PARF_DBI_BASE_ADDR (default 0x0) and PARF_ATU_BASE_ADDR (default
0x1000) respectively to make sure DBI and ATU blocks are at expected
memory locations.
The register offsets PARF_DBI_BASE_ADDR_V2, PARF_SLV_ADDR_SPACE_SIZE_V2
and PARF_ATU_BASE_ADDR are applicable for platforms that use Qcom IP
rev 1.9.0, 2.7.0 and 2.9.0. PARF_DBI_BASE_ADDR_V2 and
PARF_SLV_ADDR_SPACE_SIZE_V2 are applicable for Qcom IP rev 2.3.3.
PARF_DBI_BASE_ADDR and PARF_SLV_ADDR_SPACE_SIZE are applicable for Qcom
IP rev 1.0.0, 2.3.2 and 2.4.0. Update init()/post_init() functions of the
respective Qcom IP versions to program applicable PARF_DBI_BASE_ADDR,
PARF_SLV_ADDR_SPACE_SIZE and PARF_ATU_BASE_ADDR register offsets. Update
the SLV_ADDR_SPACE_SZ macro to 0x80000000 to set highest bit in
PARF_SLV_ADDR_SPACE_SIZE register.
Cache DBI and iATU physical addresses in 'struct dw_pcie' so that
pcie_qcom.c driver can program these addresses in the PARF_DBI_BASE_ADDR
and PARF_ATU_BASE_ADDR registers.
Suggested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/linux-pci/20240814220338.1969668-1-quic_pyarlaga@quicinc.com
Signed-off-by: Prudhvi Yarlagadda <quic_pyarlaga@quicinc.com>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Mayank Rana <quic_mrana@quicinc.com>
---
drivers/pci/controller/dwc/pcie-designware.c | 2 +
drivers/pci/controller/dwc/pcie-designware.h | 2 +
drivers/pci/controller/dwc/pcie-qcom.c | 72 ++++++++++++++++----
3 files changed, 61 insertions(+), 15 deletions(-)
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -112,6 +112,7 @@ int dw_pcie_get_resources(struct dw_pcie
pci->dbi_base = devm_pci_remap_cfg_resource(pci->dev, res);
if (IS_ERR(pci->dbi_base))
return PTR_ERR(pci->dbi_base);
+ pci->dbi_phys_addr = res->start;
}
/* DBI2 is mainly useful for the endpoint controller */
@@ -134,6 +135,7 @@ int dw_pcie_get_resources(struct dw_pcie
pci->atu_base = devm_ioremap_resource(pci->dev, res);
if (IS_ERR(pci->atu_base))
return PTR_ERR(pci->atu_base);
+ pci->atu_phys_addr = res->start;
} else {
pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
}
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -384,8 +384,10 @@ struct dw_pcie_ops {
struct dw_pcie {
struct device *dev;
void __iomem *dbi_base;
+ resource_size_t dbi_phys_addr;
void __iomem *dbi_base2;
void __iomem *atu_base;
+ resource_size_t atu_phys_addr;
size_t atu_size;
u32 num_ib_windows;
u32 num_ob_windows;
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -43,6 +43,7 @@
#define PARF_PHY_REFCLK 0x4c
#define PARF_CONFIG_BITS 0x50
#define PARF_DBI_BASE_ADDR 0x168
+#define PARF_SLV_ADDR_SPACE_SIZE 0x16c
#define PARF_MHI_CLOCK_RESET_CTRL 0x174
#define PARF_AXI_MSTR_WR_ADDR_HALT 0x178
#define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8
@@ -50,7 +51,12 @@
#define PARF_LTSSM 0x1b0
#define PARF_SID_OFFSET 0x234
#define PARF_BDF_TRANSLATE_CFG 0x24c
-#define PARF_SLV_ADDR_SPACE_SIZE 0x358
+#define PARF_DBI_BASE_ADDR_V2 0x350
+#define PARF_DBI_BASE_ADDR_V2_HI 0x354
+#define PARF_SLV_ADDR_SPACE_SIZE_V2 0x358
+#define PARF_SLV_ADDR_SPACE_SIZE_V2_HI 0x35c
+#define PARF_ATU_BASE_ADDR 0x634
+#define PARF_ATU_BASE_ADDR_HI 0x638
#define PARF_DEVICE_TYPE 0x1000
#define PARF_BDF_TO_SID_TABLE_N 0x2000
#define PARF_BDF_TO_SID_CFG 0x2c00
@@ -105,7 +111,7 @@
#define PHY_RX0_EQ(x) FIELD_PREP(GENMASK(26, 24), x)
/* PARF_SLV_ADDR_SPACE_SIZE register value */
-#define SLV_ADDR_SPACE_SZ 0x10000000
+#define SLV_ADDR_SPACE_SZ 0x80000000
/* PARF_MHI_CLOCK_RESET_CTRL register fields */
#define AHB_CLK_EN BIT(0)
@@ -285,6 +291,50 @@ static void qcom_pcie_clear_hpc(struct d
dw_pcie_dbi_ro_wr_dis(pci);
}
+static void qcom_pcie_configure_dbi_base(struct qcom_pcie *pcie)
+{
+ struct dw_pcie *pci = pcie->pci;
+
+ if (pci->dbi_phys_addr) {
+ /*
+ * PARF_DBI_BASE_ADDR register is in CPU domain and require to
+ * be programmed with CPU physical address.
+ */
+ writel(lower_32_bits(pci->dbi_phys_addr), pcie->parf +
+ PARF_DBI_BASE_ADDR);
+ writel(SLV_ADDR_SPACE_SZ, pcie->parf +
+ PARF_SLV_ADDR_SPACE_SIZE);
+ }
+}
+
+static void qcom_pcie_configure_dbi_atu_base(struct qcom_pcie *pcie)
+{
+ struct dw_pcie *pci = pcie->pci;
+
+ if (pci->dbi_phys_addr) {
+ /*
+ * PARF_DBI_BASE_ADDR_V2 and PARF_ATU_BASE_ADDR registers are
+ * in CPU domain and require to be programmed with CPU
+ * physical addresses.
+ */
+ writel(lower_32_bits(pci->dbi_phys_addr), pcie->parf +
+ PARF_DBI_BASE_ADDR_V2);
+ writel(upper_32_bits(pci->dbi_phys_addr), pcie->parf +
+ PARF_DBI_BASE_ADDR_V2_HI);
+
+ if (pci->atu_phys_addr) {
+ writel(lower_32_bits(pci->atu_phys_addr), pcie->parf +
+ PARF_ATU_BASE_ADDR);
+ writel(upper_32_bits(pci->atu_phys_addr), pcie->parf +
+ PARF_ATU_BASE_ADDR_HI);
+ }
+
+ writel(0x0, pcie->parf + PARF_SLV_ADDR_SPACE_SIZE_V2);
+ writel(SLV_ADDR_SPACE_SZ, pcie->parf +
+ PARF_SLV_ADDR_SPACE_SIZE_V2_HI);
+ }
+}
+
static void qcom_pcie_2_1_0_ltssm_enable(struct qcom_pcie *pcie)
{
u32 val;
@@ -501,8 +551,7 @@ err_assert_reset:
static int qcom_pcie_post_init_1_0_0(struct qcom_pcie *pcie)
{
- /* change DBI base address */
- writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+ qcom_pcie_configure_dbi_base(pcie);
if (IS_ENABLED(CONFIG_PCI_MSI)) {
u32 val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT);
@@ -589,8 +638,7 @@ static int qcom_pcie_post_init_2_3_2(str
val &= ~PHY_TEST_PWR_DOWN;
writel(val, pcie->parf + PARF_PHY_CTRL);
- /* change DBI base address */
- writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+ qcom_pcie_configure_dbi_base(pcie);
/* MAC PHY_POWERDOWN MUX DISABLE */
val = readl(pcie->parf + PARF_SYS_CTRL);
@@ -772,13 +820,11 @@ static int qcom_pcie_post_init_2_3_3(str
u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
u32 val;
- writel(SLV_ADDR_SPACE_SZ, pcie->parf + PARF_SLV_ADDR_SPACE_SIZE);
-
val = readl(pcie->parf + PARF_PHY_CTRL);
val &= ~PHY_TEST_PWR_DOWN;
writel(val, pcie->parf + PARF_PHY_CTRL);
- writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+ qcom_pcie_configure_dbi_atu_base(pcie);
writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
| SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
@@ -874,8 +920,7 @@ static int qcom_pcie_init_2_7_0(struct q
val &= ~PHY_TEST_PWR_DOWN;
writel(val, pcie->parf + PARF_PHY_CTRL);
- /* change DBI base address */
- writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+ qcom_pcie_configure_dbi_atu_base(pcie);
/* MAC PHY_POWERDOWN MUX DISABLE */
val = readl(pcie->parf + PARF_SYS_CTRL);
@@ -1074,14 +1119,11 @@ static int qcom_pcie_post_init_2_9_0(str
u32 val;
int i;
- writel(SLV_ADDR_SPACE_SZ,
- pcie->parf + PARF_SLV_ADDR_SPACE_SIZE);
-
val = readl(pcie->parf + PARF_PHY_CTRL);
val &= ~PHY_TEST_PWR_DOWN;
writel(val, pcie->parf + PARF_PHY_CTRL);
- writel(0, pcie->parf + PARF_DBI_BASE_ADDR);
+ qcom_pcie_configure_dbi_atu_base(pcie);
writel(DEVICE_TYPE_RC, pcie->parf + PARF_DEVICE_TYPE);
writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
@@ -0,0 +1,28 @@
From f1aaa788b997ba8a7810da0696e89fd3f79ecce3 Mon Sep 17 00:00:00 2001
From: devi priya <quic_devipriy@quicinc.com>
Date: Thu, 16 May 2024 08:54:34 +0530
Subject: [PATCH 1/3] phy: qcom-qmp: Add missing offsets for Qserdes PLL
registers.
Add missing register offsets for Qserdes PLL.
Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
Signed-off-by: devi priya <quic_devipriy@quicinc.com>
Link: https://lore.kernel.org/r/20240516032436.2681828-3-quic_devipriy@quicinc.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-qserdes-pll.h | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-pll.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-pll.h
@@ -8,6 +8,9 @@
/* QMP V2 PHY for PCIE gen3 ports - QSERDES PLL registers */
#define QSERDES_PLL_BG_TIMER 0x00c
+#define QSERDES_PLL_SSC_EN_CENTER 0x010
+#define QSERDES_PLL_SSC_ADJ_PER1 0x014
+#define QSERDES_PLL_SSC_ADJ_PER2 0x018
#define QSERDES_PLL_SSC_PER1 0x01c
#define QSERDES_PLL_SSC_PER2 0x020
#define QSERDES_PLL_SSC_STEP_SIZE1_MODE0 0x024
@@ -0,0 +1,41 @@
From 71ae2acf1d7542ecd21c6933cae8fe65d550074b Mon Sep 17 00:00:00 2001
From: devi priya <quic_devipriy@quicinc.com>
Date: Thu, 16 May 2024 08:54:35 +0530
Subject: [PATCH 2/3] phy: qcom-qmp: Add missing register definitions for PCS
V5
Add missing register offsets for PCS V5 registers.
Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
Signed-off-by: devi priya <quic_devipriy@quicinc.com>
Link: https://lore.kernel.org/r/20240516032436.2681828-4-quic_devipriy@quicinc.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5.h
@@ -11,8 +11,22 @@
#define QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG2 0x0c
#define QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG4 0x14
#define QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x20
+#define QPHY_V5_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L 0x44
+#define QPHY_V5_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H 0x48
+#define QPHY_V5_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L 0x4c
+#define QPHY_V5_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H 0x50
#define QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1 0x54
+#define QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG1 0x5c
+#define QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG2 0x60
+#define QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG4 0x68
+#define QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG2 0x7c
+#define QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG4 0x84
+#define QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5 0x88
+#define QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG6 0x8c
#define QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS 0x94
+#define QPHY_V5_PCS_PCIE_EQ_CONFIG1 0xa4
#define QPHY_V5_PCS_PCIE_EQ_CONFIG2 0xa8
+#define QPHY_V5_PCS_PCIE_PRESET_P10_PRE 0xc0
+#define QPHY_V5_PCS_PCIE_PRESET_P10_POST 0xe4
#endif
@@ -0,0 +1,358 @@
From 2f2f5c13cc5ea87f1dd2debfd06fe5f624e5c0fd Mon Sep 17 00:00:00 2001
From: devi priya <quic_devipriy@quicinc.com>
Date: Thu, 16 May 2024 08:54:36 +0530
Subject: [PATCH 3/3] phy: qcom-qmp-pcie: Add support for IPQ9574 g3x1 and g3x2
PCIEs
Add support for a single-lane and two-lane PCIe PHYs
found on Qualcomm IPQ9574 platform.
Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
Co-developed-by: Anusha Rao <quic_anusha@quicinc.com>
Signed-off-by: Anusha Rao <quic_anusha@quicinc.com>
Signed-off-by: devi priya <quic_devipriy@quicinc.com>
Link: https://lore.kernel.org/r/20240516032436.2681828-5-quic_devipriy@quicinc.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 309 +++++++++++++++++++++++
1 file changed, 309 insertions(+)
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -514,6 +514,243 @@ static const struct qmp_phy_init_tbl ipq
QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
};
+static const struct qmp_phy_init_tbl ipq9574_gen3x1_pcie_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x31),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER1, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER2, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x21),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x68),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xab),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xd4),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xa0),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x53),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x29),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xa0),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_EN_CENTER, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_ADJ_PER1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_ADJ_PER2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE0, 0x19),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE1, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x89),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x10),
+};
+
+static const struct qmp_phy_init_tbl ipq9574_gen3x2_pcie_serdes_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x31),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_MAP, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER1, 0xff),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER2, 0x3f),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x30),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x21),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x68),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xab),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0xd4),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xa0),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TIMER, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x53),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x29),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0xaa),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xa0),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_EN_CENTER, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER1, 0x7d),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_PER2, 0x01),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_ADJ_PER1, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_ADJ_PER2, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0a),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE0, 0x19),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE1, 0x28),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x89),
+ QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x10),
+};
+
+static const struct qmp_phy_init_tbl ipq9574_pcie_rx_tbl[] = {
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x03),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_ENABLES, 0x1c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x61),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1e),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER, 0x04),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0x70),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL1, 0x73),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x80),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x09),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0xf0),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x02),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0x2f),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0xd3),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x40),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
+ QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
+};
+
+static const struct qmp_phy_init_tbl ipq9574_gen3x1_pcie_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_DCC_CAL_CONFIG, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_G12S1_TXDEEMPH_M3P5DB, 0x10),
+};
+
+static const struct qmp_phy_init_tbl ipq9574_gen3x1_pcie_pcs_misc_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG2, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG1, 0x14),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG1, 0x10),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_EQ_CONFIG2, 0x0b),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_PRE, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_PRESET_P10_POST, 0x58),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_CONFIG2, 0x52),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_MODE2_CONFIG2, 0x50),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_MODE2_CONFIG4, 0x1a),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x06),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_OSC_DTCT_MODE2_CONFIG6, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+};
+
+static const struct qmp_phy_init_tbl ipq9574_gen3x2_pcie_pcs_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x0d),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_G12S1_TXDEEMPH_M3P5DB, 0x10),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_DCC_CAL_CONFIG, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL, 0xaa),
+};
+
+static const struct qmp_phy_init_tbl ipq9574_gen3x2_pcie_pcs_misc_tbl[] = {
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG2, 0x1d),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG1, 0x14),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG1, 0x10),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_EQ_CONFIG2, 0x0b),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_PRESET_P10_PRE, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_PRESET_P10_POST, 0x58),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG1, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG2, 0x52),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_CONFIG4, 0x19),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_INT_AUX_CLK_CONFIG1, 0x00),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG2, 0x49),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG4, 0x2a),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x02),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_OSC_DTCT_MODE2_CONFIG6, 0x03),
+ QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
+};
+
static const struct qmp_phy_init_tbl sdm845_qmp_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
@@ -2354,6 +2591,16 @@ static const struct qmp_pcie_offsets qmp
.rx2 = 0x1800,
};
+static const struct qmp_pcie_offsets qmp_pcie_offsets_ipq9574 = {
+ .serdes = 0,
+ .pcs = 0x1000,
+ .pcs_misc = 0x1400,
+ .tx = 0x0200,
+ .rx = 0x0400,
+ .tx2 = 0x0600,
+ .rx2 = 0x0800,
+};
+
static const struct qmp_pcie_offsets qmp_pcie_offsets_v5_20 = {
.serdes = 0x1000,
.pcs = 0x1200,
@@ -2466,6 +2713,62 @@ static const struct qmp_phy_cfg ipq6018_
.phy_status = PHYSTATUS,
};
+static const struct qmp_phy_cfg ipq9574_gen3x1_pciephy_cfg = {
+ .lanes = 1,
+
+ .offsets = &qmp_pcie_offsets_v4x1,
+
+ .tbls = {
+ .serdes = ipq9574_gen3x1_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(ipq9574_gen3x1_pcie_serdes_tbl),
+ .tx = ipq8074_pcie_gen3_tx_tbl,
+ .tx_num = ARRAY_SIZE(ipq8074_pcie_gen3_tx_tbl),
+ .rx = ipq9574_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(ipq9574_pcie_rx_tbl),
+ .pcs = ipq9574_gen3x1_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(ipq9574_gen3x1_pcie_pcs_tbl),
+ .pcs_misc = ipq9574_gen3x1_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(ipq9574_gen3x1_pcie_pcs_misc_tbl),
+ },
+ .reset_list = ipq8074_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
+ .vreg_list = NULL,
+ .num_vregs = 0,
+ .regs = pciephy_v4_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+ .pipe_clock_rate = 250000000,
+};
+
+static const struct qmp_phy_cfg ipq9574_gen3x2_pciephy_cfg = {
+ .lanes = 2,
+
+ .offsets = &qmp_pcie_offsets_ipq9574,
+
+ .tbls = {
+ .serdes = ipq9574_gen3x2_pcie_serdes_tbl,
+ .serdes_num = ARRAY_SIZE(ipq9574_gen3x2_pcie_serdes_tbl),
+ .tx = ipq8074_pcie_gen3_tx_tbl,
+ .tx_num = ARRAY_SIZE(ipq8074_pcie_gen3_tx_tbl),
+ .rx = ipq9574_pcie_rx_tbl,
+ .rx_num = ARRAY_SIZE(ipq9574_pcie_rx_tbl),
+ .pcs = ipq9574_gen3x2_pcie_pcs_tbl,
+ .pcs_num = ARRAY_SIZE(ipq9574_gen3x2_pcie_pcs_tbl),
+ .pcs_misc = ipq9574_gen3x2_pcie_pcs_misc_tbl,
+ .pcs_misc_num = ARRAY_SIZE(ipq9574_gen3x2_pcie_pcs_misc_tbl),
+ },
+ .reset_list = ipq8074_pciephy_reset_l,
+ .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l),
+ .vreg_list = NULL,
+ .num_vregs = 0,
+ .regs = pciephy_v5_regs_layout,
+
+ .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
+ .phy_status = PHYSTATUS,
+ .pipe_clock_rate = 250000000,
+};
+
static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
.lanes = 1,
@@ -3718,6 +4021,12 @@ static const struct of_device_id qmp_pci
.compatible = "qcom,ipq8074-qmp-pcie-phy",
.data = &ipq8074_pciephy_cfg,
}, {
+ .compatible = "qcom,ipq9574-qmp-gen3x1-pcie-phy",
+ .data = &ipq9574_gen3x1_pciephy_cfg,
+ }, {
+ .compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy",
+ .data = &ipq9574_gen3x2_pciephy_cfg,
+ }, {
.compatible = "qcom,msm8998-qmp-pcie-phy",
.data = &msm8998_pciephy_cfg,
}, {
@@ -0,0 +1,468 @@
From d80c7fbfa908e3d893a1ea7fe178dfa82ed66bf1 Mon Sep 17 00:00:00 2001
From: devi priya <quic_devipriy@quicinc.com>
Date: Thu, 1 Aug 2024 11:18:01 +0530
Subject: [PATCH 1/2] arm64: dts: qcom: ipq9574: Add PCIe PHYs and controller
nodes
Add PCIe0, PCIe1, PCIe2, PCIe3 (and corresponding PHY) devices
found on IPQ9574 platform. The PCIe0 & PCIe1 are 1-lane Gen3
host whereas PCIe2 & PCIe3 are 2-lane Gen3 host.
Signed-off-by: devi priya <quic_devipriy@quicinc.com>
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
Link: https://lore.kernel.org/r/20240801054803.3015572-3-quic_srichara@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
---
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 420 +++++++++++++++++++++++++-
1 file changed, 416 insertions(+), 4 deletions(-)
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -239,6 +239,52 @@
reg = <0x00060000 0x6000>;
};
+ pcie0_phy: phy@84000 {
+ compatible = "qcom,ipq9574-qmp-gen3x1-pcie-phy";
+ reg = <0x00084000 0x1000>;
+
+ clocks = <&gcc GCC_PCIE0_AUX_CLK>,
+ <&gcc GCC_PCIE0_AHB_CLK>,
+ <&gcc GCC_PCIE0_PIPE_CLK>;
+ clock-names = "aux", "cfg_ahb", "pipe";
+
+ assigned-clocks = <&gcc GCC_PCIE0_AUX_CLK>;
+ assigned-clock-rates = <20000000>;
+
+ resets = <&gcc GCC_PCIE0_PHY_BCR>,
+ <&gcc GCC_PCIE0PHY_PHY_BCR>;
+ reset-names = "phy", "common";
+
+ #clock-cells = <0>;
+ clock-output-names = "gcc_pcie0_pipe_clk_src";
+
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ pcie2_phy: phy@8c000 {
+ compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy";
+ reg = <0x0008c000 0x2000>;
+
+ clocks = <&gcc GCC_PCIE2_AUX_CLK>,
+ <&gcc GCC_PCIE2_AHB_CLK>,
+ <&gcc GCC_PCIE2_PIPE_CLK>;
+ clock-names = "aux", "cfg_ahb", "pipe";
+
+ assigned-clocks = <&gcc GCC_PCIE2_AUX_CLK>;
+ assigned-clock-rates = <20000000>;
+
+ resets = <&gcc GCC_PCIE2_PHY_BCR>,
+ <&gcc GCC_PCIE2PHY_PHY_BCR>;
+ reset-names = "phy", "common";
+
+ #clock-cells = <0>;
+ clock-output-names = "gcc_pcie2_pipe_clk_src";
+
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
rng: rng@e3000 {
compatible = "qcom,prng-ee";
reg = <0x000e3000 0x1000>;
@@ -268,6 +314,52 @@
assigned-clock-rates-u64 = /bits/ 64 <12000000000>;
};
+ pcie3_phy: phy@f4000 {
+ compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy";
+ reg = <0x000f4000 0x2000>;
+
+ clocks = <&gcc GCC_PCIE3_AUX_CLK>,
+ <&gcc GCC_PCIE3_AHB_CLK>,
+ <&gcc GCC_PCIE3_PIPE_CLK>;
+ clock-names = "aux", "cfg_ahb", "pipe";
+
+ assigned-clocks = <&gcc GCC_PCIE3_AUX_CLK>;
+ assigned-clock-rates = <20000000>;
+
+ resets = <&gcc GCC_PCIE3_PHY_BCR>,
+ <&gcc GCC_PCIE3PHY_PHY_BCR>;
+ reset-names = "phy", "common";
+
+ #clock-cells = <0>;
+ clock-output-names = "gcc_pcie3_pipe_clk_src";
+
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ pcie1_phy: phy@fc000 {
+ compatible = "qcom,ipq9574-qmp-gen3x1-pcie-phy";
+ reg = <0x000fc000 0x1000>;
+
+ clocks = <&gcc GCC_PCIE1_AUX_CLK>,
+ <&gcc GCC_PCIE1_AHB_CLK>,
+ <&gcc GCC_PCIE1_PIPE_CLK>;
+ clock-names = "aux", "cfg_ahb", "pipe";
+
+ assigned-clocks = <&gcc GCC_PCIE1_AUX_CLK>;
+ assigned-clock-rates = <20000000>;
+
+ resets = <&gcc GCC_PCIE1_PHY_BCR>,
+ <&gcc GCC_PCIE1PHY_PHY_BCR>;
+ reset-names = "phy", "common";
+
+ #clock-cells = <0>;
+ clock-output-names = "gcc_pcie1_pipe_clk_src";
+
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
qfprom: efuse@a4000 {
compatible = "qcom,ipq9574-qfprom", "qcom,qfprom";
reg = <0x000a4000 0x5a1>;
@@ -334,10 +426,10 @@
clocks = <&xo_board_clk>,
<&sleep_clk>,
<0>,
- <0>,
- <0>,
- <0>,
- <0>,
+ <&pcie0_phy>,
+ <&pcie1_phy>,
+ <&pcie2_phy>,
+ <&pcie3_phy>,
<0>;
#clock-cells = <1>;
#reset-cells = <1>;
@@ -777,6 +869,326 @@
status = "disabled";
};
};
+
+ pcie1: pcie@10000000 {
+ compatible = "qcom,pcie-ipq9574";
+ reg = <0x10000000 0xf1d>,
+ <0x10000f20 0xa8>,
+ <0x10001000 0x1000>,
+ <0x000f8000 0x4000>,
+ <0x10100000 0x1000>;
+ reg-names = "dbi", "elbi", "atu", "parf", "config";
+ device_type = "pci";
+ linux,pci-domain = <1>;
+ bus-range = <0x00 0xff>;
+ num-lanes = <1>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ ranges = <0x01000000 0x0 0x00000000 0x10200000 0x0 0x100000>,
+ <0x02000000 0x0 0x10300000 0x10300000 0x0 0x7d00000>;
+
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc 0 0 35 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc 0 0 49 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc 0 0 84 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc 0 0 85 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&gcc GCC_PCIE1_AXI_M_CLK>,
+ <&gcc GCC_PCIE1_AXI_S_CLK>,
+ <&gcc GCC_PCIE1_AXI_S_BRIDGE_CLK>,
+ <&gcc GCC_PCIE1_RCHNG_CLK>,
+ <&gcc GCC_PCIE1_AHB_CLK>,
+ <&gcc GCC_PCIE1_AUX_CLK>;
+ clock-names = "axi_m",
+ "axi_s",
+ "axi_bridge",
+ "rchng",
+ "ahb",
+ "aux";
+
+ resets = <&gcc GCC_PCIE1_PIPE_ARES>,
+ <&gcc GCC_PCIE1_CORE_STICKY_ARES>,
+ <&gcc GCC_PCIE1_AXI_S_STICKY_ARES>,
+ <&gcc GCC_PCIE1_AXI_S_ARES>,
+ <&gcc GCC_PCIE1_AXI_M_STICKY_ARES>,
+ <&gcc GCC_PCIE1_AXI_M_ARES>,
+ <&gcc GCC_PCIE1_AUX_ARES>,
+ <&gcc GCC_PCIE1_AHB_ARES>;
+ reset-names = "pipe",
+ "sticky",
+ "axi_s_sticky",
+ "axi_s",
+ "axi_m_sticky",
+ "axi_m",
+ "aux",
+ "ahb";
+
+ phys = <&pcie1_phy>;
+ phy-names = "pciephy";
+ interconnects = <&gcc MASTER_ANOC_PCIE1 &gcc SLAVE_ANOC_PCIE1>,
+ <&gcc MASTER_SNOC_PCIE1 &gcc SLAVE_SNOC_PCIE1>;
+ interconnect-names = "pcie-mem", "cpu-pcie";
+ status = "disabled";
+ };
+
+ pcie3: pcie@18000000 {
+ compatible = "qcom,pcie-ipq9574";
+ reg = <0x18000000 0xf1d>,
+ <0x18000f20 0xa8>,
+ <0x18001000 0x1000>,
+ <0x000f0000 0x4000>,
+ <0x18100000 0x1000>;
+ reg-names = "dbi", "elbi", "atu", "parf", "config";
+ device_type = "pci";
+ linux,pci-domain = <3>;
+ bus-range = <0x00 0xff>;
+ num-lanes = <2>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ ranges = <0x01000000 0x0 0x00000000 0x18200000 0x0 0x100000>,
+ <0x02000000 0x0 0x18300000 0x18300000 0x0 0x7d00000>;
+
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc 0 0 189 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc 0 0 190 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc 0 0 191 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc 0 0 192 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&gcc GCC_PCIE3_AXI_M_CLK>,
+ <&gcc GCC_PCIE3_AXI_S_CLK>,
+ <&gcc GCC_PCIE3_AXI_S_BRIDGE_CLK>,
+ <&gcc GCC_PCIE3_RCHNG_CLK>,
+ <&gcc GCC_PCIE3_AHB_CLK>,
+ <&gcc GCC_PCIE3_AUX_CLK>;
+ clock-names = "axi_m",
+ "axi_s",
+ "axi_bridge",
+ "rchng",
+ "ahb",
+ "aux";
+
+ resets = <&gcc GCC_PCIE3_PIPE_ARES>,
+ <&gcc GCC_PCIE3_CORE_STICKY_ARES>,
+ <&gcc GCC_PCIE3_AXI_S_STICKY_ARES>,
+ <&gcc GCC_PCIE3_AXI_S_ARES>,
+ <&gcc GCC_PCIE3_AXI_M_STICKY_ARES>,
+ <&gcc GCC_PCIE3_AXI_M_ARES>,
+ <&gcc GCC_PCIE3_AUX_ARES>,
+ <&gcc GCC_PCIE3_AHB_ARES>;
+ reset-names = "pipe",
+ "sticky",
+ "axi_s_sticky",
+ "axi_s",
+ "axi_m_sticky",
+ "axi_m",
+ "aux",
+ "ahb";
+
+ phys = <&pcie3_phy>;
+ phy-names = "pciephy";
+ interconnects = <&gcc MASTER_ANOC_PCIE3 &gcc SLAVE_ANOC_PCIE3>,
+ <&gcc MASTER_SNOC_PCIE3 &gcc SLAVE_SNOC_PCIE3>;
+ interconnect-names = "pcie-mem", "cpu-pcie";
+ status = "disabled";
+ };
+
+ pcie2: pcie@20000000 {
+ compatible = "qcom,pcie-ipq9574";
+ reg = <0x20000000 0xf1d>,
+ <0x20000f20 0xa8>,
+ <0x20001000 0x1000>,
+ <0x00088000 0x4000>,
+ <0x20100000 0x1000>;
+ reg-names = "dbi", "elbi", "atu", "parf", "config";
+ device_type = "pci";
+ linux,pci-domain = <2>;
+ bus-range = <0x00 0xff>;
+ num-lanes = <2>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ ranges = <0x01000000 0x0 0x00000000 0x20200000 0x0 0x100000>,
+ <0x02000000 0x0 0x20300000 0x20300000 0x0 0x7d00000>;
+
+ interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc 0 0 164 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc 0 0 165 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc 0 0 186 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc 0 0 187 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&gcc GCC_PCIE2_AXI_M_CLK>,
+ <&gcc GCC_PCIE2_AXI_S_CLK>,
+ <&gcc GCC_PCIE2_AXI_S_BRIDGE_CLK>,
+ <&gcc GCC_PCIE2_RCHNG_CLK>,
+ <&gcc GCC_PCIE2_AHB_CLK>,
+ <&gcc GCC_PCIE2_AUX_CLK>;
+ clock-names = "axi_m",
+ "axi_s",
+ "axi_bridge",
+ "rchng",
+ "ahb",
+ "aux";
+
+ resets = <&gcc GCC_PCIE2_PIPE_ARES>,
+ <&gcc GCC_PCIE2_CORE_STICKY_ARES>,
+ <&gcc GCC_PCIE2_AXI_S_STICKY_ARES>,
+ <&gcc GCC_PCIE2_AXI_S_ARES>,
+ <&gcc GCC_PCIE2_AXI_M_STICKY_ARES>,
+ <&gcc GCC_PCIE2_AXI_M_ARES>,
+ <&gcc GCC_PCIE2_AUX_ARES>,
+ <&gcc GCC_PCIE2_AHB_ARES>;
+ reset-names = "pipe",
+ "sticky",
+ "axi_s_sticky",
+ "axi_s",
+ "axi_m_sticky",
+ "axi_m",
+ "aux",
+ "ahb";
+
+ phys = <&pcie2_phy>;
+ phy-names = "pciephy";
+ interconnects = <&gcc MASTER_ANOC_PCIE2 &gcc SLAVE_ANOC_PCIE2>,
+ <&gcc MASTER_SNOC_PCIE2 &gcc SLAVE_SNOC_PCIE2>;
+ interconnect-names = "pcie-mem", "cpu-pcie";
+ status = "disabled";
+ };
+
+ pcie0: pci@28000000 {
+ compatible = "qcom,pcie-ipq9574";
+ reg = <0x28000000 0xf1d>,
+ <0x28000f20 0xa8>,
+ <0x28001000 0x1000>,
+ <0x00080000 0x4000>,
+ <0x28100000 0x1000>;
+ reg-names = "dbi", "elbi", "atu", "parf", "config";
+ device_type = "pci";
+ linux,pci-domain = <0>;
+ bus-range = <0x00 0xff>;
+ num-lanes = <1>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ ranges = <0x01000000 0x0 0x00000000 0x28200000 0x0 0x100000>,
+ <0x02000000 0x0 0x28300000 0x28300000 0x0 0x7d00000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc 0 0 75 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc 0 0 78 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc 0 0 79 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc 0 0 83 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&gcc GCC_PCIE0_AXI_M_CLK>,
+ <&gcc GCC_PCIE0_AXI_S_CLK>,
+ <&gcc GCC_PCIE0_AXI_S_BRIDGE_CLK>,
+ <&gcc GCC_PCIE0_RCHNG_CLK>,
+ <&gcc GCC_PCIE0_AHB_CLK>,
+ <&gcc GCC_PCIE0_AUX_CLK>;
+ clock-names = "axi_m",
+ "axi_s",
+ "axi_bridge",
+ "rchng",
+ "ahb",
+ "aux";
+
+ resets = <&gcc GCC_PCIE0_PIPE_ARES>,
+ <&gcc GCC_PCIE0_CORE_STICKY_ARES>,
+ <&gcc GCC_PCIE0_AXI_S_STICKY_ARES>,
+ <&gcc GCC_PCIE0_AXI_S_ARES>,
+ <&gcc GCC_PCIE0_AXI_M_STICKY_ARES>,
+ <&gcc GCC_PCIE0_AXI_M_ARES>,
+ <&gcc GCC_PCIE0_AUX_ARES>,
+ <&gcc GCC_PCIE0_AHB_ARES>;
+ reset-names = "pipe",
+ "sticky",
+ "axi_s_sticky",
+ "axi_s",
+ "axi_m_sticky",
+ "axi_m",
+ "aux",
+ "ahb";
+
+ phys = <&pcie0_phy>;
+ phy-names = "pciephy";
+ interconnects = <&gcc MASTER_ANOC_PCIE0 &gcc SLAVE_ANOC_PCIE0>,
+ <&gcc MASTER_SNOC_PCIE0 &gcc SLAVE_SNOC_PCIE0>;
+ interconnect-names = "pcie-mem", "cpu-pcie";
+ status = "disabled";
+ };
+
};
thermal-zones {
@@ -0,0 +1,152 @@
From 438d05fb9be6bcd565e713c7e8d9ffb97e5f8d1e Mon Sep 17 00:00:00 2001
From: devi priya <quic_devipriy@quicinc.com>
Date: Thu, 1 Aug 2024 11:18:02 +0530
Subject: [PATCH 2/2] arm64: dts: qcom: ipq9574: Enable PCIe PHYs and
controllers
Enable the PCIe controller and PHY nodes corresponding to RDP 433.
Signed-off-by: devi priya <quic_devipriy@quicinc.com>
Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com>
Link: https://lore.kernel.org/r/20240801054803.3015572-4-quic_srichara@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
---
arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts | 113 ++++++++++++++++++++
1 file changed, 113 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
@@ -8,6 +8,7 @@
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
#include "ipq9574-rdp-common.dtsi"
/ {
@@ -15,6 +16,45 @@
compatible = "qcom,ipq9574-ap-al02-c7", "qcom,ipq9574";
};
+&pcie1_phy {
+ status = "okay";
+};
+
+&pcie1 {
+ pinctrl-0 = <&pcie1_default>;
+ pinctrl-names = "default";
+
+ perst-gpios = <&tlmm 26 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 27 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pcie2_phy {
+ status = "okay";
+};
+
+&pcie2 {
+ pinctrl-0 = <&pcie2_default>;
+ pinctrl-names = "default";
+
+ perst-gpios = <&tlmm 29 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pcie3_phy {
+ status = "okay";
+};
+
+&pcie3 {
+ pinctrl-0 = <&pcie3_default>;
+ pinctrl-names = "default";
+
+ perst-gpios = <&tlmm 32 GPIO_ACTIVE_LOW>;
+ wake-gpios = <&tlmm 33 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
&sdhc_1 {
pinctrl-0 = <&sdc_default_state>;
pinctrl-names = "default";
@@ -28,6 +68,79 @@
};
&tlmm {
+
+ pcie1_default: pcie1-default-state {
+ clkreq-n-pins {
+ pins = "gpio25";
+ function = "pcie1_clk";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ perst-n-pins {
+ pins = "gpio26";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ output-low;
+ };
+
+ wake-n-pins {
+ pins = "gpio27";
+ function = "pcie1_wake";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+ };
+
+ pcie2_default: pcie2-default-state {
+ clkreq-n-pins {
+ pins = "gpio28";
+ function = "pcie2_clk";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ perst-n-pins {
+ pins = "gpio29";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ output-low;
+ };
+
+ wake-n-pins {
+ pins = "gpio30";
+ function = "pcie2_wake";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+ };
+
+ pcie3_default: pcie3-default-state {
+ clkreq-n-pins {
+ pins = "gpio31";
+ function = "pcie3_clk";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+
+ perst-n-pins {
+ pins = "gpio32";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ output-low;
+ };
+
+ wake-n-pins {
+ pins = "gpio33";
+ function = "pcie3_wake";
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+ };
+
sdc_default_state: sdc-default-state {
clk-pins {
pins = "gpio5";
@@ -0,0 +1,131 @@
From 980136d1c2b95644b96df6c7ec00ca5d7c87f37f Mon Sep 17 00:00:00 2001
From: Krishna chaitanya chundru <quic_krichai@quicinc.com>
Date: Wed, 19 Jun 2024 20:41:10 +0530
Subject: [PATCH] PCI: qcom: Add ICC bandwidth vote for CPU to PCIe path
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
To access the host controller registers of the host controller and the
endpoint BAR/config space, the CPU-PCIe ICC (interconnect) path should
be voted otherwise it may lead to NoC (Network on chip) timeout.
We are surviving because of other driver voting for this path.
As there is less access on this path compared to PCIe to mem path
add minimum vote i.e 1KBps bandwidth always which is sufficient enough
to keep the path active and is recommended by HW team.
During S2RAM (Suspend-to-RAM), the DBI access can happen very late (while
disabling the boot CPU). So do not disable the CPU-PCIe interconnect path
during S2RAM as that may lead to NoC error.
Link: https://lore.kernel.org/linux-pci/20240619-opp_support-v15-1-aa769a2173a3@quicinc.com
Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
drivers/pci/controller/dwc/pcie-qcom.c | 45 +++++++++++++++++++++++++++++++---
1 file changed, 41 insertions(+), 4 deletions(-)
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -245,6 +245,7 @@ struct qcom_pcie {
struct phy *phy;
struct gpio_desc *reset;
struct icc_path *icc_mem;
+ struct icc_path *icc_cpu;
const struct qcom_pcie_cfg *cfg;
struct dentry *debugfs;
bool suspended;
@@ -1357,6 +1358,9 @@ static int qcom_pcie_icc_init(struct qco
if (IS_ERR(pcie->icc_mem))
return PTR_ERR(pcie->icc_mem);
+ pcie->icc_cpu = devm_of_icc_get(pci->dev, "cpu-pcie");
+ if (IS_ERR(pcie->icc_cpu))
+ return PTR_ERR(pcie->icc_cpu);
/*
* Some Qualcomm platforms require interconnect bandwidth constraints
* to be set before enabling interconnect clocks.
@@ -1366,11 +1370,25 @@ static int qcom_pcie_icc_init(struct qco
*/
ret = icc_set_bw(pcie->icc_mem, 0, MBps_to_icc(250));
if (ret) {
- dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
+ dev_err(pci->dev, "Failed to set bandwidth for PCIe-MEM interconnect path: %d\n",
ret);
return ret;
}
+ /*
+ * Since the CPU-PCIe path is only used for activities like register
+ * access of the host controller and endpoint Config/BAR space access,
+ * HW team has recommended to use a minimal bandwidth of 1KBps just to
+ * keep the path active.
+ */
+ ret = icc_set_bw(pcie->icc_cpu, 0, kBps_to_icc(1));
+ if (ret) {
+ dev_err(pci->dev, "Failed to set bandwidth for CPU-PCIe interconnect path: %d\n",
+ ret);
+ icc_set_bw(pcie->icc_mem, 0, 0);
+ return ret;
+ }
+
return 0;
}
@@ -1411,7 +1429,7 @@ static void qcom_pcie_icc_update(struct
ret = icc_set_bw(pcie->icc_mem, 0, width * bw);
if (ret) {
- dev_err(pci->dev, "failed to set interconnect bandwidth: %d\n",
+ dev_err(pci->dev, "Failed to set bandwidth for PCIe-MEM interconnect path: %d\n",
ret);
}
}
@@ -1573,7 +1591,7 @@ static int qcom_pcie_suspend_noirq(struc
*/
ret = icc_set_bw(pcie->icc_mem, 0, kBps_to_icc(1));
if (ret) {
- dev_err(dev, "Failed to set interconnect bandwidth: %d\n", ret);
+ dev_err(dev, "Failed to set bandwidth for PCIe-MEM interconnect path: %d\n", ret);
return ret;
}
@@ -1597,7 +1615,18 @@ static int qcom_pcie_suspend_noirq(struc
pcie->suspended = true;
}
- return 0;
+ /*
+ * Only disable CPU-PCIe interconnect path if the suspend is non-S2RAM.
+ * Because on some platforms, DBI access can happen very late during the
+ * S2RAM and a non-active CPU-PCIe interconnect path may lead to NoC
+ * error.
+ */
+ if (pm_suspend_target_state != PM_SUSPEND_MEM) {
+ ret = icc_disable(pcie->icc_cpu);
+ if (ret)
+ dev_err(dev, "Failed to disable CPU-PCIe interconnect path: %d\n", ret);
+ }
+ return ret;
}
static int qcom_pcie_resume_noirq(struct device *dev)
@@ -1605,6 +1634,14 @@ static int qcom_pcie_resume_noirq(struct
struct qcom_pcie *pcie = dev_get_drvdata(dev);
int ret;
+ if (pm_suspend_target_state != PM_SUSPEND_MEM) {
+ ret = icc_enable(pcie->icc_cpu);
+ if (ret) {
+ dev_err(dev, "Failed to enable CPU-PCIe interconnect path: %d\n", ret);
+ return ret;
+ }
+ }
+
if (pcie->suspended) {
ret = qcom_pcie_host_init(&pcie->pci->pp);
if (ret)
@@ -0,0 +1,44 @@
From c87d58bc7f831bf3d887e6ec846246cb673c2e50 Mon Sep 17 00:00:00 2001
From: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
Date: Thu, 13 Mar 2025 12:44:22 +0530
Subject: [PATCH] arm64: dts: qcom: ipq9574: fix the msi interrupt numbers of
pcie3
The MSI interrupt numbers of the PCIe3 controller are incorrect. Due
to this, the functional bring up of the QDSP6 processor on the PCIe
endpoint has failed. Correct the MSI interrupt numbers to properly
bring up the QDSP6 processor on the PCIe endpoint.
Fixes: d80c7fbfa908 ("arm64: dts: qcom: ipq9574: Add PCIe PHYs and controller nodes")
Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
Link: https://lore.kernel.org/r/20250313071422.510-1-quic_mmanikan@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
---
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -968,14 +968,14 @@
ranges = <0x01000000 0x0 0x00000000 0x18200000 0x0 0x100000>,
<0x02000000 0x0 0x18300000 0x18300000 0x0 0x7d00000>;
- interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi0",
"msi1",
"msi2",
@@ -1,13 +1,40 @@
From 968c5e8220209eb2185654f01748c349515a3b8e Mon Sep 17 00:00:00 2001
From: Md Sadre Alam <quic_mdalam@quicinc.com>
Date: Thu, 15 Feb 2024 12:26:40 +0530
Subject: [PATCH v10 7/8] arm64: dts: qcom: ipq9574: Add SPI nand support
To: <broonie@kernel.org>, <robh@kernel.org>, <krzk+dt@kernel.org>,
<conor+dt@kernel.org>, <andersson@kernel.org>,
<konradybcio@kernel.org>, <miquel.raynal@bootlin.com>,
<richard@nod.at>, <vigneshr@ti.com>,
<manivannan.sadhasivam@linaro.org>,
<linux-arm-msm@vger.kernel.org>, <linux-spi@vger.kernel.org>,
<devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linux-mtd@lists.infradead.org>
Cc: <quic_srichara@quicinc.com>, <quic_varada@quicinc.com>,
<quic_mdalam@quicinc.com>
Subject: [PATCH v14 7/8] arm64: dts: qcom: ipq9574: Add SPI nand support
Date: Wed, 20 Nov 2024 14:45:05 +0530 [thread overview]
Message-ID: <20241120091507.1404368-8-quic_mdalam@quicinc.com> (raw)
In-Reply-To: <20241120091507.1404368-1-quic_mdalam@quicinc.com>
Add SPI NAND support for ipq9574 SoC.
Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com>
---
Change in [v14]
* No change
Change in [v13]
* No change
Change in [v12]
* No change
Change in [v11]
* No change
Change in [v10]
* No change
@@ -54,11 +81,11 @@ Change in [v1]
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 27 ++++++++++++
2 files changed, 70 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
@@ -59,4 +59,47 @@
bias-pull-down;
};
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
@@ -95,6 +95,49 @@
drive-strength = <8>;
bias-disable;
};
+
+ qpic_snand_default_state: qpic-snand-default-state {
@@ -104,9 +131,11 @@ Change in [v1]
+ nand-ecc-step-size = <512>;
+ };
};
&usb_0_dwc3 {
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -355,6 +355,33 @@
@@ -447,6 +447,33 @@
reg = <0x01937000 0x21000>;
};
@@ -122,7 +151,7 @@ Change in [v1]
+ };
+
+ qpic_nand: spi@79b0000 {
+ compatible = "qcom,spi-qpic-snand", "qcom,ipq9574-nand";
+ compatible = "qcom,ipq9574-snand";
+ reg = <0x79b0000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
@@ -54,7 +54,7 @@ Change in [v1]
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
@@ -24,7 +24,7 @@
@@ -64,7 +64,7 @@
mmc-hs400-enhanced-strobe;
max-frequency = <384000000>;
bus-width = <8>;
@@ -3118,7 +3118,7 @@ Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
+ .driver = {
+ .name = "qcom,nsscc-ipq9574",
+ .of_match_table = nss_cc_ipq9574_match_table,
+ .sync_state = icc_sync_state, /* TODO seems to cause hang */
+ .sync_state = icc_sync_state,
+ },
+};
+
@@ -22,11 +22,10 @@ Signed-off-by: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>
#include <dt-bindings/thermal/thermal.h>
/ {
@@ -804,6 +806,26 @@
status = "disabled";
};
@@ -1216,6 +1218,25 @@
status = "disabled";
};
+
+ nsscc: clock-controller@39b00000 {
+ compatible = "qcom,ipq9574-nsscc";
+ reg = <0x39b00000 0x80000>;
@@ -24,7 +24,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
@@ -102,7 +102,7 @@
@@ -145,7 +145,7 @@
};
&usb_0_qmpphy {
@@ -33,7 +33,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
vdda-phy-supply = <&regulator_fixed_0p925>;
status = "okay";
@@ -110,7 +110,7 @@
@@ -153,7 +153,7 @@
&usb_0_qusbphy {
vdd-supply = <&regulator_fixed_0p925>;
@@ -30,7 +30,7 @@ Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
*/
#include <dt-bindings/clock/qcom,apss-ipq.h>
@@ -826,6 +826,114 @@
@@ -1237,6 +1237,114 @@
#power-domain-cells = <1>;
#interconnect-cells = <1>;
};
@@ -15,7 +15,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -251,6 +251,8 @@
@@ -297,6 +297,8 @@
mdio: mdio@90000 {
compatible = "qcom,ipq9574-mdio", "qcom,ipq4019-mdio";
reg = <0x00090000 0x64>;
@@ -24,7 +24,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
#address-cells = <1>;
#size-cells = <0>;
clocks = <&gcc GCC_MDIO_AHB_CLK>;
@@ -322,6 +324,22 @@
@@ -414,6 +416,22 @@
interrupt-controller;
#interrupt-cells = <2>;
@@ -15,11 +15,10 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -952,6 +952,44 @@
"ch_tx";
};
@@ -1256,6 +1256,44 @@
#interconnect-cells = <1>;
};
+
+ ethernet@3a000000 {
+ compatible = "qcom,ipq9574-ppe";
+ reg = <0x3a000000 0xbef800>;
@@ -57,6 +56,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ "memnoc_nssnoc",
+ "memnoc_nssnoc_1";
+ };
};
thermal-zones {
+
pcsuniphy0: ethernet-uniphy@7a00000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -14,7 +14,7 @@ Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -989,6 +989,74 @@
@@ -1292,6 +1292,74 @@
"nssnoc_memnoc",
"memnoc_nssnoc",
"memnoc_nssnoc_1";
@@ -87,5 +87,5 @@ Signed-off-by: Pavithra R <quic_pavir@quicinc.com>
+ "edma_misc";
+ };
};
};
pcsuniphy0: ethernet-uniphy@7a00000 {
@@ -18,23 +18,8 @@ Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
@@ -3,11 +3,13 @@
* IPQ9574 RDP433 board device tree source
*
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+
#include "ipq9574-rdp-common.dtsi"
/ {
@@ -15,6 +17,46 @@
compatible = "qcom,ipq9574-ap-al02-c7", "qcom,ipq9574";
@@ -55,6 +55,46 @@
status = "okay";
};
+&mdio {
@@ -80,8 +65,8 @@ Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
&sdhc_1 {
pinctrl-0 = <&sdc_default_state>;
pinctrl-names = "default";
@@ -103,3 +145,130 @@
nand-ecc-step-size = <512>;
@@ -173,3 +213,130 @@
};
};
};
+
@@ -213,8 +198,8 @@ Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
+};
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -953,7 +953,7 @@
};
@@ -1256,7 +1256,7 @@
#interconnect-cells = <1>;
};
- ethernet@3a000000 {
@@ -21,7 +21,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
#include <dt-bindings/thermal/thermal.h>
/ {
@@ -832,12 +833,12 @@
@@ -1243,12 +1244,12 @@
<&cmn_pll NSS_1200MHZ_CLK>,
<&cmn_pll PPE_353MHZ_CLK>,
<&gcc GPLL0_OUT_AUX>,
@@ -104,7 +104,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+ partition@4d0000 {
+ label = "0:rpm";
+ reg = <0x4d0000 0x20000>;
+ // read-only;
+ read-only;
+ };
+
+ partition@4f0000 {
@@ -13,7 +13,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
@@ -49,11 +49,17 @@
@@ -87,11 +87,17 @@
phy4: ethernet-phy@8 {
compatible ="ethernet-phy-ieee802.3-c45";
reg = <8>;
@@ -0,0 +1,50 @@
From 2f328bd852cbb27cf0d2cad1727d8fb7a69abe87 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 30 Jan 2025 00:39:30 +0100
Subject: [PATCH 2/2] arm64: dts: qcom: ipq9574: add QPIC SPI NAND default
partition nodes
Add QPIC SPI NAND default partition nodes for RDP reference board.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
.../boot/dts/qcom/ipq9574-rdp-common.dtsi | 28 +++++++++++++++++++
1 file changed, 28 insertions(+)
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
@@ -281,6 +281,34 @@
nand-ecc-engine = <&qpic_nand>;
nand-ecc-strength = <4>;
nand-ecc-step-size = <512>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "0:training";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "0:license";
+ reg = <0x80000 0x40000>;
+ read-only;
+ };
+
+ partition@c0000 {
+ label = "rootfs";
+ reg = <0xc0000 0x3c00000>;
+ };
+
+ partition@3cc0000 {
+ label = "rootfs_1";
+ reg = <0x3cc0000 0x3c00000>;
+ };
+ };
};
};
@@ -0,0 +1,66 @@
From afba5111aed03a05aa7fd46d3d9911319fa87a29 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 30 Jan 2025 16:07:14 +0100
Subject: [PATCH 1/3] PM: runtime: add of_pm_clk_add_clk_index OP variant
Add of_pm_clk_add_clk_index OP variant of of_pm_clk_add_clk to take as
argument the clock index in DT instead of the name. This is to handle
case where clock-names property is not used by the node but clocks are
referenced with a dt-binding header or internally in the driver.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/base/power/clock_ops.c | 31 +++++++++++++++++++++++++++++++
include/linux/pm_clock.h | 1 +
2 files changed, 32 insertions(+)
--- a/drivers/base/power/clock_ops.c
+++ b/drivers/base/power/clock_ops.c
@@ -259,6 +259,37 @@ int pm_clk_add_clk(struct device *dev, s
}
EXPORT_SYMBOL_GPL(pm_clk_add_clk);
+/**
+ * of_pm_clk_add_clk_index - Start using a device clock for power management.
+ * @dev: Device whose clock is going to be used for power management.
+ * @index: Index of clock that is going to be used for power management.
+ *
+ * Add the clock described in the 'clocks' device-tree node at the index
+ * provided, to the list of clocks used for the power management of @dev.
+ * On success, returns 0. Returns a negative error code if the clock is not
+ * found or cannot be added.
+ */
+int of_pm_clk_add_clk_index(struct device *dev, int index)
+{
+ struct clk *clk;
+ int ret;
+
+ if (!dev || !dev->of_node || index < 0)
+ return -EINVAL;
+
+ clk = of_clk_get(dev->of_node, index);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ ret = pm_clk_add_clk(dev, clk);
+ if (ret) {
+ clk_put(clk);
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_pm_clk_add_clk_index);
/**
* of_pm_clk_add_clk - Start using a device clock for power management.
--- a/include/linux/pm_clock.h
+++ b/include/linux/pm_clock.h
@@ -41,6 +41,7 @@ extern int pm_clk_create(struct device *
extern void pm_clk_destroy(struct device *dev);
extern int pm_clk_add(struct device *dev, const char *con_id);
extern int pm_clk_add_clk(struct device *dev, struct clk *clk);
+extern int of_pm_clk_add_clk_index(struct device *dev, int index);
extern int of_pm_clk_add_clk(struct device *dev, const char *name);
extern int of_pm_clk_add_clks(struct device *dev);
extern void pm_clk_remove(struct device *dev, const char *con_id);
@@ -0,0 +1,120 @@
From 9408076fd9e4d41876af41523cad9bfa77b3a557 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 30 Jan 2025 16:11:14 +0100
Subject: [PATCH 2/3] clk: qcom: nsscc: Attach required NSSNOC clock to PM
domain
There is currently a problem with ICC clock disabling the NSSNOC clock
as there isn't any user for them on calling sync_state.
This cause the kernel to stall if NSS is enabled and reboot with the watchdog.
This is caused by the fact that the NSSNOC clock nsscc, snoc and snoc_1
are actually required to make the NSS work and make the system continue
booting.
To attach these clock, setup pm-clk in nsscc and setup the correct
resume/suspend OPs.
With this change, the clock gets correctly attached and are not disabled
when ICC call the sync_state.
Suggested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/qcom/nsscc-ipq9574.c | 49 +++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
--- a/drivers/clk/qcom/nsscc-ipq9574.c
+++ b/drivers/clk/qcom/nsscc-ipq9574.c
@@ -12,6 +12,8 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/platform_device.h>
@@ -41,6 +43,9 @@ enum {
DT_UNIPHY1_NSS_TX_CLK,
DT_UNIPHY2_NSS_RX_CLK,
DT_UNIPHY2_NSS_TX_CLK,
+ DT_GCC_NSSNOC_NSSCC_CLK,
+ DT_GCC_NSSNOC_SNOC_CLK,
+ DT_GCC_NSSNOC_SNOC_1_CLK,
};
enum {
@@ -3046,6 +3051,10 @@ static const struct qcom_cc_desc nss_cc_
.icc_first_node_id = IPQ_NSSCC_ID,
};
+static const struct dev_pm_ops nsscc_pm_ops = {
+ SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
+};
+
static const struct of_device_id nss_cc_ipq9574_match_table[] = {
{ .compatible = "qcom,ipq9574-nsscc" },
{ }
@@ -3054,7 +3063,33 @@ MODULE_DEVICE_TABLE(of, nss_cc_ipq9574_m
static int nss_cc_ipq9574_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct regmap *regmap;
+ int ret;
+
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ return ret;
+
+ ret = devm_pm_clk_create(dev);
+ if (ret)
+ return ret;
+
+ ret = of_pm_clk_add_clk_index(dev, DT_GCC_NSSNOC_NSSCC_CLK);
+ if (ret)
+ return dev_err_probe(dev, ret,"failed to acquire nssnoc clock\n");
+
+ ret = of_pm_clk_add_clk_index(dev, DT_GCC_NSSNOC_SNOC_CLK);
+ if (ret)
+ return dev_err_probe(dev, ret,"failed to acquire snoc clock\n");
+
+ ret = of_pm_clk_add_clk_index(dev, DT_GCC_NSSNOC_SNOC_1_CLK);
+ if (ret)
+ return dev_err_probe(dev, ret,"failed to acquire snoc_1 clock\n");
+
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret)
+ return ret;
regmap = qcom_cc_map(pdev, &nss_cc_ipq9574_desc);
if (IS_ERR(regmap))
@@ -3062,7 +3097,18 @@ static int nss_cc_ipq9574_probe(struct p
clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
- return qcom_cc_really_probe(&pdev->dev, &nss_cc_ipq9574_desc, regmap);
+ ret = qcom_cc_really_probe(dev, &nss_cc_ipq9574_desc, regmap);
+ if (ret)
+ goto err_put_pm;
+
+ pm_runtime_put(dev);
+
+ return 0;
+
+err_put_pm:
+ pm_runtime_put_sync(dev);
+
+ return ret;
}
static struct platform_driver nss_cc_ipq9574_driver = {
@@ -3071,6 +3117,7 @@ static struct platform_driver nss_cc_ipq
.name = "qcom,nsscc-ipq9574",
.of_match_table = nss_cc_ipq9574_match_table,
.sync_state = icc_sync_state,
+ .pm = &nsscc_pm_ops,
},
};
@@ -0,0 +1,26 @@
From 893fda72edd2a0b3d92be41af417d315c9c5c253 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 30 Jan 2025 16:23:03 +0100
Subject: [PATCH 3/3] arm64: dts: qcom: ipq9574: add NSSNOC clock to nss node
Add NSSNOC clock to nss node to attach the clock with PM clock and fix
the boot stall after ICC sync_state.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -1250,7 +1250,9 @@
<&pcsuniphy1 UNIPHY_NSS_TX_CLK>,
<&pcsuniphy2 UNIPHY_NSS_RX_CLK>,
<&pcsuniphy2 UNIPHY_NSS_TX_CLK>,
- <&gcc GCC_NSSCC_CLK>;
+ <&gcc GCC_NSSNOC_NSSCC_CLK>,
+ <&gcc GCC_NSSNOC_SNOC_CLK>,
+ <&gcc GCC_NSSNOC_SNOC_1_CLK>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
@@ -0,0 +1,46 @@
From 145aa2977a42b97d052ed0984fb305a853f55d49 Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Wed, 11 Apr 2025 15:14:19 +0300
Subject: [PATCH] clk: qcom: nsscc-ipq9574: enable bus clock
Enable bus clock, otherwise nsscc registers are unaccessible.
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
arch/arm64/boot/dts/qcom/ipq9574.dtsi | 3 +-
drivers/clk/qcom/nsscc-ipq9574.c | 5 +
2 file changed, 7 insertions(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -1252,7 +1252,8 @@
<&pcsuniphy2 UNIPHY_NSS_TX_CLK>,
<&gcc GCC_NSSNOC_NSSCC_CLK>,
<&gcc GCC_NSSNOC_SNOC_CLK>,
- <&gcc GCC_NSSNOC_SNOC_1_CLK>;
+ <&gcc GCC_NSSNOC_SNOC_1_CLK>,
+ <&gcc GCC_NSSCC_CLK>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
--- a/drivers/clk/qcom/nsscc-ipq9574.c
+++ b/drivers/clk/qcom/nsscc-ipq9574.c
@@ -46,6 +46,7 @@ enum {
DT_GCC_NSSNOC_NSSCC_CLK,
DT_GCC_NSSNOC_SNOC_CLK,
DT_GCC_NSSNOC_SNOC_1_CLK,
+ DT_GCC_NSS_BUS_CLK,
};
enum {
@@ -3075,6 +3076,10 @@ static int nss_cc_ipq9574_probe(struct p
if (ret)
return ret;
+ ret = of_pm_clk_add_clk_index(dev, DT_GCC_NSS_BUS_CLK);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "Fail to add bus clock\n");
+
ret = of_pm_clk_add_clk_index(dev, DT_GCC_NSSNOC_NSSCC_CLK);
if (ret)
return dev_err_probe(dev, ret,"failed to acquire nssnoc clock\n");
@@ -0,0 +1,46 @@
From ce4c7eea1b6f05723240aadc5e1c240d26a6ef88 Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Mon, 31 Mar 2025 15:39:59 +0300
Subject: [PATCH] clk: qcom: nsscc-ipq9574: fix port5 clock config
Currently there is no configuration to derive 25/125MHz port5 clock
from uniphy1 running at 125MHz. This is needed for SGMII mode when
port5 is using uniphy1.
Fix this by adding option such clock config option.
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
drivers/clk/qcom/nsscc-ipq9574.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/clk/qcom/nsscc-ipq9574.c
+++ b/drivers/clk/qcom/nsscc-ipq9574.c
@@ -387,11 +387,13 @@ static const struct freq_multi_tbl ftbl_
static const struct freq_conf ftbl_nss_cc_port5_rx_clk_src_25[] = {
C(P_UNIPHY1_NSS_RX_CLK, 12.5, 0, 0),
+ C(P_UNIPHY1_NSS_RX_CLK, 5, 0, 0),
C(P_UNIPHY0_NSS_RX_CLK, 5, 0, 0),
};
static const struct freq_conf ftbl_nss_cc_port5_rx_clk_src_125[] = {
C(P_UNIPHY1_NSS_RX_CLK, 2.5, 0, 0),
+ C(P_UNIPHY1_NSS_RX_CLK, 1, 0, 0),
C(P_UNIPHY0_NSS_RX_CLK, 1, 0, 0),
};
@@ -412,11 +414,13 @@ static const struct freq_multi_tbl ftbl_
static const struct freq_conf ftbl_nss_cc_port5_tx_clk_src_25[] = {
C(P_UNIPHY1_NSS_TX_CLK, 12.5, 0, 0),
+ C(P_UNIPHY1_NSS_TX_CLK, 5, 0, 0),
C(P_UNIPHY0_NSS_TX_CLK, 5, 0, 0),
};
static const struct freq_conf ftbl_nss_cc_port5_tx_clk_src_125[] = {
C(P_UNIPHY1_NSS_TX_CLK, 2.5, 0, 0),
+ C(P_UNIPHY1_NSS_TX_CLK, 1, 0, 0),
C(P_UNIPHY0_NSS_TX_CLK, 1, 0, 0),
};
@@ -0,0 +1,48 @@
From 4c432babdc195a0dbef70ca67c92cec8adf01e30 Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Fri, 28 Mar 2025 14:22:21 +0200
Subject: [PATCH 5/6] net: pcs: ipq-uniphy: keep autoneg enabled in SGMII mode
For PHYs that don't use in-band-status (e.g. 2.5G PHY swiching between
SGMII and 2500base-x), SGMII autoneg still must be enabled. Only mode
that should use forced speed is 1000base-x
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
drivers/net/pcs/pcs-qcom-ipq-uniphy.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
+++ b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
@@ -520,7 +520,7 @@ static int ipq_unipcs_config_sgmii(struc
mutex_unlock(&qunipcs->shared_lock);
/* In-band autoneg mode is enabled by default for each PCS channel */
- if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
+ if (interface != PHY_INTERFACE_MODE_1000BASEX)
return 0;
/* Force speed mode */
@@ -758,10 +758,11 @@ ipq_unipcs_link_up_clock_rate_set(struct
static void ipq_unipcs_link_up_config_sgmii(struct ipq_uniphy_pcs *qunipcs,
int channel,
unsigned int neg_mode,
- int speed)
+ int speed,
+ phy_interface_t interface)
{
/* No need to config PCS speed if in-band autoneg is enabled */
- if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
+ if (interface != PHY_INTERFACE_MODE_1000BASEX)
goto pcs_adapter_reset;
/* PCS speed set for force mode */
@@ -966,7 +967,7 @@ static void ipq_unipcs_link_up(struct ph
case PHY_INTERFACE_MODE_PSGMII:
case PHY_INTERFACE_MODE_1000BASEX:
ipq_unipcs_link_up_config_sgmii(qunipcs, channel,
- neg_mode, speed);
+ neg_mode, speed, interface);
break;
case PHY_INTERFACE_MODE_2500BASEX:
ipq_unipcs_link_up_config_2500basex(qunipcs,
@@ -0,0 +1,64 @@
From 3bbf1aad312de653b894c2e60ea1b37ce912c6fe Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Fri, 28 Mar 2025 14:10:22 +0200
Subject: [PATCH 3/6] net: pcs: ipq-uniphy: control MISC2 register for 2.5G
support
When 2500base-x mode is enabled MISC2 regsister needs to have different
value than for other 1G modes.
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
drivers/net/pcs/pcs-qcom-ipq-uniphy.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
--- a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
+++ b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
@@ -20,6 +20,11 @@
#define PCS_CALIBRATION 0x1e0
#define PCS_CALIBRATION_DONE BIT(7)
+#define PCS_MISC2 0x218
+#define PCS_MISC2_MODE_MASK GENMASK(6, 5)
+#define PCS_MISC2_MODE_SGMII FIELD_PREP(PCS_MISC2_MODE_MASK, 0x1)
+#define PCS_MISC2_MODE_SGMII_PLUS FIELD_PREP(PCS_MISC2_MODE_MASK, 0x2)
+
#define PCS_MODE_CTRL 0x46c
#define PCS_MODE_SEL_MASK GENMASK(12, 8)
#define PCS_MODE_SGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
@@ -422,6 +427,9 @@ static int ipq_unipcs_config_mode(struct
ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
PCS_MODE_SEL_MASK | PCS_MODE_AN_MODE,
PCS_MODE_SGMII);
+ ipq_unipcs_reg_modify32(qunipcs, PCS_MISC2,
+ PCS_MISC2_MODE_MASK,
+ PCS_MISC2_MODE_SGMII);
break;
case PHY_INTERFACE_MODE_QSGMII:
rate = 125000000;
@@ -438,17 +446,25 @@ static int ipq_unipcs_config_mode(struct
PCS_MODE_PSGMII);
break;
case PHY_INTERFACE_MODE_1000BASEX:
+ rate = 125000000;
ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
PCS_MODE_SEL_MASK |
PCS_MODE_SGMII_CTRL_MASK,
PCS_MODE_SGMII |
PCS_MODE_SGMII_CTRL_1000BASEX);
+ ipq_unipcs_reg_modify32(qunipcs, PCS_MISC2,
+ PCS_MISC2_MODE_MASK,
+ PCS_MISC2_MODE_SGMII);
break;
case PHY_INTERFACE_MODE_2500BASEX:
rate = 312500000;
ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
PCS_MODE_SEL_MASK,
PCS_MODE_SGMII_PLUS);
+ ipq_unipcs_reg_modify32(qunipcs, PCS_MISC2,
+ PCS_MISC2_MODE_MASK,
+ PCS_MISC2_MODE_SGMII_PLUS);
+
break;
case PHY_INTERFACE_MODE_USXGMII:
case PHY_INTERFACE_MODE_10GBASER:
@@ -0,0 +1,24 @@
From d75aa2977a42b97d052ed0984fb305a853f55d49 Mon Sep 17 00:00:00 2001
From: Mantas Pucka <mantas@8devices.com>
Date: Wed, 9 Apr 2025 11:16:49 +0300
Subject: [PATCH] net: pcs: ipq-uniphy: fix USXGMII link-up failure
USXGMII link-up may fail due to too short delay after PLL reset.
Increase the delay to fix this.
Signed-off-by: Mantas Pucka <mantas@8devices.com>
---
drivers/net/pcs/pcs-qcom-ipq-uniphy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
+++ b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
@@ -490,7 +490,7 @@ static int ipq_unipcs_config_mode(struct
/* PCS PLL reset */
ipq_unipcs_reg_modify32(qunipcs, PCS_PLL_RESET, PCS_ANA_SW_RESET, 0);
- fsleep(10000);
+ fsleep(20000);
ipq_unipcs_reg_modify32(qunipcs, PCS_PLL_RESET,
PCS_ANA_SW_RESET, PCS_ANA_SW_RESET);
@@ -12,7 +12,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
+++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp433.dts
@@ -161,6 +161,7 @@
@@ -229,6 +229,7 @@
reg = <1>;
phy-mode = "qsgmii";
managed = "in-band-status";
@@ -20,7 +20,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
phy-handle = <&phy0>;
pcs-handle = <&pcsuniphy0_ch0>;
clocks = <&nsscc NSS_CC_PORT1_MAC_CLK>,
@@ -181,6 +182,7 @@
@@ -249,6 +250,7 @@
reg = <2>;
phy-mode = "qsgmii";
managed = "in-band-status";
@@ -28,7 +28,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
phy-handle = <&phy1>;
pcs-handle = <&pcsuniphy0_ch1>;
clocks = <&nsscc NSS_CC_PORT2_MAC_CLK>,
@@ -201,6 +203,7 @@
@@ -269,6 +271,7 @@
reg = <3>;
phy-mode = "qsgmii";
managed = "in-band-status";
@@ -36,7 +36,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
phy-handle = <&phy2>;
pcs-handle = <&pcsuniphy0_ch2>;
clocks = <&nsscc NSS_CC_PORT3_MAC_CLK>,
@@ -221,6 +224,7 @@
@@ -289,6 +292,7 @@
reg = <4>;
phy-mode = "qsgmii";
managed = "in-band-status";
@@ -44,7 +44,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
phy-handle = <&phy3>;
pcs-handle = <&pcsuniphy0_ch3>;
clocks = <&nsscc NSS_CC_PORT4_MAC_CLK>,
@@ -241,6 +245,7 @@
@@ -309,6 +313,7 @@
reg = <5>;
phy-mode = "usxgmii";
managed = "in-band-status";
@@ -52,7 +52,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
phy-handle = <&phy4>;
pcs-handle = <&pcsuniphy1_ch0>;
clocks = <&nsscc NSS_CC_PORT5_MAC_CLK>,
@@ -261,6 +266,7 @@
@@ -329,6 +334,7 @@
reg = <6>;
phy-mode = "usxgmii";
managed = "in-band-status";
+2
View File
@@ -26,6 +26,7 @@ use crate::util::prelude::*;
pub(crate) const HMAC_SIZE_V2: usize = 8;
#[allow(unused)]
pub(crate) trait HashedStream {
fn hash_stream(&self) -> [u8; 20];
}
@@ -98,6 +99,7 @@ impl<S> HashedWriteStream<S> {
})
}
#[allow(unused)]
pub(crate) fn hash(&self) -> [u8; 20] {
self.hmac
.borrow()
+7 -5
View File
@@ -252,7 +252,7 @@ pub(crate) fn get_sip003_arg() -> Option<Args> {
let opts: HashMap<_, _> = opts.into_iter().collect();
let threads = opts.get("threads").map(|s| s.parse::<u8>().unwrap());
let v3 = opts.get("v3").is_some();
let v3 = opts.contains_key("v3");
let passwd = opts
.get("passwd")
.expect("need passwd param(like passwd=123456)");
@@ -262,15 +262,17 @@ pub(crate) fn get_sip003_arg() -> Option<Args> {
v3,
..Default::default()
};
let args = if opts.get("server").is_some() {
let args = if opts.contains_key("server") {
let tls_addr = opts
.get("tls")
.expect("tls param must be specified(like tls=xxx.com:443)");
let tls_addrs = parse_server_addrs(tls_addr)
.expect("tls param parse failed(like tls=xxx.com:443 or tls=yyy.com:1.2.3.4:443;zzz.com:443;xxx.com)");
let wildcard_sni =
WildcardSNI::from_str(opts.get("wildcard-sni").map(AsRef::as_ref).unwrap_or("off"), true)
.expect("wildcard_sni format error");
let wildcard_sni = WildcardSNI::from_str(
opts.get("wildcard-sni").map(AsRef::as_ref).unwrap_or("off"),
true,
)
.expect("wildcard_sni format error");
Args {
cmd: crate::Commands::Server {
listen: format!("{ss_remote_host}:{ss_remote_port}"),
+3 -3
View File
@@ -6,7 +6,7 @@ pub fn parse_sip003_options(s: &str) -> Result<Vec<(String, String)>, anyhow::Er
let mut i = 0;
while i < s.len() {
// read key
let (offset, key) = index_unescaped(&s[i..], &[b'=', b';']).context("read key")?;
let (offset, key) = index_unescaped(&s[i..], b"=;").context("read key")?;
if key.is_empty() {
bail!("empty key in {}", &s[i..]);
}
@@ -21,7 +21,7 @@ pub fn parse_sip003_options(s: &str) -> Result<Vec<(String, String)>, anyhow::Er
// skip equals
i += 1;
// read value
let (offset, value) = index_unescaped(&s[i..], &[b'=', b';']).context("read value")?;
let (offset, value) = index_unescaped(&s[i..], b"=;").context("read value")?;
i += offset;
opts.push((key, value));
// Skip the semicolon.
@@ -36,7 +36,7 @@ fn index_unescaped(s: &str, term: &[u8]) -> Result<(usize, String), anyhow::Erro
while i < s.len() {
let mut b: u8 = s.as_bytes()[i];
if term.iter().any(|&e| b == e) {
if term.contains(&b) {
break;
}
if b == b'\\' {
+1 -1
View File
@@ -599,7 +599,7 @@ pub(crate) async fn resolve(addr: &str) -> std::io::Result<std::net::SocketAddr>
addr_iter.next().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("unable to resolve addr: {}", addr),
format!("unable to resolve addr: {addr}"),
)
})
}
+16 -16
View File
@@ -4,7 +4,7 @@ use shadow_tls::{RunningArgs, TlsAddrs, TlsExtConfig, TlsNames, V3Mode};
mod utils;
use utils::*;
// handshake: bing.com(tls1.2 only)
// handshake: badssl.com(tls1.2 only)
// data: captive.apple.com:80
// protocol: v2
#[test]
@@ -12,7 +12,7 @@ fn tls12_v2() {
let client = RunningArgs::Client {
listen_addr: "127.0.0.1:30000".to_string(),
target_addr: "127.0.0.1:30001".to_string(),
tls_names: TlsNames::try_from("bing.com").unwrap(),
tls_names: TlsNames::try_from("badssl.com").unwrap(),
tls_ext: TlsExtConfig::new(None),
password: "test".to_string(),
nodelay: true,
@@ -22,7 +22,7 @@ fn tls12_v2() {
let server = RunningArgs::Server {
listen_addr: "127.0.0.1:30001".to_string(),
target_addr: "captive.apple.com:80".to_string(),
tls_addr: TlsAddrs::try_from("bing.com").unwrap(),
tls_addr: TlsAddrs::try_from("badssl.com").unwrap(),
password: "test".to_string(),
nodelay: true,
fastopen: true,
@@ -31,7 +31,7 @@ fn tls12_v2() {
test_ok(client, server, CAPTIVE_HTTP_REQUEST, CAPTIVE_HTTP_RESP);
}
// handshake: bing.com(tls1.2 only)
// handshake: badssl.com(tls1.2 only)
// data: captive.apple.com:80
// protocol: v3 lossy
#[test]
@@ -39,7 +39,7 @@ fn tls12_v3_lossy() {
let client = RunningArgs::Client {
listen_addr: "127.0.0.1:30002".to_string(),
target_addr: "127.0.0.1:30003".to_string(),
tls_names: TlsNames::try_from("bing.com").unwrap(),
tls_names: TlsNames::try_from("badssl.com").unwrap(),
tls_ext: TlsExtConfig::new(None),
password: "test".to_string(),
nodelay: true,
@@ -49,7 +49,7 @@ fn tls12_v3_lossy() {
let server = RunningArgs::Server {
listen_addr: "127.0.0.1:30003".to_string(),
target_addr: "captive.apple.com:80".to_string(),
tls_addr: TlsAddrs::try_from("bing.com").unwrap(),
tls_addr: TlsAddrs::try_from("badssl.com").unwrap(),
password: "test".to_string(),
nodelay: true,
fastopen: true,
@@ -58,7 +58,7 @@ fn tls12_v3_lossy() {
utils::test_ok(client, server, CAPTIVE_HTTP_REQUEST, CAPTIVE_HTTP_RESP);
}
// handshake: bing.com(tls1.2 only)
// handshake: badssl.com(tls1.2 only)
// data: captive.apple.com:80
// protocol: v3 strict
// v3 strict cannot work with tls1.2, so it must fail
@@ -68,7 +68,7 @@ fn tls12_v3_strict() {
let client = RunningArgs::Client {
listen_addr: "127.0.0.1:30004".to_string(),
target_addr: "127.0.0.1:30005".to_string(),
tls_names: TlsNames::try_from("bing.com").unwrap(),
tls_names: TlsNames::try_from("badssl.com").unwrap(),
tls_ext: TlsExtConfig::new(None),
password: "test".to_string(),
nodelay: true,
@@ -78,7 +78,7 @@ fn tls12_v3_strict() {
let server = RunningArgs::Server {
listen_addr: "127.0.0.1:30005".to_string(),
target_addr: "captive.apple.com:80".to_string(),
tls_addr: TlsAddrs::try_from("bing.com").unwrap(),
tls_addr: TlsAddrs::try_from("badssl.com").unwrap(),
password: "test".to_string(),
nodelay: true,
fastopen: true,
@@ -87,8 +87,8 @@ fn tls12_v3_strict() {
utils::test_ok(client, server, CAPTIVE_HTTP_REQUEST, CAPTIVE_HTTP_RESP);
}
// handshake: bing.com(tls1.2 only)
// data: bing.com:443
// handshake: badssl.com(tls1.2 only)
// data: badssl.com:443
// protocol: v2
// Note: v2 can not defend against hijack attack.
// Here hijack means directly connect to the handshake server.
@@ -98,8 +98,8 @@ fn tls12_v3_strict() {
fn tls12_v2_hijack() {
let client = RunningArgs::Client {
listen_addr: "127.0.0.1:30006".to_string(),
target_addr: "bing.com:443".to_string(),
tls_names: TlsNames::try_from("bing.com").unwrap(),
target_addr: "badssl.com:443".to_string(),
tls_names: TlsNames::try_from("badssl.com").unwrap(),
tls_ext: TlsExtConfig::new(None),
password: "test".to_string(),
nodelay: true,
@@ -109,7 +109,7 @@ fn tls12_v2_hijack() {
test_hijack(client);
}
// handshake: bing.com(tls1.2 only)
// handshake: badssl.com(tls1.2 only)
// data: captive.apple.com:80
// protocol: v3 lossy
// (v3 strict can not work with tls1.2)
@@ -121,8 +121,8 @@ fn tls12_v2_hijack() {
fn tls12_v3_lossy_hijack() {
let client = RunningArgs::Client {
listen_addr: "127.0.0.1:30007".to_string(),
target_addr: "bing.com:443".to_string(),
tls_names: TlsNames::try_from("bing.com").unwrap(),
target_addr: "badssl.com:443".to_string(),
tls_names: TlsNames::try_from("badssl.com").unwrap(),
tls_ext: TlsExtConfig::new(None),
password: "test".to_string(),
nodelay: true,
@@ -20,10 +20,6 @@ jobs:
toolchain: stable
- target: aarch64-unknown-linux-musl
toolchain: stable
- target: x86_64-unknown-linux-gnu:centos
toolchain: stable
- target: aarch64-unknown-linux-gnu:centos
toolchain: stable
#- target: mips-unknown-linux-gnu
# toolchain: nightly
#- target: mipsel-unknown-linux-gnu
@@ -178,7 +178,6 @@ flate2 = { version = "1.0", optional = true }
brotli = { version = "8.0", optional = true }
zstd = { version = "0.13", optional = true }
tun = { version = "0.7", optional = true, features = ["async"] }
etherparse = { version = "0.18", optional = true }
smoltcp = { version = "0.12", optional = true, default-features = false, features = [
"std",
@@ -206,6 +205,9 @@ nix = { version = "0.29", features = ["ioctl"] }
[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.59", features = ["Win32_Networking_WinSock"] }
[target.'cfg(any(target_os = "ios", target_os = "macos", target_os = "linux", target_os = "android", target_os = "windows", target_os = "freebsd"))'.dependencies]
tun = { version = "0.7", optional = true, features = ["async"] }
[dev-dependencies]
byteorder = "1.5"
env_logger = "0.11"
@@ -12,6 +12,7 @@ cfg_if! {
}
#[cfg(unix)]
#[allow(dead_code)]
pub fn set_ipv6_only<S>(socket: &S, ipv6_only: bool) -> io::Result<()>
where
S: std::os::unix::io::AsRawFd,
@@ -10,5 +10,8 @@ cfg_if! {
target_os = "openbsd"))] {
mod bsd;
pub use self::bsd::*;
} else {
mod not_supported;
pub use self::not_supported::*;
}
}
@@ -0,0 +1,21 @@
use std::{io, net::SocketAddr};
use shadowsocks::net::AcceptOpts;
use tokio::net::{TcpListener, TcpStream};
use crate::{
config::RedirType,
local::redir::redir_ext::{TcpListenerRedirExt, TcpStreamRedirExt},
};
impl TcpListenerRedirExt for TcpListener {
async fn bind_redir(_ty: RedirType, _addr: SocketAddr, _accept_opts: AcceptOpts) -> io::Result<TcpListener> {
unimplemented!("TCP transparent proxy is not supported on this platform")
}
}
impl TcpStreamRedirExt for TcpStream {
fn destination_addr(&self, _ty: RedirType) -> io::Result<SocketAddr> {
unimplemented!("TCP transparent proxy is not supported on this platform")
}
}
@@ -1,4 +1,8 @@
use std::{io, net::SocketAddr};
use std::{
io,
net::SocketAddr,
task::{Context, Poll},
};
use crate::{
config::RedirType,
@@ -1,5 +1,7 @@
//! Fake `tun` for those platforms that doesn't support `tun`
#![allow(dead_code)]
use std::{
io::{self, Read, Write},
net::IpAddr,
@@ -9,7 +11,142 @@ use std::{
};
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use tun::{AbstractDevice, Configuration, Error as TunError};
/// TUN interface OSI layer of operation.
#[derive(Clone, Copy, Default, Debug, Eq, PartialEq)]
pub enum Layer {
L2,
#[default]
L3,
}
/// Configuration builder for a TUN interface.
#[derive(Clone, Default, Debug)]
pub struct Configuration;
impl Configuration {
/// Set the tun name.
///
/// [Note: on macOS, the tun name must be the form `utunx` where `x` is a number, such as `utun3`. -- end note]
pub fn tun_name<S: AsRef<str>>(&mut self, _tun_name: S) -> &mut Self {
self
}
/// Set the address.
pub fn address(&mut self, _value: IpAddr) -> &mut Self {
self
}
/// Set the destination address.
pub fn destination(&mut self, _value: IpAddr) -> &mut Self {
self
}
/// Set the broadcast address.
pub fn broadcast(&mut self, _value: IpAddr) -> &mut Self {
self
}
/// Set the netmask.
pub fn netmask(&mut self, _value: IpAddr) -> &mut Self {
self
}
/// Set the MTU.
pub fn mtu(&mut self, _value: u16) -> &mut Self {
self
}
/// Set the interface to be enabled once created.
pub fn up(&mut self) -> &mut Self {
self
}
/// Set the interface to be disabled once created.
pub fn down(&mut self) -> &mut Self {
self
}
/// Set the OSI layer of operation.
pub fn layer(&mut self, _value: Layer) -> &mut Self {
self
}
/// Set the raw fd.
#[cfg(unix)]
pub fn raw_fd(&mut self, _fd: ::std::os::fd::RawFd) -> &mut Self {
self
}
}
/// tun Error type
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("not implementated")]
NotImplemented,
#[error(transparent)]
Io(#[from] std::io::Error),
}
pub type Result<T, E = Error> = ::std::result::Result<T, E>;
/// A TUN abstract device interface.
pub trait AbstractDevice: Read + Write {
/// Reconfigure the device.
fn configure(&mut self, _config: &Configuration) -> Result<()> {
Ok(())
}
/// Get the device index.
fn tun_index(&self) -> Result<i32>;
/// Get the device tun name.
fn tun_name(&self) -> Result<String>;
/// Set the device tun name.
fn set_tun_name(&mut self, tun_name: &str) -> Result<()>;
/// Turn on or off the interface.
fn enabled(&mut self, value: bool) -> Result<()>;
/// Get the address.
fn address(&self) -> Result<IpAddr>;
/// Set the address.
fn set_address(&mut self, value: IpAddr) -> Result<()>;
/// Get the destination address.
fn destination(&self) -> Result<IpAddr>;
/// Set the destination address.
fn set_destination(&mut self, value: IpAddr) -> Result<()>;
/// Get the broadcast address.
fn broadcast(&self) -> Result<IpAddr>;
/// Set the broadcast address.
fn set_broadcast(&mut self, value: IpAddr) -> Result<()>;
/// Get the netmask.
fn netmask(&self) -> Result<IpAddr>;
/// Set the netmask.
fn set_netmask(&mut self, value: IpAddr) -> Result<()>;
/// Get the MTU.
fn mtu(&self) -> Result<u16>;
/// Set the MTU.
///
/// [Note: This setting has no effect on the Windows platform due to the mtu of wintun is always 65535. --end note]
fn set_mtu(&mut self, value: u16) -> Result<()>;
/// Return whether the underlying tun device on the platform has packet information
///
/// [Note: This value is not used to specify whether the packets delivered from/to tun have packet information. -- end note]
fn packet_information(&self) -> bool;
}
pub struct FakeQueue;
@@ -32,60 +169,60 @@ impl Write for FakeQueue {
pub struct FakeDevice;
impl AbstractDevice for FakeDevice {
fn tun_name(&self) -> tun::Result<String> {
Err(TunError::NotImplemented)
fn tun_name(&self) -> Result<String> {
Err(Error::NotImplemented)
}
fn tun_index(&self) -> tun::Result<i32> {
Err(TunError::NotImplemented)
fn tun_index(&self) -> Result<i32> {
Err(Error::NotImplemented)
}
fn set_tun_name(&mut self, _: &str) -> tun::Result<()> {
Err(TunError::NotImplemented)
fn set_tun_name(&mut self, _: &str) -> Result<()> {
Err(Error::NotImplemented)
}
fn enabled(&mut self, _: bool) -> tun::Result<()> {
Err(TunError::NotImplemented)
fn enabled(&mut self, _: bool) -> Result<()> {
Err(Error::NotImplemented)
}
fn address(&self) -> tun::Result<IpAddr> {
Err(TunError::NotImplemented)
fn address(&self) -> Result<IpAddr> {
Err(Error::NotImplemented)
}
fn set_address(&mut self, _: IpAddr) -> tun::Result<()> {
Err(TunError::NotImplemented)
fn set_address(&mut self, _: IpAddr) -> Result<()> {
Err(Error::NotImplemented)
}
fn destination(&self) -> tun::Result<IpAddr> {
Err(TunError::NotImplemented)
fn destination(&self) -> Result<IpAddr> {
Err(Error::NotImplemented)
}
fn set_destination(&mut self, _: IpAddr) -> tun::Result<()> {
Err(TunError::NotImplemented)
fn set_destination(&mut self, _: IpAddr) -> Result<()> {
Err(Error::NotImplemented)
}
fn broadcast(&self) -> tun::Result<IpAddr> {
Err(TunError::NotImplemented)
fn broadcast(&self) -> Result<IpAddr> {
Err(Error::NotImplemented)
}
fn set_broadcast(&mut self, _: IpAddr) -> tun::Result<()> {
Err(TunError::NotImplemented)
fn set_broadcast(&mut self, _: IpAddr) -> Result<()> {
Err(Error::NotImplemented)
}
fn netmask(&self) -> tun::Result<IpAddr> {
Err(TunError::NotImplemented)
fn netmask(&self) -> Result<IpAddr> {
Err(Error::NotImplemented)
}
fn set_netmask(&mut self, _: IpAddr) -> tun::Result<()> {
Err(TunError::NotImplemented)
fn set_netmask(&mut self, _: IpAddr) -> Result<()> {
Err(Error::NotImplemented)
}
fn mtu(&self) -> tun::Result<u16> {
Err(TunError::NotImplemented)
fn mtu(&self) -> Result<u16> {
Err(Error::NotImplemented)
}
fn set_mtu(&mut self, _: u16) -> tun::Result<()> {
Err(TunError::NotImplemented)
fn set_mtu(&mut self, _: u16) -> Result<()> {
Err(Error::NotImplemented)
}
fn packet_information(&self) -> bool {
@@ -158,6 +295,6 @@ impl AsyncWrite for AsyncDevice {
}
/// Create a TUN device with the given name.
pub fn create_as_async(_: &Configuration) -> Result<AsyncDevice, TunError> {
Err(TunError::NotImplemented)
pub fn create_as_async(_: &Configuration) -> Result<AsyncDevice, Error> {
Err(Error::NotImplemented)
}
@@ -33,10 +33,10 @@ cfg_if! {
create_as_async, AsyncDevice, Configuration as TunConfiguration, AbstractDevice, Error as TunError, Layer,
};
} else {
use tun::{AbstractDevice, Configuration as TunConfiguration, Error as TunError, Layer};
mod fake_tun;
use self::fake_tun::{create_as_async, AsyncDevice};
use self::fake_tun::{
AbstractDevice, AsyncDevice, Configuration as TunConfiguration, Error as TunError, Layer, create_as_async,
};
}
}