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: Sanyog Kale <sanyog.r.kale@intel.com> Signed-off-by: Shreyas NC <shreyas.nc@intel.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Родитель
9b5c132a1e
Коммит
30246e2d78
|
@ -397,6 +397,69 @@ static int intel_config_stream(struct sdw_intel *sdw,
|
||||||
return -EIO;
|
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
|
* DAI routines
|
||||||
*/
|
*/
|
||||||
|
@ -750,6 +813,8 @@ static struct sdw_master_ops sdw_intel_ops = {
|
||||||
.xfer_msg_defer = cdns_xfer_msg_defer,
|
.xfer_msg_defer = cdns_xfer_msg_defer,
|
||||||
.reset_page_addr = cdns_reset_page_addr,
|
.reset_page_addr = cdns_reset_page_addr,
|
||||||
.set_bus_conf = cdns_bus_conf,
|
.set_bus_conf = cdns_bus_conf,
|
||||||
|
.pre_bank_switch = intel_pre_bank_switch,
|
||||||
|
.post_bank_switch = intel_post_bank_switch,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Загрузка…
Ссылка в новой задаче