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

/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Synopsys DesignWare PCIe host controller driver
 *
 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
 *		https://www.samsung.com
 *
 * Author: Jingoo Han <[email protected]>
 */

#ifndef _PCIE_DESIGNWARE_H
#define _PCIE_DESIGNWARE_H

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/dma/edma.h>
#include <linux/gpio/consumer.h>
#include <linux/irq.h>
#include <linux/msi.h>
#include <linux/pci.h>
#include <linux/reset.h>

#include <linux/pci-epc.h>
#include <linux/pci-epf.h>

/* DWC PCIe IP-core versions (native support since v4.70a) */
#define DW_PCIE_VER_365A
#define DW_PCIE_VER_460A
#define DW_PCIE_VER_470A
#define DW_PCIE_VER_480A
#define DW_PCIE_VER_490A
#define DW_PCIE_VER_520A
#define DW_PCIE_VER_540A

#define __dw_pcie_ver_cmp(_pci, _ver, _op)

#define dw_pcie_ver_is(_pci, _ver)

#define dw_pcie_ver_is_ge(_pci, _ver)

#define dw_pcie_ver_type_is(_pci, _ver, _type)

#define dw_pcie_ver_type_is_ge(_pci, _ver, _type)

/* DWC PCIe controller capabilities */
#define DW_PCIE_CAP_REQ_RES
#define DW_PCIE_CAP_IATU_UNROLL
#define DW_PCIE_CAP_CDM_CHECK

#define dw_pcie_cap_is(_pci, _cap)

#define dw_pcie_cap_set(_pci, _cap)

/* Parameters for the waiting for link up routine */
#define LINK_WAIT_MAX_RETRIES
#define LINK_WAIT_SLEEP_MS

/* Parameters for the waiting for iATU enabled routine */
#define LINK_WAIT_MAX_IATU_RETRIES
#define LINK_WAIT_IATU

/* Synopsys-specific PCIe configuration registers */
#define PCIE_PORT_FORCE
#define PORT_FORCE_DO_DESKEW_FOR_SRIS

#define PCIE_PORT_AFR
#define PORT_AFR_N_FTS_MASK
#define PORT_AFR_N_FTS(n)
#define PORT_AFR_CC_N_FTS_MASK
#define PORT_AFR_CC_N_FTS(n)
#define PORT_AFR_ENTER_ASPM
#define PORT_AFR_L0S_ENTRANCE_LAT_SHIFT
#define PORT_AFR_L0S_ENTRANCE_LAT_MASK
#define PORT_AFR_L1_ENTRANCE_LAT_SHIFT
#define PORT_AFR_L1_ENTRANCE_LAT_MASK

#define PCIE_PORT_LINK_CONTROL
#define PORT_LINK_DLL_LINK_EN
#define PORT_LINK_FAST_LINK_MODE
#define PORT_LINK_MODE_MASK
#define PORT_LINK_MODE(n)
#define PORT_LINK_MODE_1_LANES
#define PORT_LINK_MODE_2_LANES
#define PORT_LINK_MODE_4_LANES
#define PORT_LINK_MODE_8_LANES

#define PCIE_PORT_LANE_SKEW
#define PORT_LANE_SKEW_INSERT_MASK

#define PCIE_PORT_DEBUG0
#define PORT_LOGIC_LTSSM_STATE_MASK
#define PORT_LOGIC_LTSSM_STATE_L0
#define PCIE_PORT_DEBUG1
#define PCIE_PORT_DEBUG1_LINK_UP
#define PCIE_PORT_DEBUG1_LINK_IN_TRAINING

#define PCIE_LINK_WIDTH_SPEED_CONTROL
#define PORT_LOGIC_N_FTS_MASK
#define PORT_LOGIC_SPEED_CHANGE
#define PORT_LOGIC_LINK_WIDTH_MASK
#define PORT_LOGIC_LINK_WIDTH(n)
#define PORT_LOGIC_LINK_WIDTH_1_LANES
#define PORT_LOGIC_LINK_WIDTH_2_LANES
#define PORT_LOGIC_LINK_WIDTH_4_LANES
#define PORT_LOGIC_LINK_WIDTH_8_LANES

#define PCIE_MSI_ADDR_LO
#define PCIE_MSI_ADDR_HI
#define PCIE_MSI_INTR0_ENABLE
#define PCIE_MSI_INTR0_MASK
#define PCIE_MSI_INTR0_STATUS

#define GEN3_RELATED_OFF
#define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL
#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE
#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT
#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK
#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_16_0GT

#define GEN3_EQ_CONTROL_OFF
#define GEN3_EQ_CONTROL_OFF_FB_MODE
#define GEN3_EQ_CONTROL_OFF_PHASE23_EXIT_MODE
#define GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC
#define GEN3_EQ_CONTROL_OFF_FOM_INC_INITIAL_EVAL

