Skip to content

Commit e4bd249

Browse files
committed
fixup! soundwire: cadence: add paranoid check on self-clearing bit
Add more flexibility for initial delay and iterations on reset to figure out why this HW_RESET bit is not cleared. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
1 parent f23f72d commit e4bd249

3 files changed

Lines changed: 37 additions & 17 deletions

File tree

drivers/soundwire/cadence_master.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -980,27 +980,45 @@ static void cdns_update_slave_status_work(struct work_struct *work)
980980
}
981981

982982
/* paranoia check to make sure self-cleared bits are indeed cleared */
983-
void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string)
983+
void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string,
984+
bool initial_delay, int reset_iterations)
984985
{
985986
u32 mcp_control;
986987
u32 mcp_config_update;
988+
int i;
989+
990+
if (initial_delay)
991+
usleep_range(1000, 1500);
987992

988993
mcp_control = cdns_readl(cdns, CDNS_MCP_CONTROL);
989994

995+
/* the following bits should be cleared immediately */
990996
if (mcp_control & CDNS_MCP_CONTROL_CMD_RST)
991997
dev_err(cdns->dev, "%s failed: MCP_CONTROL_CMD_RST is not cleared\n", string);
992998
if (mcp_control & CDNS_MCP_CONTROL_SOFT_RST)
993999
dev_err(cdns->dev, "%s failed: MCP_CONTROL_SOFT_RST is not cleared\n", string);
9941000
if (mcp_control & CDNS_MCP_CONTROL_SW_RST)
9951001
dev_err(cdns->dev, "%s failed: MCP_CONTROL_SW_RST is not cleared\n", string);
996-
if (mcp_control & CDNS_MCP_CONTROL_HW_RST)
997-
dev_err(cdns->dev, "%s failed: MCP_CONTROL_HW_RST is not cleared\n", string);
9981002
if (mcp_control & CDNS_MCP_CONTROL_CLK_STOP_CLR)
9991003
dev_err(cdns->dev, "%s failed: MCP_CONTROL_CLK_STOP_CLR is not cleared\n", string);
1000-
10011004
mcp_config_update = cdns_readl(cdns, CDNS_MCP_CONFIG_UPDATE);
10021005
if (mcp_config_update & CDNS_MCP_CONFIG_UPDATE_BIT)
10031006
dev_err(cdns->dev, "%s failed: MCP_CONFIG_UPDATE_BIT is not cleared\n", string);
1007+
1008+
i = 0;
1009+
while (mcp_control & CDNS_MCP_CONTROL_HW_RST) {
1010+
if (i == reset_iterations) {
1011+
dev_err(cdns->dev, "%s failed: MCP_CONTROL_HW_RST is not cleared\n", string);
1012+
break;
1013+
}
1014+
1015+
dev_dbg(cdns->dev, "%s: MCP_CONTROL_HW_RST is not cleared at iteration %d\n", string, i);
1016+
i++;
1017+
1018+
usleep_range(1000, 1500);
1019+
mcp_control = cdns_readl(cdns, CDNS_MCP_CONTROL);
1020+
}
1021+
10041022
}
10051023
EXPORT_SYMBOL(sdw_cdns_check_self_clearing_bits);
10061024

@@ -1281,7 +1299,7 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
12811299

12821300
cdns_init_clock_ctrl(cdns);
12831301

1284-
sdw_cdns_check_self_clearing_bits(cdns, __func__);
1302+
sdw_cdns_check_self_clearing_bits(cdns, __func__, false, 0);
12851303

12861304
/* reset msg_count to default value of FIFOLEVEL */
12871305
cdns->msg_count = cdns_readl(cdns, CDNS_MCP_FIFOLEVEL);
@@ -1527,7 +1545,7 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
15271545
struct sdw_slave *slave;
15281546
int ret;
15291547

1530-
sdw_cdns_check_self_clearing_bits(cdns, __func__);
1548+
sdw_cdns_check_self_clearing_bits(cdns, __func__, false, 0);
15311549

15321550
/* Check suspend status */
15331551
if (sdw_cdns_is_clock_stop(cdns)) {

drivers/soundwire/cadence_master.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params);
188188
int cdns_set_sdw_stream(struct snd_soc_dai *dai,
189189
void *stream, bool pcm, int direction);
190190

191-
void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string);
191+
void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string,
192+
bool initial_delay, int reset_iterations);
192193

193194
#endif /* __SDW_CADENCE_H */

drivers/soundwire/intel.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "intel.h"
2424

2525
#define INTEL_MASTER_SUSPEND_DELAY_MS 3000
26+
#define INTEL_MASTER_RESET_ITERATIONS 10
2627

2728
/*
2829
* debug/config flags for the Intel SoundWire Master.
@@ -1467,8 +1468,8 @@ int intel_link_startup(struct auxiliary_device *auxdev)
14671468
goto err_interrupt;
14681469
}
14691470
}
1470-
usleep_range(1000, 1500);
1471-
sdw_cdns_check_self_clearing_bits(cdns, __func__);
1471+
sdw_cdns_check_self_clearing_bits(cdns, __func__,
1472+
true, INTEL_MASTER_RESET_ITERATIONS);
14721473

14731474
/* Register DAIs */
14741475
ret = intel_register_dai(sdw);
@@ -1785,8 +1786,8 @@ static int __maybe_unused intel_resume(struct device *dev)
17851786
return ret;
17861787
}
17871788
}
1788-
usleep_range(1000, 1500);
1789-
sdw_cdns_check_self_clearing_bits(cdns, __func__);
1789+
sdw_cdns_check_self_clearing_bits(cdns, __func__,
1790+
true, INTEL_MASTER_RESET_ITERATIONS);
17901791

17911792
/*
17921793
* after system resume, the pm_runtime suspend() may kick in
@@ -1871,8 +1872,8 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
18711872
return ret;
18721873
}
18731874
}
1874-
usleep_range(1000, 1500);
1875-
sdw_cdns_check_self_clearing_bits(cdns, "intel_resume_runtime TEARDOWN");
1875+
sdw_cdns_check_self_clearing_bits(cdns, "intel_resume_runtime TEARDOWN",
1876+
true, INTEL_MASTER_RESET_ITERATIONS);
18761877

18771878
} else if (clock_stop_quirks & SDW_INTEL_CLK_STOP_BUS_RESET) {
18781879
ret = intel_init(sdw);
@@ -1947,8 +1948,8 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
19471948
}
19481949
}
19491950
}
1950-
usleep_range(1000, 1500);
1951-
sdw_cdns_check_self_clearing_bits(cdns, "intel_resume_runtime BUS_RESET");
1951+
sdw_cdns_check_self_clearing_bits(cdns, "intel_resume_runtime BUS_RESET",
1952+
true, INTEL_MASTER_RESET_ITERATIONS);
19521953

19531954
} else if (!clock_stop_quirks) {
19541955

@@ -1974,8 +1975,8 @@ static int __maybe_unused intel_resume_runtime(struct device *dev)
19741975
return ret;
19751976
}
19761977

1977-
usleep_range(1000, 1500);
1978-
sdw_cdns_check_self_clearing_bits(cdns, "intel_resume_runtime no_quirks");
1978+
sdw_cdns_check_self_clearing_bits(cdns, "intel_resume_runtime no_quirks",
1979+
true, INTEL_MASTER_RESET_ITERATIONS);
19791980
} else {
19801981
dev_err(dev, "%s clock_stop_quirks %x unsupported\n",
19811982
__func__, clock_stop_quirks);

0 commit comments

Comments
 (0)