linux/drivers/pci/controller/pcie-apple.c

// SPDX-License-Identifier: GPL-2.0
/*
 * PCIe host bridge driver for Apple system-on-chips.
 *
 * The HW is ECAM compliant, so once the controller is initialized,
 * the driver mostly deals MSI mapping and handling of per-port
 * interrupts (INTx, management and error signals).
 *
 * Initialization requires enabling power and clocks, along with a
 * number of register pokes.
 *
 * Copyright (C) 2021 Alyssa Rosenzweig <[email protected]>
 * Copyright (C) 2021 Google LLC
 * Copyright (C) 2021 Corellium LLC
 * Copyright (C) 2021 Mark Kettenis <[email protected]>
 *
 * Author: Alyssa Rosenzweig <[email protected]>
 * Author: Marc Zyngier <[email protected]>
 */

#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/iopoll.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/msi.h>
#include <linux/notifier.h>
#include <linux/of_irq.h>
#include <linux/pci-ecam.h>

#define CORE_RC_PHYIF_CTL
#define CORE_RC_PHYIF_CTL_RUN
#define CORE_RC_PHYIF_STAT
#define CORE_RC_PHYIF_STAT_REFCLK
#define CORE_RC_CTL
#define CORE_RC_CTL_RUN
#define CORE_RC_STAT
#define CORE_RC_STAT_READY
#define CORE_FABRIC_STAT
#define CORE_FABRIC_STAT_MASK
#define CORE_LANE_CFG(port)
#define CORE_LANE_CFG_REFCLK0REQ
#define CORE_LANE_CFG_REFCLK1REQ
#define CORE_LANE_CFG_REFCLK0ACK
#define CORE_LANE_CFG_REFCLK1ACK
#define CORE_LANE_CFG_REFCLKEN
#define CORE_LANE_CTL(port)
#define CORE_LANE_CTL_CFGACC

#define PORT_LTSSMCTL
#define PORT_LTSSMCTL_START
#define PORT_INTSTAT
#define PORT_INT_TUNNEL_ERR
#define PORT_INT_CPL_TIMEOUT
#define PORT_INT_RID2SID_MAPERR
#define PORT_INT_CPL_ABORT
#define PORT_INT_MSI_BAD_DATA
#define PORT_INT_MSI_ERR
#define PORT_INT_REQADDR_GT32
#define PORT_INT_AF_TIMEOUT
#define PORT_INT_LINK_DOWN
#define PORT_INT_LINK_UP
#define PORT_INT_LINK_BWMGMT
#define PORT_INT_AER_MASK
#define PORT_INT_PORT_ERR
#define PORT_INT_INTx(i)
#define PORT_INT_INTx_MASK
#define PORT_INTMSK
#define PORT_INTMSKSET
#define PORT_INTMSKCLR
#define PORT_MSICFG
#define PORT_MSICFG_EN
#define PORT_MSICFG_L2MSINUM_SHIFT
#define PORT_MSIBASE
#define PORT_MSIBASE_1_SHIFT
#define PORT_MSIADDR
#define PORT_LINKSTS
#define PORT_LINKSTS_UP
#define PORT_LINKSTS_BUSY
#define PORT_LINKCMDSTS
#define PORT_OUTS_NPREQS
#define PORT_OUTS_NPREQS_REQ
#define PORT_OUTS_NPREQS_CPL
#define PORT_RXWR_FIFO
#define PORT_RXWR_FIFO_HDR
#define PORT_RXWR_FIFO_DATA
#define PORT_RXRD_FIFO
#define PORT_RXRD_FIFO_REQ
#define PORT_OUTS_CPLS
#define PORT_OUTS_CPLS_SHRD
#define PORT_OUTS_CPLS_WAIT
#define PORT_APPCLK
#define PORT_APPCLK_EN
#define PORT_APPCLK_CGDIS
#define PORT_STATUS
#define PORT_STATUS_READY
#define PORT_REFCLK
#define PORT_REFCLK_EN
#define PORT_REFCLK_CGDIS
#define PORT_PERST
#define PORT_PERST_OFF
#define PORT_RID2SID(i16)
#define PORT_RID2SID_VALID
#define PORT_RID2SID_SID_SHIFT
#define PORT_RID2SID_BUS_SHIFT
#define PORT_RID2SID_DEV_SHIFT
#define PORT_RID2SID_FUNC_SHIFT
#define PORT_OUTS_PREQS_HDR
#define PORT_OUTS_PREQS_HDR_MASK
#define PORT_OUTS_PREQS_DATA
#define PORT_OUTS_PREQS_DATA_MASK
#define PORT_TUNCTRL
#define PORT_TUNCTRL_PERST_ON
#define PORT_TUNCTRL_PERST_ACK_REQ
#define PORT_TUNSTAT
#define PORT_TUNSTAT_PERST_ON
#define PORT_TUNSTAT_PERST_ACK_PEND
#define PORT_PREFMEM_ENABLE

