Skip to content

Commit 29fdad6

Browse files
committed
Merge remote-tracking branch tech/bus/pci/pwrctl into qcom-next
2 parents 45d5279 + 606cc88 commit 29fdad6

10 files changed

Lines changed: 294 additions & 35 deletions

File tree

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/pci/toshiba,tc9563.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Toshiba TC9563 PCIe switch
8+
9+
maintainers:
10+
- Krishna chaitanya chundru <quic_krichai@quicinc.com>
11+
12+
description: |
13+
Toshiba TC9563 PCIe switch has one upstream and three downstream ports.
14+
The 3rd downstream port has integrated endpoint device of Ethernet MAC.
15+
Other two downstream ports are supposed to connect to external device.
16+
17+
The TC9563 PCIe switch can be configured through I2C interface before
18+
PCIe link is established to change FTS, ASPM related entry delays,
19+
tx amplitude etc for better power efficiency and functionality.
20+
21+
properties:
22+
compatible:
23+
enum:
24+
- pci1179,0623
25+
26+
reg:
27+
maxItems: 1
28+
29+
reset-gpios:
30+
maxItems: 1
31+
description:
32+
GPIO controlling the RESX# pin.
33+
34+
vdd18-supply: true
35+
36+
vdd09-supply: true
37+
38+
vddc-supply: true
39+
40+
vddio1-supply: true
41+
42+
vddio2-supply: true
43+
44+
vddio18-supply: true
45+
46+
i2c-parent:
47+
$ref: /schemas/types.yaml#/definitions/phandle-array
48+
description:
49+
A phandle to the parent I2C node and the slave address of the device
50+
used to do configure tc9563 to change FTS, tx amplitude etc.
51+
items:
52+
- description: Phandle to the I2C controller node
53+
- description: I2C slave address
54+
55+
patternProperties:
56+
"^pcie@[1-3],0$":
57+
description:
58+
child nodes describing the internal downstream ports
59+
the tc9563 switch.
60+
type: object
61+
allOf:
62+
- $ref: "#/$defs/tc9563-node"
63+
- $ref: /schemas/pci/pci-pci-bridge.yaml#
64+
unevaluatedProperties: false
65+
66+
$defs:
67+
tc9563-node:
68+
type: object
69+
70+
properties:
71+
toshiba,tx-amplitude-microvolt:
72+
description:
73+
Change Tx Margin setting for low power consumption.
74+
75+
toshiba,no-dfe-support:
76+
type: boolean
77+
description:
78+
Disable DFE (Decision Feedback Equalizer), which mitigates
79+
intersymbol interference and some reflections caused by impedance mismatches.
80+
81+
required:
82+
- reset-gpios
83+
- vdd18-supply
84+
- vdd09-supply
85+
- vddc-supply
86+
- vddio1-supply
87+
- vddio2-supply
88+
- vddio18-supply
89+
- i2c-parent
90+
91+
allOf:
92+
- $ref: "#/$defs/tc9563-node"
93+
- $ref: /schemas/pci/pci-bus-common.yaml#
94+
95+
unevaluatedProperties: false
96+
97+
examples:
98+
- |
99+
#include <dt-bindings/gpio/gpio.h>
100+
101+
pcie {
102+
#address-cells = <3>;
103+
#size-cells = <2>;
104+
105+
pcie@0 {
106+
device_type = "pci";
107+
reg = <0x0 0x0 0x0 0x0 0x0>;
108+
109+
#address-cells = <3>;
110+
#size-cells = <2>;
111+
ranges;
112+
bus-range = <0x01 0xff>;
113+
114+
pcie@0,0 {
115+
compatible = "pci1179,0623";
116+
117+
reg = <0x10000 0x0 0x0 0x0 0x0>;
118+
device_type = "pci";
119+
#address-cells = <3>;
120+
#size-cells = <2>;
121+
ranges;
122+
bus-range = <0x02 0xff>;
123+
124+
i2c-parent = <&qup_i2c 0x77>;
125+
126+
vdd18-supply = <&vdd>;
127+
vdd09-supply = <&vdd>;
128+
vddc-supply = <&vdd>;
129+
vddio1-supply = <&vdd>;
130+
vddio2-supply = <&vdd>;
131+
vddio18-supply = <&vdd>;
132+
133+
reset-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
134+
135+
pcie@1,0 {
136+
compatible = "pciclass,0604";
137+
reg = <0x20800 0x0 0x0 0x0 0x0>;
138+
#address-cells = <3>;
139+
#size-cells = <2>;
140+
device_type = "pci";
141+
ranges;
142+
bus-range = <0x03 0xff>;
143+
144+
toshiba,no-dfe-support;
145+
};
146+
147+
pcie@2,0 {
148+
compatible = "pciclass,0604";
149+
reg = <0x21000 0x0 0x0 0x0 0x0>;
150+
#address-cells = <3>;
151+
#size-cells = <2>;
152+
device_type = "pci";
153+
ranges;
154+
bus-range = <0x04 0xff>;
155+
};
156+
157+
pcie@3,0 {
158+
compatible = "pciclass,0604";
159+
reg = <0x21800 0x0 0x0 0x0 0x0>;
160+
#address-cells = <3>;
161+
#size-cells = <2>;
162+
device_type = "pci";
163+
ranges;
164+
bus-range = <0x05 0xff>;
165+
166+
toshiba,tx-amplitude-microvolt = <10>;
167+
168+
ethernet@0,0 {
169+
reg = <0x50000 0x0 0x0 0x0 0x0>;
170+
};
171+
172+
ethernet@0,1 {
173+
reg = <0x50100 0x0 0x0 0x0 0x0>;
174+
};
175+
};
176+
};
177+
};
178+
};

