Skip to content

Commit cff18e2

Browse files
committed
Merge remote-tracking branch 'soundwire/next' into sound/upstream-20260402
2 parents 5f752da + b8f2d65 commit cff18e2

10 files changed

Lines changed: 138 additions & 36 deletions

File tree

drivers/soundwire/amd_manager.c

Lines changed: 89 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,36 @@
2727

2828
#define to_amd_sdw(b) container_of(b, struct amd_sdw_manager, bus)
2929

30+
static int amd_sdw_clk_init_ctrl(struct amd_sdw_manager *amd_manager)
31+
{
32+
struct sdw_bus *bus = &amd_manager->bus;
33+
struct sdw_master_prop *prop = &bus->prop;
34+
u32 divider;
35+
36+
dev_dbg(amd_manager->dev, "mclk %d max %d row %d col %d frame_rate:%d\n",
37+
prop->mclk_freq, prop->max_clk_freq, prop->default_row,
38+
prop->default_col, prop->default_frame_rate);
39+
40+
if (!prop->default_frame_rate || !prop->default_row) {
41+
dev_err(amd_manager->dev, "Default frame_rate %d or row %d is invalid\n",
42+
prop->default_frame_rate, prop->default_row);
43+
return -EINVAL;
44+
}
45+
46+
/* Set clock divider */
47+
divider = (prop->mclk_freq / bus->params.curr_dr_freq);
48+
writel(divider, amd_manager->mmio + ACP_SW_CLK_FREQUENCY_CTRL);
49+
50+
/* Set frame shape base on the actual bus frequency. */
51+
prop->default_col = bus->params.curr_dr_freq /
52+
prop->default_frame_rate / prop->default_row;
53+
amd_manager->cols_index = sdw_find_col_index(prop->default_col);
54+
amd_manager->rows_index = sdw_find_row_index(prop->default_row);
55+
bus->params.col = prop->default_col;
56+
bus->params.row = prop->default_row;
57+
return 0;
58+
}
59+
3060
static int amd_init_sdw_manager(struct amd_sdw_manager *amd_manager)
3161
{
3262
u32 val;
@@ -437,12 +467,16 @@ static u32 amd_sdw_read_ping_status(struct sdw_bus *bus)
437467

438468
static int amd_sdw_compute_params(struct sdw_bus *bus, struct sdw_stream_runtime *stream)
439469
{
470+
struct amd_sdw_manager *amd_manager = to_amd_sdw(bus);
440471
struct sdw_transport_data t_data = {0};
441472
struct sdw_master_runtime *m_rt;
442473
struct sdw_port_runtime *p_rt;
443474
struct sdw_bus_params *b_params = &bus->params;
444475
int port_bo, hstart, hstop, sample_int;
445-
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;
446480

447481
port_bo = 0;
448482
hstart = 1;
@@ -453,11 +487,51 @@ static int amd_sdw_compute_params(struct sdw_bus *bus, struct sdw_stream_runtime
453487
list_for_each_entry(m_rt, &bus->m_rt_list, bus_node) {
454488
rate = m_rt->stream->params.rate;
455489
bps = m_rt->stream->params.bps;
490+
channels = m_rt->stream->params.ch_count;
456491
sample_int = (bus->params.curr_dr_freq / rate);
492+
493+
/* Compute slots required for this stream dynamically */
494+
stream_slot_size = bps * channels;
495+
457496
list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
458-
port_bo = (p_rt->num * 64) + 1;
459-
dev_dbg(bus->dev, "p_rt->num=%d hstart=%d hstop=%d port_bo=%d\n",
460-
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+
461535
sdw_fill_xport_params(&p_rt->transport_params, p_rt->num,
462536
false, SDW_BLK_GRP_CNT_1, sample_int,
463537
port_bo, port_bo >> 8, hstart, hstop,
@@ -960,6 +1034,9 @@ int amd_sdw_manager_start(struct amd_sdw_manager *amd_manager)
9601034

9611035
prop = &amd_manager->bus.prop;
9621036
if (!prop->hw_disabled) {
1037+
ret = amd_sdw_clk_init_ctrl(amd_manager);
1038+
if (ret)
1039+
return ret;
9631040
ret = amd_init_sdw_manager(amd_manager);
9641041
if (ret)
9651042
return ret;
@@ -984,7 +1061,6 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
9841061
struct resource *res;
9851062
struct device *dev = &pdev->dev;
9861063
struct sdw_master_prop *prop;
987-
struct sdw_bus_params *params;
9881064
struct amd_sdw_manager *amd_manager;
9891065
int ret;
9901066

@@ -1047,15 +1123,14 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
10471123
default:
10481124
return -EINVAL;
10491125
}
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;
10501131

1051-
params = &amd_manager->bus.params;
1052-
1053-
params->col = AMD_SDW_DEFAULT_COLUMNS;
1054-
params->row = AMD_SDW_DEFAULT_ROWS;
10551132
prop = &amd_manager->bus.prop;
1056-
prop->clk_freq = &amd_sdw_freq_tbl[0];
10571133
prop->mclk_freq = AMD_SDW_BUS_BASE_FREQ;
1058-
prop->max_clk_freq = AMD_SDW_DEFAULT_CLK_FREQ;
10591134

10601135
ret = sdw_bus_master_add(&amd_manager->bus, dev, dev->fwnode);
10611136
if (ret) {
@@ -1347,6 +1422,9 @@ static int __maybe_unused amd_resume_runtime(struct device *dev)
13471422
}
13481423
}
13491424
sdw_clear_slave_status(bus, SDW_UNATTACH_REQUEST_MASTER_RESET);
1425+
ret = amd_sdw_clk_init_ctrl(amd_manager);
1426+
if (ret)
1427+
return ret;
13501428
amd_init_sdw_manager(amd_manager);
13511429
amd_enable_sdw_interrupts(amd_manager);
13521430
ret = amd_enable_sdw_manager(amd_manager);

drivers/soundwire/amd_manager.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,6 @@
203203
#define AMD_SDW_DEVICE_STATE_D3 3
204204
#define ACP_PME_EN 0x0001400
205205

206-
static u32 amd_sdw_freq_tbl[AMD_SDW_MAX_FREQ_NUM] = {
207-
AMD_SDW_DEFAULT_CLK_FREQ,
208-
};
209-
210206
struct sdw_manager_dp_reg {
211207
u32 frame_fmt_reg;
212208
u32 sample_int_reg;

drivers/soundwire/bus.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,8 +1899,8 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
18991899

19001900
if (status[i] == SDW_SLAVE_UNATTACHED &&
19011901
slave->status != SDW_SLAVE_UNATTACHED) {
1902-
dev_warn(&slave->dev, "Slave %d state check1: UNATTACHED, status was %d\n",
1903-
i, slave->status);
1902+
dev_dbg(&slave->dev, "Slave %d state check1: UNATTACHED, status was %d\n",
1903+
i, slave->status);
19041904
sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
19051905

19061906
/* Ensure driver knows that peripheral unattached */
@@ -1951,8 +1951,8 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
19511951
if (slave->status == SDW_SLAVE_UNATTACHED)
19521952
break;
19531953

1954-
dev_warn(&slave->dev, "Slave %d state check2: UNATTACHED, status was %d\n",
1955-
i, slave->status);
1954+
dev_dbg(&slave->dev, "Slave %d state check2: UNATTACHED, status was %d\n",
1955+
i, slave->status);
19561956

19571957
sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
19581958
break;

drivers/soundwire/cadence_master.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,14 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
933933

934934
cdns_read_response(cdns);
935935

936+
/*
937+
* Clear interrupt before signalling the completion to avoid
938+
* a race between this thread and the main thread starting
939+
* another TX.
940+
*/
941+
cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_RX_WL);
942+
int_status &= ~CDNS_MCP_INT_RX_WL;
943+
936944
if (defer && defer->msg) {
937945
cdns_fill_msg_resp(cdns, defer->msg,
938946
defer->length, 0);

drivers/soundwire/intel_ace2x.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
8282
int len;
8383
int i;
8484

85+
if (cdns->bus.bpt_stream) {
86+
dev_err(cdns->dev, "%s: BPT stream already exists\n", __func__);
87+
return -EAGAIN;
88+
}
89+
8590
stream = sdw_alloc_stream("BPT", SDW_STREAM_BPT);
8691
if (!stream)
8792
return -ENOMEM;

drivers/soundwire/intel_auxdevice.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ struct wake_capable_part {
5353
static struct wake_capable_part wake_capable_list[] = {
5454
{0x01fa, 0x4243},
5555
{0x01fa, 0x4245},
56+
{0x01fa, 0x4249},
57+
{0x01fa, 0x4747},
5658
{0x025d, 0x5682},
5759
{0x025d, 0x700},
5860
{0x025d, 0x711},

drivers/soundwire/slave.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ static bool find_slave(struct sdw_bus *bus,
115115
u64 addr;
116116
int ret;
117117

118+
if (acpi_bus_get_status(adev) || !acpi_dev_ready_for_enumeration(adev))
119+
return false;
120+
118121
ret = acpi_get_local_u64_address(adev->handle, &addr);
119122
if (ret < 0)
120123
return false;

drivers/soundwire/stream.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/delay.h>
99
#include <linux/device.h>
1010
#include <linux/init.h>
11+
#include <linux/iopoll.h>
1112
#include <linux/module.h>
1213
#include <linux/mod_devicetable.h>
1314
#include <linux/slab.h>
@@ -18,6 +19,8 @@
1819
#include <sound/soc.h>
1920
#include "bus.h"
2021

22+
#define SDW_PORT_PREP_POLL_USEC 1000
23+
2124
/*
2225
* Array of supported rows and columns as per MIPI SoundWire Specification 1.1
2326
*
@@ -443,7 +446,6 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
443446
struct sdw_port_runtime *p_rt,
444447
bool prep)
445448
{
446-
struct completion *port_ready;
447449
struct sdw_dpn_prop *dpn_prop;
448450
struct sdw_prepare_ch prep_ch;
449451
u32 imp_def_interrupts;
@@ -518,14 +520,18 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
518520
return ret;
519521
}
520522

521-
/* Wait for completion on port ready */
522-
port_ready = &s_rt->slave->port_ready[prep_ch.num];
523-
wait_for_completion_timeout(port_ready,
524-
msecs_to_jiffies(ch_prep_timeout));
523+
/*
524+
* Poll for NOT_PREPARED==0. Cannot use the interrupt because
525+
* this code holds bus_lock which blocks interrupt handling.
526+
*/
527+
ret = read_poll_timeout(sdw_read_no_pm, val,
528+
(val < 0) || ((val & p_rt->ch_mask) == 0),
529+
SDW_PORT_PREP_POLL_USEC, ch_prep_timeout * USEC_PER_MSEC,
530+
false, s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num));
531+
if (ret || (val < 0)) {
532+
if (val < 0)
533+
ret = val;
525534

526-
val = sdw_read_no_pm(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num));
527-
if ((val < 0) || (val & p_rt->ch_mask)) {
528-
ret = (val < 0) ? val : -ETIMEDOUT;
529535
dev_err(&s_rt->slave->dev,
530536
"Chn prep failed for port %d: %d\n", prep_ch.num, ret);
531537
return ret;

include/linux/soundwire/sdw.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ struct sdw_slave_intr_status {
532532
};
533533

534534
/**
535-
* sdw_reg_bank - SoundWire register banks
535+
* enum sdw_reg_bank - SoundWire register banks
536536
* @SDW_BANK0: Soundwire register bank 0
537537
* @SDW_BANK1: Soundwire register bank 1
538538
*/
@@ -751,7 +751,7 @@ struct sdw_port_params {
751751
* struct sdw_transport_params: Data Port Transport Parameters
752752
*
753753
* @blk_grp_ctrl_valid: Port implements block group control
754-
* @num: Port number
754+
* @port_num: Port number
755755
* @blk_grp_ctrl: Block group control value
756756
* @sample_interval: Sample interval
757757
* @offset1: Blockoffset of the payload data
@@ -782,7 +782,7 @@ struct sdw_transport_params {
782782
/**
783783
* struct sdw_enable_ch: Enable/disable Data Port channel
784784
*
785-
* @num: Port number
785+
* @port_num: Port number
786786
* @ch_mask: Active channel mask
787787
* @enable: Enable (true) /disable (false) channel
788788
*/
@@ -885,7 +885,7 @@ void sdw_bus_master_delete(struct sdw_bus *bus);
885885
void sdw_show_ping_status(struct sdw_bus *bus, bool sync_delay);
886886

887887
/**
888-
* sdw_port_config: Master or Slave Port configuration
888+
* struct sdw_port_config: Master or Slave Port configuration
889889
*
890890
* @num: Port number
891891
* @ch_mask: channels mask for port
@@ -896,7 +896,7 @@ struct sdw_port_config {
896896
};
897897

898898
/**
899-
* sdw_stream_config: Master or Slave stream configuration
899+
* struct sdw_stream_config: Master or Slave stream configuration
900900
*
901901
* @frame_rate: Audio frame rate of the stream, in Hz
902902
* @ch_count: Channel count of the stream
@@ -913,7 +913,7 @@ struct sdw_stream_config {
913913
};
914914

915915
/**
916-
* sdw_stream_state: Stream states
916+
* enum sdw_stream_state: Stream states
917917
*
918918
* @SDW_STREAM_ALLOCATED: New stream allocated.
919919
* @SDW_STREAM_CONFIGURED: Stream configured
@@ -934,7 +934,7 @@ enum sdw_stream_state {
934934
};
935935

936936
/**
937-
* sdw_stream_params: Stream parameters
937+
* struct sdw_stream_params: Stream parameters
938938
*
939939
* @rate: Sampling frequency, in Hz
940940
* @ch_count: Number of channels
@@ -947,7 +947,7 @@ struct sdw_stream_params {
947947
};
948948

949949
/**
950-
* sdw_stream_runtime: Runtime stream parameters
950+
* struct sdw_stream_runtime: Runtime stream parameters
951951
*
952952
* @name: SoundWire stream name
953953
* @params: Stream parameters
@@ -983,7 +983,7 @@ struct sdw_stream_runtime {
983983
* @defer_msg: Defer message
984984
* @params: Current bus parameters
985985
* @stream_refcount: number of streams currently using this bus
986-
* @btp_stream_refcount: number of BTP streams currently using this bus (should
986+
* @bpt_stream_refcount: number of BTP streams currently using this bus (should
987987
* be zero or one, multiple streams per link is not supported).
988988
* @bpt_stream: pointer stored to handle BTP streams.
989989
* @ops: Master callback ops

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)