Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pr5042 mod #5047

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions drivers/soundwire/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ static inline int do_transfer_defer(struct sdw_bus *bus,
enum sdw_command_response resp;
int ret = 0, i;

dev_warn(bus->dev, "%s\n", __func__);
defer->msg = msg;
defer->length = msg->len;
init_completion(&defer->complete);
Expand Down Expand Up @@ -292,12 +293,20 @@ int sdw_transfer(struct sdw_bus *bus, struct sdw_msg *msg)
{
int ret;

dev_warn(bus->dev, "%s: dev %d addr %#x flags %#x\n",
__func__, msg->dev_num, msg->addr, msg->flags);

mutex_lock(&bus->msg_lock);

dev_warn(bus->dev, "%s: after mutex\n", __func__);

ret = sdw_transfer_unlocked(bus, msg);

mutex_unlock(&bus->msg_lock);

dev_warn(bus->dev, "%s: done\n", __func__);


return ret;
}

Expand Down Expand Up @@ -1628,12 +1637,14 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
}

/* Read Intstat 1, Intstat 2 and Intstat 3 registers */
dev_warn(&slave->dev, "%s: before SDW_SCP_INT1 read\n", __func__);
ret = sdw_read_no_pm(slave, SDW_SCP_INT1);
if (ret < 0) {
dev_err(&slave->dev,
"SDW_SCP_INT1 read failed:%d\n", ret);
goto io_err;
}
dev_warn(&slave->dev, "%s: after SDW_SCP_INT1 read\n", __func__);
buf = ret;

ret = sdw_nread_no_pm(slave, SDW_SCP_INTSTAT2, 2, buf2);
Expand Down
69 changes: 65 additions & 4 deletions drivers/soundwire/cadence_master.c
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@ irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
return IRQ_NONE;

int_status = cdns_readl(cdns, CDNS_MCP_INTSTAT);
dev_warn(cdns->dev, "%s int_status %#x\n", __func__, int_status);

/* check for reserved values read as zero */
if (int_status & CDNS_MCP_INT_RESERVED)
Expand Down Expand Up @@ -1002,6 +1003,7 @@ static void cdns_update_slave_status_work(struct work_struct *work)
u32 slave0, slave1;
u64 slave_intstat;
u32 device0_status;
u32 mcp_int_mask;
int retry_count = 0;

/*
Expand Down Expand Up @@ -1068,8 +1070,12 @@ static void cdns_update_slave_status_work(struct work_struct *work)
}

/* unmask Slave interrupt now */
mcp_int_mask = CDNS_MCP_INT_SLAVE_MASK;
if (cdns->slave_alerts_disabled)
mcp_int_mask &= ~CDNS_MCP_INT_SLAVE_ALERT;

cdns_updatel(cdns, CDNS_MCP_INTMASK,
CDNS_MCP_INT_SLAVE_MASK, CDNS_MCP_INT_SLAVE_MASK);
CDNS_MCP_INT_SLAVE_MASK, mcp_int_mask);

}

Expand Down Expand Up @@ -1162,6 +1168,31 @@ static void cdns_enable_slave_interrupts(struct sdw_cdns *cdns, bool state)
cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
}

/**
* sdw_cdns_enable_slave_alerts() - Enable SDW slave alerts
* @cdns: Cadence instance
* @state: boolean for true/false
*/
void sdw_cdns_enable_slave_alerts(struct sdw_cdns *cdns, bool state)
{
u32 mask;

mask = cdns_readl(cdns, CDNS_MCP_INTMASK);
if (state)
mask |= CDNS_MCP_INT_SLAVE_ALERT;
else
mask &= ~CDNS_MCP_INT_SLAVE_ALERT;

cdns_writel(cdns, CDNS_MCP_INTMASK, mask);

cdns->slave_alerts_disabled = !state;

/* FIXME: for some reason this locks the device */
//if (!state)
// flush_work(&cdns->work);
}
EXPORT_SYMBOL(sdw_cdns_enable_slave_alerts);

/**
* sdw_cdns_enable_interrupt() - Enable SDW interrupts
* @cdns: Cadence instance
Expand Down Expand Up @@ -1347,6 +1378,31 @@ static void cdns_init_clock_ctrl(struct sdw_cdns *cdns)
cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, ssp_interval);
}

/**
* sdw_cdns_soft_reset() - Cadence soft-reset
* @cdns: Cadence instance
*/
int sdw_cdns_soft_reset(struct sdw_cdns *cdns)
{
int ret;

cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_SOFT_RST,
CDNS_MCP_CONTROL_SOFT_RST);

ret = cdns_config_update(cdns);
if (ret < 0) {
dev_err(cdns->dev, "%s: config update failed\n", __func__);
return ret;
}

ret = cdns_set_wait(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_SOFT_RST, 0);
if (ret < 0)
dev_err(cdns->dev, "Soft Reset timed out\n");

