Skip to content

Commit c11dfed

Browse files
committed
Merge branch 'remotes/lorenzo/pci/qcom'
- Add DT clock/reset info for SDM845 PCIe controller (Bjorn Andersson) - Add support for SDM845 PCIe controller to the qcom driver (Bjorn Andersson) * remotes/lorenzo/pci/qcom: PCI: qcom: Add support for SDM845 PCIe controller dt-bindings: PCI: qcom: Add support for SDM845 PCIe
2 parents d869363 + ed8cc3b commit c11dfed

File tree

2 files changed

+169
-0
lines changed

2 files changed

+169
-0
lines changed

Documentation/devicetree/bindings/pci/qcom,pcie.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- "qcom,pcie-ipq4019" for ipq4019
1212
- "qcom,pcie-ipq8074" for ipq8074
1313
- "qcom,pcie-qcs404" for qcs404
14+
- "qcom,pcie-sdm845" for sdm845
1415

1516
- reg:
1617
Usage: required
@@ -126,6 +127,18 @@
126127
- "master_bus" AXI Master clock
127128
- "slave_bus" AXI Slave clock
128129

130+
-clock-names:
131+
Usage: required for sdm845
132+
Value type: <stringlist>
133+
Definition: Should contain the following entries
134+
- "aux" Auxiliary clock
135+
- "cfg" Configuration clock
136+
- "bus_master" Master AXI clock
137+
- "bus_slave" Slave AXI clock
138+
- "slave_q2a" Slave Q2A clock
139+
- "tbu" PCIe TBU clock
140+
- "pipe" PIPE clock
141+
129142
- resets:
130143
Usage: required
131144
Value type: <prop-encoded-array>
@@ -188,6 +201,12 @@
188201
- "pwr" PWR reset
189202
- "ahb" AHB reset
190203

204+
- reset-names:
205+
Usage: required for sdm845
206+
Value type: <stringlist>
207+
Definition: Should contain the following entries
208+
- "pci" PCIe core reset
209+
191210
- power-domains:
192211
Usage: required for apq8084 and msm8996/apq8096
193212
Value type: <prop-encoded-array>

drivers/pci/controller/dwc/pcie-qcom.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#define PCIE20_PARF_LTSSM 0x1B0
5555
#define PCIE20_PARF_SID_OFFSET 0x234
5656
#define PCIE20_PARF_BDF_TRANSLATE_CFG 0x24C
57+
#define PCIE20_PARF_DEVICE_TYPE 0x1000
5758

5859
#define PCIE20_ELBI_SYS_CTRL 0x04
5960
#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0)
@@ -80,6 +81,8 @@
8081
#define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE 0x358
8182
#define SLV_ADDR_SPACE_SZ 0x10000000
8283

84+
#define DEVICE_TYPE_RC 0x4
85+
8386
#define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
8487
struct qcom_pcie_resources_2_1_0 {
8588
struct clk *iface_clk;
@@ -139,12 +142,20 @@ struct qcom_pcie_resources_2_3_3 {
139142
struct reset_control *rst[7];
140143
};
141144

145+
struct qcom_pcie_resources_2_7_0 {
146+
struct clk_bulk_data clks[6];
147+
struct regulator_bulk_data supplies[2];
148+
struct reset_control *pci_reset;
149+
struct clk *pipe_clk;
150+
};
151+
142152
union qcom_pcie_resources {
143153
struct qcom_pcie_resources_1_0_0 v1_0_0;
144154
struct qcom_pcie_resources_2_1_0 v2_1_0;
145155
struct qcom_pcie_resources_2_3_2 v2_3_2;
146156
struct qcom_pcie_resources_2_3_3 v2_3_3;
147157
struct qcom_pcie_resources_2_4_0 v2_4_0;
158+
struct qcom_pcie_resources_2_7_0 v2_7_0;
148159
};
149160

150161
struct qcom_pcie;
@@ -1068,6 +1079,134 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)
10681079
return ret;
10691080
}
10701081

