Skip to content

Commit

Permalink
Soundwire: stream: program BUSCLOCK_SCALE
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Bard Liao authored and Vinod Koul committed Dec 23, 2024
1 parent 8f4e334 commit 645291c
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
10 changes: 10 additions & 0 deletions drivers/soundwire/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
36 changes: 36 additions & 0 deletions drivers/soundwire/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

/*
Expand Down
1 change: 1 addition & 0 deletions include/linux/soundwire/sdw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit 645291c

Please sign in to comment.