#define GEN3_EQ_FB_MODE_DIR_CHANGE_OFF
#define GEN3_EQ_FMDC_T_MIN_PHASE23
#define GEN3_EQ_FMDC_N_EVALS
#define GEN3_EQ_FMDC_MAX_PRE_CUSROR_DELTA
#define GEN3_EQ_FMDC_MAX_POST_CUSROR_DELTA

#define PCIE_PORT_MULTI_LANE_CTRL
#define PORT_MLTI_UPCFG_SUPPORT

#define PCIE_VERSION_NUMBER
#define PCIE_VERSION_TYPE

/*
 * iATU inbound and outbound windows CSRs. Before the IP-core v4.80a each
 * iATU region CSRs had been indirectly accessible by means of the dedicated
 * viewport selector. The iATU/eDMA CSRs space was re-designed in DWC PCIe
 * v4.80a in a way so the viewport was unrolled into the directly accessible
 * iATU/eDMA CSRs space.
 */
#define PCIE_ATU_VIEWPORT
#define PCIE_ATU_REGION_DIR_IB
#define PCIE_ATU_REGION_DIR_OB
#define PCIE_ATU_VIEWPORT_BASE
#define PCIE_ATU_UNROLL_BASE(dir, index)
#define PCIE_ATU_VIEWPORT_SIZE
#define PCIE_ATU_REGION_CTRL1
#define PCIE_ATU_INCREASE_REGION_SIZE
#define PCIE_ATU_TYPE_MEM
#define PCIE_ATU_TYPE_IO
#define PCIE_ATU_TYPE_CFG0
#define PCIE_ATU_TYPE_CFG1
#define PCIE_ATU_TYPE_MSG
#define PCIE_ATU_TD
#define PCIE_ATU_FUNC_NUM(pf)
#define PCIE_ATU_REGION_CTRL2
#define PCIE_ATU_ENABLE
#define PCIE_ATU_BAR_MODE_ENABLE
#define PCIE_ATU_INHIBIT_PAYLOAD
#define PCIE_ATU_FUNC_NUM_MATCH_EN
#define PCIE_ATU_LOWER_BASE
#define PCIE_ATU_UPPER_BASE
#define PCIE_ATU_LIMIT
#define PCIE_ATU_LOWER_TARGET
#define PCIE_ATU_BUS(x)
#define PCIE_ATU_DEV(x)
#define PCIE_ATU_FUNC(x)
#define PCIE_ATU_UPPER_TARGET
#define PCIE_ATU_UPPER_LIMIT

#define PCIE_MISC_CONTROL_1_OFF
#define PCIE_DBI_RO_WR_EN

#define PCIE_MSIX_DOORBELL
#define PCIE_MSIX_DOORBELL_PF_SHIFT

/*
 * eDMA CSRs. DW PCIe IP-core v4.70a and older had the eDMA registers accessible
 * over the Port Logic registers space. Afterwards the unrolled mapping was
 * introduced so eDMA and iATU could be accessed via a dedicated registers
 * space.
 */
#define PCIE_DMA_VIEWPORT_BASE
#define PCIE_DMA_UNROLL_BASE
#define PCIE_DMA_CTRL
#define PCIE_DMA_NUM_WR_CHAN
#define PCIE_DMA_NUM_RD_CHAN

#define PCIE_PL_CHK_REG_CONTROL_STATUS
#define PCIE_PL_CHK_REG_CHK_REG_START
#define PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS
#define PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR
#define PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR
#define PCIE_PL_CHK_REG_CHK_REG_COMPLETE

#define PCIE_PL_CHK_REG_ERR_ADDR

/*
 * 16.0 GT/s (Gen 4) lane margining register definitions
 */
#define GEN4_LANE_MARGINING_1_OFF
#define MARGINING_MAX_VOLTAGE_OFFSET
#define MARGINING_NUM_VOLTAGE_STEPS
#define MARGINING_MAX_TIMING_OFFSET
#define MARGINING_NUM_TIMING_STEPS

#define GEN4_LANE_MARGINING_2_OFF
#define MARGINING_IND_ERROR_SAMPLER
#define MARGINING_SAMPLE_REPORTING_METHOD
#define MARGINING_IND_LEFT_RIGHT_TIMING
#define MARGINING_IND_UP_DOWN_VOLTAGE
#define MARGINING_VOLTAGE_SUPPORTED
#define MARGINING_MAXLANES
#define MARGINING_SAMPLE_RATE_TIMING
#define MARGINING_SAMPLE_RATE_VOLTAGE
/*
 * iATU Unroll-specific register definitions
 * From 4.80 core version the address translation will be made by unroll
 */
