Commit 30246e2d authored by Shreyas NC's avatar Shreyas NC Committed by Vinod Koul
Browse files

soundwire: intel: Add pre/post bank switch ops



To support multi link on Intel platforms, we need to update
SDW SHIM registers.

So, add pre/post bank switch ops for the same in Intel driver.

Signed-off-by: default avatarSanyog Kale <sanyog.r.kale@intel.com>
Signed-off-by: default avatarShreyas NC <shreyas.nc@intel.com>
Acked-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 9b5c132a
Loading
Loading
Loading
Loading
+65 −0
Original line number Diff line number Diff line
@@ -397,6 +397,69 @@ static int intel_config_stream(struct sdw_intel *sdw,
	return -EIO;
}

/*
 * bank switch routines
 */

static int intel_pre_bank_switch(struct sdw_bus *bus)
{
	struct sdw_cdns *cdns = bus_to_cdns(bus);
	struct sdw_intel *sdw = cdns_to_intel(cdns);
	void __iomem *shim = sdw->res->shim;
	int sync_reg;

	/* Write to register only for multi-link */
	if (!bus->multi_link)
		return 0;

	/* Read SYNC register */
	sync_reg = intel_readl(shim, SDW_SHIM_SYNC);
	sync_reg |= SDW_SHIM_SYNC_CMDSYNC << sdw->instance;
	intel_writel(shim, SDW_SHIM_SYNC, sync_reg);

	return 0;
}

static int intel_post_bank_switch(struct sdw_bus *bus)
{
	struct sdw_cdns *cdns = bus_to_cdns(bus);
	struct sdw_intel *sdw = cdns_to_intel(cdns);
	void __iomem *shim = sdw->res->shim;
	int sync_reg, ret;

	/* Write to register only for multi-link */
	if (!bus->multi_link)
		return 0;

	/* Read SYNC register */
	sync_reg = intel_readl(shim, SDW_SHIM_SYNC);

	/*
	 * post_bank_switch() ops is called from the bus in loop for
	 * all the Masters in the steam with the expectation that
	 * we trigger the bankswitch for the only first Master in the list
	 * and do nothing for the other Masters
	 *
	 * So, set the SYNCGO bit only if CMDSYNC bit is set for any Master.
	 */
	if (!(sync_reg & SDW_SHIM_SYNC_CMDSYNC_MASK))
		return 0;

	/*
	 * Set SyncGO bit to synchronously trigger a bank switch for
	 * all the masters. A write to SYNCGO bit clears CMDSYNC bit for all
	 * the Masters.
	 */
	sync_reg |= SDW_SHIM_SYNC_SYNCGO;

	ret = intel_clear_bit(shim, SDW_SHIM_SYNC, sync_reg,
					SDW_SHIM_SYNC_SYNCGO);
	if (ret < 0)
		dev_err(sdw->cdns.dev, "Post bank switch failed: %d", ret);

	return ret;
}

/*
 * DAI routines
 */
@@ -750,6 +813,8 @@ static struct sdw_master_ops sdw_intel_ops = {
	.xfer_msg_defer = cdns_xfer_msg_defer,
	.reset_page_addr = cdns_reset_page_addr,
	.set_bus_conf = cdns_bus_conf,
	.pre_bank_switch = intel_pre_bank_switch,
	.post_bank_switch = intel_post_bank_switch,
};

/*