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

Source file repositories/reference/linux-study-clean/drivers/pci/controller/dwc/pcie-kirin.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/controller/dwc/pcie-kirin.c
Extension
.c
Size
18776 bytes
Lines
768
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: implementation source
Status
source implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

struct kirin_pcie {
	enum pcie_kirin_phy_type	type;

	struct dw_pcie	*pci;
	struct regmap   *apb;
	struct phy	*phy;
	void		*phy_priv;	/* only for PCIE_KIRIN_INTERNAL_PHY */

	/* DWC PERST# */
	struct gpio_desc *id_dwc_perst_gpio;

	/* Per-slot PERST# */
	int		num_slots;
	struct gpio_desc *id_reset_gpio[MAX_PCI_SLOTS];
	const char	*reset_names[MAX_PCI_SLOTS];

	/* Per-slot clkreq */
	int		n_gpio_clkreq;
	struct gpio_desc *id_clkreq_gpio[MAX_PCI_SLOTS];
	const char	*clkreq_names[MAX_PCI_SLOTS];
};

/*
 * Kirin 960 PHY. Can't be split into a PHY driver without changing the
 * DT schema.
 */

#define REF_CLK_FREQ			100000000

/* PHY info located in APB */
#define PCIE_APB_PHY_CTRL0	0x0
#define PCIE_APB_PHY_CTRL1	0x4
#define PCIE_APB_PHY_STATUS0   0x400
#define PIPE_CLK_STABLE		BIT(19)
#define PHY_REF_PAD_BIT		BIT(8)
#define PHY_PWR_DOWN_BIT	BIT(22)
#define PHY_RST_ACK_BIT		BIT(16)

/* peri_crg ctrl */
#define CRGCTRL_PCIE_ASSERT_OFFSET	0x88
#define CRGCTRL_PCIE_ASSERT_BIT		0x8c000000

/* Time for delay */
#define REF_2_PERST_MIN		21000
#define REF_2_PERST_MAX		25000
#define PERST_2_ACCESS_MIN	10000
#define PERST_2_ACCESS_MAX	12000
#define PIPE_CLK_WAIT_MIN	550
#define PIPE_CLK_WAIT_MAX	600
#define TIME_CMOS_MIN		100
#define TIME_CMOS_MAX		105
#define TIME_PHY_PD_MIN		10
#define TIME_PHY_PD_MAX		11

struct hi3660_pcie_phy {
	struct device	*dev;
	void __iomem	*base;
	struct regmap	*crgctrl;
	struct regmap	*sysctrl;
	struct clk	*apb_sys_clk;
	struct clk	*apb_phy_clk;
	struct clk	*phy_ref_clk;
	struct clk	*aclk;
	struct clk	*aux_clk;
};

/* Registers in PCIePHY */
static inline void kirin_apb_phy_writel(struct hi3660_pcie_phy *hi3660_pcie_phy,
					u32 val, u32 reg)
{
	writel(val, hi3660_pcie_phy->base + reg);
}

static inline u32 kirin_apb_phy_readl(struct hi3660_pcie_phy *hi3660_pcie_phy,
				      u32 reg)
{
	return readl(hi3660_pcie_phy->base + reg);
}

static int hi3660_pcie_phy_get_clk(struct hi3660_pcie_phy *phy)
{
	struct device *dev = phy->dev;

	phy->phy_ref_clk = devm_clk_get(dev, "pcie_phy_ref");
	if (IS_ERR(phy->phy_ref_clk))
		return PTR_ERR(phy->phy_ref_clk);

	phy->aux_clk = devm_clk_get(dev, "pcie_aux");
	if (IS_ERR(phy->aux_clk))
		return PTR_ERR(phy->aux_clk);

Annotation

Implementation Notes