drivers/pci/controller/dwc/pcie-designware-host.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,10 +727,28 @@ void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, unsigned int devfn,
727727
}
728728
EXPORT_SYMBOL_GPL(dw_pcie_own_conf_map_bus);
729729

730+
static int dw_pcie_op_start_link(struct pci_bus *bus)
731+
{
732+
struct dw_pcie_rp *pp = bus->sysdata;
733+
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
734+
735+
return dw_pcie_host_start_link(pci);
736+
}
737+
738+
static void dw_pcie_op_stop_link(struct pci_bus *bus)
739+
{
740+
struct dw_pcie_rp *pp = bus->sysdata;
741+
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
742+
743+
dw_pcie_host_stop_link(pci);
744+
}
745+
730746
static struct pci_ops dw_pcie_ops = {
731747
.map_bus = dw_pcie_own_conf_map_bus,
732748
.read = pci_generic_config_read,
733749
.write = pci_generic_config_write,
750+
.start_link = dw_pcie_op_start_link,
751+
.stop_link = dw_pcie_op_stop_link,
734752
};
735753

736754
static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)

drivers/pci/controller/dwc/pcie-designware.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,8 @@ struct dw_pcie_ops {
484484
enum dw_pcie_ltssm (*get_ltssm)(struct dw_pcie *pcie);
485485
int (*start_link)(struct dw_pcie *pcie);
486486
void (*stop_link)(struct dw_pcie *pcie);
487+
int (*host_start_link)(struct dw_pcie *pcie);
488+
void (*host_stop_link)(struct dw_pcie *pcie);
487489
};
488490

489491
struct debugfs_info {
@@ -743,6 +745,20 @@ static inline void dw_pcie_stop_link(struct dw_pcie *pci)
743745
pci->ops->stop_link(pci);
744746
}
745747

748+
static inline int dw_pcie_host_start_link(struct dw_pcie *pci)
749+
{
750+
if (pci->ops && pci->ops->host_start_link)
751+
return pci->ops->host_start_link(pci);
752+
753+
return 0;
754+
}
755+
756+
static inline void dw_pcie_host_stop_link(struct dw_pcie *pci)
757+
{
758+
if (pci->ops && pci->ops->host_stop_link)
759+
pci->ops->host_stop_link(pci);
760+
}
761+
746762
static inline enum dw_pcie_ltssm dw_pcie_get_ltssm(struct dw_pcie *pci)
747763
{
748764
u32 val;

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ struct qcom_pcie_ops {
257257
void (*host_post_init)(struct qcom_pcie *pcie);
258258
void (*deinit)(struct qcom_pcie *pcie);
259259
void (*ltssm_enable)(struct qcom_pcie *pcie);
260+
void (*ltssm_disable)(struct qcom_pcie *pcie);
260261
int (*config_sid)(struct qcom_pcie *pcie);
261262
};
262263

@@ -647,6 +648,37 @@ static int qcom_pcie_post_init_1_0_0(struct qcom_pcie *pcie)
647648
return 0;
648649
}
649650

