Skip to content

Commit

Permalink
Merge remote-tracking branch 'sof/integration/soundwire-debug-fixes' …
Browse files Browse the repository at this point in the history
…into integration/soundwire-latest

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
  • Loading branch information
plbossart committed Jan 8, 2020
2 parents 9a4f5e2 + 10a651d commit 07348fa
Show file tree
Hide file tree
Showing 10 changed files with 668 additions and 51 deletions.
4 changes: 4 additions & 0 deletions drivers/soundwire/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,15 @@ config SOUNDWIRE_CADENCE
config SOUNDWIRE_INTEL
tristate "Intel SoundWire Master driver"
select SOUNDWIRE_CADENCE
select SOUNDWIRE_GENERIC_ALLOCATION
depends on ACPI && SND_SOC
help
SoundWire Intel Master driver.
If you have an Intel platform which has a SoundWire Master then
enable this config option to get the SoundWire support for that
device.

config SOUNDWIRE_GENERIC_ALLOCATION
tristate

endif
4 changes: 4 additions & 0 deletions drivers/soundwire/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
#
# Makefile for soundwire core
#
ccflags-y += -DDEBUG

#Bus Objs
soundwire-bus-objs := bus_type.o bus.o master.o slave.o mipi_disco.o stream.o
obj-$(CONFIG_SOUNDWIRE) += soundwire-bus.o

soundwire-generic-allocation-objs := generic_bandwidth_allocation.o
obj-$(CONFIG_SOUNDWIRE_GENERIC_ALLOCATION) += soundwire-generic-allocation.o

ifdef CONFIG_DEBUG_FS
soundwire-bus-objs += debugfs.o
endif
Expand Down
96 changes: 73 additions & 23 deletions drivers/soundwire/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ int sdw_add_bus_master(struct sdw_bus *bus)
return -EINVAL;
}

if (!bus->compute_params) {
dev_err(bus->dev,
"Bandwidth allocation not configured, compute_parems no set\n");
return -EINVAL;
}

mutex_init(&bus->msg_lock);
mutex_init(&bus->bus_lock);
INIT_LIST_HEAD(&bus->slaves);
Expand Down Expand Up @@ -541,27 +547,42 @@ static int sdw_get_device_num(struct sdw_slave *slave)
static int sdw_assign_device_num(struct sdw_slave *slave)
{
int ret, dev_num;
bool new_device = false;

dev_dbg(slave->bus->dev, "in %s\n", __func__);


dev_dbg(slave->bus->dev, "in %s\n", __func__);

/* check first if device number is assigned, if so reuse that */
if (!slave->dev_num) {
mutex_lock(&slave->bus->bus_lock);
dev_num = sdw_get_device_num(slave);
mutex_unlock(&slave->bus->bus_lock);
if (dev_num < 0) {
dev_err(slave->bus->dev, "Get dev_num failed: %d\n",
dev_num);
return dev_num;
if (!slave->dev_num_sticky) {
mutex_lock(&slave->bus->bus_lock);
dev_num = sdw_get_device_num(slave);
mutex_unlock(&slave->bus->bus_lock);
if (dev_num < 0) {
dev_err(slave->bus->dev, "Get dev_num failed: %d\n",
dev_num);
return dev_num;
}
slave->dev_num = dev_num;
slave->dev_num_sticky = dev_num;
new_device = true;
} else {
slave->dev_num = slave->dev_num_sticky;
}
} else {
}

if (!new_device)
dev_info(slave->bus->dev,
"Slave already registered dev_num:%d\n",
"Slave already registered, reusing dev_num:%d\n",
slave->dev_num);

/* Clear the slave->dev_num to transfer message on device 0 */
dev_num = slave->dev_num;
slave->dev_num = 0;
}
/* Clear the slave->dev_num to transfer message on device 0 */
dev_num = slave->dev_num;
slave->dev_num = 0;

dev_dbg(slave->bus->dev, "in %s, writing dev_num %d\n", __func__, dev_num);
ret = sdw_write_no_pm(slave, SDW_SCP_DEVNUMBER, dev_num);
if (ret < 0) {
dev_err(&slave->dev, "Program device_num %d failed: %d\n",
Expand All @@ -570,7 +591,7 @@ static int sdw_assign_device_num(struct sdw_slave *slave)
}

/* After xfer of msg, restore dev_num */
slave->dev_num = dev_num;
slave->dev_num = slave->dev_num_sticky;

return 0;
}
Expand Down Expand Up @@ -679,6 +700,8 @@ static int sdw_program_device_num(struct sdw_bus *bus)

} while (ret == 0 && count < (SDW_MAX_DEVICES * 2));

dev_err(bus->dev, "End of %s ret %d\n", __func__, ret);

return ret;
}

