mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
Soundwire: stream: program BUSCLOCK_SCALE
We need to program bus clock scale to adjust the bus clock if current bus clock doesn't fit the bandwidth. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Link: https://lore.kernel.org/r/20241218080155.102405-8-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
8f4e3343ed
commit
645291cfe5
3 changed files with 47 additions and 0 deletions
|
|
@ -813,6 +813,16 @@ void sdw_extract_slave_id(struct sdw_bus *bus,
|
|||
}
|
||||
EXPORT_SYMBOL(sdw_extract_slave_id);
|
||||
|
||||
bool is_clock_scaling_supported_by_slave(struct sdw_slave *slave)
|
||||
{
|
||||
/*
|
||||
* Dynamic scaling is a defined by SDCA. However, some devices expose the class ID but
|
||||
* can't support dynamic scaling. We might need a quirk to handle such devices.
|
||||
*/
|
||||
return slave->id.class_id;
|
||||
}
|
||||
EXPORT_SYMBOL(is_clock_scaling_supported_by_slave);
|
||||
|
||||
static int sdw_program_device_num(struct sdw_bus *bus, bool *programmed)
|
||||
{
|
||||
u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};
|
||||
|
|
|
|||
|
|
@ -629,8 +629,44 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt)
|
|||
static int sdw_program_params(struct sdw_bus *bus, bool prepare)
|
||||
{
|
||||
struct sdw_master_runtime *m_rt;
|
||||
struct sdw_slave *slave;
|
||||
int ret = 0;
|
||||
u32 addr1;
|
||||
|
||||
/* Check if all Peripherals comply with SDCA */
|
||||
list_for_each_entry(slave, &bus->slaves, node) {
|
||||
if (!slave->dev_num_sticky)
|
||||
continue;
|
||||
if (!is_clock_scaling_supported_by_slave(slave)) {
|
||||
dev_dbg(&slave->dev, "The Peripheral doesn't comply with SDCA\n");
|
||||
goto manager_runtime;
|
||||
}
|
||||
}
|
||||
|
||||
if (bus->params.next_bank)
|
||||
addr1 = SDW_SCP_BUSCLOCK_SCALE_B1;
|
||||
else
|
||||
addr1 = SDW_SCP_BUSCLOCK_SCALE_B0;
|
||||
|
||||
/* Program SDW_SCP_BUSCLOCK_SCALE if all Peripherals comply with SDCA */
|
||||
list_for_each_entry(slave, &bus->slaves, node) {
|
||||
int scale_index;
|
||||
u8 base;
|
||||
|
||||
if (!slave->dev_num_sticky)
|
||||
continue;
|
||||
scale_index = sdw_slave_get_scale_index(slave, &base);
|
||||
if (scale_index < 0)
|
||||
return scale_index;
|
||||
|
||||
ret = sdw_write_no_pm(slave, addr1, scale_index);
|
||||
if (ret < 0) {
|
||||
dev_err(&slave->dev, "SDW_SCP_BUSCLOCK_SCALE register write failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
manager_runtime:
|
||||
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1041,6 +1041,7 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus);
|
|||
|
||||
int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id);
|
||||
void sdw_extract_slave_id(struct sdw_bus *bus, u64 addr, struct sdw_slave_id *id);
|
||||
bool is_clock_scaling_supported_by_slave(struct sdw_slave *slave);
|
||||
|
||||
#if IS_ENABLED(CONFIG_SOUNDWIRE)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue