linux/drivers/pci/controller/dwc/pci-imx6.c

// SPDX-License-Identifier: GPL-2.0
/*
 * PCIe host controller driver for Freescale i.MX6 SoCs
 *
 * Copyright (C) 2013 Kosagi
 *		https://www.kosagi.com
 *
 * Author: Sean Cross <[email protected]>
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/resource.h>
#include <linux/signal.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/reset.h>
#include <linux/phy/pcie.h>
#include <linux/phy/phy.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>

#include "pcie-designware.h"

#define IMX8MQ_GPR_PCIE_REF_USE_PAD
#define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN
#define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE
#define IMX8MQ_GPR_PCIE_VREG_BYPASS
#define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE
#define IMX8MQ_PCIE2_BASE_ADDR

#define IMX95_PCIE_PHY_GEN_CTRL
#define IMX95_PCIE_REF_USE_PAD

#define IMX95_PCIE_SS_RW_REG_0
#define IMX95_PCIE_REF_CLKEN
#define IMX95_PCIE_PHY_CR_PARA_SEL

#define IMX95_PE0_GEN_CTRL_1
#define IMX95_PCIE_DEVICE_TYPE

#define IMX95_PE0_GEN_CTRL_3
#define IMX95_PCIE_LTSSM_EN

#define to_imx_pcie(x)

enum imx_pcie_variants {};

#define IMX_PCIE_FLAG_IMX_PHY
#define IMX_PCIE_FLAG_IMX_SPEED_CHANGE
#define IMX_PCIE_FLAG_SUPPORTS_SUSPEND
#define IMX_PCIE_FLAG_HAS_PHYDRV
#define IMX_PCIE_FLAG_HAS_APP_RESET
#define IMX_PCIE_FLAG_HAS_PHY_RESET
#define IMX_PCIE_FLAG_HAS_SERDES
#define IMX_PCIE_FLAG_SUPPORT_64BIT
#define IMX_PCIE_FLAG_CPU_ADDR_FIXUP

#define imx_check_flag(pci, val)

#define IMX_PCIE_MAX_CLKS
#define IMX_PCIE_MAX_INSTANCES

struct imx_pcie;

struct imx_pcie_drvdata {};

struct imx_pcie {};

/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
#define PHY_PLL_LOCK_WAIT_USLEEP_MAX
#define PHY_PLL_LOCK_WAIT_TIMEOUT

/* PCIe Port Logic registers (memory-mapped) */
#define PL_OFFSET

#define PCIE_PHY_CTRL
#define PCIE_PHY_CTRL_DATA(x)
#define PCIE_PHY_CTRL_CAP_ADR
#define PCIE_PHY_CTRL_CAP_DAT
#define PCIE_PHY_CTRL_WR
#define PCIE_PHY_CTRL_RD

#define PCIE_PHY_STAT
#define PCIE_PHY_STAT_ACK

/* PHY registers (not memory-mapped) */
#define PCIE_PHY_ATEOVRD
#define PCIE_PHY_ATEOVRD_EN
#define PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT
#define PCIE_PHY_ATEOVRD_REF_CLKDIV_MASK

#define PCIE_PHY_MPLL_OVRD_IN_LO
#define PCIE_PHY_MPLL_MULTIPLIER_SHIFT
#define PCIE_PHY_MPLL_MULTIPLIER_MASK
#define PCIE_PHY_MPLL_MULTIPLIER_OVRD

#define PCIE_PHY_RX_ASIC_OUT
#define PCIE_PHY_RX_ASIC_OUT_VALID

/* iMX7 PCIe PHY registers */
#define PCIE_PHY_CMN_REG4
/* These are probably the bits that *aren't* DCC_FB_EN */
#define PCIE_PHY_CMN_REG4_DCC_FB_EN

#define PCIE_PHY_CMN_REG15
#define PCIE_PHY_CMN_REG15_DLY_4
#define PCIE_PHY_CMN_REG15_PLL_PD
#define PCIE_PHY_CMN_REG15_OVRD_PLL_PD

#define PCIE_PHY_CMN_REG24
#define PCIE_PHY_CMN_REG24_RX_EQ
#define PCIE_PHY_CMN_REG24_RX_EQ_SEL

#define PCIE_PHY_CMN_REG26
#define PCIE_PHY_CMN_REG26_ATT_MODE

#define PHY_RX_OVRD_IN_LO
#define PHY_RX_OVRD_IN_LO_RX_DATA_EN
#define PHY_RX_OVRD_IN_LO_RX_PLL_EN

static unsigned int imx_pcie_grp_offset(const struct imx_pcie *imx_pcie)
{}

static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie)
{}

static void imx_pcie_configure_type(struct imx_pcie *imx_pcie)
{}

static int pcie_phy_poll_ack(struct imx_pcie *imx_pcie, bool exp_val)
{}

static int pcie_phy_wait_ack(struct imx_pcie *imx_pcie, int addr)
{}

/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
static int pcie_phy_read(struct imx_pcie *imx_pcie, int addr, u16 *data)
{}

static int pcie_phy_write(struct imx_pcie *imx_pcie, int addr, u16 data)
{}

static int imx8mq_pcie_init_phy(struct imx_pcie *imx_pcie)
{}

static int imx7d_pcie_init_phy(struct imx_pcie *imx_pcie)
{}

