Commit 5f2c4de7 authored by John Madieu's avatar John Madieu Committed by Manivannan Sadhasivam
Browse files

PCI: rzg3s-host: Add SoC-specific configuration and initialization callbacks



Add optional cfg_pre_init, cfg_post_init, and cfg_deinit callbacks
to handle SoC-specific configuration methods. While RZ/G3S uses the Linux
reset framework with dedicated reset lines, other SoC variants like RZ/G3E
control configuration resets through PCIe AXI registers.

As Linux reset bulk API gracefully handles optional NULL reset lines
(num_cfg_resets = 0 for RZ/G3E), the driver continues to use the standard
reset framework when reset lines are available, while custom callbacks
are only invoked when provided.

This provides a balanced pattern where:
- RZ/G3S: Uses callbacks that fall back to the reset framework
- RZ/G3E: Sets num_cfg_resets=0, provides
  cfg_pre_init/cfg_post_init/cfg_deinit

Signed-off-by: default avatarJohn Madieu <john.madieu.xa@bp.renesas.com>
Signed-off-by: default avatarManivannan Sadhasivam <mani@kernel.org>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> # RZ/V2N EVK
Tested-by: default avatarClaudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: default avatarClaudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Link: https://patch.msgid.link/20260306143423.19562-10-john.madieu.xa@bp.renesas.com
parent 4ec4ccda
Loading
Loading
Loading
Loading
+44 −17
Original line number Diff line number Diff line
@@ -233,6 +233,9 @@ struct rzg3s_pcie_host;
/**
 * struct rzg3s_pcie_soc_data - SoC specific data
 * @init_phy: PHY initialization function
 * @config_pre_init: Optional callback for SoC-specific pre-configuration
 * @config_post_init: Callback for SoC-specific post-configuration
 * @config_deinit: Callback for SoC-specific de-initialization
 * @power_resets: array with the resets that need to be de-asserted after
 *                power-on
 * @cfg_resets: array with the resets that need to be de-asserted after
@@ -243,6 +246,9 @@ struct rzg3s_pcie_host;
 */
struct rzg3s_pcie_soc_data {
	int (*init_phy)(struct rzg3s_pcie_host *host);
	void (*config_pre_init)(struct rzg3s_pcie_host *host);
	int (*config_post_init)(struct rzg3s_pcie_host *host);
	int (*config_deinit)(struct rzg3s_pcie_host *host);
	const char * const *power_resets;
	const char * const *cfg_resets;
	struct rzg3s_sysc_info sysc_info;
@@ -1109,6 +1115,18 @@ static int rzg3s_pcie_config_init(struct rzg3s_pcie_host *host)
	return 0;
}

static int rzg3s_pcie_config_post_init(struct rzg3s_pcie_host *host)
{
	return reset_control_bulk_deassert(host->data->num_cfg_resets,
					   host->cfg_resets);
}

static int rzg3s_pcie_config_deinit(struct rzg3s_pcie_host *host)
{
	return reset_control_bulk_assert(host->data->num_cfg_resets,
					 host->cfg_resets);
}

static void rzg3s_pcie_irq_init(struct rzg3s_pcie_host *host)
{
	/*
@@ -1257,22 +1275,26 @@ static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
	u32 val;
	int ret;

	/* SoC-specific pre-configuration */
	if (host->data->config_pre_init)
		host->data->config_pre_init(host);

	/* Initialize the PCIe related registers */
	ret = rzg3s_pcie_config_init(host);
	if (ret)
		return ret;
		goto config_deinit;

	ret = rzg3s_pcie_host_init_port(host);
	if (ret)
		return ret;
		goto config_deinit;

	/* Initialize the interrupts */
	rzg3s_pcie_irq_init(host);

	ret = reset_control_bulk_deassert(host->data->num_cfg_resets,
					  host->cfg_resets);
	/* SoC-specific post-configuration */
	ret = host->data->config_post_init(host);
	if (ret)
		goto disable_port_refclk;
		goto config_deinit_and_refclk;

	/* Wait for link up */
	ret = readl_poll_timeout(host->axi + RZG3S_PCI_PCSTAT1, val,
@@ -1281,18 +1303,20 @@ static int rzg3s_pcie_host_init(struct rzg3s_pcie_host *host)
				 PCIE_LINK_WAIT_SLEEP_MS * MILLI *
				 PCIE_LINK_WAIT_MAX_RETRIES);
	if (ret)
		goto cfg_resets_deassert;
		goto config_deinit_post;

	val = readl_relaxed(host->axi + RZG3S_PCI_PCSTAT2);
	dev_info(host->dev, "PCIe link status [0x%x]\n", val);

	return 0;

cfg_resets_deassert:
	reset_control_bulk_assert(host->data->num_cfg_resets,
				  host->cfg_resets);
disable_port_refclk:
config_deinit_post:
	host->data->config_deinit(host);
config_deinit_and_refclk:
	clk_disable_unprepare(host->port.refclk);
config_deinit:
	if (host->data->config_pre_init)
		host->data->config_deinit(host);
	return ret;
}

@@ -1653,7 +1677,7 @@ static int rzg3s_pcie_probe(struct platform_device *pdev)

host_probe_teardown:
	rzg3s_pcie_teardown_irqdomain(host);
	reset_control_bulk_assert(host->data->num_cfg_resets, host->cfg_resets);
	host->data->config_deinit(host);
rpm_put:
	pm_runtime_put_sync(dev);
rpm_disable:
@@ -1686,15 +1710,15 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev)

	clk_disable_unprepare(port->refclk);

	ret = reset_control_bulk_assert(data->num_cfg_resets,
					host->cfg_resets);
	/* SoC-specific de-initialization */
	ret = data->config_deinit(host);
	if (ret)
		goto refclk_restore;

	ret = reset_control_bulk_assert(data->num_power_resets,
					host->power_resets);
	if (ret)
		goto cfg_resets_restore;
		goto config_reinit;

	ret = rzg3s_sysc_config_func(sysc, RZG3S_SYSC_FUNC_ID_RST_RSM_B, 0);
	if (ret)
@@ -1706,9 +1730,10 @@ static int rzg3s_pcie_suspend_noirq(struct device *dev)
power_resets_restore:
	reset_control_bulk_deassert(data->num_power_resets,
				    host->power_resets);
cfg_resets_restore:
	reset_control_bulk_deassert(data->num_cfg_resets,
				    host->cfg_resets);
config_reinit:
	if (data->config_pre_init)
		data->config_pre_init(host);
	data->config_post_init(host);
refclk_restore:
	clk_prepare_enable(port->refclk);
	pm_runtime_resume_and_get(dev);
@@ -1773,6 +1798,8 @@ static const struct rzg3s_pcie_soc_data rzg3s_soc_data = {
	.num_power_resets = ARRAY_SIZE(rzg3s_soc_power_resets),
	.cfg_resets = rzg3s_soc_cfg_resets,
	.num_cfg_resets = ARRAY_SIZE(rzg3s_soc_cfg_resets),
	.config_post_init = rzg3s_pcie_config_post_init,
	.config_deinit = rzg3s_pcie_config_deinit,
	.init_phy = rzg3s_soc_pcie_init_phy,
	.sysc_info = {
		.functions = {