651+
static int qcom_pcie_host_start_link(struct dw_pcie *pci)
652+
{
653+
struct qcom_pcie *pcie = to_qcom_pcie(pci);
654+
655+
qcom_ep_reset_deassert(pcie);
656+
657+
if (pcie->cfg->ops->ltssm_enable)
658+
pcie->cfg->ops->ltssm_enable(pcie);
659+
660+
return 0;
661+
}
662+
663+
static void qcom_pcie_host_stop_link(struct dw_pcie *pci)
664+
{
665+
struct qcom_pcie *pcie = to_qcom_pcie(pci);
666+
667+
qcom_ep_reset_assert(pcie);
668+
669+
if (pcie->cfg->ops->ltssm_disable)
670+
pcie->cfg->ops->ltssm_disable(pcie);
671+
}
672+
673+
static void qcom_pcie_2_3_2_ltssm_disable(struct qcom_pcie *pcie)
674+
{
675+
u32 val;
676+
677+
val = readl(pcie->parf + PARF_LTSSM);
678+
val &= ~LTSSM_EN;
679+
writel(val, pcie->parf + PARF_LTSSM);
680+
}
681+
650682
static void qcom_pcie_2_3_2_ltssm_enable(struct qcom_pcie *pcie)
651683
{
652684
u32 val;
@@ -1399,6 +1431,7 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
13991431
.host_post_init = qcom_pcie_host_post_init_2_7_0,
14001432
.deinit = qcom_pcie_deinit_2_7_0,
14011433
.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
1434+
.ltssm_disable = qcom_pcie_2_3_2_ltssm_disable,
14021435
.config_sid = qcom_pcie_config_sid_1_9_0,
14031436
};
14041437

@@ -1466,6 +1499,8 @@ static const struct qcom_pcie_cfg cfg_sc8280xp = {
14661499
static const struct dw_pcie_ops dw_pcie_ops = {
14671500
.link_up = qcom_pcie_link_up,
14681501
.start_link = qcom_pcie_start_link,
1502+
.host_start_link = qcom_pcie_host_start_link,
1503+
.host_stop_link = qcom_pcie_host_stop_link,
14691504
};
14701505

14711506
static int qcom_pcie_icc_init(struct qcom_pcie *pcie)

drivers/pci/hotplug/pciehp_ctrl.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ void pciehp_handle_disable_request(struct controller *ctrl)
230230

231231
void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
232232
{
233-
int present, link_active;
233+
bool link_active;
234+
int present;
234235

235236
/*
236237
* If the slot is on and presence or link has changed, turn it off.
@@ -260,8 +261,8 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
260261
/* Turn the slot on if it's occupied or link is up */
261262
mutex_lock(&ctrl->state_lock);
262263
present = pciehp_card_present(ctrl);
263-
link_active = pciehp_check_link_active(ctrl);
264-
if (present <= 0 && link_active <= 0) {
264+
link_active = pcie_link_is_active(ctrl->pcie->port);
265+
if (present <= 0 && !link_active) {
265266
if (ctrl->state == BLINKINGON_STATE) {
266267
ctrl->state = OFF_STATE;
267268
cancel_delayed_work(&ctrl->button_work);

drivers/pci/hotplug/pciehp_hpc.c

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -221,33 +221,6 @@ static void pcie_write_cmd_nowait(struct controller *ctrl, u16 cmd, u16 mask)
221221
pcie_do_write_cmd(ctrl, cmd, mask, false);
222222
}
223223

224-
/**
225-
* pciehp_check_link_active() - Is the link active
226-
* @ctrl: PCIe hotplug controller
227-
*
228-
* Check whether the downstream link is currently active. Note it is
229-
* possible that the card is removed immediately after this so the
230-
* caller may need to take it into account.
231-
*
232-
* If the hotplug controller itself is not available anymore returns
233-
* %-ENODEV.
234-
*/
235-
int pciehp_check_link_active(struct controller *ctrl)
236-
{
237-
struct pci_dev *pdev = ctrl_dev(ctrl);
238-
u16 lnk_status;
239-
int ret;
240-
241-
ret = pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);
242-
if (ret == PCIBIOS_DEVICE_NOT_FOUND || PCI_POSSIBLE_ERROR(lnk_status))
243-
return -ENODEV;
244-
245-
ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
246-
ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
247-
248-
return ret;
249-
}
250-
251224
static bool pci_bus_check_dev(struct pci_bus *bus, int devfn)
252225
{
253226
u32 l;
@@ -467,7 +440,7 @@ int pciehp_card_present_or_link_active(struct controller *ctrl)
467440
if (ret)
468441
return ret;
469442

470-
return pciehp_check_link_active(ctrl);
443+
return pcie_link_is_active(ctrl_dev(ctrl));
471444
}
472445

473446
int pciehp_query_power_fault(struct controller *ctrl)
@@ -921,7 +894,7 @@ int pciehp_slot_reset(struct pcie_device *dev)
921894
pcie_capability_write_word(dev->port, PCI_EXP_SLTSTA,
922895
PCI_EXP_SLTSTA_DLLSC);
923896

924-
if (!pciehp_check_link_active(ctrl))
897+
if (!pcie_link_is_active(ctrl_dev(ctrl)))
925898
pciehp_request(ctrl, PCI_EXP_SLTSTA_DLLSC);
926899

927900
return 0;

0 commit comments

Comments
 (0)