Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81c45fec authored by Yan He's avatar Yan He
Browse files

msm: pcie: Add PCIe features for APQ8084



This change adds PCIe Root Complex features on APQ8084 as follows.
1> New power-on sequence of PCIe core and PHY on 8084.
2> Support new PCIe PHY.
3> Use device tree for PCIe Root Complex.
4> Update the suspend/resume functions.
5> Support multiple controllers.

Change-Id: I9d71485cf736f732611e97300b299520d38fe7f6
Signed-off-by: default avatarYan He <yanhe@codeaurora.org>
parent 55558bcf
Loading
Loading
Loading
Loading
+83 −0
Original line number Diff line number Diff line
MSM PCIe

MSM PCI express root complex

Required properties:
  - compatible: should be "qcom,msm-pcie"
  - cell-index: defines root complex ID.
  - qcom,ctrl-amt: Number of controllers.
  - #address-cells: Should provide a value of 0.
  - reg: should contain PCIe register maps.
  - reg-names: indicates various resources passed to driver by name.
		Should be "parf", "dm_core", "elbi", "conf", "bars", "phy".
		These correspond to different modules within the PCIe core.
  - interrupts: Should be in the format <0 1 2> and it is an index to the
		interrupt-map that contains PCIe related interrupts.
  - #interrupt-cells: Should provide a value of 1.
  - #interrupt-map-mask: should provide a value of 0xffffffff.
  - interrupt-map:  Must create mapping for the number of interrupts
		    that are defined in above interrupts property.
		    For PCIe device node, it should define 13 mappings for
		    the corresponding PCIe interrupts supporting the specification.
  - interrupt-names: indicates interrupts passed to driver by name.
		     Should be "int_msi", "int_a", "int_b", "int_c", "int_d",
		     "int_pls_pme", "int_pme_legacy", "int_pls_err",
		     "int_aer_legacy", "int_pls_link_up",
		     "int_pls_link_down", "int_bridge_flush_n", "int_wake"
		     These correspond to the standard PCIe specification to support
		     MSIs, virtual IRQ's (INT#), link state notifications.
  - perst-gpio: PERST GPIO specified by PCIe spec.
  - wake-gpio: WAKE GPIO specified by PCIe spec.
  - clkreq-gpio: CLKREQ GPIO specified by PCIe spec.
  - <supply-name>-supply: phandle to the regulator device tree node.
    Refer to the schematics for the corresponding voltage regulators.
    vreg-1.8-supply: phandle to the analog supply for the PCIe controller.
    vreg-3.3-supply: phandle to the analog supply for the PCIe controller.
    vreg-0.9-supply: phandle to the analog supply for the PCIe controller.

Example:

	pcie0: qcom,pcie@fc520000 {
		compatible = "qcom,msm_pcie";
		cell-index = <0>;
		qcom,ctrl-amt = <1>;
		#address-cells = <0>;
		reg = <0xfc520000 0x2000>,
		      <0xfc526000 0x1000>,
		      <0xff000000 0x1000>,
		      <0xff001000 0x1000>,
		      <0xff100000 0x1000>,
		      <0xff200000 0xe00000>;
		reg-names = "parf", "dm_core", "elbi",
				"conf", "bars";
		interrupt-parent = <&pcie0>;
		interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12>;
		#interrupt-cells = <1>;
		interrupt-map-mask = <0xffffffff>;
		interrupt-map = <0 &intc 0 243 0
				1 &intc 0 244 0
				2 &intc 0 245 0
				3 &intc 0 247 0
				4 &intc 0 248 0
				5 &intc 0 249 0
				6 &intc 0 250 0
				7 &intc 0 251 0
				8 &intc 0 252 0
				9 &intc 0 253 0
				10 &intc 0 254 0
				11 &intc 0 255 0
				12 &msmgpio 69 0x2>;
		interrupt-names = "int_msi", "int_a", "int_b", "int_c", "int_d",
				"int_pls_pme", "int_pme_legacy", "int_pls_err",
				"int_aer_legacy", "int_pls_link_up",
				"int_pls_link_down", "int_bridge_flush_n",
				"int_wake";
		perst-gpio = <&msmgpio 70 0>;
		wake-gpio = <&msmgpio 69 0>;
		clkreq-gpio = <&msmgpio 68 0>;

		gdsc-vdd-supply = <&gdsc_pcie_0>;
		vreg-1.8-supply = <&pma8084_l12>;
		vreg-0.9-supply = <&pma8084_l4>;
		vreg-3.3-supply = <&wlan_vreg>;
	};
