From 929e19e29efbba6929823b20554efd2d0c48d837 Mon Sep 17 00:00:00 2001 From: Rajkumar Ayyasamy Date: Mon, 17 Dec 2018 17:47:17 +0530 Subject: [PATCH] ipq6018: Added pcie support Change-Id: Iff5db65fd2f4391f04c8c717fa7a75d35ef5b65a Signed-off-by: Rajkumar Ayyasamy --- arch/arm/dts/ipq6018-emulation.dts | 1 + arch/arm/dts/ipq6018-soc.dtsi | 33 +++++++++++ board/qca/arm/ipq6018/ipq6018.c | 92 ++++++++++++++++++++++++++++++ board/qca/arm/ipq6018/ipq6018.h | 20 +++++++ drivers/pci/pci_ipq.c | 2 + include/configs/ipq6018.h | 8 +++ 6 files changed, 156 insertions(+) diff --git a/arch/arm/dts/ipq6018-emulation.dts b/arch/arm/dts/ipq6018-emulation.dts index f4b37bc354..b654a397d5 100644 --- a/arch/arm/dts/ipq6018-emulation.dts +++ b/arch/arm/dts/ipq6018-emulation.dts @@ -27,6 +27,7 @@ i2c0 = "/i2c@78b6000"; usb0 = "/xhci@8a00000"; usb1 = "/xhci@7000000"; + pci0 = "/pci@20000000"; }; serial@78af000 { compatible = "qca,ipq-uartdm"; diff --git a/arch/arm/dts/ipq6018-soc.dtsi b/arch/arm/dts/ipq6018-soc.dtsi index f40c0c718b..ebff637978 100644 --- a/arch/arm/dts/ipq6018-soc.dtsi +++ b/arch/arm/dts/ipq6018-soc.dtsi @@ -66,5 +66,38 @@ reg = <0x7000000 0xcd00>; }; + pci@20000000 { + compatible = "qcom,ipq6018-pcie"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x20000000 0xf1d + 0x80000 0x2000 + 0x20000f20 0xa8 + 0x20001000 0x1000 + 0x20300000 0xd00000 + 0x20100000 0x100000 + 0x01875004 0x40 + 0x84000 0x1000>; + reg-names = "pci_dbi", "parf", "elbi","dm_iatu", "axi_bars", + "axi_conf", "pci_rst", "pci_phy"; + perst_gpio = <60>; + gen3 = <1>; + + pci_gpio { + gpio1 { + gpio = <60>; + func = <0>; + out = ; + pull = ; + drvstr = ; + oe = ; + vm = ; + od_en = ; + pu_res = ; + }; + + }; + }; + }; diff --git a/board/qca/arm/ipq6018/ipq6018.c b/board/qca/arm/ipq6018/ipq6018.c index 619878c0a8..6aeaa7a0bf 100644 --- a/board/qca/arm/ipq6018/ipq6018.c +++ b/board/qca/arm/ipq6018/ipq6018.c @@ -237,6 +237,98 @@ void board_nand_init(void) #endif } +#ifdef CONFIG_PCI_IPQ +static void pcie_v2_clock_init() +{ + /* Enable PCIE CLKS */ + writel(0x2, GCC_PCIE0_AUX_CMD_RCGR); + writel(0x107, GCC_PCIE0_AXI_CFG_RCGR); + writel(0x1, GCC_PCIE0_AXI_CMD_RCGR); + mdelay(100); + writel(0x2, GCC_PCIE0_AXI_CMD_RCGR); + writel(0x20000001, GCC_PCIE0_AHB_CBCR); + writel(0x4FF1, GCC_PCIE0_AXI_M_CBCR); + writel(0x20004FF1, GCC_PCIE0_AXI_S_CBCR); + writel(0x1, GCC_PCIE0_AUX_CBCR); + writel(0x80004FF1, GCC_PCIE0_PIPE_CBCR); + writel(0x1, GCC_PCIE0_AXI_S_BRIDGE_CBCR); + writel(0x10F, GCC_PCIE0_RCHNG_CFG_RCGR); + writel(0x3, GCC_PCIE0_RCHNG_CMD_RCGR); +} + +static void pcie_v2_clock_deinit() +{ + writel(0x0, GCC_PCIE0_AUX_CMD_RCGR); + writel(0x0, GCC_PCIE0_AXI_CFG_RCGR); + writel(0x0, GCC_PCIE0_AXI_CMD_RCGR); + mdelay(100); + writel(0x0, GCC_SYS_NOC_PCIE0_AXI_CLK); + writel(0x0, GCC_PCIE0_AHB_CBCR); + writel(0x0, GCC_PCIE0_AXI_M_CBCR); + writel(0x0, GCC_PCIE0_AXI_S_CBCR); + writel(0x0, GCC_PCIE0_AUX_CBCR); + writel(0x0, GCC_PCIE0_PIPE_CBCR); + writel(0x0, GCC_PCIE0_AXI_S_BRIDGE_CBCR); + writel(0x0, GCC_PCIE0_RCHNG_CFG_RCGR); + writel(0x0, GCC_PCIE0_RCHNG_CMD_RCGR); +} + +void board_pci_init(int id) +{ + int node, gpio_node; + char name[16]; + + snprintf(name, sizeof(name), "pci%d", id); + node = fdt_path_offset(gd->fdt_blob, name); + if (node < 0) { + printf("Could not find PCI in device tree\n"); + return; + } + gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "pci_gpio"); + if (gpio_node >= 0) + qca_gpio_init(gpio_node); + + pcie_v2_clock_init(); + + return; +} + +void board_pci_deinit() +{ + int node, gpio_node, i, err; + char name[16]; + struct fdt_resource parf; + struct fdt_resource pci_phy; + + for (i = 0; i < PCI_MAX_DEVICES; i++) { + snprintf(name, sizeof(name), "pci%d", i); + node = fdt_path_offset(gd->fdt_blob, name); + if (node < 0) { + printf("Could not find PCI in device tree\n"); + return; + } + err = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names", "parf", + &parf); + writel(0x0, parf.start + 0x358); + writel(0x1, parf.start + 0x40); + err = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names", "pci_phy", + &pci_phy); + if (err < 0) + return; + + writel(0x1, pci_phy.start + 800); + writel(0x0, pci_phy.start + 804); + gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "pci_gpio"); + if (gpio_node >= 0) + qca_gpio_deinit(gpio_node); + + } + + pcie_v2_clock_deinit(); + + return ; +} +#endif void set_flash_secondary_type(qca_smem_flash_info_t *smem) { return; diff --git a/board/qca/arm/ipq6018/ipq6018.h b/board/qca/arm/ipq6018/ipq6018.h index 78876c3cdb..b8d8b08e08 100644 --- a/board/qca/arm/ipq6018/ipq6018.h +++ b/board/qca/arm/ipq6018/ipq6018.h @@ -177,6 +177,21 @@ #define USB3_PHY_START_CONTROL 0x808 #define USB3_PHY_SW_RESET 0x800 +#define GCC_SYS_NOC_PCIE0_AXI_CLK 0x01826048 +#define GCC_PCIE0_PHY_BCR 0x01875038 +#define GCC_PCIE0PHY_PHY_BCR 0x0187503C +#define GCC_PCIE0_AXI_M_CBCR 0x01875008 +#define GCC_PCIE0_AXI_S_CBCR 0x0187500C +#define GCC_PCIE0_AHB_CBCR 0x01875010 +#define GCC_PCIE0_AUX_CBCR 0x01875014 +#define GCC_PCIE0_PIPE_CBCR 0x01875018 +#define GCC_PCIE0_AUX_CMD_RCGR 0x01875024 +#define GCC_PCIE0_AXI_CMD_RCGR 0x01875054 +#define GCC_PCIE0_AXI_CFG_RCGR 0x01875058 +#define GCC_PCIE0_AXI_S_BRIDGE_CBCR 0x01875048 +#define GCC_PCIE0_RCHNG_CMD_RCGR 0x01875070 +#define GCC_PCIE0_RCHNG_CFG_RCGR 0x01875074 + struct smem_ram_ptn { char name[16]; unsigned long long start; @@ -243,5 +258,10 @@ int ipq_board_usb_init(void); #define MSM_SDC1_BASE 0x7800000 #define MSM_SDC1_SDHCI_BASE 0x7804000 +#ifdef CONFIG_PCI_IPQ + +void board_pci_init(int id); +__weak void board_pcie_clock_init(int id) {} +#endif #endif /* _IPQ6018_CDP_H_ */ diff --git a/drivers/pci/pci_ipq.c b/drivers/pci/pci_ipq.c index 061d271e24..53b1c7c56d 100644 --- a/drivers/pci/pci_ipq.c +++ b/drivers/pci/pci_ipq.c @@ -358,6 +358,7 @@ static const struct udevice_id pcie_ver_ids[] = { { .compatible = "qcom,ipq806x-pcie", .data = PCIE_V0 }, { .compatible = "qcom,ipq40xx-pcie", .data = PCIE_V1 }, { .compatible = "qcom,ipq807x-pcie", .data = PCIE_V2 }, + { .compatible = "qcom,ipq6018-pcie", .data = PCIE_V2 }, { }, }; @@ -865,6 +866,7 @@ static int ipq_pcie_parse_dt(const void *fdt, int id, pcie->is_gen3 = 0; if(pcie->version == PCIE_V2) { + pcie->is_gen3 = fdtdec_get_int(fdt, node, "gen3", 0); err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pci_phy", &pcie->pci_phy); if (err < 0) { diff --git a/include/configs/ipq6018.h b/include/configs/ipq6018.h index e00461369f..83d8bfe518 100644 --- a/include/configs/ipq6018.h +++ b/include/configs/ipq6018.h @@ -149,6 +149,14 @@ extern loff_t board_env_size; #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #endif +#define CONFIG_PCI_IPQ +#define PCI_MAX_DEVICES 1 +#ifdef CONFIG_PCI_IPQ +#define CONFIG_PCI +#define CONFIG_CMD_PCI +#define CONFIG_PCI_SCAN_SHOW +#endif + /* * SPI Flash Configs */