return ret;
}
EXPORT_SYMBOL(sdw_cdns_soft_reset);

/**
* sdw_cdns_init() - Cadence initialization
* @cdns: Cadence instance
Expand All @@ -1370,6 +1426,11 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
cdns_ip_updatel(cdns, CDNS_IP_MCP_CONTROL, CDNS_IP_MCP_CONTROL_CMD_ACCEPT,
CDNS_IP_MCP_CONTROL_CMD_ACCEPT);

/* disable wakeup */
cdns_ip_updatel(cdns, CDNS_IP_MCP_CONTROL,
CDNS_IP_MCP_CONTROL_BLOCK_WAKEUP,
0);

/* Configure mcp config */
val = cdns_readl(cdns, CDNS_MCP_CONFIG);

Expand Down Expand Up @@ -1688,9 +1749,6 @@ int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset)
{
int ret;

/* unmask Slave interrupts that were masked when stopping the clock */
cdns_enable_slave_interrupts(cdns, true);

ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
CDNS_MCP_CONTROL_CLK_STOP_CLR);
if (ret < 0) {
Expand Down Expand Up @@ -1728,6 +1786,9 @@ int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset)
dev_err(cdns->dev, "bus failed to exit clock stop %d\n", ret);
}

/* unmask Slave interrupts that were masked when stopping the clock */
cdns_enable_slave_interrupts(cdns, true);

return ret;
}
EXPORT_SYMBOL(sdw_cdns_clock_restart);
Expand Down
5 changes: 5 additions & 0 deletions drivers/soundwire/cadence_master.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ struct sdw_cdns {

u32 ip_offset;

bool slave_alerts_disabled;

/*
* The datasheet says the RX FIFO AVAIL can be 2 entries more
* than the FIFO capacity, so allow for this.
Expand Down Expand Up @@ -163,6 +165,7 @@ int sdw_cdns_probe(struct sdw_cdns *cdns);
irqreturn_t sdw_cdns_irq(int irq, void *dev_id);
irqreturn_t sdw_cdns_thread(int irq, void *dev_id);

int sdw_cdns_soft_reset(struct sdw_cdns *cdns);
int sdw_cdns_init(struct sdw_cdns *cdns);
int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
struct sdw_cdns_stream_config config);
Expand Down Expand Up @@ -202,4 +205,6 @@ void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string
void sdw_cdns_config_update(struct sdw_cdns *cdns);
int sdw_cdns_config_update_set_wait(struct sdw_cdns *cdns);

void sdw_cdns_enable_slave_alerts(struct sdw_cdns *cdns, bool state);

#endif /* __SDW_CADENCE_H */
13 changes: 13 additions & 0 deletions drivers/soundwire/intel_ace2x.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ static void intel_shim_vs_init(struct sdw_intel *sdw)
dodse = intel_prop->dodse;
dods = intel_prop->dods;

dev_dbg_once(sdw->cdns.dev, "%s: clde %#x doaise2 %#x dodse2 %#x clds %#x clss %#x\n",
__func__, clde, doaise2, dodse2, clds, clss);
dev_dbg_once(sdw->cdns.dev, "%s: doaise %#x doais %#x dodse %#x dods %#x\n",
__func__, doaise, doais, dodse, dods);

act = intel_readw(shim_vs, SDW_SHIM2_INTEL_VS_ACTMCTL);
u16p_replace_bits(&act, clde, SDW_SHIM3_INTEL_VS_ACTMCTL_CLDE);
u16p_replace_bits(&act, doaise2, SDW_SHIM3_INTEL_VS_ACTMCTL_DOAISE2);
Expand Down Expand Up @@ -222,19 +227,27 @@ static void intel_sync_arm(struct sdw_intel *sdw)

mutex_lock(sdw->link_res->shim_lock);

dev_info(sdw->cdns.dev, "%s: started\n", __func__);

hdac_bus_eml_sdw_sync_arm_unlocked(sdw->link_res->hbus, link_id);

dev_info(sdw->cdns.dev, "%s: done\n", __func__);

mutex_unlock(sdw->link_res->shim_lock);
}

static int intel_sync_go_unlocked(struct sdw_intel *sdw)
{
int ret;

dev_info(sdw->cdns.dev, "%s: started\n", __func__);

ret = hdac_bus_eml_sdw_sync_go_unlocked(sdw->link_res->hbus);
if (ret < 0)
dev_err(sdw->cdns.dev, "%s: SyncGO clear failed: %d\n", __func__, ret);

dev_info(sdw->cdns.dev, "%s: done\n", __func__);

return ret;
}

Expand Down
19 changes: 17 additions & 2 deletions drivers/soundwire/intel_bus_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ int intel_start_bus(struct sdw_intel *sdw)
struct sdw_bus *bus = &cdns->bus;
int ret;