+1 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ obj-$(CONFIG_PM) += pm-boot.o
obj-$(CONFIG_MSM_IDLE_STATS) += pm-stats.o
obj-$(CONFIG_MSM_NOPM) += no-pm.o

obj-$(CONFIG_MSM_PCIE) += pcie.o pcie_irq.o
obj-$(CONFIG_MSM_PCIE) += pcie.o pcie_irq.o pcie_phy.o

obj-$(CONFIG_MSM_SPM_V2) += spm-v2.o spm_devices.o

+0 −26
Original line number Diff line number Diff line
@@ -15,30 +15,4 @@

#include <linux/types.h>

/* gpios */
enum msm_pcie_gpio {
	MSM_PCIE_GPIO_RST_N,
	MSM_PCIE_GPIO_PWR_EN,
	MSM_PCIE_MAX_GPIO
};

/* gpio info structure */
struct msm_pcie_gpio_info_t {
	char      *name;
	uint32_t   num;
	uint32_t   on;
};

/* msm pcie platfrom data */
struct msm_pcie_platform {
	struct msm_pcie_gpio_info_t  *gpio;

	uint32_t                      axi_addr;
	uint32_t                      axi_size;
	uint32_t                      wake_n;
	uint32_t                      vreg_n;
	uint32_t                      parf_deemph;
	uint32_t                      parf_swing;
};

#endif
+851 −403

File changed.

Preview size limit exceeded, changes collapsed.

+93 −10
Original line number Diff line number Diff line
@@ -20,14 +20,73 @@
#include <linux/types.h>
#include <mach/msm_pcie.h>

#define MSM_PCIE_MAX_VREG 4
#define MSM_PCIE_MAX_CLK  3
#define MSM_PCIE_MAX_VREG 3
#define MSM_PCIE_MAX_CLK  6
#define MSM_PCIE_MAX_PIPE_CLK 1

#define MAX_RC_NUM 2

#ifdef CONFIG_ARM_LPAE
#define PCIE_UPPER_ADDR(addr) ((u32)((addr) >> 32))
#else
#define PCIE_UPPER_ADDR(addr) (0x0)
#endif
#define PCIE_LOWER_ADDR(addr) ((u32)((addr) & 0xffffffff))

#define PCIE_MSI_NR_IRQS 256

#define PCIE_DBG(x...) do {              \
	if (msm_pcie_get_debug_mask())   \
		pr_info(x);              \
	} while (0)

#define PCIE_BUS_PRIV_DATA(pdev) \
	(((struct pci_sys_data *)pdev->bus->sysdata)->private_data)

enum msm_pcie_res {
	MSM_PCIE_RES_PARF,
	MSM_PCIE_RES_PHY,
	MSM_PCIE_RES_DM_CORE,
	MSM_PCIE_RES_ELBI,
	MSM_PCIE_RES_CONF,
	MSM_PCIE_RES_BARS,
	MSM_PCIE_MAX_RES,
};

