@@ -53,9 +53,16 @@ struct rcar_gen4_pcie {
void __iomem *base;
struct platform_device *pdev;
enum dw_pcie_device_mode mode;
+
+ int (*start_link_enable)(struct rcar_gen4_pcie *rcar);
};
#define to_rcar_gen4_pcie(_dw) container_of(_dw, struct rcar_gen4_pcie, dw)
+struct rcar_gen4_pcie_platdata {
+ enum dw_pcie_device_mode mode;
+ int (*start_link_enable)(struct rcar_gen4_pcie *rcar);
+};
+
/* Common */
static void rcar_gen4_pcie_ltssm_enable(struct rcar_gen4_pcie *rcar,
bool enable)
@@ -123,9 +130,13 @@ static int rcar_gen4_pcie_speed_change(struct dw_pcie *dw)
static int rcar_gen4_pcie_start_link(struct dw_pcie *dw)
{
struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
- int i, changes;
+ int i, changes, ret;
- rcar_gen4_pcie_ltssm_enable(rcar, true);
+ if (rcar->start_link_enable) {
+ ret = rcar->start_link_enable(rcar);
+ if (ret)
+ return ret;
+ }
/*
* Require direct speed change with retrying here if the link_gen is
@@ -435,7 +446,10 @@ static void rcar_gen4_remove_dw_pcie_ep(struct rcar_gen4_pcie *rcar)
/* Common */
static int rcar_gen4_add_dw_pcie(struct rcar_gen4_pcie *rcar)
{
- rcar->mode = (uintptr_t)of_device_get_match_data(&rcar->pdev->dev);
+ const struct rcar_gen4_pcie_platdata *pd = of_device_get_match_data(&rcar->pdev->dev);
+
+ rcar->mode = pd->mode;
+ rcar->start_link_enable = pd->start_link_enable;
switch (rcar->mode) {
case DW_PCIE_RC_TYPE:
@@ -498,14 +512,47 @@ static void rcar_gen4_pcie_remove(struct platform_device *pdev)
rcar_gen4_pcie_unprepare(rcar);
}
+static int r8a779f0_pcie_start_link_enable(struct rcar_gen4_pcie *rcar)
+{
+ rcar_gen4_pcie_ltssm_enable(rcar, true);
+
+ return 0;
+}
+
+static struct rcar_gen4_pcie_platdata platdata_r8a779f0_pcie = {
+ .mode = DW_PCIE_RC_TYPE,
+ .start_link_enable = r8a779f0_pcie_start_link_enable,
+};
+
+static struct rcar_gen4_pcie_platdata platdata_r8a779f0_pcie_ep = {
+ .mode = DW_PCIE_EP_TYPE,
+ .start_link_enable = r8a779f0_pcie_start_link_enable,
+};
+
+static struct rcar_gen4_pcie_platdata platdata_rcar_gen4_pcie = {
+ .mode = DW_PCIE_RC_TYPE,
+};
+
+static struct rcar_gen4_pcie_platdata platdata_rcar_gen4_pcie_ep = {
+ .mode = DW_PCIE_EP_TYPE,
+};
+
static const struct of_device_id rcar_gen4_pcie_of_match[] = {
+ {
+ .compatible = "renesas,r8a779f0-pcie",
+ .data = &platdata_r8a779f0_pcie,
+ },
+ {
+ .compatible = "renesas,r8a779f0-pcie-ep",
+ .data = &platdata_r8a779f0_pcie_ep,
+ },
{
.compatible = "renesas,rcar-gen4-pcie",
- .data = (void *)DW_PCIE_RC_TYPE,
+ .data = &platdata_rcar_gen4_pcie,
},
{
.compatible = "renesas,rcar-gen4-pcie-ep",
- .data = (void *)DW_PCIE_EP_TYPE,
+ .data = &platdata_rcar_gen4_pcie_ep,
},
{},
};
This driver can reuse other R-Car Gen4 SoC support. However, some initializing settings differs between r8a779f0 and others. So, add a new function pointer start_link_enable() to support other R-Car Gen4 SoC in the future. No behavior changes. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> --- drivers/pci/controller/dwc/pcie-rcar-gen4.c | 57 +++++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-)