Skip to content

Commit

Permalink
Merge tag 'soundwire-6.14-rc1' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/vkoul/soundwire

Pull soundwire updates from Vinod Koul:

 - SoundWire multi lane support to use multiple lanes if supported

 - Stream handling of DEPREPARED state

 - AMD wake register programming for power off mode

* tag 'soundwire-6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire:
  soundwire: amd: clear wake enable register for power off mode
  soundwire: generic_bandwidth_allocation: count the bandwidth of active streams only
  SoundWire: pass stream to compute_params()
  soundwire: generic_bandwidth_allocation: add lane in sdw_group_params
  soundwire: generic_bandwidth_allocation: select data lane
  soundwire: generic_bandwidth_allocation: check required freq accurately
  soundwire: generic_bandwidth_allocation: correct clk_freq check in sdw_select_row_col
  Soundwire: generic_bandwidth_allocation: set frame shape on fly
  Soundwire: stream: program BUSCLOCK_SCALE
  Soundwire: add sdw_slave_get_scale_index helper
  soundwire: generic_bandwidth_allocation: skip DEPREPARED streams
  soundwire: stream: set DEPREPARED state earlier
  soundwire: add lane_used_bandwidth in struct sdw_bus
  soundwire: mipi_disco: read lane mapping properties from ACPI
  soundwire: add lane field in sdw_port_runtime
  soundwire: bus: Move irq mapping cleanup into devres
  • Loading branch information
torvalds committed Jan 29, 2025
2 parents 9f10e7f + 74148bb commit 72deda0
Show file tree
Hide file tree
Showing 11 changed files with 513 additions and 163 deletions.
5 changes: 3 additions & 2 deletions drivers/soundwire/amd_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ static u32 amd_sdw_read_ping_status(struct sdw_bus *bus)
return slave_stat;
}

static int amd_sdw_compute_params(struct sdw_bus *bus)
static int amd_sdw_compute_params(struct sdw_bus *bus, struct sdw_stream_runtime *stream)
{
struct sdw_transport_data t_data = {0};
struct sdw_master_runtime *m_rt;
Expand All @@ -410,7 +410,7 @@ static int amd_sdw_compute_params(struct sdw_bus *bus)
sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
false, SDW_BLK_GRP_CNT_1, sample_int,
port_bo, port_bo >> 8, hstart, hstop,
SDW_BLK_PKG_PER_PORT, 0x0);
SDW_BLK_PKG_PER_PORT, p_rt->lane);

sdw_fill_port_params(&p_rt->port_params,
p_rt->num, bps,
Expand Down Expand Up @@ -1190,6 +1190,7 @@ static int __maybe_unused amd_resume_runtime(struct device *dev)
if (amd_manager->power_mode_mask & AMD_SDW_CLK_STOP_MODE) {
return amd_sdw_clock_stop_exit(amd_manager);
} else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) {
writel(0x00, amd_manager->acp_mmio + ACP_SW_WAKE_EN(amd_manager->instance));
val = readl(amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL);
if (val) {
val |= AMD_SDW_CLK_RESUME_REQ;
Expand Down
65 changes: 44 additions & 21 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 Expand Up @@ -1276,23 +1286,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,
Expand All @@ -1311,19 +1310,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",
Expand Down Expand Up @@ -1354,6 +1353,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,
Expand All @@ -1373,10 +1400,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;
}

Expand Down
3 changes: 3 additions & 0 deletions drivers/soundwire/bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ int sdw_find_col_index(int col);
* @transport_params: Transport parameters
* @port_params: Port parameters
* @port_node: List node for Master or Slave port_list
* @lane: Which lane is used
*
* SoundWire spec has no mention of ports for Master interface but the
* concept is logically extended.
Expand All @@ -100,6 +101,7 @@ struct sdw_port_runtime {
struct sdw_transport_params transport_params;
struct sdw_port_params port_params;
struct list_head port_node;
unsigned int lane;
};

/**
Expand Down Expand Up @@ -149,6 +151,7 @@ struct sdw_transport_data {
int hstop;
int block_offset;
int sub_block_offset;
unsigned int lane;
};

struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave,
Expand Down
3 changes: 0 additions & 3 deletions drivers/soundwire/bus_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ static int sdw_drv_remove(struct device *dev)

slave->probed = false;

if (slave->prop.use_domain_irq)
sdw_irq_dispose_mapping(slave);

mutex_unlock(&slave->sdw_dev_lock);

if (drv->remove)
Expand Down
Loading

0 comments on commit 72deda0

Please sign in to comment.