@@ -48,7 +48,9 @@
#define RCAR_GEN4_PCIE_EP_FUNC_DBI_OFFSET 0x1000
#define RCAR_GEN4_PCIE_EP_FUNC_DBI2_OFFSET 0x800
+struct rcar_gen4_pcie;
struct rcar_gen4_pcie_drvdata {
+ int (*ltssm_control)(struct rcar_gen4_pcie *rcar, bool enable);
enum dw_pcie_device_mode mode;
};
@@ -61,27 +63,6 @@ struct rcar_gen4_pcie {
#define to_rcar_gen4_pcie(_dw) container_of(_dw, struct rcar_gen4_pcie, dw)
/* Common */
-static void rcar_gen4_pcie_ltssm_enable(struct rcar_gen4_pcie *rcar,
- bool enable)
-{
- u32 val;
-
- val = readl(rcar->base + PCIERSTCTRL1);
- if (enable) {
- val |= APP_LTSSM_ENABLE;
- val &= ~APP_HOLD_PHY_RST;
- } else {
- /*
- * Since the datasheet of R-Car doesn't mention how to assert
- * the APP_HOLD_PHY_RST, don't assert it again. Otherwise,
- * hang-up issue happened in the dw_edma_core_off() when
- * the controller didn't detect a PCI device.
- */
- val &= ~APP_LTSSM_ENABLE;
- }
- writel(val, rcar->base + PCIERSTCTRL1);
-}
-
static int rcar_gen4_pcie_link_up(struct dw_pcie *dw)
{
struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
@@ -127,9 +108,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->drvdata->ltssm_control) {
+ ret = rcar->drvdata->ltssm_control(rcar, true);
+ if (ret)
+ return ret;
+ }
/*
* Require direct speed change with retrying here if the link_gen is
@@ -157,7 +142,8 @@ static void rcar_gen4_pcie_stop_link(struct dw_pcie *dw)
{
struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
- rcar_gen4_pcie_ltssm_enable(rcar, false);
+ if (rcar->drvdata->ltssm_control)
+ rcar->drvdata->ltssm_control(rcar, false);
}
static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar)
@@ -520,6 +506,38 @@ static void rcar_gen4_pcie_remove(struct platform_device *pdev)
rcar_gen4_pcie_unprepare(rcar);
}
+static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
+{
+ u32 val;
+
+ val = readl(rcar->base + PCIERSTCTRL1);
+ if (enable) {
+ val |= APP_LTSSM_ENABLE;
+ val &= ~APP_HOLD_PHY_RST;
+ } else {
+ /*
+ * Since the datasheet of R-Car doesn't mention how to assert
+ * the APP_HOLD_PHY_RST, don't assert it again. Otherwise,
+ * hang-up issue happened in the dw_edma_core_off() when
+ * the controller didn't detect a PCI device.
+ */
+ val &= ~APP_LTSSM_ENABLE;
+ }
+ writel(val, rcar->base + PCIERSTCTRL1);
+
+ return 0;
+}
+
+static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie = {
+ .ltssm_control = r8a779f0_pcie_ltssm_control,
+ .mode = DW_PCIE_RC_TYPE,
+};
+
+static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie_ep = {
+ .ltssm_control = r8a779f0_pcie_ltssm_control,
+ .mode = DW_PCIE_EP_TYPE,
+};
+
static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie = {
.mode = DW_PCIE_RC_TYPE,
};
@@ -529,6 +547,14 @@ static struct rcar_gen4_pcie_drvdata drvdata_rcar_gen4_pcie_ep = {
};
static const struct of_device_id rcar_gen4_pcie_of_match[] = {
+ {
+ .compatible = "renesas,r8a779f0-pcie",
+ .data = &drvdata_r8a779f0_pcie,
+ },
+ {
+ .compatible = "renesas,r8a779f0-pcie-ep",
+ .data = &drvdata_r8a779f0_pcie_ep,
+ },
{
.compatible = "renesas,rcar-gen4-pcie",
.data = &drvdata_rcar_gen4_pcie,