Skip to content

Commit 645291c

Browse files
bardliaovinodkoul
authored andcommitted
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>
1 parent 8f4e334 commit 645291c

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

drivers/soundwire/bus.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,16 @@ void sdw_extract_slave_id(struct sdw_bus *bus,
813813
}
814814
EXPORT_SYMBOL(sdw_extract_slave_id);
815815

816+
bool is_clock_scaling_supported_by_slave(struct sdw_slave *slave)
817+
{
818+
/*
819+
* Dynamic scaling is a defined by SDCA. However, some devices expose the class ID but
820+
* can't support dynamic scaling. We might need a quirk to handle such devices.
821+
*/
822+
return slave->id.class_id;
823+
}
824+
EXPORT_SYMBOL(is_clock_scaling_supported_by_slave);
825+
816826
static int sdw_program_device_num(struct sdw_bus *bus, bool *programmed)
817827
{
818828
u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};

drivers/soundwire/stream.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,8 +629,44 @@ static int sdw_notify_config(struct sdw_master_runtime *m_rt)
629629
static int sdw_program_params(struct sdw_bus *bus, bool prepare)
630630
{
631631
struct sdw_master_runtime *m_rt;
632+
struct sdw_slave *slave;
632633
int ret = 0;
634+
u32 addr1;
635+
636+
/* Check if all Peripherals comply with SDCA */
637+
list_for_each_entry(slave, &bus->slaves, node) {
638+
if (!slave->dev_num_sticky)
639+
continue;
640+
if (!is_clock_scaling_supported_by_slave(slave)) {
641+
dev_dbg(&slave->dev, "The Peripheral doesn't comply with SDCA\n");
642+
goto manager_runtime;
643+
}
644+
}
645+
646+
if (bus->params.next_bank)
647+
addr1 = SDW_SCP_BUSCLOCK_SCALE_B1;
648+
else
649+
addr1 = SDW_SCP_BUSCLOCK_SCALE_B0;
650+
651+
/* Program SDW_SCP_BUSCLOCK_SCALE if all Peripherals comply with SDCA */
652+
list_for_each_entry(slave, &bus->slaves, node) {
653+
int scale_index;
654+
u8 base;
655+
656+
if (!slave->dev_num_sticky)
657+
continue;
658+
scale_index = sdw_slave_get_scale_index(slave, &base);
659+
if (scale_index < 0)
660+
return scale_index;
661+
662+
ret = sdw_write_no_pm(slave, addr1, scale_index);
663+
if (ret < 0) {
664+
dev_err(&slave->dev, "SDW_SCP_BUSCLOCK_SCALE register write failed\n");
665+
return ret;
666+
}
667+
}
633668

669+
manager_runtime:
634670
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
635671

636672
/*

include/linux/soundwire/sdw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,7 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus);
10411041

10421042
int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id);
10431043
void sdw_extract_slave_id(struct sdw_bus *bus, u64 addr, struct sdw_slave_id *id);
1044+
bool is_clock_scaling_supported_by_slave(struct sdw_slave *slave);
10441045

10451046
#if IS_ENABLED(CONFIG_SOUNDWIRE)
10461047

0 commit comments

Comments
 (0)