static int imx_pcie_init_phy(struct imx_pcie *imx_pcie)
{}

static int imx6sx_pcie_init_phy(struct imx_pcie *imx_pcie)
{}

static void imx7d_pcie_wait_for_phy_pll_lock(struct imx_pcie *imx_pcie)
{}

static int imx_setup_phy_mpll(struct imx_pcie *imx_pcie)
{}

static void imx_pcie_reset_phy(struct imx_pcie *imx_pcie)
{}

#ifdef CONFIG_ARM
/*  Added for PCI abort handling */
static int imx6q_pcie_abort_handler(unsigned long addr,
		unsigned int fsr, struct pt_regs *regs)
{
	unsigned long pc = instruction_pointer(regs);
	unsigned long instr = *(unsigned long *)pc;
	int reg = (instr >> 12) & 15;

	/*
	 * If the instruction being executed was a read,
	 * make it look like it read all-ones.
	 */
	if ((instr & 0x0c100000) == 0x04100000) {
		unsigned long val;

		if (instr & 0x00400000)
			val = 255;
		else
			val = -1;

		regs->uregs[reg] = val;
		regs->ARM_pc += 4;
		return 0;
	}

	if ((instr & 0x0e100090) == 0x00100090) {
		regs->uregs[reg] = -1;
		regs->ARM_pc += 4;
		return 0;
	}

	return 1;
}
#endif

static int imx_pcie_attach_pd(struct device *dev)
{}

static int imx6sx_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
{}

static int imx6q_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
{}

static int imx8mm_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
{}

static int imx7d_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
{}

static int imx_pcie_clk_enable(struct imx_pcie *imx_pcie)
{}

static void imx_pcie_clk_disable(struct imx_pcie *imx_pcie)
{}

static int imx6sx_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
{}

static int imx6qp_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
{}

static int imx6q_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
{}

static int imx7d_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
{}

static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
{}

static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
{}

static int imx_pcie_wait_for_speed_change(struct imx_pcie *imx_pcie)
{}

static void imx_pcie_ltssm_enable(struct device *dev)
{}

static void imx_pcie_ltssm_disable(struct device *dev)
{}

static int imx_pcie_start_link(struct dw_pcie *pci)
{}

static void imx_pcie_stop_link(struct dw_pcie *pci)
{}

static int imx_pcie_host_init(struct dw_pcie_rp *pp)
{}

static void imx_pcie_host_exit(struct dw_pcie_rp *pp)
{}

static u64 imx_pcie_cpu_addr_fixup(struct dw_pcie *pcie, u64 cpu_addr)
{}

static const struct dw_pcie_host_ops imx_pcie_host_ops =;

static const struct dw_pcie_ops dw_pcie_ops =;

static void imx_pcie_ep_init(struct dw_pcie_ep *ep)
{}

static int imx_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
				  unsigned int type, u16 interrupt_num)
{}

static const struct pci_epc_features imx8m_pcie_epc_features =;

/*
 * BAR#	| Default BAR enable	| Default BAR Type	| Default BAR Size	| BAR Sizing Scheme
 * ================================================================================================
 * BAR0	| Enable		| 64-bit		| 1 MB			| Programmable Size
 * BAR1	| Disable		| 32-bit		| 64 KB			| Fixed Size
 *        BAR1 should be disabled if BAR0 is 64bit.
 * BAR2	| Enable		| 32-bit		| 1 MB			| Programmable Size
 * BAR3	| Enable		| 32-bit		| 64 KB			| Programmable Size
 * BAR4	| Enable		| 32-bit		| 1M			| Programmable Size
 * BAR5	| Enable		| 32-bit		| 64 KB			| Programmable Size
 */
static const struct pci_epc_features imx95_pcie_epc_features =;

static const struct pci_epc_features*
imx_pcie_ep_get_features(struct dw_pcie_ep *ep)
{}

static const struct dw_pcie_ep_ops pcie_ep_ops =;

static int imx_add_pcie_ep(struct imx_pcie *imx_pcie,
			   struct platform_device *pdev)
{}

static void imx_pcie_pm_turnoff(struct imx_pcie *imx_pcie)
{}

static void imx_pcie_msi_save_restore(struct imx_pcie *imx_pcie, bool save)
{}

static int imx_pcie_suspend_noirq(struct device *dev)
{}

static int imx_pcie_resume_noirq(struct device *dev)
{}

static const struct dev_pm_ops imx_pcie_pm_ops =;

static int imx_pcie_probe(struct platform_device *pdev)
{}

static void imx_pcie_shutdown(struct platform_device *pdev)
{}

static const char * const imx6q_clks[] =;
static const char * const imx8mm_clks[] =;
static const char * const imx8mq_clks[] =;
static const char * const imx6sx_clks[] =;
static const char * const imx8q_clks[] =;

static const struct imx_pcie_drvdata drvdata[] =;

static const struct of_device_id imx_pcie_of_match[] =;

static struct platform_driver imx_pcie_driver =;

static void imx_pcie_quirk(struct pci_dev *dev)
{}
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_SYNOPSYS, 0xabcd,
			PCI_CLASS_BRIDGE_PCI, 8, imx_pcie_quirk);

static int __init imx_pcie_init(void)
{}
device_initcall(imx_pcie_init);