]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: rzg3s-host: Make SYSC register offsets SoC-specific
authorJohn Madieu <john.madieu.xa@bp.renesas.com>
Fri, 6 Mar 2026 14:34:14 +0000 (15:34 +0100)
committerManivannan Sadhasivam <mani@kernel.org>
Sun, 15 Mar 2026 15:35:43 +0000 (21:05 +0530)
In preparation for adding RZ/G3E support, move the RST_RSM_B register
offset and mask into a SoC-specific data structure. Compared with RZ/G3S,
the RZ/G3E SYSC controls different functionalities for the PCIe controller.

Make SYSC operations conditional on the presence of register offset
information, allowing the driver to handle SoCs that don't use the
RST_RSM_B signal.

Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> # RZ/V2N EVK
Tested-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Link: https://patch.msgid.link/20260306143423.19562-8-john.madieu.xa@bp.renesas.com
drivers/pci/controller/pcie-rzg3s-host.c

index 872683211bab149203bae66f3fbfbfa95783a565..f5a0b7c6e773668d65800a4bc88b0713d4e01aaf 100644 (file)
 
 #define RZG3S_PCI_CFG_PCIEC                    0x60
 
-/* System controller registers */
-#define RZG3S_SYS_PCIE_RST_RSM_B               0xd74
-#define RZG3S_SYS_PCIE_RST_RSM_B_MASK          BIT(0)
-
 /* Maximum number of windows */
 #define RZG3S_MAX_WINDOWS                      8
 
 /* Timeouts experimentally determined */
 #define RZG3S_REQ_ISSUE_TIMEOUT_US             2500
 
+/**
+ * struct rzg3s_sysc_function - System Controller function descriptor
+ * @offset: Register offset from the System Controller base address
+ * @mask: Bit mask for the function within the register
+ */
+struct rzg3s_sysc_function {
+       u32 offset;
+       u32 mask;
+};
+
+/**
+ * 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_MAX: Max SYSC function ID
+ */
+enum rzg3s_sysc_func_id {
+       RZG3S_SYSC_FUNC_ID_RST_RSM_B,
+       RZG3S_SYSC_FUNC_ID_MAX,
+};
+
+/**
+ * struct rzg3s_sysc_info - RZ/G3S System Controller info
+ * @functions: SYSC function descriptors array
+ */
+struct rzg3s_sysc_info {
+       const struct rzg3s_sysc_function functions[RZG3S_SYSC_FUNC_ID_MAX];
+};
+
+/**
+ * struct rzg3s_sysc - RZ/G3S System Controller descriptor
+ * @regmap: System controller regmap
+ * @info: System controller info
+ */
+struct rzg3s_sysc {
+       struct regmap *regmap;
+       const struct rzg3s_sysc_info *info;
+};
+
 /**
  * struct rzg3s_pcie_msi - RZ/G3S PCIe MSI data structure
  * @domain: IRQ domain
@@ -203,6 +237,7 @@ struct rzg3s_pcie_host;
  *                power-on
  * @cfg_resets: array with the resets that need to be de-asserted after
  *              configuration
+ * @sysc_info: SYSC info
  * @num_power_resets: number of power resets
  * @num_cfg_resets: number of configuration resets
  */
@@ -210,6 +245,7 @@ struct rzg3s_pcie_soc_data {
        int (*init_phy)(struct rzg3s_pcie_host *host);
        const char * const *power_resets;
        const char * const *cfg_resets;
+       struct rzg3s_sysc_info sysc_info;
        u8 num_power_resets;
        u8 num_cfg_resets;
 };
