Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: hisi: Add support for HiSilicon Hip06 PCIe host controllers

Add support for the HiSilicon Hip06 SoC. Documentation has been updated to
include Hip06. Add Gabriele Paoloni as maintainer of the driver.

Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Zhou Wang <wangzhou1@hisilicon.com>

authored by

Gabriele Paoloni and committed by
Bjorn Helgaas
5930fe4e 1ec21837

+73 -17
+4 -4
Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
··· 1 - HiSilicon PCIe host bridge DT description 1 + HiSilicon Hip05 and Hip06 PCIe host bridge DT description 2 2 3 3 HiSilicon PCIe host controller is based on Designware PCI core. 4 4 It shares common functions with PCIe Designware core driver and inherits ··· 7 7 8 8 Additional properties are described here: 9 9 10 - Required properties: 11 - - compatible: Should contain "hisilicon,hip05-pcie". 10 + Required properties 11 + - compatible: Should contain "hisilicon,hip05-pcie" or "hisilicon,hip06-pcie". 12 12 - reg: Should contain rc_dbi, config registers location and length. 13 13 - reg-names: Must include the following entries: 14 14 "rc_dbi": controller configuration registers; ··· 20 20 - status: Either "ok" or "disabled". 21 21 - dma-coherent: Present if DMA operations are coherent. 22 22 23 - Example: 23 + Hip05 Example (note that Hip06 is the same except compatible): 24 24 pcie@0xb0080000 { 25 25 compatible = "hisilicon,hip05-pcie", "snps,dw-pcie"; 26 26 reg = <0 0xb0080000 0 0x10000>, <0x220 0x00000000 0 0x2000>;
+1
MAINTAINERS
··· 8240 8240 8241 8241 PCIE DRIVER FOR HISILICON 8242 8242 M: Zhou Wang <wangzhou1@hisilicon.com> 8243 + M: Gabriele Paoloni <gabriele.paoloni@huawei.com> 8243 8244 L: linux-pci@vger.kernel.org 8244 8245 S: Maintained 8245 8246 F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
+3 -2
drivers/pci/host/Kconfig
··· 166 166 167 167 config PCI_HISI 168 168 depends on OF && ARM64 169 - bool "HiSilicon SoC HIP05 PCIe controller" 169 + bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers" 170 170 select PCIEPORTBUS 171 171 select PCIE_DW 172 172 help 173 - Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC 173 + Say Y here if you want PCIe controller support on HiSilicon 174 + Hip05 and Hip06 SoCs 174 175 175 176 endmenu
+65 -11
drivers/pci/host/pcie-hisi.c
··· 1 1 /* 2 - * PCIe host controller driver for HiSilicon Hip05 SoC 2 + * PCIe host controller driver for HiSilicon SoCs 3 3 * 4 4 * Copyright (C) 2015 HiSilicon Co., Ltd. http://www.hisilicon.com 5 5 * 6 - * Author: Zhou Wang <wangzhou1@hisilicon.com> 7 - * Dacai Zhu <zhudacai@hisilicon.com> 6 + * Authors: Zhou Wang <wangzhou1@hisilicon.com> 7 + * Dacai Zhu <zhudacai@hisilicon.com> 8 + * Gabriele Paoloni <gabriele.paoloni@huawei.com> 8 9 * 9 10 * This program is free software; you can redistribute it and/or modify 10 11 * it under the terms of the GNU General Public License version 2 as ··· 17 16 #include <linux/of_address.h> 18 17 #include <linux/of_pci.h> 19 18 #include <linux/platform_device.h> 19 + #include <linux/of_device.h> 20 20 #include <linux/regmap.h> 21 21 22 22 #include "pcie-designware.h" 23 23 24 - #define PCIE_SUBCTRL_SYS_STATE4_REG 0x6818 25 - #define PCIE_LTSSM_LINKUP_STATE 0x11 26 - #define PCIE_LTSSM_STATE_MASK 0x3F 24 + #define PCIE_LTSSM_LINKUP_STATE 0x11 25 + #define PCIE_LTSSM_STATE_MASK 0x3F 26 + #define PCIE_SUBCTRL_SYS_STATE4_REG 0x6818 27 + #define PCIE_SYS_STATE4 0x31c 28 + #define PCIE_HIP06_CTRL_OFF 0x1000 27 29 28 30 #define to_hisi_pcie(x) container_of(x, struct hisi_pcie, pp) 31 + 32 + struct hisi_pcie; 33 + 34 + struct pcie_soc_ops { 35 + int (*hisi_pcie_link_up)(struct hisi_pcie *pcie); 36 + }; 29 37 30 38 struct hisi_pcie { 31 39 struct regmap *subctrl; 32 40 void __iomem *reg_base; 33 41 u32 port_id; 34 42 struct pcie_port pp; 43 + struct pcie_soc_ops *soc_ops; 35 44 }; 36 45 37 46 static inline void hisi_pcie_apb_writel(struct hisi_pcie *pcie, ··· 55 44 return readl(pcie->reg_base + reg); 56 45 } 57 46 58 - /* Hip05 PCIe host only supports 32-bit config access */ 47 + /* HipXX PCIe host only supports 32-bit config access */ 59 48 static int hisi_pcie_cfg_read(struct pcie_port *pp, int where, int size, 60 49 u32 *val) 61 50 { ··· 78 67 return PCIBIOS_SUCCESSFUL; 79 68 } 80 69 81 - /* Hip05 PCIe host only supports 32-bit config access */ 70 + /* HipXX PCIe host only supports 32-bit config access */ 82 71 static int hisi_pcie_cfg_write(struct pcie_port *pp, int where, int size, 83 72 u32 val) 84 73 { ··· 105 94 return PCIBIOS_SUCCESSFUL; 106 95 } 107 96 108 - static int hisi_pcie_link_up(struct pcie_port *pp) 97 + static int hisi_pcie_link_up_hip05(struct hisi_pcie *hisi_pcie) 109 98 { 110 99 u32 val; 111 - struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp); 112 100 113 101 regmap_read(hisi_pcie->subctrl, PCIE_SUBCTRL_SYS_STATE4_REG + 114 102 0x100 * hisi_pcie->port_id, &val); 115 103 116 104 return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE); 105 + } 106 + 107 + static int hisi_pcie_link_up_hip06(struct hisi_pcie *hisi_pcie) 108 + { 109 + u32 val; 110 + 111 + val = hisi_pcie_apb_readl(hisi_pcie, PCIE_HIP06_CTRL_OFF + 112 + PCIE_SYS_STATE4); 113 + 114 + return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE); 115 + } 116 + 117 + static int hisi_pcie_link_up(struct pcie_port *pp) 118 + { 119 + struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp); 120 + 121 + return hisi_pcie->soc_ops->hisi_pcie_link_up(hisi_pcie); 117 122 } 118 123 119 124 static struct pcie_host_ops hisi_pcie_host_ops = { ··· 170 143 { 171 144 struct hisi_pcie *hisi_pcie; 172 145 struct pcie_port *pp; 146 + const struct of_device_id *match; 173 147 struct resource *reg; 148 + struct device_driver *driver; 174 149 int ret; 175 150 176 151 hisi_pcie = devm_kzalloc(&pdev->dev, sizeof(*hisi_pcie), GFP_KERNEL); ··· 181 152 182 153 pp = &hisi_pcie->pp; 183 154 pp->dev = &pdev->dev; 155 + driver = (pdev->dev).driver; 156 + 157 + match = of_match_device(driver->of_match_table, &pdev->dev); 158 + hisi_pcie->soc_ops = (struct pcie_soc_ops *) match->data; 184 159 185 160 hisi_pcie->subctrl = 186 161 syscon_regmap_lookup_by_compatible("hisilicon,pcie-sas-subctrl"); ··· 213 180 return 0; 214 181 } 215 182 183 + static struct pcie_soc_ops hip05_ops = { 184 + &hisi_pcie_link_up_hip05 185 + }; 186 + 187 + static struct pcie_soc_ops hip06_ops = { 188 + &hisi_pcie_link_up_hip06 189 + }; 190 + 216 191 static const struct of_device_id hisi_pcie_of_match[] = { 217 - {.compatible = "hisilicon,hip05-pcie",}, 192 + { 193 + .compatible = "hisilicon,hip05-pcie", 194 + .data = (void *) &hip05_ops, 195 + }, 196 + { 197 + .compatible = "hisilicon,hip06-pcie", 198 + .data = (void *) &hip06_ops, 199 + }, 218 200 {}, 219 201 }; 202 + 220 203 221 204 MODULE_DEVICE_TABLE(of, hisi_pcie_of_match); 222 205 ··· 245 196 }; 246 197 247 198 module_platform_driver(hisi_pcie_driver); 199 + 200 + MODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>"); 201 + MODULE_AUTHOR("Dacai Zhu <zhudacai@hisilicon.com>"); 202 + MODULE_AUTHOR("Gabriele Paoloni <gabriele.paoloni@huawei.com>"); 203 + MODULE_LICENSE("GPL v2");