提交 5930fe4e 编写于 作者: G Gabriele Paoloni 提交者: Bjorn Helgaas

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: NGabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: NZhou Wang <wangzhou1@hisilicon.com>
上级 1ec21837
HiSilicon PCIe host bridge DT description HiSilicon Hip05 and Hip06 PCIe host bridge DT description
HiSilicon PCIe host controller is based on Designware PCI core. HiSilicon PCIe host controller is based on Designware PCI core.
It shares common functions with PCIe Designware core driver and inherits It shares common functions with PCIe Designware core driver and inherits
...@@ -7,8 +7,8 @@ Documentation/devicetree/bindings/pci/designware-pci.txt. ...@@ -7,8 +7,8 @@ Documentation/devicetree/bindings/pci/designware-pci.txt.
Additional properties are described here: Additional properties are described here:
Required properties: Required properties
- compatible: Should contain "hisilicon,hip05-pcie". - compatible: Should contain "hisilicon,hip05-pcie" or "hisilicon,hip06-pcie".
- reg: Should contain rc_dbi, config registers location and length. - reg: Should contain rc_dbi, config registers location and length.
- reg-names: Must include the following entries: - reg-names: Must include the following entries:
"rc_dbi": controller configuration registers; "rc_dbi": controller configuration registers;
...@@ -20,7 +20,7 @@ Optional properties: ...@@ -20,7 +20,7 @@ Optional properties:
- status: Either "ok" or "disabled". - status: Either "ok" or "disabled".
- dma-coherent: Present if DMA operations are coherent. - dma-coherent: Present if DMA operations are coherent.
Example: Hip05 Example (note that Hip06 is the same except compatible):
pcie@0xb0080000 { pcie@0xb0080000 {
compatible = "hisilicon,hip05-pcie", "snps,dw-pcie"; compatible = "hisilicon,hip05-pcie", "snps,dw-pcie";
reg = <0 0xb0080000 0 0x10000>, <0x220 0x00000000 0 0x2000>; reg = <0 0xb0080000 0 0x10000>, <0x220 0x00000000 0 0x2000>;
......
...@@ -8240,6 +8240,7 @@ F: drivers/pci/host/pci-xgene-msi.c ...@@ -8240,6 +8240,7 @@ F: drivers/pci/host/pci-xgene-msi.c
PCIE DRIVER FOR HISILICON PCIE DRIVER FOR HISILICON
M: Zhou Wang <wangzhou1@hisilicon.com> M: Zhou Wang <wangzhou1@hisilicon.com>
M: Gabriele Paoloni <gabriele.paoloni@huawei.com>
L: linux-pci@vger.kernel.org L: linux-pci@vger.kernel.org
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
......
...@@ -166,10 +166,11 @@ config PCIE_ALTERA_MSI ...@@ -166,10 +166,11 @@ config PCIE_ALTERA_MSI
config PCI_HISI config PCI_HISI
depends on OF && ARM64 depends on OF && ARM64
bool "HiSilicon SoC HIP05 PCIe controller" bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers"
select PCIEPORTBUS select PCIEPORTBUS
select PCIE_DW select PCIE_DW
help help
Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC Say Y here if you want PCIe controller support on HiSilicon
Hip05 and Hip06 SoCs
endmenu endmenu
/* /*
* PCIe host controller driver for HiSilicon Hip05 SoC * PCIe host controller driver for HiSilicon SoCs
* *
* Copyright (C) 2015 HiSilicon Co., Ltd. http://www.hisilicon.com * Copyright (C) 2015 HiSilicon Co., Ltd. http://www.hisilicon.com
* *
* Author: Zhou Wang <wangzhou1@hisilicon.com> * Authors: Zhou Wang <wangzhou1@hisilicon.com>
* Dacai Zhu <zhudacai@hisilicon.com> * Dacai Zhu <zhudacai@hisilicon.com>
* Gabriele Paoloni <gabriele.paoloni@huawei.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -16,21 +17,31 @@ ...@@ -16,21 +17,31 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_pci.h> #include <linux/of_pci.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include "pcie-designware.h" #include "pcie-designware.h"
#define PCIE_SUBCTRL_SYS_STATE4_REG 0x6818 #define PCIE_LTSSM_LINKUP_STATE 0x11
#define PCIE_LTSSM_LINKUP_STATE 0x11 #define PCIE_LTSSM_STATE_MASK 0x3F
#define PCIE_LTSSM_STATE_MASK 0x3F #define PCIE_SUBCTRL_SYS_STATE4_REG 0x6818
#define PCIE_SYS_STATE4 0x31c
#define PCIE_HIP06_CTRL_OFF 0x1000
#define to_hisi_pcie(x) container_of(x, struct hisi_pcie, pp) #define to_hisi_pcie(x) container_of(x, struct hisi_pcie, pp)
struct hisi_pcie;
struct pcie_soc_ops {
int (*hisi_pcie_link_up)(struct hisi_pcie *pcie);
};
struct hisi_pcie { struct hisi_pcie {
struct regmap *subctrl; struct regmap *subctrl;
void __iomem *reg_base; void __iomem *reg_base;
u32 port_id; u32 port_id;
struct pcie_port pp; struct pcie_port pp;
struct pcie_soc_ops *soc_ops;
}; };
static inline void hisi_pcie_apb_writel(struct hisi_pcie *pcie, static inline void hisi_pcie_apb_writel(struct hisi_pcie *pcie,
...@@ -44,7 +55,7 @@ static inline u32 hisi_pcie_apb_readl(struct hisi_pcie *pcie, u32 reg) ...@@ -44,7 +55,7 @@ static inline u32 hisi_pcie_apb_readl(struct hisi_pcie *pcie, u32 reg)
return readl(pcie->reg_base + reg); return readl(pcie->reg_base + reg);
} }
/* Hip05 PCIe host only supports 32-bit config access */ /* HipXX PCIe host only supports 32-bit config access */
static int hisi_pcie_cfg_read(struct pcie_port *pp, int where, int size, static int hisi_pcie_cfg_read(struct pcie_port *pp, int where, int size,
u32 *val) u32 *val)
{ {
...@@ -67,7 +78,7 @@ static int hisi_pcie_cfg_read(struct pcie_port *pp, int where, int size, ...@@ -67,7 +78,7 @@ static int hisi_pcie_cfg_read(struct pcie_port *pp, int where, int size,
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
/* Hip05 PCIe host only supports 32-bit config access */ /* HipXX PCIe host only supports 32-bit config access */
static int hisi_pcie_cfg_write(struct pcie_port *pp, int where, int size, static int hisi_pcie_cfg_write(struct pcie_port *pp, int where, int size,
u32 val) u32 val)
{ {
...@@ -94,10 +105,9 @@ static int hisi_pcie_cfg_write(struct pcie_port *pp, int where, int size, ...@@ -94,10 +105,9 @@ static int hisi_pcie_cfg_write(struct pcie_port *pp, int where, int size,
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int hisi_pcie_link_up(struct pcie_port *pp) static int hisi_pcie_link_up_hip05(struct hisi_pcie *hisi_pcie)
{ {
u32 val; u32 val;
struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
regmap_read(hisi_pcie->subctrl, PCIE_SUBCTRL_SYS_STATE4_REG + regmap_read(hisi_pcie->subctrl, PCIE_SUBCTRL_SYS_STATE4_REG +
0x100 * hisi_pcie->port_id, &val); 0x100 * hisi_pcie->port_id, &val);
...@@ -105,6 +115,23 @@ static int hisi_pcie_link_up(struct pcie_port *pp) ...@@ -105,6 +115,23 @@ static int hisi_pcie_link_up(struct pcie_port *pp)
return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE); return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
} }
static int hisi_pcie_link_up_hip06(struct hisi_pcie *hisi_pcie)
{
u32 val;
val = hisi_pcie_apb_readl(hisi_pcie, PCIE_HIP06_CTRL_OFF +
PCIE_SYS_STATE4);
return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
}
static int hisi_pcie_link_up(struct pcie_port *pp)
{
struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
return hisi_pcie->soc_ops->hisi_pcie_link_up(hisi_pcie);
}
static struct pcie_host_ops hisi_pcie_host_ops = { static struct pcie_host_ops hisi_pcie_host_ops = {
.rd_own_conf = hisi_pcie_cfg_read, .rd_own_conf = hisi_pcie_cfg_read,
.wr_own_conf = hisi_pcie_cfg_write, .wr_own_conf = hisi_pcie_cfg_write,
...@@ -143,7 +170,9 @@ static int __init hisi_pcie_probe(struct platform_device *pdev) ...@@ -143,7 +170,9 @@ static int __init hisi_pcie_probe(struct platform_device *pdev)
{ {
struct hisi_pcie *hisi_pcie; struct hisi_pcie *hisi_pcie;
struct pcie_port *pp; struct pcie_port *pp;
const struct of_device_id *match;
struct resource *reg; struct resource *reg;
struct device_driver *driver;
int ret; int ret;
hisi_pcie = devm_kzalloc(&pdev->dev, sizeof(*hisi_pcie), GFP_KERNEL); hisi_pcie = devm_kzalloc(&pdev->dev, sizeof(*hisi_pcie), GFP_KERNEL);
...@@ -152,6 +181,10 @@ static int __init hisi_pcie_probe(struct platform_device *pdev) ...@@ -152,6 +181,10 @@ static int __init hisi_pcie_probe(struct platform_device *pdev)
pp = &hisi_pcie->pp; pp = &hisi_pcie->pp;
pp->dev = &pdev->dev; pp->dev = &pdev->dev;
driver = (pdev->dev).driver;
match = of_match_device(driver->of_match_table, &pdev->dev);
hisi_pcie->soc_ops = (struct pcie_soc_ops *) match->data;
hisi_pcie->subctrl = hisi_pcie->subctrl =
syscon_regmap_lookup_by_compatible("hisilicon,pcie-sas-subctrl"); syscon_regmap_lookup_by_compatible("hisilicon,pcie-sas-subctrl");
...@@ -180,11 +213,27 @@ static int __init hisi_pcie_probe(struct platform_device *pdev) ...@@ -180,11 +213,27 @@ static int __init hisi_pcie_probe(struct platform_device *pdev)
return 0; return 0;
} }
static struct pcie_soc_ops hip05_ops = {
&hisi_pcie_link_up_hip05
};
static struct pcie_soc_ops hip06_ops = {
&hisi_pcie_link_up_hip06
};
static const struct of_device_id hisi_pcie_of_match[] = { static const struct of_device_id hisi_pcie_of_match[] = {
{.compatible = "hisilicon,hip05-pcie",}, {
.compatible = "hisilicon,hip05-pcie",
.data = (void *) &hip05_ops,
},
{
.compatible = "hisilicon,hip06-pcie",
.data = (void *) &hip06_ops,
},
{}, {},
}; };
MODULE_DEVICE_TABLE(of, hisi_pcie_of_match); MODULE_DEVICE_TABLE(of, hisi_pcie_of_match);
static struct platform_driver hisi_pcie_driver = { static struct platform_driver hisi_pcie_driver = {
...@@ -196,3 +245,8 @@ static struct platform_driver hisi_pcie_driver = { ...@@ -196,3 +245,8 @@ static struct platform_driver hisi_pcie_driver = {
}; };
module_platform_driver(hisi_pcie_driver); module_platform_driver(hisi_pcie_driver);
MODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>");
MODULE_AUTHOR("Dacai Zhu <zhudacai@hisilicon.com>");
MODULE_AUTHOR("Gabriele Paoloni <gabriele.paoloni@huawei.com>");
MODULE_LICENSE("GPL v2");
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册