mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
Soundwire: add sdw_slave_get_scale_index helper
Currently, we only set peripheral frequency when the peripheral is initialized. However, curr_dr_freq may change to get required bandwidth. For example, curr_dr_freq may increase from 4.8MHz to 9.6MHz when the 4th stream is opened. Add a helper to get the scale index so that we can get the scale index and program it. 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-7-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
fdd1faeeec
commit
8f4e3343ed
|
|
@ -1276,23 +1276,12 @@ int sdw_configure_dpn_intr(struct sdw_slave *slave,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int sdw_slave_set_frequency(struct sdw_slave *slave)
|
||||
int sdw_slave_get_scale_index(struct sdw_slave *slave, u8 *base)
|
||||
{
|
||||
u32 mclk_freq = slave->bus->prop.mclk_freq;
|
||||
u32 curr_freq = slave->bus->params.curr_dr_freq >> 1;
|
||||
unsigned int scale;
|
||||
u8 scale_index;
|
||||
u8 base;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* frequency base and scale registers are required for SDCA
|
||||
* devices. They may also be used for 1.2+/non-SDCA devices.
|
||||
* Driver can set the property, we will need a DisCo property
|
||||
* to discover this case from platform firmware.
|
||||
*/
|
||||
if (!slave->id.class_id && !slave->prop.clock_reg_supported)
|
||||
return 0;
|
||||
|
||||
if (!mclk_freq) {
|
||||
dev_err(&slave->dev,
|
||||
|
|
@ -1311,19 +1300,19 @@ static int sdw_slave_set_frequency(struct sdw_slave *slave)
|
|||
*/
|
||||
if (!(19200000 % mclk_freq)) {
|
||||
mclk_freq = 19200000;
|
||||
base = SDW_SCP_BASE_CLOCK_19200000_HZ;
|
||||
*base = SDW_SCP_BASE_CLOCK_19200000_HZ;
|
||||
} else if (!(22579200 % mclk_freq)) {
|
||||
mclk_freq = 22579200;
|
||||
base = SDW_SCP_BASE_CLOCK_22579200_HZ;
|
||||
*base = SDW_SCP_BASE_CLOCK_22579200_HZ;
|
||||
} else if (!(24576000 % mclk_freq)) {
|
||||
mclk_freq = 24576000;
|
||||
base = SDW_SCP_BASE_CLOCK_24576000_HZ;
|
||||
*base = SDW_SCP_BASE_CLOCK_24576000_HZ;
|
||||
} else if (!(32000000 % mclk_freq)) {
|
||||
mclk_freq = 32000000;
|
||||
base = SDW_SCP_BASE_CLOCK_32000000_HZ;
|
||||
*base = SDW_SCP_BASE_CLOCK_32000000_HZ;
|
||||
} else if (!(96000000 % mclk_freq)) {
|
||||
mclk_freq = 24000000;
|
||||
base = SDW_SCP_BASE_CLOCK_24000000_HZ;
|
||||
*base = SDW_SCP_BASE_CLOCK_24000000_HZ;
|
||||
} else {
|
||||
dev_err(&slave->dev,
|
||||
"Unsupported clock base, mclk %d\n",
|
||||
|
|
@ -1354,6 +1343,34 @@ static int sdw_slave_set_frequency(struct sdw_slave *slave)
|
|||
}
|
||||
scale_index++;
|
||||
|
||||
dev_dbg(&slave->dev,
|
||||
"Configured bus base %d, scale %d, mclk %d, curr_freq %d\n",
|
||||
*base, scale_index, mclk_freq, curr_freq);
|
||||
|
||||
return scale_index;
|
||||
}
|
||||
EXPORT_SYMBOL(sdw_slave_get_scale_index);
|
||||
|
||||
static int sdw_slave_set_frequency(struct sdw_slave *slave)
|
||||
{
|
||||
int scale_index;
|
||||
u8 base;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* frequency base and scale registers are required for SDCA
|
||||
* devices. They may also be used for 1.2+/non-SDCA devices.
|
||||
* Driver can set the property directly, for now there's no
|
||||
* DisCo property to discover support for the scaling registers
|
||||
* from platform firmware.
|
||||
*/
|
||||
if (!slave->id.class_id && !slave->prop.clock_reg_supported)
|
||||
return 0;
|
||||
|
||||
scale_index = sdw_slave_get_scale_index(slave, &base);
|
||||
if (scale_index < 0)
|
||||
return scale_index;
|
||||
|
||||
ret = sdw_write_no_pm(slave, SDW_SCP_BUS_CLOCK_BASE, base);
|
||||
if (ret < 0) {
|
||||
dev_err(&slave->dev,
|
||||
|
|
@ -1373,10 +1390,6 @@ static int sdw_slave_set_frequency(struct sdw_slave *slave)
|
|||
dev_err(&slave->dev,
|
||||
"SDW_SCP_BUSCLOCK_SCALE_B1 write failed:%d\n", ret);
|
||||
|
||||
dev_dbg(&slave->dev,
|
||||
"Configured bus base %d, scale %d, mclk %d, curr_freq %d\n",
|
||||
base, scale_index, mclk_freq, curr_freq);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1052,6 +1052,8 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
|
|||
int sdw_stream_remove_slave(struct sdw_slave *slave,
|
||||
struct sdw_stream_runtime *stream);
|
||||
|
||||
int sdw_slave_get_scale_index(struct sdw_slave *slave, u8 *base);
|
||||
|
||||
/* messaging and data APIs */
|
||||
int sdw_read(struct sdw_slave *slave, u32 addr);
|
||||
int sdw_write(struct sdw_slave *slave, u32 addr, u8 value);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user