]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
soundwire: cadence_master: fix divider setting in clock register
authorRander Wang <rander.wang@linux.intel.com>
Tue, 6 Aug 2019 00:55:18 +0000 (19:55 -0500)
committerVinod Koul <vkoul@kernel.org>
Wed, 21 Aug 2019 09:06:02 +0000 (14:36 +0530)
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: Rander Wang <rander.wang@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20190806005522.22642-14-pierre-louis.bossart@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/soundwire/cadence_master.c

index eea5618083fefbf494055a5a9f791616190ed8ce..92d1387c6d2b721bb5dae8afc522fd72b49bc147 100644 (file)
@@ -58,6 +58,7 @@
 #define CDNS_MCP_SSP_CTRL1                     0x28
 #define CDNS_MCP_CLK_CTRL0                     0x30
 #define CDNS_MCP_CLK_CTRL1                     0x38
+#define CDNS_MCP_CLK_MCLKD_MASK                GENMASK(7, 0)
 
 #define CDNS_MCP_STAT                          0x40
 
@@ -842,10 +843,11 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
 
        /* Set clock divider */
        divider = (prop->mclk_freq / prop->max_clk_freq) - 1;
-       val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
-       val |= divider;
-       cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
-       cdns_writel(cdns, CDNS_MCP_CLK_CTRL1, val);
+
+       cdns_updatel(cdns, CDNS_MCP_CLK_CTRL0,
+                    CDNS_MCP_CLK_MCLKD_MASK, divider);
+       cdns_updatel(cdns, CDNS_MCP_CLK_CTRL1,
+                    CDNS_MCP_CLK_MCLKD_MASK, divider);
 
        /*
         * 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)
 {
        struct sdw_master_prop *prop = &bus->prop;
        struct sdw_cdns *cdns = bus_to_cdns(bus);
-       int mcp_clkctrl_off, mcp_clkctrl;
+       int mcp_clkctrl_off;
        int divider;
 
        if (!params->curr_dr_freq) {
@@ -912,9 +914,7 @@ int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
        else
                mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
 
-       mcp_clkctrl = cdns_readl(cdns, mcp_clkctrl_off);
-       mcp_clkctrl |= divider;
-       cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
+       cdns_updatel(cdns, mcp_clkctrl_off, CDNS_MCP_CLK_MCLKD_MASK, divider);
 
        return 0;
 }