enum msm_pcie_irq {
	MSM_PCIE_INT_MSI,
	MSM_PCIE_INT_A,
	MSM_PCIE_INT_B,
	MSM_PCIE_INT_C,
	MSM_PCIE_INT_D,
	MSM_PCIE_INT_PLS_PME,
	MSM_PCIE_INT_PME_LEGACY,
	MSM_PCIE_INT_PLS_ERR,
	MSM_PCIE_INT_AER_LEGACY,
	MSM_PCIE_INT_LINK_UP,
	MSM_PCIE_INT_LINK_DOWN,
	MSM_PCIE_INT_BRIDGE_FLUSH_N,
	MSM_PCIE_INT_WAKE,
	MSM_PCIE_MAX_IRQ,
};

/* gpios */
enum msm_pcie_gpio {
	MSM_PCIE_GPIO_PERST,
	MSM_PCIE_GPIO_WAKE,
	MSM_PCIE_GPIO_CLKREQ,
	MSM_PCIE_MAX_GPIO
};

/* gpio info structure */
struct msm_pcie_gpio_info_t {
	char      *name;
	uint32_t   num;
	bool       out;
	uint32_t   on;
	uint32_t   init;
};

/* voltage regulator info structrue */
struct msm_pcie_vreg_info_t {
	struct regulator  *hdl;
@@ -41,6 +100,7 @@ struct msm_pcie_vreg_info_t {
struct msm_pcie_clk_info_t {
	struct clk  *hdl;
	char        *name;
	u32         freq;
};

/* resource info structure */
@@ -50,33 +110,56 @@ struct msm_pcie_res_info_t {
	void __iomem    *base;
};

/* irq info structrue */
struct msm_pcie_irq_info_t {
	char              *name;
	uint32_t          num;
};

/* msm pcie device structure */
struct msm_pcie_dev_t {
	struct platform_device       *pdev;

	struct msm_pcie_vreg_info_t  *vreg;
	struct msm_pcie_gpio_info_t  *gpio;
	struct msm_pcie_clk_info_t   *clk;
	struct msm_pcie_res_info_t   *res;
	struct regulator *gdsc;
	struct msm_pcie_vreg_info_t  vreg[MSM_PCIE_MAX_VREG];
	struct msm_pcie_gpio_info_t  gpio[MSM_PCIE_MAX_GPIO];
	struct msm_pcie_clk_info_t   clk[MSM_PCIE_MAX_CLK];
	struct msm_pcie_clk_info_t   pipeclk[MSM_PCIE_MAX_PIPE_CLK];
	struct msm_pcie_res_info_t   res[MSM_PCIE_MAX_RES];
	struct msm_pcie_irq_info_t   irq[MSM_PCIE_MAX_IRQ];

	void __iomem                 *parf;
	void __iomem                 *phy;
	void __iomem                 *elbi;
	void __iomem                 *pcie20;
	void __iomem                 *axi_conf;
	void __iomem                 *dm_core;
	void __iomem                 *conf;
	void __iomem                 *bars;

	uint32_t                      axi_bar_start;
	uint32_t                      axi_bar_end;

	struct resource               dev_mem_res;
	struct resource               *dev_mem_res;

	uint32_t                      wake_n;
	uint32_t                      vreg_n;
	uint32_t                      gpio_n;
	uint32_t                      parf_deemph;
	uint32_t                      parf_swing;

	bool                         cfg_access;
	spinlock_t                   cfg_lock;
	unsigned long                irqsave_flags;

	struct irq_domain            *irq_domain;
	DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_NR_IRQS);
};

extern uint32_t msm_pcie_irq_init(struct msm_pcie_dev_t *dev);
extern void msm_pcie_config_msi_controller(struct msm_pcie_dev_t *dev);
extern int32_t msm_pcie_irq_init(struct msm_pcie_dev_t *dev);
extern void msm_pcie_irq_deinit(struct msm_pcie_dev_t *dev);
extern int msm_pcie_get_debug_mask(void);

extern void pcie_phy_init(struct msm_pcie_dev_t *dev);
extern bool pcie_phy_is_ready(struct msm_pcie_dev_t *dev);

#endif
Loading