ret = sdw_cdns_soft_reset(cdns);
if (ret < 0) {
dev_err(dev, "%s: unable to soft-reset Cadence IP: %d\n", __func__, ret);
return ret;
}

/*
* follow recommended programming flows to avoid timeouts when
* gsync is enabled
Expand Down Expand Up @@ -232,6 +238,8 @@ int intel_pre_bank_switch(struct sdw_intel *sdw)
if (!bus->multi_link)
return 0;

sdw_cdns_enable_slave_alerts(cdns, false);

sdw_intel_sync_arm(sdw);

return 0;
Expand All @@ -257,13 +265,20 @@ int intel_post_bank_switch(struct sdw_intel *sdw)
*
* So, set the SYNCGO bit only if CMDSYNC bit is set for any Master.
*/
if (sdw_intel_sync_check_cmdsync_unlocked(sdw))
if (sdw_intel_sync_check_cmdsync_unlocked(sdw)) {
ret = sdw_intel_sync_go_unlocked(sdw);

if (!ret) {
dev_info(sdw->cdns.dev, "%s: sync_go wait start\n", __func__);
usleep_range(2000, 2100);
dev_info(sdw->cdns.dev, "%s: sync_go wait done\n", __func__);
}
}
mutex_unlock(sdw->link_res->shim_lock);

if (ret < 0)
dev_err(sdw->cdns.dev, "Post bank switch failed: %d\n", ret);

sdw_cdns_enable_slave_alerts(cdns, true);

return ret;
}
19 changes: 17 additions & 2 deletions drivers/soundwire/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,8 @@ static int sdw_ml_sync_bank_switch(struct sdw_bus *bus, bool multi_link)
bus->bank_switch_timeout);

if (!time_left) {
dev_err(bus->dev, "Controller Timed out on bank switch\n");
dev_err(bus->dev, "%s: master %d:%d timed out on bank switch\n",
__func__, bus->controller_id, bus->link_id);
return -ETIMEDOUT;
}

Expand Down Expand Up @@ -1325,12 +1326,15 @@ static void sdw_acquire_bus_lock(struct sdw_stream_runtime *stream)
struct sdw_master_runtime *m_rt;
struct sdw_bus *bus;

pr_warn("%s: acquiring locks for stream %s\n", __func__, stream->name);

/* Iterate for all Master(s) in Master list */
list_for_each_entry(m_rt, &stream->master_list, stream_node) {
bus = m_rt->bus;

mutex_lock(&bus->bus_lock);
}
pr_warn("%s: acquired locks for stream %s\n", __func__, stream->name);
}

/**
Expand All @@ -1347,11 +1351,14 @@ static void sdw_release_bus_lock(struct sdw_stream_runtime *stream)
struct sdw_master_runtime *m_rt;
struct sdw_bus *bus;

pr_warn("%s: releasing locks for stream %s\n", __func__, stream->name);

/* Iterate for all Master(s) in Master list */
list_for_each_entry_reverse(m_rt, &stream->master_list, stream_node) {
bus = m_rt->bus;
mutex_unlock(&bus->bus_lock);
}
pr_warn("%s: released locks for stream %s\n", __func__, stream->name);
}

static int _sdw_prepare_stream(struct sdw_stream_runtime *stream,
Expand All @@ -1363,6 +1370,8 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream,
struct sdw_bus_params params;
int ret;

pr_warn("%s: start for stream %s\n", __func__, stream->name);

/* Prepare Master(s) and Slave(s) port(s) associated with stream */
list_for_each_entry(m_rt, &stream->master_list, stream_node) {
bus = m_rt->bus;
Expand Down Expand Up @@ -1400,12 +1409,16 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream,
}
}

pr_warn("%s: before bank switch for stream %s\n", __func__, stream->name);

ret = do_bank_switch(stream);
if (ret < 0) {
pr_err("%s: do_bank_switch failed: %d\n", __func__, ret);
pr_err("%s: do_bank_switch failed for stream %s: %d\n", __func__, stream->name, ret);
goto restore_params;
}

pr_warn("%s: after bank switch for stream %s\n", __func__, stream->name);

list_for_each_entry(m_rt, &stream->master_list, stream_node) {
bus = m_rt->bus;

Expand All @@ -1420,6 +1433,8 @@ static int _sdw_prepare_stream(struct sdw_stream_runtime *stream,

stream->state = SDW_STREAM_PREPARED;

pr_warn("%s: plb done for stream %s\n", __func__, stream->name);

return ret;

restore_params:
Expand Down
1 change: 1 addition & 0 deletions sound/soc/sof/intel/lnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ static void lnl_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable)
{
struct hdac_bus *bus = sof_to_bus(sdev);

dev_warn(sdev->dev, "%s enable? %d\n", __func__, enable);
hdac_bus_eml_enable_interrupt(bus, true, AZX_REG_ML_LEPTR_ID_SDW, enable);
}

Expand Down
Loading