Expand All @@ -687,7 +710,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
{
mutex_lock(&slave->bus->bus_lock);

dev_vdbg(&slave->dev,
dev_dbg(&slave->dev,
"%s: changing status slave %d status %d new status %d\n",
__func__, slave->dev_num, slave->status, status);

Expand Down Expand Up @@ -1226,22 +1249,31 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
bool slave_notify = false;
u8 buf, buf2[2], _buf, _buf2[2];

dev_dbg(slave->bus->dev, "%s: start\n", __func__);

sdw_modify_slave_status(slave, SDW_SLAVE_ALERT);

ret = pm_runtime_get_sync(&slave->dev);
if (ret < 0 && ret != -EACCES) {
dev_err(&slave->dev, "Failed to resume device: %d\n", ret);
pm_runtime_put_noidle(slave->bus->dev);
return ret;
}

/* Read Instat 1, Instat 2 and Instat 3 registers */
ret = sdw_read(slave, SDW_SCP_INT1);
if (ret < 0) {
dev_err(slave->bus->dev,
"SDW_SCP_INT1 read failed:%d\n", ret);
return ret;
goto io_err;
}
buf = ret;

ret = sdw_nread(slave, SDW_SCP_INTSTAT2, 2, buf2);
if (ret < 0) {
dev_err(slave->bus->dev,
"SDW_SCP_INT2/3 read failed:%d\n", ret);
return ret;
goto io_err;
}

do {
Expand Down Expand Up @@ -1321,7 +1353,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
if (ret < 0) {
dev_err(slave->bus->dev,
"SDW_SCP_INT1 write failed:%d\n", ret);
return ret;
goto io_err;
}

/*
Expand All @@ -1332,15 +1364,15 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
if (ret < 0) {
dev_err(slave->bus->dev,
"SDW_SCP_INT1 read failed:%d\n", ret);
return ret;
goto io_err;
}
_buf = ret;

ret = sdw_nread(slave, SDW_SCP_INTSTAT2, 2, _buf2);
if (ret < 0) {
dev_err(slave->bus->dev,
"SDW_SCP_INT2/3 read failed:%d\n", ret);
return ret;
goto io_err;
}

/* Make sure no interrupts are pending */
Expand All @@ -1361,6 +1393,12 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
if (count == SDW_READ_INTR_CLEAR_RETRY)
dev_warn(slave->bus->dev, "Reached MAX_RETRY on alert read\n");

io_err:
pm_runtime_mark_last_busy(&slave->dev);
pm_runtime_put_autosuspend(&slave->dev);

dev_dbg(slave->bus->dev, "%s: end\n", __func__);

return ret;
}

Expand Down Expand Up @@ -1405,6 +1443,8 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
bool attached_initializing;
int i, ret = 0;

dev_dbg(bus->dev, "%s: start\n", __func__);

/* first check if any Slaves fell off the bus */
for (i = 1; i <= SDW_MAX_DEVICES; i++) {
mutex_lock(&bus->bus_lock);
Expand Down Expand Up @@ -1467,14 +1507,17 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
break;

case SDW_SLAVE_ATTACHED:
if (slave->status == SDW_SLAVE_ATTACHED)
if (slave->status == SDW_SLAVE_ATTACHED) {
dev_err(bus->dev, "Slave %d status attached, was already attached, ignoring\n", i);
break;

}
prev_status = slave->status;
sdw_modify_slave_status(slave, SDW_SLAVE_ATTACHED);

if (prev_status == SDW_SLAVE_ALERT)
if (prev_status == SDW_SLAVE_ALERT) {
dev_err(bus->dev, "Slave %d status attached, was alert, ignoring\n", i);
break;
}

attached_initializing = true;

Expand All @@ -1492,14 +1535,21 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
break;
}

dev_err(bus->dev, "Updating Slave %d status\n", i);
ret = sdw_update_slave_status(slave, status[i]);
if (ret)
dev_err(slave->bus->dev,
"Update Slave status failed:%d\n", ret);

if (attached_initializing)
complete(&slave->initialization_complete);

dev_err(bus->dev, "%s: Updating Slave %d status done\n",
__func__, i);
}

dev_dbg(bus->dev, "%s: end\n", __func__);

return ret;
}
EXPORT_SYMBOL(sdw_handle_slave_status);
Expand Down
46 changes: 44 additions & 2 deletions drivers/soundwire/bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct sdw_msg {
};

#define SDW_DOUBLE_RATE_FACTOR 2
#define SDW_STRM_RATE_GROUPING 1

extern int sdw_rows[SDW_FRAME_ROWS];
extern int sdw_cols[SDW_FRAME_COLS];
Expand Down Expand Up @@ -153,9 +154,50 @@ int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg,
int sdw_fill_msg(struct sdw_msg *msg, struct sdw_slave *slave,
u32 addr, size_t count, u16 dev_num, u8 flags, u8 *buf);

/* Retrieve and return channel count from channel mask */
static inline int sdw_ch_mask_to_ch(int ch_mask)
{
int c = 0;

for (c = 0; ch_mask; ch_mask >>= 1)
c += ch_mask & 1;

return c;
}

/* Fill transport parameter data structure */
static inline void sdw_fill_xport_params(struct sdw_transport_params *params,
int port_num, bool grp_ctrl_valid,
int grp_ctrl, int sample_int,
int off1, int off2,
int hstart, int hstop,
int pack_mode, int lane_ctrl)
{
params->port_num = port_num;
params->blk_grp_ctrl_valid = grp_ctrl_valid;
params->blk_grp_ctrl = grp_ctrl;
params->sample_interval = sample_int;
params->offset1 = off1;
params->offset2 = off2;
params->hstart = hstart;
params->hstop = hstop;
params->blk_pkg_mode = pack_mode;
params->lane_ctrl = lane_ctrl;
}

/* Fill port parameter data structure */
static inline void sdw_fill_port_params(struct sdw_port_params *params,
int port_num, int bps,
int flow_mode, int data_mode)
{
params->num = port_num;
params->bps = bps;
params->flow_mode = flow_mode;
params->data_mode = data_mode;
}

/* Read-Modify-Write Slave register */
static inline int
sdw_update(struct sdw_slave *slave, u32 addr, u8 mask, u8 val)
static inline int sdw_update(struct sdw_slave *slave, u32 addr, u8 mask, u8 val)
{
int tmp;

Expand Down
Loading

0 comments on commit 07348fa

Please sign in to comment.