1082+
static int qcom_pcie_get_resources_2_7_0(struct qcom_pcie *pcie)
1083+
{
1084+
struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
1085+
struct dw_pcie *pci = pcie->pci;
1086+
struct device *dev = pci->dev;
1087+
int ret;
1088+
1089+
res->pci_reset = devm_reset_control_get_exclusive(dev, "pci");
1090+
if (IS_ERR(res->pci_reset))
1091+
return PTR_ERR(res->pci_reset);
1092+
1093+
res->supplies[0].supply = "vdda";
1094+
res->supplies[1].supply = "vddpe-3v3";
1095+
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(res->supplies),
1096+
res->supplies);
1097+
if (ret)
1098+
return ret;
1099+
1100+
res->clks[0].id = "aux";
1101+
res->clks[1].id = "cfg";
1102+
res->clks[2].id = "bus_master";
1103+
res->clks[3].id = "bus_slave";
1104+
res->clks[4].id = "slave_q2a";
1105+
res->clks[5].id = "tbu";
1106+
1107+
ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
1108+
if (ret < 0)
1109+
return ret;
1110+
1111+
res->pipe_clk = devm_clk_get(dev, "pipe");
1112+
return PTR_ERR_OR_ZERO(res->pipe_clk);
1113+
}
1114+
1115+
static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
1116+
{
1117+
struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
1118+
struct dw_pcie *pci = pcie->pci;
1119+
struct device *dev = pci->dev;
1120+
u32 val;
1121+
int ret;
1122+
1123+
ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies);
1124+
if (ret < 0) {
1125+
dev_err(dev, "cannot enable regulators\n");
1126+
return ret;
1127+
}
1128+
1129+
ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
1130+
if (ret < 0)
1131+
goto err_disable_regulators;
1132+
1133+
ret = reset_control_assert(res->pci_reset);
1134+
if (ret < 0) {
1135+
dev_err(dev, "cannot deassert pci reset\n");
1136+
goto err_disable_clocks;
1137+
}
1138+
1139+
usleep_range(1000, 1500);
1140+
1141+
ret = reset_control_deassert(res->pci_reset);
1142+
if (ret < 0) {
1143+
dev_err(dev, "cannot deassert pci reset\n");
1144+
goto err_disable_clocks;
1145+
}
1146+
1147+
ret = clk_prepare_enable(res->pipe_clk);
1148+
if (ret) {
1149+
dev_err(dev, "cannot prepare/enable pipe clock\n");
1150+
goto err_disable_clocks;
1151+
}
1152+
1153+
/* configure PCIe to RC mode */
1154+
writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
1155+
1156+
/* enable PCIe clocks and resets */
1157+
val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
1158+
val &= ~BIT(0);
1159+
writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
1160+
1161+
/* change DBI base address */
1162+
writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
1163+
1164+
/* MAC PHY_POWERDOWN MUX DISABLE */
1165+
val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
1166+
val &= ~BIT(29);
1167+
writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
1168+
1169+
val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
1170+
val |= BIT(4);
1171+
writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
1172+
1173+
if (IS_ENABLED(CONFIG_PCI_MSI)) {
1174+
val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
1175+
val |= BIT(31);
1176+
writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT);
1177+
}
1178+
1179+
return 0;
1180+
err_disable_clocks:
1181+
clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
1182+
err_disable_regulators:
1183+
regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
1184+
1185+
return ret;
1186+
}
1187+
1188+
static void qcom_pcie_deinit_2_7_0(struct qcom_pcie *pcie)
1189+
{
1190+
struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
1191+
1192+
clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
1193+
regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
1194+
}
1195+
1196+
static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie)
1197+
{
1198+
struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
1199+
1200+
return clk_prepare_enable(res->pipe_clk);
1201+
}
1202+
1203+
static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
1204+
{
1205+
struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
1206+
1207+
clk_disable_unprepare(res->pipe_clk);
1208+
}
1209+
10711210
static int qcom_pcie_link_up(struct dw_pcie *pci)
10721211
{
10731212
u16 val = readw(pci->dbi_base + PCIE20_CAP + PCI_EXP_LNKSTA);
@@ -1167,6 +1306,16 @@ static const struct qcom_pcie_ops ops_2_3_3 = {
11671306
.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
11681307
};
11691308

1309+
/* Qcom IP rev.: 2.7.0 Synopsys IP rev.: 4.30a */
1310+
static const struct qcom_pcie_ops ops_2_7_0 = {
1311+
.get_resources = qcom_pcie_get_resources_2_7_0,
1312+
.init = qcom_pcie_init_2_7_0,
1313+
.deinit = qcom_pcie_deinit_2_7_0,
1314+
.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
1315+
.post_init = qcom_pcie_post_init_2_7_0,
1316+
.post_deinit = qcom_pcie_post_deinit_2_7_0,
1317+
};
1318+
11701319
static const struct dw_pcie_ops dw_pcie_ops = {
11711320
.link_up = qcom_pcie_link_up,
11721321
};
@@ -1282,6 +1431,7 @@ static const struct of_device_id qcom_pcie_match[] = {
12821431
{ .compatible = "qcom,pcie-ipq8074", .data = &ops_2_3_3 },
12831432
{ .compatible = "qcom,pcie-ipq4019", .data = &ops_2_4_0 },
12841433
{ .compatible = "qcom,pcie-qcs404", .data = &ops_2_4_0 },
1434+
{ .compatible = "qcom,pcie-sdm845", .data = &ops_2_7_0 },
12851435
{ }
12861436
};
12871437

0 commit comments

Comments
 (0)