#define RZG3S_PCI_PERM_CFG_HWINIT_EN BIT(2)
#define RZG3S_PCI_PERM_PIPE_PHY_REG_EN BIT(1)
+#define RZG3S_PCI_RESET 0x310
+#define RZG3S_PCI_RESET_RST_OUT_B BIT(6)
+#define RZG3S_PCI_RESET_RST_PS_B BIT(5)
+#define RZG3S_PCI_RESET_RST_LOAD_B BIT(4)
+#define RZG3S_PCI_RESET_RST_CFG_B BIT(3)
+#define RZG3S_PCI_RESET_RST_RSM_B BIT(2)
+#define RZG3S_PCI_RESET_RST_GP_B BIT(1)
+#define RZG3S_PCI_RESET_RST_B BIT(0)
+
#define RZG3S_PCI_MSIRE(id) (0x600 + (id) * 0x10)
#define RZG3S_PCI_MSIRE_ENA BIT(0)
/**
* enum rzg3s_sysc_func_id - System controller function IDs
* @RZG3S_SYSC_FUNC_ID_RST_RSM_B: RST_RSM_B SYSC function ID
+ * @RZG3S_SYSC_FUNC_ID_L1_ALLOW: L1 allow SYSC function ID
+ * @RZG3S_SYSC_FUNC_ID_MODE: Mode SYSC function ID
* @RZG3S_SYSC_FUNC_ID_MAX: Max SYSC function ID
*/
enum rzg3s_sysc_func_id {
RZG3S_SYSC_FUNC_ID_RST_RSM_B,
+ RZG3S_SYSC_FUNC_ID_L1_ALLOW,
+ RZG3S_SYSC_FUNC_ID_MODE,
RZG3S_SYSC_FUNC_ID_MAX,
};
host->cfg_resets);
}
+static void rzg3e_pcie_config_pre_init(struct rzg3s_pcie_host *host)
+{
+ u32 mask = RZG3S_PCI_RESET_RST_LOAD_B | RZG3S_PCI_RESET_RST_CFG_B;
+
+ /* De-assert LOAD_B and CFG_B */
+ rzg3s_pcie_update_bits(host->axi, RZG3S_PCI_RESET, mask, mask);
+}
+
+static int rzg3e_pcie_config_deinit(struct rzg3s_pcie_host *host)
+{
+ writel_relaxed(0, host->axi + RZG3S_PCI_RESET);
+ return 0;
+}
+
+static int rzg3e_pcie_config_post_init(struct rzg3s_pcie_host *host)
+{
+ u32 mask = RZG3S_PCI_RESET_RST_PS_B | RZG3S_PCI_RESET_RST_GP_B |
+ RZG3S_PCI_RESET_RST_B;
+
+ /* De-assert PS_B, GP_B, RST_B */
+ rzg3s_pcie_update_bits(host->axi, RZG3S_PCI_RESET, mask, mask);
+
+ /* Flush deassert */
+ readl_relaxed(host->axi + RZG3S_PCI_RESET);
+
+ /*
+ * According to the RZ/G3E HW manual (Rev.1.15, Table 6.6-130
+ * Initialization Procedure (RC)), hardware requires >= 500us delay
+ * before final reset deassert.
+ */
+ fsleep(500);
+
+ /* De-assert OUT_B and RSM_B */
+ mask = RZG3S_PCI_RESET_RST_OUT_B | RZG3S_PCI_RESET_RST_RSM_B;
+ rzg3s_pcie_update_bits(host->axi, RZG3S_PCI_RESET, mask, mask);
+
+ return 0;
+}
+
static void rzg3s_pcie_irq_init(struct rzg3s_pcie_host *host)
{
/*
if (ret)
goto config_deinit;
+ /* Enable ASPM L1 transition for SoCs that use it */
+ ret = rzg3s_sysc_config_func(host->sysc,
+ RZG3S_SYSC_FUNC_ID_L1_ALLOW, 1);
+ if (ret)
+ goto config_deinit_and_refclk;
+
/* Initialize the interrupts */
rzg3s_pcie_irq_init(host);
goto port_refclk_put;
}
+ /* Put controller in RC mode */
+ ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_MODE, 1);
+ if (ret)
+ goto port_refclk_put;
+
ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 1);
if (ret)
goto port_refclk_put;
struct rzg3s_sysc *sysc = host->sysc;
int ret;
+ ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_MODE, 1);
+ if (ret)
+ return ret;
+
ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 1);
if (ret)
return ret;
},
};
+static const char * const rzg3e_soc_power_resets[] = { "aresetn" };
+
+static const struct rzg3s_pcie_soc_data rzg3e_soc_data = {
+ .power_resets = rzg3e_soc_power_resets,
+ .num_power_resets = ARRAY_SIZE(rzg3e_soc_power_resets),
+ .config_pre_init = rzg3e_pcie_config_pre_init,
+ .config_post_init = rzg3e_pcie_config_post_init,
+ .config_deinit = rzg3e_pcie_config_deinit,
+ .sysc_info = {
+ .functions = {
+ [RZG3S_SYSC_FUNC_ID_L1_ALLOW] = {
+ .offset = 0x1020,
+ .mask = BIT(0),
+ },
+ [RZG3S_SYSC_FUNC_ID_MODE] = {
+ .offset = 0x1024,
+ .mask = BIT(0),
+ },
+ },
+ },
+};
+
static const struct of_device_id rzg3s_pcie_of_match[] = {
{
.compatible = "renesas,r9a08g045-pcie",
.data = &rzg3s_soc_data,
},
+ {
+ .compatible = "renesas,r9a09g047-pcie",
+ .data = &rzg3e_soc_data,
+ },
{}
};