提交 7144257e 编写于 作者: A Alexandru Gagniuc 提交者: Caspar Zhang

PCI: pciehp: Disable in-band presence detect when possible

task #29600094

commit 202853595e53f981c86656c49fc1cc1e3620f558 upstream.
Backport summary: for 4.19 kernel ICX PCIe Gen4 support.

The presence detect state (PDS) is normally a logical OR of in-band and
out-of-band (OOB) presence detect.  As of PCIe 4.0, there is the option to
disable in-band presence so that the PDS bit always reflects the state of
the out-of-band presence.

The recommendation of the PCIe spec is to disable in-band presence whenever
supported (PCIe r5.0, appendix I implementation note):

  Due to architectural issues, the in-band (Physical-Layer-based) portion
  of the PD mechanism is deprecated for use with async hot-plug. One issue
  is that in-band PD as architected does not detect adapter removal during
  certain LTSSM states, notably the L1 and Disabled States.  Another issue
  is that when both in-band and OOB PD are being used together, the
  Presence Detect State bit and its associated interrupt mechanism always
  reflect the logical OR of the inband and OOB PD states, and with some
  hot-plug hardware configurations, it is important for software to detect
  and respond to in-band and OOB PD events independently.  If OOB PD is
  being used and the associated DSP supports In-Band PD Disable, it is
  recommended that the In-Band PD Disable bit be Set, and the Presence
  Detect State bit and its associated interrupt mechanism be used
  exclusively for OOB PD.  As a substitute for in-band PD with async
  hot-plug, the reference model uses either the DPC or the DLL Link Active
  mechanism.

Link: https://lore.kernel.org/r/20191025190047.38130-2-stuart.w.hayes@gmail.com
[bhelgaas: move PCI_EXP_SLTCAP2 read earlier & print PCI_EXP_SLTCAP2_IBPD
value (suggested by Lukas)]
Signed-off-by: NAlexandru Gagniuc <mr.nuke.me@gmail.com>
Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: NAndy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: NLukas Wunner <lukas@wunner.de>

(cherry picked from commit 202853595e53f981c86656c49fc1cc1e3620f558)
Signed-off-by: NEthan Zhao <haifeng.zhao@intel.com>

Conflicts:
	drivers/pci/hotplug/pciehp.h
	drivers/pci/hotplug/pciehp_hpc.c