@@ -233,7 +269,7 @@ struct rzg3s_pcie_port {
  * @dev: struct device
  * @power_resets: reset control signals that should be set after power up
  * @cfg_resets: reset control signals that should be set after configuration
- * @sysc: SYSC regmap
+ * @sysc: SYSC descriptor
  * @intx_domain: INTx IRQ domain
  * @data: SoC specific data
  * @msi: MSI data structure
@@ -248,7 +284,7 @@ struct rzg3s_pcie_host {
        struct device *dev;
        struct reset_control_bulk_data *power_resets;
        struct reset_control_bulk_data *cfg_resets;
-       struct regmap *sysc;
+       struct rzg3s_sysc *sysc;
        struct irq_domain *intx_domain;
        const struct rzg3s_pcie_soc_data *data;
        struct rzg3s_pcie_msi msi;
@@ -260,6 +296,23 @@ struct rzg3s_pcie_host {
 
 #define rzg3s_msi_to_host(_msi)        container_of(_msi, struct rzg3s_pcie_host, msi)
 
+static int rzg3s_sysc_config_func(struct rzg3s_sysc *sysc,
+                                 enum rzg3s_sysc_func_id fid, u32 val)
+{
+       const struct rzg3s_sysc_info *info = sysc->info;
+       const struct rzg3s_sysc_function *functions = info->functions;
+
+       if (fid >= RZG3S_SYSC_FUNC_ID_MAX)
+               return -EINVAL;
+
+       if (!functions[fid].mask)
+               return 0;
+
+       return regmap_update_bits(sysc->regmap, functions[fid].offset,
+                                 functions[fid].mask,
+                                 field_prep(functions[fid].mask, val));
+}
+
 static void rzg3s_pcie_update_bits(void __iomem *base, u32 offset, u32 mask,
                                   u32 val)
 {
@@ -1522,6 +1575,7 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
        struct device_node *sysc_np __free(device_node) =
                of_parse_phandle(np, "renesas,sysc", 0);
        struct rzg3s_pcie_host *host;
+       struct rzg3s_sysc *sysc;
        int ret;
 
        bridge = devm_pci_alloc_host_bridge(dev, sizeof(*host));
@@ -1533,6 +1587,13 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
        host->data = device_get_match_data(dev);
        platform_set_drvdata(pdev, host);
 
+       host->sysc = devm_kzalloc(dev, sizeof(*host->sysc), GFP_KERNEL);
+       if (!host->sysc)
+               return -ENOMEM;
+
+       sysc = host->sysc;
+       sysc->info = &host->data->sysc_info;
+
        host->axi = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(host->axi))
                return PTR_ERR(host->axi);
@@ -1546,15 +1607,13 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       host->sysc = syscon_node_to_regmap(sysc_np);
-       if (IS_ERR(host->sysc)) {
-               ret = PTR_ERR(host->sysc);
+       sysc->regmap = syscon_node_to_regmap(sysc_np);
+       if (IS_ERR(sysc->regmap)) {
+               ret = PTR_ERR(sysc->regmap);
                goto port_refclk_put;
        }
 
-       ret = regmap_update_bits(host->sysc, RZG3S_SYS_PCIE_RST_RSM_B,
-                                RZG3S_SYS_PCIE_RST_RSM_B_MASK,
-                                FIELD_PREP(RZG3S_SYS_PCIE_RST_RSM_B_MASK, 1));
+       ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 1);
        if (ret)
                goto port_refclk_put;
 
@@ -1606,9 +1665,7 @@ sysc_signal_restore:
         * SYSC RST_RSM_B signal need to be asserted before turning off the
         * power to the PHY.
         */
-       regmap_update_bits(host->sysc, RZG3S_SYS_PCIE_RST_RSM_B,
-                          RZG3S_SYS_PCIE_RST_RSM_B_MASK,
-                          FIELD_PREP(RZG3S_SYS_PCIE_RST_RSM_B_MASK, 0));
+       rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 0);
 port_refclk_put:
        clk_put(host->port.refclk);
 
@@ -1620,7 +1677,7 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev)
        struct rzg3s_pcie_host *host = dev_get_drvdata(dev);
        const struct rzg3s_pcie_soc_data *data = host->data;
        struct rzg3s_pcie_port *port = &host->port;
-       struct regmap *sysc = host->sysc;
+       struct rzg3s_sysc *sysc = host->sysc;
        int ret;
 
        ret = pm_runtime_put_sync(dev);
@@ -1639,9 +1696,7 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev)
        if (ret)
                goto cfg_resets_restore;
 
-       ret = regmap_update_bits(sysc, RZG3S_SYS_PCIE_RST_RSM_B,
-                                RZG3S_SYS_PCIE_RST_RSM_B_MASK,
-                                FIELD_PREP(RZG3S_SYS_PCIE_RST_RSM_B_MASK, 0));
+       ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 0);
        if (ret)
                goto power_resets_restore;
 
@@ -1664,12 +1719,10 @@ static int rzg3s_pcie_resume_noirq(struct device *dev)
 {
        struct rzg3s_pcie_host *host = dev_get_drvdata(dev);
        const struct rzg3s_pcie_soc_data *data = host->data;
-       struct regmap *sysc = host->sysc;
+       struct rzg3s_sysc *sysc = host->sysc;
        int ret;
 
-       ret = regmap_update_bits(sysc, RZG3S_SYS_PCIE_RST_RSM_B,
-                                RZG3S_SYS_PCIE_RST_RSM_B_MASK,
-                                FIELD_PREP(RZG3S_SYS_PCIE_RST_RSM_B_MASK, 1));
+       ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 1);
        if (ret)
                return ret;
 
@@ -1698,9 +1751,7 @@ assert_power_resets:
        reset_control_bulk_assert(data->num_power_resets,
                                  host->power_resets);
 assert_rst_rsm_b:
-       regmap_update_bits(sysc, RZG3S_SYS_PCIE_RST_RSM_B,
-                          RZG3S_SYS_PCIE_RST_RSM_B_MASK,
-                          FIELD_PREP(RZG3S_SYS_PCIE_RST_RSM_B_MASK, 0));
+       rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 0);
        return ret;
 }
 
@@ -1723,6 +1774,14 @@ static const struct rzg3s_pcie_soc_data rzg3s_soc_data = {
        .cfg_resets = rzg3s_soc_cfg_resets,
        .num_cfg_resets = ARRAY_SIZE(rzg3s_soc_cfg_resets),
        .init_phy = rzg3s_soc_pcie_init_phy,
+       .sysc_info = {
+               .functions = {
+                       [RZG3S_SYSC_FUNC_ID_RST_RSM_B] = {
+                               .offset = 0xd74,
+                               .mask = BIT(0),
+                       },
+               },
+       },
 };
 
 static const struct of_device_id rzg3s_pcie_of_match[] = {