#define PCIE_ATU_UNR_REGION_CTRL1
#define PCIE_ATU_UNR_REGION_CTRL2
#define PCIE_ATU_UNR_LOWER_BASE
#define PCIE_ATU_UNR_UPPER_BASE
#define PCIE_ATU_UNR_LOWER_LIMIT
#define PCIE_ATU_UNR_LOWER_TARGET
#define PCIE_ATU_UNR_UPPER_TARGET
#define PCIE_ATU_UNR_UPPER_LIMIT

/*
 * RAS-DES register definitions
 */
#define PCIE_RAS_DES_EVENT_COUNTER_CONTROL
#define EVENT_COUNTER_ALL_CLEAR
#define EVENT_COUNTER_ENABLE_ALL
#define EVENT_COUNTER_ENABLE_SHIFT
#define EVENT_COUNTER_EVENT_SEL_MASK
#define EVENT_COUNTER_EVENT_SEL_SHIFT
#define EVENT_COUNTER_EVENT_Tx_L0S
#define EVENT_COUNTER_EVENT_Rx_L0S
#define EVENT_COUNTER_EVENT_L1
#define EVENT_COUNTER_EVENT_L1_1
#define EVENT_COUNTER_EVENT_L1_2
#define EVENT_COUNTER_GROUP_SEL_SHIFT
#define EVENT_COUNTER_GROUP_5

#define PCIE_RAS_DES_EVENT_COUNTER_DATA

/*
 * The default address offset between dbi_base and atu_base. Root controller
 * drivers are not required to initialize atu_base if the offset matches this
 * default; the driver core automatically derives atu_base from dbi_base using
 * this offset, if atu_base not set.
 */
#define DEFAULT_DBI_ATU_OFFSET
#define DEFAULT_DBI_DMA_OFFSET

#define MAX_MSI_IRQS
#define MAX_MSI_IRQS_PER_CTRL
#define MAX_MSI_CTRLS
#define MSI_REG_CTRL_BLOCK_SIZE
#define MSI_DEF_NUM_VECTORS

/* Maximum number of inbound/outbound iATUs */
#define MAX_IATU_IN
#define MAX_IATU_OUT

/* Default eDMA LLP memory size */
#define DMA_LLP_MEM_SIZE

struct dw_pcie;
struct dw_pcie_rp;
struct dw_pcie_ep;

enum dw_pcie_device_mode {};

enum dw_pcie_app_clk {};

enum dw_pcie_core_clk {};

enum dw_pcie_app_rst {};

enum dw_pcie_core_rst {};

enum dw_pcie_ltssm {};

struct dw_pcie_ob_atu_cfg {};

struct dw_pcie_host_ops {};

struct dw_pcie_rp {};

struct dw_pcie_ep_ops {};

struct dw_pcie_ep_func {};

struct dw_pcie_ep {};

struct dw_pcie_ops {};

struct dw_pcie {};

#define to_dw_pcie_from_pp(port)

#define to_dw_pcie_from_ep(endpoint)

int dw_pcie_get_resources(struct dw_pcie *pci);

void dw_pcie_version_detect(struct dw_pcie *pci);

u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap);

int dw_pcie_read(void __iomem *addr, int size, u32 *val);
int dw_pcie_write(void __iomem *addr, int size, u32 val);

u32 dw_pcie_read_dbi(struct dw_pcie *pci, u32 reg, size_t size);
void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
void dw_pcie_write_dbi2(struct dw_pcie *pci, u32 reg, size_t size, u32 val);
int dw_pcie_link_up(struct dw_pcie *pci);
void dw_pcie_upconfig_setup(struct dw_pcie *pci);
int dw_pcie_wait_for_link(struct dw_pcie *pci);
int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
			      const struct dw_pcie_ob_atu_cfg *atu);
int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
			     u64 cpu_addr, u64 pci_addr, u64 size);
int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
				int type, u64 cpu_addr, u8 bar);
void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
void dw_pcie_setup(struct dw_pcie *pci);
void dw_pcie_iatu_detect(struct dw_pcie *pci);
int dw_pcie_edma_detect(struct dw_pcie *pci);
void dw_pcie_edma_remove(struct dw_pcie *pci);

int dw_pcie_suspend_noirq(struct dw_pcie *pci);
int dw_pcie_resume_noirq(struct dw_pcie *pci);

static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
{}

static inline u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg)
{}

static inline void dw_pcie_writew_dbi(struct dw_pcie *pci, u32 reg, u16 val)
{}

static inline u16 dw_pcie_readw_dbi(struct dw_pcie *pci, u32 reg)
{}

