Skip to content

Commit dd81e7c

Browse files
plbossartvinodkoul
authored andcommitted
soundwire: cadence: override PDI configurations to create loopback
When we set a source PDI, the target PDI parameters will be overridden by the source register values. The loopback streams can be independently enabled on each link. While the loopback source and target can be configured before any stream is active on each link, the loopback stream should only be prepared/triggered when the playback stream is prepared. Otherwise all registers might be programmed to their reset values and the loopback will not succeed. The SoundWire bus driver currently does not allow two streams to be triggered at the same time, so the playback will have to be started first, and later the loopback. Signed-off-by: Pierre-Louis Bossart <[email protected]> Reviewed-by: Rander Wang <[email protected]> Signed-off-by: Bard Liao <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 8fba8ac commit dd81e7c

File tree

1 file changed

+95
-35
lines changed

1 file changed

+95
-35
lines changed

drivers/soundwire/cadence_master.c

Lines changed: 95 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,20 +1374,37 @@ static int cdns_port_params(struct sdw_bus *bus,
13741374
struct sdw_port_params *p_params, unsigned int bank)
13751375
{
13761376
struct sdw_cdns *cdns = bus_to_cdns(bus);
1377-
int dpn_config = 0, dpn_config_off;
1377+
int dpn_config_off_source;
1378+
int dpn_config_off_target;
1379+
int target_num = p_params->num;
1380+
int source_num = p_params->num;
1381+
bool override = false;
1382+
int dpn_config;
1383+
1384+
if (target_num == cdns->pdi_loopback_target &&
1385+
cdns->pdi_loopback_source != -1) {
1386+
source_num = cdns->pdi_loopback_source;
1387+
override = true;
1388+
}
13781389

1379-
if (bank)
1380-
dpn_config_off = CDNS_DPN_B1_CONFIG(p_params->num);
1381-
else
1382-
dpn_config_off = CDNS_DPN_B0_CONFIG(p_params->num);
1390+
if (bank) {
1391+
dpn_config_off_source = CDNS_DPN_B1_CONFIG(source_num);
1392+
dpn_config_off_target = CDNS_DPN_B1_CONFIG(target_num);
1393+
} else {
1394+
dpn_config_off_source = CDNS_DPN_B0_CONFIG(source_num);
1395+
dpn_config_off_target = CDNS_DPN_B0_CONFIG(target_num);
1396+
}
13831397

1384-
dpn_config = cdns_readl(cdns, dpn_config_off);
1398+
dpn_config = cdns_readl(cdns, dpn_config_off_source);
13851399

1386-
u32p_replace_bits(&dpn_config, (p_params->bps - 1), CDNS_DPN_CONFIG_WL);
1387-
u32p_replace_bits(&dpn_config, p_params->flow_mode, CDNS_DPN_CONFIG_PORT_FLOW);
1388-
u32p_replace_bits(&dpn_config, p_params->data_mode, CDNS_DPN_CONFIG_PORT_DAT);
1400+
/* use port params if there is no loopback, otherwise use source as is */
1401+
if (!override) {
1402+
u32p_replace_bits(&dpn_config, p_params->bps - 1, CDNS_DPN_CONFIG_WL);
1403+
u32p_replace_bits(&dpn_config, p_params->flow_mode, CDNS_DPN_CONFIG_PORT_FLOW);
1404+
u32p_replace_bits(&dpn_config, p_params->data_mode, CDNS_DPN_CONFIG_PORT_DAT);
1405+
}
13891406

1390-
cdns_writel(cdns, dpn_config_off, dpn_config);
1407+
cdns_writel(cdns, dpn_config_off_target, dpn_config);
13911408

13921409
return 0;
13931410
}
@@ -1397,44 +1414,87 @@ static int cdns_transport_params(struct sdw_bus *bus,
13971414
enum sdw_reg_bank bank)
13981415
{
13991416
struct sdw_cdns *cdns = bus_to_cdns(bus);
1400-
int dpn_offsetctrl = 0, dpn_offsetctrl_off;
1401-
int dpn_config = 0, dpn_config_off;
1402-
int dpn_hctrl = 0, dpn_hctrl_off;
1403-
int num = t_params->port_num;
1404-
int dpn_samplectrl_off;
1417+
int dpn_config;
1418+
int dpn_config_off_source;
1419+
int dpn_config_off_target;
1420+
int dpn_hctrl;
1421+
int dpn_hctrl_off_source;
1422+
int dpn_hctrl_off_target;
1423+
int dpn_offsetctrl;
1424+
int dpn_offsetctrl_off_source;
1425+
int dpn_offsetctrl_off_target;
1426+
int dpn_samplectrl;
1427+
int dpn_samplectrl_off_source;
1428+
int dpn_samplectrl_off_target;
1429+
int source_num = t_params->port_num;
1430+
int target_num = t_params->port_num;
1431+
bool override = false;
1432+
1433+
if (target_num == cdns->pdi_loopback_target &&
1434+
cdns->pdi_loopback_source != -1) {
1435+
source_num = cdns->pdi_loopback_source;
1436+
override = true;
1437+
}
14051438

14061439
/*
14071440
* Note: Only full data port is supported on the Master side for
14081441
* both PCM and PDM ports.
14091442
*/
14101443

14111444
if (bank) {
1412-
dpn_config_off = CDNS_DPN_B1_CONFIG(num);
1413-
dpn_samplectrl_off = CDNS_DPN_B1_SAMPLE_CTRL(num);
1414-
dpn_hctrl_off = CDNS_DPN_B1_HCTRL(num);
1415-
dpn_offsetctrl_off = CDNS_DPN_B1_OFFSET_CTRL(num);
1445+
dpn_config_off_source = CDNS_DPN_B1_CONFIG(source_num);
1446+
dpn_hctrl_off_source = CDNS_DPN_B1_HCTRL(source_num);
1447+
dpn_offsetctrl_off_source = CDNS_DPN_B1_OFFSET_CTRL(source_num);
1448+
dpn_samplectrl_off_source = CDNS_DPN_B1_SAMPLE_CTRL(source_num);
1449+
1450+
dpn_config_off_target = CDNS_DPN_B1_CONFIG(target_num);
1451+
dpn_hctrl_off_target = CDNS_DPN_B1_HCTRL(target_num);
1452+
dpn_offsetctrl_off_target = CDNS_DPN_B1_OFFSET_CTRL(target_num);
1453+
dpn_samplectrl_off_target = CDNS_DPN_B1_SAMPLE_CTRL(target_num);
1454+
14161455
} else {
1417-
dpn_config_off = CDNS_DPN_B0_CONFIG(num);
1418-
dpn_samplectrl_off = CDNS_DPN_B0_SAMPLE_CTRL(num);
1419-
dpn_hctrl_off = CDNS_DPN_B0_HCTRL(num);
1420-
dpn_offsetctrl_off = CDNS_DPN_B0_OFFSET_CTRL(num);
1456+
dpn_config_off_source = CDNS_DPN_B0_CONFIG(source_num);
1457+
dpn_hctrl_off_source = CDNS_DPN_B0_HCTRL(source_num);
1458+
dpn_offsetctrl_off_source = CDNS_DPN_B0_OFFSET_CTRL(source_num);
1459+
dpn_samplectrl_off_source = CDNS_DPN_B0_SAMPLE_CTRL(source_num);
1460+
1461+
dpn_config_off_target = CDNS_DPN_B0_CONFIG(target_num);
1462+
dpn_hctrl_off_target = CDNS_DPN_B0_HCTRL(target_num);
1463+
dpn_offsetctrl_off_target = CDNS_DPN_B0_OFFSET_CTRL(target_num);
1464+
dpn_samplectrl_off_target = CDNS_DPN_B0_SAMPLE_CTRL(target_num);
14211465
}
14221466

1423-
dpn_config = cdns_readl(cdns, dpn_config_off);
1424-
u32p_replace_bits(&dpn_config, t_params->blk_grp_ctrl, CDNS_DPN_CONFIG_BGC);
1425-
u32p_replace_bits(&dpn_config, t_params->blk_pkg_mode, CDNS_DPN_CONFIG_BPM);
1426-
cdns_writel(cdns, dpn_config_off, dpn_config);
1467+
dpn_config = cdns_readl(cdns, dpn_config_off_source);
1468+
if (!override) {
1469+
u32p_replace_bits(&dpn_config, t_params->blk_grp_ctrl, CDNS_DPN_CONFIG_BGC);
1470+
u32p_replace_bits(&dpn_config, t_params->blk_pkg_mode, CDNS_DPN_CONFIG_BPM);
1471+
}
1472+
cdns_writel(cdns, dpn_config_off_target, dpn_config);
14271473

1428-
u32p_replace_bits(&dpn_offsetctrl, t_params->offset1, CDNS_DPN_OFFSET_CTRL_1);
1429-
u32p_replace_bits(&dpn_offsetctrl, t_params->offset2, CDNS_DPN_OFFSET_CTRL_2);
1430-
cdns_writel(cdns, dpn_offsetctrl_off, dpn_offsetctrl);
1474+
if (!override) {
1475+
dpn_offsetctrl = 0;
1476+
u32p_replace_bits(&dpn_offsetctrl, t_params->offset1, CDNS_DPN_OFFSET_CTRL_1);
1477+
u32p_replace_bits(&dpn_offsetctrl, t_params->offset2, CDNS_DPN_OFFSET_CTRL_2);
1478+
} else {
1479+
dpn_offsetctrl = cdns_readl(cdns, dpn_offsetctrl_off_source);
1480+
}
1481+
cdns_writel(cdns, dpn_offsetctrl_off_target, dpn_offsetctrl);
14311482

1432-
u32p_replace_bits(&dpn_hctrl, t_params->hstart, CDNS_DPN_HCTRL_HSTART);
1433-
u32p_replace_bits(&dpn_hctrl, t_params->hstop, CDNS_DPN_HCTRL_HSTOP);
1434-
u32p_replace_bits(&dpn_hctrl, t_params->lane_ctrl, CDNS_DPN_HCTRL_LCTRL);
1483+
if (!override) {
1484+
dpn_hctrl = 0;
1485+
u32p_replace_bits(&dpn_hctrl, t_params->hstart, CDNS_DPN_HCTRL_HSTART);
1486+
u32p_replace_bits(&dpn_hctrl, t_params->hstop, CDNS_DPN_HCTRL_HSTOP);
1487+
u32p_replace_bits(&dpn_hctrl, t_params->lane_ctrl, CDNS_DPN_HCTRL_LCTRL);
1488+
} else {
1489+
dpn_hctrl = cdns_readl(cdns, dpn_hctrl_off_source);
1490+
}
1491+
cdns_writel(cdns, dpn_hctrl_off_target, dpn_hctrl);
14351492

1436-
cdns_writel(cdns, dpn_hctrl_off, dpn_hctrl);
1437-
cdns_writel(cdns, dpn_samplectrl_off, (t_params->sample_interval - 1));
1493+
if (!override)
1494+
dpn_samplectrl = t_params->sample_interval - 1;
1495+
else
1496+
dpn_samplectrl = cdns_readl(cdns, dpn_samplectrl_off_source);
1497+
cdns_writel(cdns, dpn_samplectrl_off_target, dpn_samplectrl);
14381498

14391499
return 0;
14401500
}

0 commit comments

Comments
 (0)