[PATCH v2 0/2] soundwire: Remove redundant zeroing of page registers
Writing zero to the page registers after each message transaction can add up to a lot of overhead for codecs that need to transfer large amount of data - for example a firmware download.
There's no spec reason I can see for this zeroing. The page registers are only used for a paged address. The bus code uses a non-paged address for registers in page 0. It always writes the page registers at the start of a paged transaction.
If this zeroing was a workaround for anything, let me know and I will re-implement the zeroing as a quirk that can be enabled only when it is necessary.
Changes since v1: - Reworded the commit message to patch #1: - say that this is for devices that support paging - mention bit 15 as the paging flag - split a long sentence into two sentences.
No code changes.
Richard Fitzgerald (2): soundwire: bus: Don't zero page registers after every transaction soundwire: bus: Remove unused reset_page_addr() callback
drivers/soundwire/bus.c | 23 ----------------------- drivers/soundwire/cadence_master.c | 14 -------------- drivers/soundwire/cadence_master.h | 3 --- drivers/soundwire/intel_auxdevice.c | 1 - include/linux/soundwire/sdw.h | 3 --- 5 files changed, 44 deletions(-)
Zeroing the page registers at the end of every paged transaction is just overhead (40% overhead on a 1-register access, 25% on a 4-register transaction). According to the spec a peripheral that supports paging should only use the values in the page registers if the address is paged (address bit 15 set). The core SoundWire code always writes the page registers at the start of a paged transaction so there will never be a transaction that uses the stale values from a previous paged transaction.
For peripherals that need large amounts of data to be transferred, for example firmware or filter coefficients, the overhead of page register zeroing can become quite significant.
Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- drivers/soundwire/bus.c | 23 ----------------------- 1 file changed, 23 deletions(-)
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c index 633d411b64f3..b840322f7f1d 100644 --- a/drivers/soundwire/bus.c +++ b/drivers/soundwire/bus.c @@ -247,23 +247,6 @@ static inline int do_transfer_defer(struct sdw_bus *bus, return ret; }
-static int sdw_reset_page(struct sdw_bus *bus, u16 dev_num) -{ - int retry = bus->prop.err_threshold; - enum sdw_command_response resp; - int ret = 0, i; - - for (i = 0; i <= retry; i++) { - resp = bus->ops->reset_page_addr(bus, dev_num); - ret = find_response_code(resp); - /* if cmd is ok or ignored return */ - if (ret == 0 || ret == -ENODATA) - return ret; - } - - return ret; -} - static int sdw_transfer_unlocked(struct sdw_bus *bus, struct sdw_msg *msg) { int ret; @@ -275,9 +258,6 @@ static int sdw_transfer_unlocked(struct sdw_bus *bus, struct sdw_msg *msg) (msg->flags & SDW_MSG_FLAG_WRITE) ? "write" : "read", msg->addr, msg->len);
- if (msg->page) - sdw_reset_page(bus, msg->dev_num); - return ret; }
@@ -352,9 +332,6 @@ int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg, dev_err(bus->dev, "Defer trf on Slave %d failed:%d\n", msg->dev_num, ret);
- if (msg->page) - sdw_reset_page(bus, msg->dev_num); - return ret; }
A previous patch removed unnecessary zeroing of the page registers after a paged transaction, so now the reset_page_addr callback is unused and can be removed.
Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com --- drivers/soundwire/cadence_master.c | 14 -------------- drivers/soundwire/cadence_master.h | 3 --- drivers/soundwire/intel_auxdevice.c | 1 - include/linux/soundwire/sdw.h | 3 --- 4 files changed, 21 deletions(-)
diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index 521387322145..f44e8f9a1c09 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -770,20 +770,6 @@ cdns_xfer_msg_defer(struct sdw_bus *bus, } EXPORT_SYMBOL(cdns_xfer_msg_defer);
-enum sdw_command_response -cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num) -{ - struct sdw_cdns *cdns = bus_to_cdns(bus); - struct sdw_msg msg; - - /* Create dummy message with valid device number */ - memset(&msg, 0, sizeof(msg)); - msg.dev_num = dev_num; - - return cdns_program_scp_addr(cdns, &msg); -} -EXPORT_SYMBOL(cdns_reset_page_addr); - u32 cdns_read_ping_status(struct sdw_bus *bus) { struct sdw_cdns *cdns = bus_to_cdns(bus); diff --git a/drivers/soundwire/cadence_master.h b/drivers/soundwire/cadence_master.h index fa9dc38264a4..2efc857d21aa 100644 --- a/drivers/soundwire/cadence_master.h +++ b/drivers/soundwire/cadence_master.h @@ -182,9 +182,6 @@ struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns, void sdw_cdns_config_stream(struct sdw_cdns *cdns, u32 ch, u32 dir, struct sdw_cdns_pdi *pdi);
-enum sdw_command_response -cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num); - enum sdw_command_response cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg);
diff --git a/drivers/soundwire/intel_auxdevice.c b/drivers/soundwire/intel_auxdevice.c index 96c6b2112feb..5021be0f4158 100644 --- a/drivers/soundwire/intel_auxdevice.c +++ b/drivers/soundwire/intel_auxdevice.c @@ -113,7 +113,6 @@ static struct sdw_master_ops sdw_intel_ops = { .override_adr = sdw_dmi_override_adr, .xfer_msg = cdns_xfer_msg, .xfer_msg_defer = cdns_xfer_msg_defer, - .reset_page_addr = cdns_reset_page_addr, .set_bus_conf = cdns_bus_conf, .pre_bank_switch = generic_pre_bank_switch, .post_bank_switch = generic_post_bank_switch, diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index 3cd2a761911f..a8d74635ea0d 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -838,7 +838,6 @@ struct sdw_defer { * @override_adr: Override value read from firmware (quirk for buggy firmware) * @xfer_msg: Transfer message callback * @xfer_msg_defer: Defer version of transfer message callback - * @reset_page_addr: Reset the SCP page address registers * @set_bus_conf: Set the bus configuration * @pre_bank_switch: Callback for pre bank switch * @post_bank_switch: Callback for post bank switch @@ -854,8 +853,6 @@ struct sdw_master_ops { enum sdw_command_response (*xfer_msg_defer) (struct sdw_bus *bus, struct sdw_msg *msg, struct sdw_defer *defer); - enum sdw_command_response (*reset_page_addr) - (struct sdw_bus *bus, unsigned int dev_num); int (*set_bus_conf)(struct sdw_bus *bus, struct sdw_bus_params *params); int (*pre_bank_switch)(struct sdw_bus *bus);
On 23-01-23, 16:49, Richard Fitzgerald wrote:
Writing zero to the page registers after each message transaction can add up to a lot of overhead for codecs that need to transfer large amount of data - for example a firmware download.
There's no spec reason I can see for this zeroing. The page registers are only used for a paged address. The bus code uses a non-paged address for registers in page 0. It always writes the page registers at the start of a paged transaction.
If this zeroing was a workaround for anything, let me know and I will re-implement the zeroing as a quirk that can be enabled only when it is necessary.
Applied, thanks
participants (2)
-
Richard Fitzgerald
-
Vinod Koul