Skip to content

Commit 27ab4f1

Browse files
vijendarmukundavinodkoul
authored andcommitted
soundwire: amd: refactor bandwidth calculation logic
For current platforms(ACP6.3/ACP7.0/ACP7.1/ACP7.2), AMD SoundWire manager doesn't have banked registers for data port programming on Manager's side. Need to use fixed block offsets, hstart & hstop for manager ports. Earlier amd manager driver has support for 12 MHz as a bus clock frequency where frame rate is 48000 and number of bits is 500, frame shape as 50 x 10 with fixed block offset mapping based on port number. Got a new requirement to support 6 MHz as a bus clock frequency. For 6 MHz bus clock frequency amd manager driver needs to support two different frame shapes i.e number of bits as 250 with frame rate as 48000 and frame shape as 125 x 2 and for the second combination number of bits as 500 where frame rate is 24000 and frame shape is 50 x 10. Few SoundWire peripherals doesn't support 125 x 2 as a frame shape for 6 MHz bus clock frequency. They have explicit requirement for the frame shape. In this scenario, amd manager driver needs to use 50 x 10 as a frame shape where frame rate is 24000. Based on the platform and SoundWire topology for 6Mhz support frame shape will be decided which is part of SoundWire manager DisCo tables. For current platforms, amd manager driver supports only two bus clock frequencies(12 MHz & 6 MHz). Refactor bandwidth logic to support different bus clock frequencies. Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev> Link: https://patch.msgid.link/20260226065638.1251771-3-Vijendar.Mukunda@amd.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent 2a267a8 commit 27ab4f1

2 files changed

Lines changed: 57 additions & 4 deletions

File tree

drivers/soundwire/amd_manager.c

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -467,12 +467,16 @@ static u32 amd_sdw_read_ping_status(struct sdw_bus *bus)
467467

468468
static int amd_sdw_compute_params(struct sdw_bus *bus, struct sdw_stream_runtime *stream)
469469
{
470+
struct amd_sdw_manager *amd_manager = to_amd_sdw(bus);
470471
struct sdw_transport_data t_data = {0};
471472
struct sdw_master_runtime *m_rt;
472473
struct sdw_port_runtime *p_rt;
473474
struct sdw_bus_params *b_params = &bus->params;
474475
int port_bo, hstart, hstop, sample_int;
475-
unsigned int rate, bps;
476+
unsigned int rate, bps, channels;
477+
unsigned int stream_slot_size, max_slots;
478+
static unsigned int next_offset[AMD_SDW_MAX_MANAGER_COUNT] = {1};
479+
unsigned int inst_id = amd_manager->instance;
476480

477481
port_bo = 0;
478482
hstart = 1;
@@ -483,11 +487,51 @@ static int amd_sdw_compute_params(struct sdw_bus *bus, struct sdw_stream_runtime
483487
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
484488
rate = m_rt->stream->params.rate;
485489
bps = m_rt->stream->params.bps;
490+
channels = m_rt->stream->params.ch_count;
486491
sample_int = (bus->params.curr_dr_freq / rate);
492+
493+
/* Compute slots required for this stream dynamically */
494+
stream_slot_size = bps * channels;
495+
487496
list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
488-
port_bo = (p_rt->num * 64) + 1;
489-
dev_dbg(bus->dev, "p_rt->num=%d hstart=%d hstop=%d port_bo=%d\n",
490-
p_rt->num, hstart, hstop, port_bo);
497+
if (p_rt->num >= amd_manager->max_ports) {
498+
dev_err(bus->dev, "Port %d exceeds max ports %d\n",
499+
p_rt->num, amd_manager->max_ports);
500+
return -EINVAL;
501+
}
502+
503+
if (!amd_manager->port_offset_map[p_rt->num]) {
504+
/*
505+
* port block offset calculation for 6MHz bus clock frequency with
506+
* different frame sizes 50 x 10 and 125 x 2
507+
*/
508+
if (bus->params.curr_dr_freq == 12000000) {
509+
max_slots = bus->params.row * (bus->params.col - 1);
510+
if (next_offset[inst_id] + stream_slot_size <=
511+
(max_slots - 1)) {
512+
amd_manager->port_offset_map[p_rt->num] =
513+
next_offset[inst_id];
514+
next_offset[inst_id] += stream_slot_size;
515+
} else {
516+
dev_err(bus->dev,
517+
"No space for port %d\n", p_rt->num);
518+
return -ENOMEM;
519+
}
520+
} else {
521+
/*
522+
* port block offset calculation for 12MHz bus clock
523+
* frequency
524+
*/
525+
amd_manager->port_offset_map[p_rt->num] =
526+
(p_rt->num * 64) + 1;
527+
}
528+
}
529+
port_bo = amd_manager->port_offset_map[p_rt->num];
530+
dev_dbg(bus->dev,
531+
"Port=%d hstart=%d hstop=%d port_bo=%d slots=%d max_ports=%d\n",
532+
p_rt->num, hstart, hstop, port_bo, stream_slot_size,
533+
amd_manager->max_ports);
534+
491535
sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
492536
false, SDW_BLK_GRP_CNT_1, sample_int,
493537
port_bo, port_bo >> 8, hstart, hstop,
@@ -1079,6 +1123,11 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
10791123
default:
10801124
return -EINVAL;
10811125
}
1126+
amd_manager->max_ports = amd_manager->num_dout_ports + amd_manager->num_din_ports;
1127+
amd_manager->port_offset_map = devm_kcalloc(dev, amd_manager->max_ports,
1128+
sizeof(int), GFP_KERNEL);
1129+
if (!amd_manager->port_offset_map)
1130+
return -ENOMEM;
10821131

10831132
prop = &amd_manager->bus.prop;
10841133
prop->mclk_freq = AMD_SDW_BUS_BASE_FREQ;

include/linux/soundwire/sdw_amd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ struct sdw_amd_dai_runtime {
6666
* @status: peripheral devices status array
6767
* @num_din_ports: number of input ports
6868
* @num_dout_ports: number of output ports
69+
* @max_ports: total number of input ports and output ports
6970
* @cols_index: Column index in frame shape
7071
* @rows_index: Rows index in frame shape
72+
* @port_offset_map: dynamic array to map port block offset
7173
* @instance: SoundWire manager instance
7274
* @quirks: SoundWire manager quirks
7375
* @wake_en_mask: wake enable mask per SoundWire manager
@@ -92,10 +94,12 @@ struct amd_sdw_manager {
9294

9395
int num_din_ports;
9496
int num_dout_ports;
97+
int max_ports;
9598

9699
int cols_index;
97100
int rows_index;
98101

102+
int *port_offset_map;
99103
u32 instance;
100104
u32 quirks;
101105
u32 wake_en_mask;

0 commit comments

Comments
 (0)