Signed-off-by: NArtie Ding <artie.ding@linux.alibaba.com>
Acked-by: NCaspar Zhang <caspar@linux.alibaba.com>
上级 f809fe13
...@@ -109,6 +109,7 @@ struct slot { ...@@ -109,6 +109,7 @@ struct slot {
struct controller { struct controller {
struct mutex ctrl_lock; struct mutex ctrl_lock;
struct pcie_device *pcie; struct pcie_device *pcie;
unsigned int inband_presence_disabled:1;
struct rw_semaphore reset_lock; struct rw_semaphore reset_lock;
struct slot *slot; struct slot *slot;
wait_queue_head_t queue; wait_queue_head_t queue;
......
...@@ -842,8 +842,8 @@ static inline void dbg_ctrl(struct controller *ctrl) ...@@ -842,8 +842,8 @@ static inline void dbg_ctrl(struct controller *ctrl)
struct controller *pcie_init(struct pcie_device *dev) struct controller *pcie_init(struct pcie_device *dev)
{ {
struct controller *ctrl; struct controller *ctrl;
u32 slot_cap, link_cap;
u8 occupied, poweron; u8 occupied, poweron;
u32 slot_cap, slot_cap2, link_cap;
struct pci_dev *pdev = dev->port; struct pci_dev *pdev = dev->port;
ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
...@@ -870,6 +870,13 @@ struct controller *pcie_init(struct pcie_device *dev) ...@@ -870,6 +870,13 @@ struct controller *pcie_init(struct pcie_device *dev)
init_waitqueue_head(&ctrl->queue); init_waitqueue_head(&ctrl->queue);
dbg_ctrl(ctrl); dbg_ctrl(ctrl);
pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP2, &slot_cap2);
if (slot_cap2 & PCI_EXP_SLTCAP2_IBPD) {
pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_IBPD_DISABLE,
PCI_EXP_SLTCTL_IBPD_DISABLE);
ctrl->inband_presence_disabled = 1;
}
/* Check if Data Link Layer Link Active Reporting is implemented */ /* Check if Data Link Layer Link Active Reporting is implemented */
pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap); pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap);
...@@ -879,7 +886,7 @@ struct controller *pcie_init(struct pcie_device *dev) ...@@ -879,7 +886,7 @@ struct controller *pcie_init(struct pcie_device *dev)
PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_CC |
PCI_EXP_SLTSTA_DLLSC | PCI_EXP_SLTSTA_PDC); PCI_EXP_SLTSTA_DLLSC | PCI_EXP_SLTSTA_PDC);
ctrl_info(ctrl, "Slot #%d AttnBtn%c PwrCtrl%c MRL%c AttnInd%c PwrInd%c HotPlug%c Surprise%c Interlock%c NoCompl%c LLActRep%c%s\n", ctrl_info(ctrl, "Slot #%d AttnBtn%c PwrCtrl%c MRL%c AttnInd%c PwrInd%c HotPlug%c Surprise%c Interlock%c NoCompl%c IbPresDis%c LLActRep%c%s\n",
(slot_cap & PCI_EXP_SLTCAP_PSN) >> 19, (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19,
FLAG(slot_cap, PCI_EXP_SLTCAP_ABP), FLAG(slot_cap, PCI_EXP_SLTCAP_ABP),
FLAG(slot_cap, PCI_EXP_SLTCAP_PCP), FLAG(slot_cap, PCI_EXP_SLTCAP_PCP),
...@@ -890,6 +897,7 @@ struct controller *pcie_init(struct pcie_device *dev) ...@@ -890,6 +897,7 @@ struct controller *pcie_init(struct pcie_device *dev)
FLAG(slot_cap, PCI_EXP_SLTCAP_HPS), FLAG(slot_cap, PCI_EXP_SLTCAP_HPS),
FLAG(slot_cap, PCI_EXP_SLTCAP_EIP), FLAG(slot_cap, PCI_EXP_SLTCAP_EIP),
FLAG(slot_cap, PCI_EXP_SLTCAP_NCCS), FLAG(slot_cap, PCI_EXP_SLTCAP_NCCS),
FLAG(slot_cap2, PCI_EXP_SLTCAP2_IBPD),
FLAG(link_cap, PCI_EXP_LNKCAP_DLLLARC), FLAG(link_cap, PCI_EXP_LNKCAP_DLLLARC),
pdev->broken_cmd_compl ? " (with Cmd Compl erratum)" : ""); pdev->broken_cmd_compl ? " (with Cmd Compl erratum)" : "");
......
...@@ -603,6 +603,7 @@ ...@@ -603,6 +603,7 @@
#define PCI_EXP_SLTCTL_PWR_OFF 0x0400 /* Power Off */ #define PCI_EXP_SLTCTL_PWR_OFF 0x0400 /* Power Off */
#define PCI_EXP_SLTCTL_EIC 0x0800 /* Electromechanical Interlock Control */ #define PCI_EXP_SLTCTL_EIC 0x0800 /* Electromechanical Interlock Control */
#define PCI_EXP_SLTCTL_DLLSCE 0x1000 /* Data Link Layer State Changed Enable */ #define PCI_EXP_SLTCTL_DLLSCE 0x1000 /* Data Link Layer State Changed Enable */
#define PCI_EXP_SLTCTL_IBPD_DISABLE 0x4000 /* In-band PD disable */
#define PCI_EXP_SLTSTA 26 /* Slot Status */ #define PCI_EXP_SLTSTA 26 /* Slot Status */
#define PCI_EXP_SLTSTA_ABP 0x0001 /* Attention Button Pressed */ #define PCI_EXP_SLTSTA_ABP 0x0001 /* Attention Button Pressed */
#define PCI_EXP_SLTSTA_PFD 0x0002 /* Power Fault Detected */ #define PCI_EXP_SLTSTA_PFD 0x0002 /* Power Fault Detected */
...@@ -673,6 +674,7 @@ ...@@ -673,6 +674,7 @@
#define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ #define PCI_EXP_LNKSTA2 50 /* Link Status 2 */
#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 52 /* v2 endpoints with link end here */ #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 52 /* v2 endpoints with link end here */
#define PCI_EXP_SLTCAP2 52 /* Slot Capabilities 2 */ #define PCI_EXP_SLTCAP2 52 /* Slot Capabilities 2 */
#define PCI_EXP_SLTCAP2_IBPD 0x00000001 /* In-band PD Disable Supported */
#define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */
#define PCI_EXP_SLTSTA2 58 /* Slot Status 2 */ #define PCI_EXP_SLTSTA2 58 /* Slot Status 2 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册