#define MAX_RID2SID

/*
 * The doorbell address is set to 0xfffff000, which by convention
 * matches what MacOS does, and it is possible to use any other
 * address (in the bottom 4GB, as the base register is only 32bit).
 * However, it has to be excluded from the IOVA range, and the DART
 * driver has to know about it.
 */
#define DOORBELL_ADDR

struct apple_pcie {};

struct apple_pcie_port {};

static void rmw_set(u32 set, void __iomem *addr)
{}

static void rmw_clear(u32 clr, void __iomem *addr)
{}

static void apple_msi_top_irq_mask(struct irq_data *d)
{}

static void apple_msi_top_irq_unmask(struct irq_data *d)
{}

static struct irq_chip apple_msi_top_chip =;

static void apple_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
{}

static struct irq_chip apple_msi_bottom_chip =;

static int apple_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
				  unsigned int nr_irqs, void *args)
{}

static void apple_msi_domain_free(struct irq_domain *domain, unsigned int virq,
				  unsigned int nr_irqs)
{}

static const struct irq_domain_ops apple_msi_domain_ops =;

static struct msi_domain_info apple_msi_info =;

static void apple_port_irq_mask(struct irq_data *data)
{}

static void apple_port_irq_unmask(struct irq_data *data)
{}

static bool hwirq_is_intx(unsigned int hwirq)
{}

static void apple_port_irq_ack(struct irq_data *data)
{}

static int apple_port_irq_set_type(struct irq_data *data, unsigned int type)
{}

static struct irq_chip apple_port_irqchip =;

static int apple_port_irq_domain_alloc(struct irq_domain *domain,
				       unsigned int virq, unsigned int nr_irqs,
				       void *args)
{}

static void apple_port_irq_domain_free(struct irq_domain *domain,
				       unsigned int virq, unsigned int nr_irqs)
{}

static const struct irq_domain_ops apple_port_irq_domain_ops =;

static void apple_port_irq_handler(struct irq_desc *desc)
{}

static int apple_pcie_port_setup_irq(struct apple_pcie_port *port)
{}

static irqreturn_t apple_pcie_port_irq(int irq, void *data)
{}

static int apple_pcie_port_register_irqs(struct apple_pcie_port *port)
{}

static int apple_pcie_setup_refclk(struct apple_pcie *pcie,
				   struct apple_pcie_port *port)
{}

static u32 apple_pcie_rid2sid_write(struct apple_pcie_port *port,
				    int idx, u32 val)
{}

static int apple_pcie_setup_port(struct apple_pcie *pcie,
				 struct device_node *np)
{}

static int apple_msi_init(struct apple_pcie *pcie)
{}

static struct apple_pcie_port *apple_pcie_get_port(struct pci_dev *pdev)
{}

static int apple_pcie_add_device(struct apple_pcie_port *port,
				 struct pci_dev *pdev)
{}

static void apple_pcie_release_device(struct apple_pcie_port *port,
				      struct pci_dev *pdev)
{}

static int apple_pcie_bus_notifier(struct notifier_block *nb,
				   unsigned long action,
				   void *data)
{}

static struct notifier_block apple_pcie_nb =;

static int apple_pcie_init(struct pci_config_window *cfg)
{}

static int apple_pcie_probe(struct platform_device *pdev)
{}

static const struct pci_ecam_ops apple_pcie_cfg_ecam_ops =;

static const struct of_device_id apple_pcie_of_match[] =;
MODULE_DEVICE_TABLE(of, apple_pcie_of_match);

static struct platform_driver apple_pcie_driver =;
module_platform_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();