Commit a50954e2 authored by Rander Wang's avatar Rander Wang Committed by Vinod Koul

soundwire: cadence_master: fix divider setting in clock register

The existing code uses an OR operation which would mix the original
divider setting with the new one, resulting in an invalid
configuration that can make codecs hang.

Add the mask definition and use cdns_updatel to update divider
Signed-off-by: default avatarRander Wang <rander.wang@linux.intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20190806005522.22642-14-pierre-louis.bossart@linux.intel.comSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 3859872f
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#define CDNS_MCP_SSP_CTRL1 0x28 #define CDNS_MCP_SSP_CTRL1 0x28
#define CDNS_MCP_CLK_CTRL0 0x30 #define CDNS_MCP_CLK_CTRL0 0x30
#define CDNS_MCP_CLK_CTRL1 0x38 #define CDNS_MCP_CLK_CTRL1 0x38
#define CDNS_MCP_CLK_MCLKD_MASK GENMASK(7, 0)
#define CDNS_MCP_STAT 0x40 #define CDNS_MCP_STAT 0x40
...@@ -842,10 +843,11 @@ int sdw_cdns_init(struct sdw_cdns *cdns) ...@@ -842,10 +843,11 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
/* Set clock divider */ /* Set clock divider */
divider = (prop->mclk_freq / prop->max_clk_freq) - 1; divider = (prop->mclk_freq / prop->max_clk_freq) - 1;
val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
val |= divider; cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val); CDNS_MCP_CLK_MCLKD_MASK, divider);
cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val); cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
CDNS_MCP_CLK_MCLKD_MASK, divider);
/* /*
* Frame shape changes after initialization have to be done * Frame shape changes after initialization have to be done
...@@ -895,7 +897,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params) ...@@ -895,7 +897,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
{ {
struct sdw_master_prop *prop = &bus->prop; struct sdw_master_prop *prop = &bus->prop;
struct sdw_cdns *cdns = bus_to_cdns(bus); struct sdw_cdns *cdns = bus_to_cdns(bus);
int mcp_clkctrl_off, mcp_clkctrl; int mcp_clkctrl_off;
int divider; int divider;
if (!params->curr_dr_freq) { if (!params->curr_dr_freq) {
...@@ -912,9 +914,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params) ...@@ -912,9 +914,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
else else
mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0; mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
mcp_clkctrl = cdns_readl(cdns, mcp_clkctrl_off); cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, divider);
mcp_clkctrl |= divider;
cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment