Skip to content

Commit 4e63a29

Browse files
committed
soundwire: use bra if msg size > threshold
It is more efficient to read/write with bra if the message size is larger than a predefined threshold. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
1 parent 861c55b commit 4e63a29

1 file changed

Lines changed: 78 additions & 4 deletions

File tree

drivers/soundwire/bus.c

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,46 @@ static int sdw_ntransfer_no_pm(struct sdw_slave *slave, u32 addr, u8 flags,
449449
return 0;
450450
}
451451

452+
static int sdw_ntransfer_no_pm_bpt(struct sdw_slave *slave, u32 addr, u8 flags,
453+
size_t count, u8 *val)
454+
{
455+
struct sdw_bpt_section sec;
456+
struct sdw_bpt_msg msg;
457+
size_t size;
458+
int retry = 5;
459+
int ret;
460+
461+
msg.sections = 1;
462+
msg.dev_num = slave->dev_num;
463+
msg.flags = flags;
464+
msg.sec = &sec;
465+
466+
while (count) {
467+
size = min_t(size_t, count, SDW_BPT_MSG_MAX_BYTES);
468+
469+
sec.addr = addr;
470+
sec.len = size;
471+
sec.buf = val;
472+
473+
do {
474+
ret = sdw_bpt_send_sync(slave->bus, slave, &msg);
475+
if (ret == -EAGAIN)
476+
msleep(10);
477+
retry--;
478+
} while (ret == -EAGAIN && retry > 0);
479+
480+
if (ret < 0)
481+
return ret;
482+
483+
addr += size;
484+
val += size;
485+
count -= size;
486+
retry = 5;
487+
}
488+
489+
return 0;
490+
}
491+
452492
/**
453493
* sdw_nread_no_pm() - Read "n" contiguous SDW Slave registers with no PM
454494
* @slave: SDW Slave
@@ -457,10 +497,26 @@ static int sdw_ntransfer_no_pm(struct sdw_slave *slave, u32 addr, u8 flags,
457497
* @val: Buffer for values to be read
458498
*
459499
* Note that if the message crosses a page boundary each page will be
460-
* transferred under a separate invocation of the msg_lock.
500+
* transferred under a separate invocation of the msg_lock if it is not
501+
* transferred via BPT.
461502
*/
462503
int sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
463504
{
505+
struct sdw_bus *bus = slave->bus;
506+
int ret;
507+
508+
if (!bus->ops->bpt_send_async || !bus->ops->bpt_wait ||
509+
count < bus->bra_r_threshold)
510+
goto fallback;
511+
512+
ret = sdw_ntransfer_no_pm_bpt(slave, addr, SDW_MSG_FLAG_READ, count, val);
513+
if (!ret)
514+
return 0;
515+
516+
dev_dbg(&slave->dev,
517+
"BPT read failed for addr %x, count %zu, ret %d fallback to normal read\n",
518+
addr, count, ret);
519+
fallback:
464520
return sdw_ntransfer_no_pm(slave, addr, SDW_MSG_FLAG_READ, count, val);
465521
}
466522
EXPORT_SYMBOL(sdw_nread_no_pm);
@@ -473,10 +529,26 @@ EXPORT_SYMBOL(sdw_nread_no_pm);
473529
* @val: Buffer for values to be written
474530
*
475531
* Note that if the message crosses a page boundary each page will be
476-
* transferred under a separate invocation of the msg_lock.
532+
* transferred under a separate invocation of the msg_lock if it is not
533+
* transferred via BPT.
477534
*/
478535
int sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val)
479536
{
537+
struct sdw_bus *bus = slave->bus;
538+
int ret;
539+
540+
if (!bus->ops->bpt_send_async || !bus->ops->bpt_wait ||
541+
count < bus->bra_w_threshold)
542+
goto fallback;
543+
544+
ret = sdw_ntransfer_no_pm_bpt(slave, addr, SDW_MSG_FLAG_WRITE, count, (u8 *)val);
545+
if (!ret)
546+
return 0;
547+
548+
dev_dbg(&slave->dev,
549+
"BPT write failed for addr %x, count %zu, ret %d fallback to normal write\n",
550+
addr, count, ret);
551+
fallback:
480552
return sdw_ntransfer_no_pm(slave, addr, SDW_MSG_FLAG_WRITE, count, (u8 *)val);
481553
}
482554
EXPORT_SYMBOL(sdw_nwrite_no_pm);
@@ -614,7 +686,8 @@ EXPORT_SYMBOL(sdw_update);
614686
* This version of the function will take a PM reference to the slave
615687
* device.
616688
* Note that if the message crosses a page boundary each page will be
617-
* transferred under a separate invocation of the msg_lock.
689+
* transferred under a separate invocation of the msg_lock if it is not
690+
* transferred via BPT.
618691
*/
619692
int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
620693
{
@@ -645,7 +718,8 @@ EXPORT_SYMBOL(sdw_nread);
645718
* This version of the function will take a PM reference to the slave
646719
* device.
647720
* Note that if the message crosses a page boundary each page will be
648-
* transferred under a separate invocation of the msg_lock.
721+
* transferred under a separate invocation of the msg_lock if it is not
722+
* transferred via BPT.
649723
*/
650724
int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val)
651725
{

0 commit comments

Comments
 (0)