static inline void dw_pcie_writeb_dbi(struct dw_pcie *pci, u32 reg, u8 val)
{}

static inline u8 dw_pcie_readb_dbi(struct dw_pcie *pci, u32 reg)
{}

static inline void dw_pcie_writel_dbi2(struct dw_pcie *pci, u32 reg, u32 val)
{}

static inline unsigned int dw_pcie_ep_get_dbi_offset(struct dw_pcie_ep *ep,
						     u8 func_no)
{}

static inline u32 dw_pcie_ep_read_dbi(struct dw_pcie_ep *ep, u8 func_no,
				      u32 reg, size_t size)
{}

static inline void dw_pcie_ep_write_dbi(struct dw_pcie_ep *ep, u8 func_no,
					u32 reg, size_t size, u32 val)
{}

static inline void dw_pcie_ep_writel_dbi(struct dw_pcie_ep *ep, u8 func_no,
					 u32 reg, u32 val)
{}

static inline u32 dw_pcie_ep_readl_dbi(struct dw_pcie_ep *ep, u8 func_no,
				       u32 reg)
{}

static inline void dw_pcie_ep_writew_dbi(struct dw_pcie_ep *ep, u8 func_no,
					 u32 reg, u16 val)
{}

static inline u16 dw_pcie_ep_readw_dbi(struct dw_pcie_ep *ep, u8 func_no,
				       u32 reg)
{}

static inline void dw_pcie_ep_writeb_dbi(struct dw_pcie_ep *ep, u8 func_no,
					 u32 reg, u8 val)
{}

static inline u8 dw_pcie_ep_readb_dbi(struct dw_pcie_ep *ep, u8 func_no,
				      u32 reg)
{}

static inline unsigned int dw_pcie_ep_get_dbi2_offset(struct dw_pcie_ep *ep,
						      u8 func_no)
{}

static inline void dw_pcie_ep_write_dbi2(struct dw_pcie_ep *ep, u8 func_no,
					 u32 reg, size_t size, u32 val)
{}

static inline void dw_pcie_ep_writel_dbi2(struct dw_pcie_ep *ep, u8 func_no,
					  u32 reg, u32 val)
{}

static inline void dw_pcie_dbi_ro_wr_en(struct dw_pcie *pci)
{}

static inline void dw_pcie_dbi_ro_wr_dis(struct dw_pcie *pci)
{}

static inline int dw_pcie_start_link(struct dw_pcie *pci)
{}

static inline void dw_pcie_stop_link(struct dw_pcie *pci)
{}

static inline enum dw_pcie_ltssm dw_pcie_get_ltssm(struct dw_pcie *pci)
{}

#ifdef CONFIG_PCIE_DW_HOST
irqreturn_t dw_handle_msi_irq(struct dw_pcie_rp *pp);
int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
int dw_pcie_host_init(struct dw_pcie_rp *pp);
void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, unsigned int devfn,
				       int where);
#else
static inline irqreturn_t dw_handle_msi_irq(struct dw_pcie_rp *pp)
{
	return IRQ_NONE;
}

static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
{
	return 0;
}

static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
{
	return 0;
}

static inline void dw_pcie_host_deinit(struct dw_pcie_rp *pp)
{
}

static inline int dw_pcie_allocate_domains(struct dw_pcie_rp *pp)
{
	return 0;
}
static inline void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus,
						     unsigned int devfn,
						     int where)
{
	return NULL;
}
#endif

#ifdef CONFIG_PCIE_DW_EP
void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
void dw_pcie_ep_linkdown(struct dw_pcie_ep *ep);
int dw_pcie_ep_init(struct dw_pcie_ep *ep);
int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep);
void dw_pcie_ep_deinit(struct dw_pcie_ep *ep);
void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep);
int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no);
int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
			     u8 interrupt_num);
int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
			     u16 interrupt_num);
int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no,
				       u16 interrupt_num);
void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar);
struct dw_pcie_ep_func *
dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no);
#else
static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
{
}

static inline void dw_pcie_ep_linkdown(struct dw_pcie_ep *ep)
{
}

static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep)
{
	return 0;
}

static inline int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
{
	return 0;
}

static inline void dw_pcie_ep_deinit(struct dw_pcie_ep *ep)
{
}

static inline void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
{
}

static inline int dw_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep, u8 func_no)
{
	return 0;
}

static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
					   u8 interrupt_num)
{
	return 0;
}

static inline int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
					   u16 interrupt_num)
{
	return 0;
}

static inline int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep,
						     u8 func_no,
						     u16 interrupt_num)
{
	return 0;
}

static inline void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
{
}

static inline struct dw_pcie_ep_func *
dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no)
{
	return NULL;
}
#endif
#endif /* _PCIE_DESIGNWARE_H */