soundwire updates for 6.1-rc1
- Pierre-Louis Bossart did another round of Intel driver cleanup to prepare for future code reorg which is expected in next cycle - Richard Fitzgerald provided bus unattach notifications processing during re-enumeration along with Cadence driver updates for this. - Srinivas Kandagatla added Qualcomm driver updates to handle device0 status -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmNAJmQACgkQfBQHDyUj g0eNjw//XQ/pkdB3MiRp6lmUv+99m15i2gzUgVQUKL+cKin5gN/prw8zYZHKcEHi FkTCUr4j06Q5LUIsmT1v0li4ZYVIaMbDB35IDRRPXKsXDHOzUmXLEeUFQln/HIo3 hYuftjjOhuCFvOBrLRMzp9dUtmjkjix8g0Sn63f/Xj7j+IbwSYlAeW1xkMfyzGkW 8Bp5TulkLwA1ce0JRnxMI7tijrYIfUmadvMGFOIgTwo0KgkbPUZgEQ2TN1p66FJf 20VmM4Uy7gnV7XxU1oDqfxeVRuRHz8ZZSpUU0mnnZWFkP2v00e/x7Jz/mzzZMceW aTlDCzJF6SlwaW1MyGkHEaypHtR9ZX8Ak+GFfBzYzzwGaNu8YS1745tI3JWGQ17U cvJonYwCWJI2+YmK1ei29vmX3Z/uCmpxQoxWYyqvDRNIln/2efoAf7SlewhV/sAO 2PZ6kJWGxxWjH6ckvjsqh2plgOt6itcyafKE/yHF9ApbSU4dqZj3lE2Ls2lBROom q591cenZ2VLFy2co894/TVHibyvBxBIO77uwKMH9pHMmD8FeWiAwoWuK3QM/uD4e zFmAyDbuZR4JW92jTNGya88VqYGeWzbq9xkY2DOlSbWBkVicZgPnF6pH8wBuudK6 SFbyo+Uo3WmplccgJHSer98ZRlhI8uQNPOvrxckQOXbYvVTIFvc= =CgPW -----END PGP SIGNATURE----- Merge tag 'soundwire-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire Pull soundwire updates from Vinod Koul: "Updates for Intel, Cadence and Qualcomm drivers: - another round of Intel driver cleanup to prepare for future code reorg which is expected in next cycle (Pierre-Louis Bossart) - bus unattach notifications processing during re-enumeration along with Cadence driver updates for this (Richard Fitzgerald) - Qualcomm driver updates to handle device0 status (Srinivas Kandagatla)" * tag 'soundwire-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/soundwire: (42 commits) soundwire: intel: add helper to stop bus soundwire: intel: introduce helpers to start bus soundwire: intel: introduce intel_shim_check_wake() helper soundwire: intel: simplify read ops assignment soundwire: intel: remove intel_init() wrapper soundwire: intel: move shim initialization before power up/down soundwire: intel: remove clock_stop parameter in intel_shim_init() soundwire: intel: move all PDI initialization under intel_register_dai() soundwire: intel: move DAI registration and debugfs init earlier soundwire: intel: simplify flow and use devm_ for DAI registration soundwire: intel: fix error handling on dai registration issues soundwire: cadence: Simplify error paths in cdns_xfer_msg() soundwire: cadence: Fix error check in cdns_xfer_msg() soundwire: cadence: Write to correct address for each FIFO chunk soundwire: bus: Fix wrong port number in sdw_handle_slave_alerts() soundwire: qcom: do not send status of device 0 during alert soundwire: qcom: update status from device id 1 soundwire: cadence: Don't overwrite msg->buf during write commands soundwire: bus: Don't exit early if no device IDs were programmed soundwire: cadence: Fix lost ATTACHED interrupts when enumerating ...
This commit is contained in:
commit
881eccbef5
|
@ -11,11 +11,12 @@
|
|||
#include "bus.h"
|
||||
#include "sysfs_local.h"
|
||||
|
||||
static DEFINE_IDA(sdw_ida);
|
||||
static DEFINE_IDA(sdw_bus_ida);
|
||||
static DEFINE_IDA(sdw_peripheral_ida);
|
||||
|
||||
static int sdw_get_id(struct sdw_bus *bus)
|
||||
{
|
||||
int rc = ida_alloc(&sdw_ida, GFP_KERNEL);
|
||||
int rc = ida_alloc(&sdw_bus_ida, GFP_KERNEL);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
@ -75,7 +76,6 @@ int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
|
|||
|
||||
/*
|
||||
* Initialize multi_link flag
|
||||
* TODO: populate this flag by reading property from FW node
|
||||
*/
|
||||
bus->multi_link = false;
|
||||
if (bus->ops->read_prop) {
|
||||
|
@ -157,9 +157,11 @@ static int sdw_delete_slave(struct device *dev, void *data)
|
|||
|
||||
mutex_lock(&bus->bus_lock);
|
||||
|
||||
if (slave->dev_num) /* clear dev_num if assigned */
|
||||
if (slave->dev_num) { /* clear dev_num if assigned */
|
||||
clear_bit(slave->dev_num, bus->assigned);
|
||||
|
||||
if (bus->dev_num_ida_min)
|
||||
ida_free(&sdw_peripheral_ida, slave->dev_num);
|
||||
}
|
||||
list_del_init(&slave->node);
|
||||
mutex_unlock(&bus->bus_lock);
|
||||
|
||||
|
@ -179,7 +181,7 @@ void sdw_bus_master_delete(struct sdw_bus *bus)
|
|||
sdw_master_device_del(bus);
|
||||
|
||||
sdw_bus_debugfs_exit(bus);
|
||||
ida_free(&sdw_ida, bus->id);
|
||||
ida_free(&sdw_bus_ida, bus->id);
|
||||
}
|
||||
EXPORT_SYMBOL(sdw_bus_master_delete);
|
||||
|
||||
|
@ -671,10 +673,18 @@ static int sdw_get_device_num(struct sdw_slave *slave)
|
|||
{
|
||||
int bit;
|
||||
|
||||
bit = find_first_zero_bit(slave->bus->assigned, SDW_MAX_DEVICES);
|
||||
if (bit == SDW_MAX_DEVICES) {
|
||||
bit = -ENODEV;
|
||||
goto err;
|
||||
if (slave->bus->dev_num_ida_min) {
|
||||
bit = ida_alloc_range(&sdw_peripheral_ida,
|
||||
slave->bus->dev_num_ida_min, SDW_MAX_DEVICES,
|
||||
GFP_KERNEL);
|
||||
if (bit < 0)
|
||||
goto err;
|
||||
} else {
|
||||
bit = find_first_zero_bit(slave->bus->assigned, SDW_MAX_DEVICES);
|
||||
if (bit == SDW_MAX_DEVICES) {
|
||||
bit = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -751,7 +761,7 @@ void sdw_extract_slave_id(struct sdw_bus *bus,
|
|||
}
|
||||
EXPORT_SYMBOL(sdw_extract_slave_id);
|
||||
|
||||
static int sdw_program_device_num(struct sdw_bus *bus)
|
||||
static int sdw_program_device_num(struct sdw_bus *bus, bool *programmed)
|
||||
{
|
||||
u8 buf[SDW_NUM_DEV_ID_REGISTERS] = {0};
|
||||
struct sdw_slave *slave, *_s;
|
||||
|
@ -761,6 +771,8 @@ static int sdw_program_device_num(struct sdw_bus *bus)
|
|||
int count = 0, ret;
|
||||
u64 addr;
|
||||
|
||||
*programmed = false;
|
||||
|
||||
/* No Slave, so use raw xfer api */
|
||||
ret = sdw_fill_msg(&msg, NULL, SDW_SCP_DEVID_0,
|
||||
SDW_NUM_DEV_ID_REGISTERS, 0, SDW_MSG_FLAG_READ, buf);
|
||||
|
@ -795,6 +807,16 @@ static int sdw_program_device_num(struct sdw_bus *bus)
|
|||
if (sdw_compare_devid(slave, id) == 0) {
|
||||
found = true;
|
||||
|
||||
/*
|
||||
* To prevent skipping state-machine stages don't
|
||||
* program a device until we've seen it UNATTACH.
|
||||
* Must return here because no other device on #0
|
||||
* can be detected until this one has been
|
||||
* assigned a device ID.
|
||||
*/
|
||||
if (slave->status != SDW_SLAVE_UNATTACHED)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Assign a new dev_num to this Slave and
|
||||
* not mark it present. It will be marked
|
||||
|
@ -809,6 +831,8 @@ static int sdw_program_device_num(struct sdw_bus *bus)
|
|||
return ret;
|
||||
}
|
||||
|
||||
*programmed = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -848,13 +872,13 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
|
|||
mutex_lock(&bus->bus_lock);
|
||||
|
||||
dev_vdbg(bus->dev,
|
||||
"%s: changing status slave %d status %d new status %d\n",
|
||||
__func__, slave->dev_num, slave->status, status);
|
||||
"changing status slave %d status %d new status %d\n",
|
||||
slave->dev_num, slave->status, status);
|
||||
|
||||
if (status == SDW_SLAVE_UNATTACHED) {
|
||||
dev_dbg(&slave->dev,
|
||||
"%s: initializing enumeration and init completion for Slave %d\n",
|
||||
__func__, slave->dev_num);
|
||||
"initializing enumeration and init completion for Slave %d\n",
|
||||
slave->dev_num);
|
||||
|
||||
init_completion(&slave->enumeration_complete);
|
||||
init_completion(&slave->initialization_complete);
|
||||
|
@ -862,8 +886,8 @@ static void sdw_modify_slave_status(struct sdw_slave *slave,
|
|||
} else if ((status == SDW_SLAVE_ATTACHED) &&
|
||||
(slave->status == SDW_SLAVE_UNATTACHED)) {
|
||||
dev_dbg(&slave->dev,
|
||||
"%s: signaling enumeration completion for Slave %d\n",
|
||||
__func__, slave->dev_num);
|
||||
"signaling enumeration completion for Slave %d\n",
|
||||
slave->dev_num);
|
||||
|
||||
complete(&slave->enumeration_complete);
|
||||
}
|
||||
|
@ -1630,7 +1654,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
|
|||
port = buf2[0] & SDW_SCP_INTSTAT2_PORT4_10;
|
||||
for_each_set_bit(bit, &port, 8) {
|
||||
/* scp2 ports start from 4 */
|
||||
port_num = bit + 3;
|
||||
port_num = bit + 4;
|
||||
sdw_handle_port_interrupt(slave,
|
||||
port_num,
|
||||
&port_status[port_num]);
|
||||
|
@ -1642,7 +1666,7 @@ static int sdw_handle_slave_alerts(struct sdw_slave *slave)
|
|||
port = buf2[1] & SDW_SCP_INTSTAT3_PORT11_14;
|
||||
for_each_set_bit(bit, &port, 8) {
|
||||
/* scp3 ports start from 11 */
|
||||
port_num = bit + 10;
|
||||
port_num = bit + 11;
|
||||
sdw_handle_port_interrupt(slave,
|
||||
port_num,
|
||||
&port_status[port_num]);
|
||||
|
@ -1768,7 +1792,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
|
|||
{
|
||||
enum sdw_slave_status prev_status;
|
||||
struct sdw_slave *slave;
|
||||
bool attached_initializing;
|
||||
bool attached_initializing, id_programmed;
|
||||
int i, ret = 0;
|
||||
|
||||
/* first check if any Slaves fell off the bus */
|
||||
|
@ -1789,19 +1813,33 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
|
|||
dev_warn(&slave->dev, "Slave %d state check1: UNATTACHED, status was %d\n",
|
||||
i, slave->status);
|
||||
sdw_modify_slave_status(slave, SDW_SLAVE_UNATTACHED);
|
||||
|
||||
/* Ensure driver knows that peripheral unattached */
|
||||
ret = sdw_update_slave_status(slave, status[i]);
|
||||
if (ret < 0)
|
||||
dev_warn(&slave->dev, "Update Slave status failed:%d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (status[0] == SDW_SLAVE_ATTACHED) {
|
||||
dev_dbg(bus->dev, "Slave attached, programming device number\n");
|
||||
ret = sdw_program_device_num(bus);
|
||||
if (ret < 0)
|
||||
dev_err(bus->dev, "Slave attach failed: %d\n", ret);
|
||||
|
||||
/*
|
||||
* programming a device number will have side effects,
|
||||
* so we deal with other devices at a later time
|
||||
* Programming a device number will have side effects,
|
||||
* so we deal with other devices at a later time.
|
||||
* This relies on those devices reporting ATTACHED, which will
|
||||
* trigger another call to this function. This will only
|
||||
* happen if at least one device ID was programmed.
|
||||
* Error returns from sdw_program_device_num() are currently
|
||||
* ignored because there's no useful recovery that can be done.
|
||||
* Returning the error here could result in the current status
|
||||
* of other devices not being handled, because if no device IDs
|
||||
* were programmed there's nothing to guarantee a status change
|
||||
* to trigger another call to this function.
|
||||
*/
|
||||
return ret;
|
||||
sdw_program_device_num(bus, &id_programmed);
|
||||
if (id_programmed)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Continue to check other slave statuses */
|
||||
|
@ -1870,8 +1908,8 @@ int sdw_handle_slave_status(struct sdw_bus *bus,
|
|||
"Update Slave status failed:%d\n", ret);
|
||||
if (attached_initializing) {
|
||||
dev_dbg(&slave->dev,
|
||||
"%s: signaling initialization completion for Slave %d\n",
|
||||
__func__, slave->dev_num);
|
||||
"signaling initialization completion for Slave %d\n",
|
||||
slave->dev_num);
|
||||
|
||||
complete(&slave->initialization_complete);
|
||||
|
||||
|
|
|
@ -544,9 +544,12 @@ cdns_fill_msg_resp(struct sdw_cdns *cdns,
|
|||
return SDW_CMD_IGNORED;
|
||||
}
|
||||
|
||||
/* fill response */
|
||||
for (i = 0; i < count; i++)
|
||||
msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA, cdns->response_buf[i]);
|
||||
if (msg->flags == SDW_MSG_FLAG_READ) {
|
||||
/* fill response */
|
||||
for (i = 0; i < count; i++)
|
||||
msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA,
|
||||
cdns->response_buf[i]);
|
||||
}
|
||||
|
||||
return SDW_CMD_OK;
|
||||
}
|
||||
|
@ -566,7 +569,7 @@ _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
|
|||
}
|
||||
|
||||
base = CDNS_MCP_CMD_BASE;
|
||||
addr = msg->addr;
|
||||
addr = msg->addr + offset;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
data = FIELD_PREP(CDNS_MCP_CMD_DEV_ADDR, msg->dev_num);
|
||||
|
@ -705,18 +708,15 @@ cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg)
|
|||
for (i = 0; i < msg->len / CDNS_MCP_CMD_LEN; i++) {
|
||||
ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
|
||||
CDNS_MCP_CMD_LEN, false);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
if (ret != SDW_CMD_OK)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(msg->len % CDNS_MCP_CMD_LEN))
|
||||
goto exit;
|
||||
return SDW_CMD_OK;
|
||||
|
||||
ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
|
||||
msg->len % CDNS_MCP_CMD_LEN, false);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
return _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
|
||||
msg->len % CDNS_MCP_CMD_LEN, false);
|
||||
}
|
||||
EXPORT_SYMBOL(cdns_xfer_msg);
|
||||
|
||||
|
@ -790,6 +790,7 @@ static int cdns_update_slave_status(struct sdw_cdns *cdns,
|
|||
enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
|
||||
bool is_slave = false;
|
||||
u32 mask;
|
||||
u32 val;
|
||||
int i, set_status;
|
||||
|
||||
memset(status, 0, sizeof(status));
|
||||
|
@ -797,41 +798,38 @@ static int cdns_update_slave_status(struct sdw_cdns *cdns,
|
|||
for (i = 0; i <= SDW_MAX_DEVICES; i++) {
|
||||
mask = (slave_intstat >> (i * CDNS_MCP_SLAVE_STATUS_NUM)) &
|
||||
CDNS_MCP_SLAVE_STATUS_BITS;
|
||||
if (!mask)
|
||||
continue;
|
||||
|
||||
is_slave = true;
|
||||
set_status = 0;
|
||||
|
||||
if (mask & CDNS_MCP_SLAVE_INTSTAT_RESERVED) {
|
||||
status[i] = SDW_SLAVE_RESERVED;
|
||||
set_status++;
|
||||
if (mask) {
|
||||
is_slave = true;
|
||||
|
||||
if (mask & CDNS_MCP_SLAVE_INTSTAT_RESERVED) {
|
||||
status[i] = SDW_SLAVE_RESERVED;
|
||||
set_status++;
|
||||
}
|
||||
|
||||
if (mask & CDNS_MCP_SLAVE_INTSTAT_ATTACHED) {
|
||||
status[i] = SDW_SLAVE_ATTACHED;
|
||||
set_status++;
|
||||
}
|
||||
|
||||
if (mask & CDNS_MCP_SLAVE_INTSTAT_ALERT) {
|
||||
status[i] = SDW_SLAVE_ALERT;
|
||||
set_status++;
|
||||
}
|
||||
|
||||
if (mask & CDNS_MCP_SLAVE_INTSTAT_NPRESENT) {
|
||||
status[i] = SDW_SLAVE_UNATTACHED;
|
||||
set_status++;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & CDNS_MCP_SLAVE_INTSTAT_ATTACHED) {
|
||||
status[i] = SDW_SLAVE_ATTACHED;
|
||||
set_status++;
|
||||
}
|
||||
|
||||
if (mask & CDNS_MCP_SLAVE_INTSTAT_ALERT) {
|
||||
status[i] = SDW_SLAVE_ALERT;
|
||||
set_status++;
|
||||
}
|
||||
|
||||
if (mask & CDNS_MCP_SLAVE_INTSTAT_NPRESENT) {
|
||||
status[i] = SDW_SLAVE_UNATTACHED;
|
||||
set_status++;
|
||||
}
|
||||
|
||||
/* first check if Slave reported multiple status */
|
||||
if (set_status > 1) {
|
||||
u32 val;
|
||||
|
||||
dev_warn_ratelimited(cdns->dev,
|
||||
"Slave %d reported multiple Status: %d\n",
|
||||
i, mask);
|
||||
|
||||
/* check latest status extracted from PING commands */
|
||||
/*
|
||||
* check that there was a single reported Slave status and when
|
||||
* there is not use the latest status extracted from PING commands
|
||||
*/
|
||||
if (set_status != 1) {
|
||||
val = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
|
||||
val >>= (i * 2);
|
||||
|
||||
|
@ -850,11 +848,6 @@ static int cdns_update_slave_status(struct sdw_cdns *cdns,
|
|||
status[i] = SDW_SLAVE_RESERVED;
|
||||
break;
|
||||
}
|
||||
|
||||
dev_warn_ratelimited(cdns->dev,
|
||||
"Slave %d status updated to %d\n",
|
||||
i, status[i]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -969,9 +962,22 @@ static void cdns_update_slave_status_work(struct work_struct *work)
|
|||
u32 device0_status;
|
||||
int retry_count = 0;
|
||||
|
||||
/*
|
||||
* Clear main interrupt first so we don't lose any assertions
|
||||
* that happen during this function.
|
||||
*/
|
||||
cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK);
|
||||
|
||||
slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
|
||||
slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
|
||||
|
||||
/*
|
||||
* Clear the bits before handling so we don't lose any
|
||||
* bits that re-assert.
|
||||
*/
|
||||
cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
|
||||
cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
|
||||
|
||||
/* combine the two status */
|
||||
slave_intstat = ((u64)slave1 << 32) | slave0;
|
||||
|
||||
|
@ -979,8 +985,6 @@ static void cdns_update_slave_status_work(struct work_struct *work)
|
|||
|
||||
update_status:
|
||||
cdns_update_slave_status(cdns, slave_intstat);
|
||||
cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
|
||||
cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
|
||||
|
||||
/*
|
||||
* When there is more than one peripheral per link, it's
|
||||
|
@ -997,6 +1001,11 @@ update_status:
|
|||
* attention with PING commands. There is no need to check for
|
||||
* ALERTS since they are not allowed until a non-zero
|
||||
* device_number is assigned.
|
||||
*
|
||||
* Do not clear the INTSTAT0/1. While looping to enumerate devices on
|
||||
* #0 there could be status changes on other devices - these must
|
||||
* be kept in the INTSTAT so they can be handled when all #0 devices
|
||||
* have been handled.
|
||||
*/
|
||||
|
||||
device0_status = cdns_readl(cdns, CDNS_MCP_SLAVE_STAT);
|
||||
|
@ -1016,8 +1025,7 @@ update_status:
|
|||
}
|
||||
}
|
||||
|
||||
/* clear and unmask Slave interrupt now */
|
||||
cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK);
|
||||
/* unmask Slave interrupt now */
|
||||
cdns_updatel(cdns, CDNS_MCP_INTMASK,
|
||||
CDNS_MCP_INT_SLAVE_MASK, CDNS_MCP_INT_SLAVE_MASK);
|
||||
|
||||
|
|
|
@ -55,7 +55,26 @@ static const struct adr_remap dell_sku_0A3E[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* The HP Omen 16-k0005TX does not expose the correct version of RT711 on link0
|
||||
* and does not expose a RT1316 on link3
|
||||
*/
|
||||
static const struct adr_remap hp_omen_16[] = {
|
||||
/* rt711-sdca on link0 */
|
||||
{
|
||||
0x000020025d071100ull,
|
||||
0x000030025d071101ull
|
||||
},
|
||||
/* rt1316-sdca on link3 */
|
||||
{
|
||||
0x000120025d071100ull,
|
||||
0x000330025d131601ull
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct dmi_system_id adr_remap_quirk_table[] = {
|
||||
/* TGL devices */
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
|
@ -78,6 +97,14 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
|
|||
},
|
||||
.driver_data = (void *)dell_sku_0A3E,
|
||||
},
|
||||
/* ADL devices */
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"),
|
||||
},
|
||||
.driver_data = (void *)hp_omen_16,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -306,7 +306,7 @@ sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
|
|||
|
||||
/* Check SNDWLCAP.LCOUNT */
|
||||
caps = ioread32(ctx->mmio_base + ctx->shim_base + SDW_SHIM_LCAP);
|
||||
caps &= GENMASK(2, 0);
|
||||
caps &= SDW_SHIM_LCAP_LCOUNT_MASK;
|
||||
|
||||
/* Check HW supported vs property value */
|
||||
if (caps < ctx->count) {
|
||||
|
|
|
@ -420,7 +420,7 @@ static int qcom_swrm_get_alert_slave_dev_num(struct qcom_swrm_ctrl *ctrl)
|
|||
|
||||
ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &val);
|
||||
|
||||
for (dev_num = 0; dev_num <= SDW_MAX_DEVICES; dev_num++) {
|
||||
for (dev_num = 1; dev_num <= SDW_MAX_DEVICES; dev_num++) {
|
||||
status = (val >> (dev_num * SWRM_MCP_SLV_STATUS_SZ));
|
||||
|
||||
if ((status & SWRM_MCP_SLV_STATUS_MASK) == SDW_SLAVE_ALERT) {
|
||||
|
@ -440,7 +440,7 @@ static void qcom_swrm_get_device_status(struct qcom_swrm_ctrl *ctrl)
|
|||
ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &val);
|
||||
ctrl->slave_status = val;
|
||||
|
||||
for (i = 0; i <= SDW_MAX_DEVICES; i++) {
|
||||
for (i = 1; i <= SDW_MAX_DEVICES; i++) {
|
||||
u32 s;
|
||||
|
||||
s = (val >> (i * 2));
|
||||
|
@ -573,11 +573,10 @@ static irqreturn_t qcom_swrm_irq_handler(int irq, void *dev_id)
|
|||
break;
|
||||
case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED:
|
||||
case SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS:
|
||||
dev_err_ratelimited(swrm->dev, "%s: SWR new slave attached\n",
|
||||
__func__);
|
||||
dev_dbg_ratelimited(swrm->dev, "SWR new slave attached\n");
|
||||
swrm->reg_read(swrm, SWRM_MCP_SLV_STATUS, &slave_status);
|
||||
if (swrm->slave_status == slave_status) {
|
||||
dev_err(swrm->dev, "Slave status not changed %x\n",
|
||||
dev_dbg(swrm->dev, "Slave status not changed %x\n",
|
||||
slave_status);
|
||||
} else {
|
||||
qcom_swrm_get_device_status(swrm);
|
||||
|
|
|
@ -892,6 +892,9 @@ struct sdw_master_ops {
|
|||
* meaningful if multi_link is set. If set to 1, hardware-based
|
||||
* synchronization will be used even if a stream only uses a single
|
||||
* SoundWire segment.
|
||||
* @dev_num_ida_min: if set, defines the minimum values for the IDA
|
||||
* used to allocate system-unique device numbers. This value needs to be
|
||||
* identical across all SoundWire bus in the system.
|
||||
*/
|
||||
struct sdw_bus {
|
||||
struct device *dev;
|
||||
|
@ -916,6 +919,7 @@ struct sdw_bus {
|
|||
u32 bank_switch_timeout;
|
||||
bool multi_link;
|
||||
int hw_sync_min_links;
|
||||
int dev_num_ida_min;
|
||||
};
|
||||
|
||||
int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
|
||||
|
|
|
@ -15,32 +15,21 @@
|
|||
#define SDW_LINK_SIZE 0x10000
|
||||
|
||||
/* Intel SHIM Registers Definition */
|
||||
/* LCAP */
|
||||
#define SDW_SHIM_LCAP 0x0
|
||||
#define SDW_SHIM_LCAP_LCOUNT_MASK GENMASK(2, 0)
|
||||
|
||||
/* LCTL */
|
||||
#define SDW_SHIM_LCTL 0x4
|
||||
#define SDW_SHIM_IPPTR 0x8
|
||||
#define SDW_SHIM_SYNC 0xC
|
||||
|
||||
#define SDW_SHIM_CTLSCAP(x) (0x010 + 0x60 * (x))
|
||||
#define SDW_SHIM_CTLS0CM(x) (0x012 + 0x60 * (x))
|
||||
#define SDW_SHIM_CTLS1CM(x) (0x014 + 0x60 * (x))
|
||||
#define SDW_SHIM_CTLS2CM(x) (0x016 + 0x60 * (x))
|
||||
#define SDW_SHIM_CTLS3CM(x) (0x018 + 0x60 * (x))
|
||||
#define SDW_SHIM_PCMSCAP(x) (0x020 + 0x60 * (x))
|
||||
|
||||
#define SDW_SHIM_PCMSYCHM(x, y) (0x022 + (0x60 * (x)) + (0x2 * (y)))
|
||||
#define SDW_SHIM_PCMSYCHC(x, y) (0x042 + (0x60 * (x)) + (0x2 * (y)))
|
||||
#define SDW_SHIM_PDMSCAP(x) (0x062 + 0x60 * (x))
|
||||
#define SDW_SHIM_IOCTL(x) (0x06C + 0x60 * (x))
|
||||
#define SDW_SHIM_CTMCTL(x) (0x06E + 0x60 * (x))
|
||||
|
||||
#define SDW_SHIM_WAKEEN 0x190
|
||||
#define SDW_SHIM_WAKESTS 0x192
|
||||
|
||||
#define SDW_SHIM_LCTL_SPA BIT(0)
|
||||
#define SDW_SHIM_LCTL_SPA_MASK GENMASK(3, 0)
|
||||
#define SDW_SHIM_LCTL_CPA BIT(8)
|
||||
#define SDW_SHIM_LCTL_CPA_MASK GENMASK(11, 8)
|
||||
|
||||
/* SYNC */
|
||||
#define SDW_SHIM_SYNC 0xC
|
||||
|
||||
#define SDW_SHIM_SYNC_SYNCPRD_VAL_24 (24000 / SDW_CADENCE_GSYNC_KHZ - 1)
|
||||
#define SDW_SHIM_SYNC_SYNCPRD_VAL_38_4 (38400 / SDW_CADENCE_GSYNC_KHZ - 1)
|
||||
#define SDW_SHIM_SYNC_SYNCPRD GENMASK(14, 0)
|
||||
|
@ -49,19 +38,33 @@
|
|||
#define SDW_SHIM_SYNC_CMDSYNC BIT(16)
|
||||
#define SDW_SHIM_SYNC_SYNCGO BIT(24)
|
||||
|
||||
/* Control stream capabililities and channel mask */
|
||||
#define SDW_SHIM_CTLSCAP(x) (0x010 + 0x60 * (x))
|
||||
#define SDW_SHIM_CTLS0CM(x) (0x012 + 0x60 * (x))
|
||||
#define SDW_SHIM_CTLS1CM(x) (0x014 + 0x60 * (x))
|
||||
#define SDW_SHIM_CTLS2CM(x) (0x016 + 0x60 * (x))
|
||||
#define SDW_SHIM_CTLS3CM(x) (0x018 + 0x60 * (x))
|
||||
|
||||
/* PCM Stream capabilities */
|
||||
#define SDW_SHIM_PCMSCAP(x) (0x020 + 0x60 * (x))
|
||||
|
||||
#define SDW_SHIM_PCMSCAP_ISS GENMASK(3, 0)
|
||||
#define SDW_SHIM_PCMSCAP_OSS GENMASK(7, 4)
|
||||
#define SDW_SHIM_PCMSCAP_BSS GENMASK(12, 8)
|
||||
|
||||
/* PCM Stream Channel Map */
|
||||
#define SDW_SHIM_PCMSYCHM(x, y) (0x022 + (0x60 * (x)) + (0x2 * (y)))
|
||||
|
||||
/* PCM Stream Channel Count */
|
||||
#define SDW_SHIM_PCMSYCHC(x, y) (0x042 + (0x60 * (x)) + (0x2 * (y)))
|
||||
|
||||
#define SDW_SHIM_PCMSYCM_LCHN GENMASK(3, 0)
|
||||
#define SDW_SHIM_PCMSYCM_HCHN GENMASK(7, 4)
|
||||
#define SDW_SHIM_PCMSYCM_STREAM GENMASK(13, 8)
|
||||
#define SDW_SHIM_PCMSYCM_DIR BIT(15)
|
||||
|
||||
#define SDW_SHIM_PDMSCAP_ISS GENMASK(3, 0)
|
||||
#define SDW_SHIM_PDMSCAP_OSS GENMASK(7, 4)
|
||||
#define SDW_SHIM_PDMSCAP_BSS GENMASK(12, 8)
|
||||
#define SDW_SHIM_PDMSCAP_CPSS GENMASK(15, 13)
|
||||
/* IO control */
|
||||
#define SDW_SHIM_IOCTL(x) (0x06C + 0x60 * (x))
|
||||
|
||||
#define SDW_SHIM_IOCTL_MIF BIT(0)
|
||||
#define SDW_SHIM_IOCTL_CO BIT(1)
|
||||
|
@ -73,13 +76,23 @@
|
|||
#define SDW_SHIM_IOCTL_CIBD BIT(8)
|
||||
#define SDW_SHIM_IOCTL_DIBD BIT(9)
|
||||
|
||||
/* Wake Enable*/
|
||||
#define SDW_SHIM_WAKEEN 0x190
|
||||
|
||||
#define SDW_SHIM_WAKEEN_ENABLE BIT(0)
|
||||
|
||||
/* Wake Status */
|
||||
#define SDW_SHIM_WAKESTS 0x192
|
||||
|
||||
#define SDW_SHIM_WAKESTS_STATUS BIT(0)
|
||||
|
||||
/* AC Timing control */
|
||||
#define SDW_SHIM_CTMCTL(x) (0x06E + 0x60 * (x))
|
||||
|
||||
#define SDW_SHIM_CTMCTL_DACTQE BIT(0)
|
||||
#define SDW_SHIM_CTMCTL_DODS BIT(1)
|
||||
#define SDW_SHIM_CTMCTL_DOAIS GENMASK(4, 3)
|
||||
|
||||
#define SDW_SHIM_WAKEEN_ENABLE BIT(0)
|
||||
#define SDW_SHIM_WAKESTS_STATUS BIT(0)
|
||||
|
||||
/* Intel ALH Register definitions */
|
||||
#define SDW_ALH_STRMZCFG(x) (0x000 + (0x4 * (x)))
|
||||
#define SDW_ALH_NUM_STREAMS 64
|
||||
|
|
Loading…
Reference in New Issue