Skip to content

Commit 3a35af3

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 a50261f commit 3a35af3

1 file changed

Lines changed: 74 additions & 2 deletions

File tree

drivers/soundwire/bus.c

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,46 @@ static int sdw_ntransfer_no_pm(struct sdw_slave *slave, u32 addr, u8 flags,
447447
return 0;
448448
}
449449

450+
static int sdw_ntransfer_no_pm_bpt(struct sdw_slave *slave, u32 addr, u8 flags,
451+
size_t count, u8 *val)
452+
{
453+
struct sdw_bpt_section sec;
454+
struct sdw_bpt_msg msg;
455+
size_t size;
456+
int retry = 5;
457+
int ret;
458+
459+
msg.sections = 1;
460+
msg.dev_num = slave->dev_num;
461+
msg.flags = flags;
462+
msg.sec = &sec;
463+
464+
while (count) {
465+
size = min_t(size_t, count, SDW_BPT_MSG_MAX_BYTES);
466+
467+
sec.addr = addr;
468+
sec.len = size;
469+
sec.buf = val;
470+
471+
do {
472+
ret = sdw_bpt_send_sync(slave->bus, slave, &msg);
473+
if (ret == -EAGAIN)
474+
msleep(10);
475+
retry--;
476+
} while (ret == -EAGAIN && retry > 0);
477+
478+
if (ret < 0)
479+
return ret;
480+
481+
addr += size;
482+
val += size;
483+
count -= size;
484+
retry = 5;
485+
}
486+
487+
return 0;
488+
}
489+
450490
/**
451491
* sdw_nread_no_pm() - Read "n" contiguous SDW Slave registers with no PM
452492
* @slave: SDW Slave
@@ -455,10 +495,26 @@ static int sdw_ntransfer_no_pm(struct sdw_slave *slave, u32 addr, u8 flags,
455495
* @val: Buffer for values to be read
456496
*
457497
* Note that if the message crosses a page boundary each page will be
458-
* transferred under a separate invocation of the msg_lock.
498+
* transferred under a separate invocation of the msg_lock if it is not
499+
* transferred via BPT.
459500
*/
460501
int sdw_nread_no_pm(struct sdw_slave *slave, u32 addr, size_t count, u8 *val)
461502
{
503+
struct sdw_bus *bus = slave->bus;
504+
int ret;
505+
506+
if (!bus->ops->bpt_send_async || !bus->ops->bpt_wait ||
507+
count < bus->bra_r_threshold)
508+
goto fallback;
509+
510+
ret = sdw_ntransfer_no_pm_bpt(slave, addr, SDW_MSG_FLAG_READ, count, val);
511+
if (!ret)
512+
return 0;
513+
514+
dev_dbg(&slave->dev,
515+
"BPT read failed for addr %x, count %zu, ret %d fallback to normal read\n",
516+
addr, count, ret);
517+
fallback:
462518
return sdw_ntransfer_no_pm(slave, addr, SDW_MSG_FLAG_READ, count, val);
463519
}
464520
EXPORT_SYMBOL(sdw_nread_no_pm);
@@ -471,10 +527,26 @@ EXPORT_SYMBOL(sdw_nread_no_pm);
471527
* @val: Buffer for values to be written
472528
*
473529
* Note that if the message crosses a page boundary each page will be
474-
* transferred under a separate invocation of the msg_lock.
530+
* transferred under a separate invocation of the msg_lock if it is not
531+
* transferred via BPT.
475532
*/
476533
int sdw_nwrite_no_pm(struct sdw_slave *slave, u32 addr, size_t count, const u8 *val)
477534
{
535+
struct sdw_bus *bus = slave->bus;
536+
int ret;
537+
538+
if (!bus->ops->bpt_send_async || !bus->ops->bpt_wait ||
539+
count < bus->bra_w_threshold)
540+
goto fallback;
541+
542+
ret = sdw_ntransfer_no_pm_bpt(slave, addr, SDW_MSG_FLAG_WRITE, count, (u8 *)val);
543+
if (!ret)
544+
return 0;
545+
546+
dev_dbg(&slave->dev,
547+
"BPT write failed for addr %x, count %zu, ret %d fallback to normal write\n",
548+
addr, count, ret);
549+
fallback:
478550
return sdw_ntransfer_no_pm(slave, addr, SDW_MSG_FLAG_WRITE, count, (u8 *)val);
479551
}
480552
EXPORT_SYMBOL(sdw_nwrite_no_pm);

0 commit comments

Comments
 (0)