diff --git a/Documentation/devicetree/bindings/sound/fsl,mqs.txt b/Documentation/devicetree/bindings/sound/fsl,mqs.txt
index 7c288461e9ce7ec6133446cf30cfa19b230229d5..092083d3a3359565206f38164895b12d3c6fe0c2 100644
--- a/Documentation/devicetree/bindings/sound/fsl,mqs.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,mqs.txt
@@ -2,7 +2,8 @@ fsl,mqs audio CODEC
 
 Required properties:
 
-  - compatible : must contain one of "fsl,imx6sx-mqs" and "fsl,codec-mqs"
+  - compatible : must contain one of "fsl,imx6sx-mqs", "fsl,codec-mqs"
+		"fsl,imx8qm-mqs".
 
   - clocks : a list of phandles + clock-specifiers, one for each entry in
     clock-names
diff --git a/sound/soc/codecs/fsl_mqs.c b/sound/soc/codecs/fsl_mqs.c
index a7ef37e1e4e50ee6b21b885399d0508957b33830..e645a7d92429936b6a07a8c820504c9ac82fc75d 100644
--- a/sound/soc/codecs/fsl_mqs.c
+++ b/sound/soc/codecs/fsl_mqs.c
@@ -22,6 +22,18 @@
 #include <sound/initval.h>
 
 
+#define REG_MQS_CTRL		0x00
+
+#define MQS_EN_MASK			(0x1 << 28)
+#define MQS_EN_SHIFT			(28)
+#define MQS_SW_RST_MASK			(0x1 << 24)
+#define MQS_SW_RST_SHIFT		(24)
+#define MQS_OVERSAMPLE_MASK		(0x1 << 20)
+#define MQS_OVERSAMPLE_SHIFT		(20)
+#define MQS_CLK_DIV_MASK		(0xFF << 0)
+#define MQS_CLK_DIV_SHIFT		(0)
+
+
 /* codec private data */
 struct fsl_mqs {
 	struct platform_device *pdev;
@@ -32,12 +44,14 @@ struct fsl_mqs {
 	unsigned int reg_mqs_ctrl;
 
 	struct clk *mclk;
+	struct clk *ipg;
 
 	unsigned long mclk_rate;
 
 	int sysclk_rate;
 	int bclk;
 	int lrclk;
+	bool use_gpr;
 	char name[32];
 };
 
@@ -66,10 +80,21 @@ static int fsl_mqs_hw_params(struct snd_pcm_substream *substream,
 	res = mqs_priv->mclk_rate % (32 * 2 * mqs_priv->lrclk * 8);
 
 	if (res == 0 && div > 0 && div <= 256) {
-		regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2,
-			IMX6SX_GPR2_MQS_CLK_DIV_MASK, (div-1) << IMX6SX_GPR2_MQS_CLK_DIV_SHIFT);
-		regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2,
-			IMX6SX_GPR2_MQS_OVERSAMPLE_MASK, 0 << IMX6SX_GPR2_MQS_OVERSAMPLE_SHIFT);
+		if (mqs_priv->use_gpr) {
+			regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2,
+				IMX6SX_GPR2_MQS_CLK_DIV_MASK,
+				(div-1) << IMX6SX_GPR2_MQS_CLK_DIV_SHIFT);
+			regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2,
+				IMX6SX_GPR2_MQS_OVERSAMPLE_MASK,
+				0 << IMX6SX_GPR2_MQS_OVERSAMPLE_SHIFT);
+		} else {
+			regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL,
+						MQS_CLK_DIV_MASK,
+						(div-1) << MQS_CLK_DIV_SHIFT);
+			regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL,
+						MQS_OVERSAMPLE_MASK,
+						0 << MQS_OVERSAMPLE_SHIFT);
+		}
 	} else
 		dev_err(&mqs_priv->pdev->dev, "can't get proper divider\n");
 
@@ -119,8 +144,19 @@ static int fsl_mqs_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_component *component = dai->component;
 	struct fsl_mqs *mqs_priv = snd_soc_component_get_drvdata(component);
 
-	regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2, IMX6SX_GPR2_MQS_EN_MASK,
+	if (mqs_priv->ipg)
+		clk_prepare_enable(mqs_priv->ipg);
+
+	if (mqs_priv->mclk)
+		clk_prepare_enable(mqs_priv->mclk);
+
+	if (mqs_priv->use_gpr)
+		regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2, IMX6SX_GPR2_MQS_EN_MASK,
 					1 << IMX6SX_GPR2_MQS_EN_SHIFT);
+	else
+		regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL,
+					MQS_EN_MASK,
+					1 << MQS_EN_SHIFT);
 	return 0;
 }
 
@@ -130,9 +166,18 @@ static void fsl_mqs_shutdown(struct snd_pcm_substream *substream,
 	struct snd_soc_component *component = dai->component;
 	struct fsl_mqs *mqs_priv = snd_soc_component_get_drvdata(component);
 
-	regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2,
+	if (mqs_priv->use_gpr)
+		regmap_update_bits(mqs_priv->gpr, IOMUXC_GPR2,
 					IMX6SX_GPR2_MQS_EN_MASK, 0);
+	else
+		regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL,
+					MQS_EN_MASK, 0);
+
+	if (mqs_priv->mclk)
+		clk_disable_unprepare(mqs_priv->mclk);
 
+	if (mqs_priv->ipg)
+		clk_disable_unprepare(mqs_priv->ipg);
 }
 
 
@@ -158,11 +203,21 @@ static struct snd_soc_dai_driver fsl_mqs_dai = {
 	.ops = &fsl_mqs_dai_ops,
 };
 
+static const struct regmap_config fsl_mqs_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = REG_MQS_CTRL,
+	.cache_type = REGCACHE_NONE,
+};
+
 static int fsl_mqs_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *gpr_np = 0;
 	struct fsl_mqs *mqs_priv;
+	struct resource *res;
+	void __iomem *regs;
 	int ret = 0;
 
 	mqs_priv = devm_kzalloc(&pdev->dev, sizeof(*mqs_priv), GFP_KERNEL);
@@ -172,18 +227,45 @@ static int fsl_mqs_probe(struct platform_device *pdev)
 	mqs_priv->pdev = pdev;
 	strncpy(mqs_priv->name, np->name, sizeof(mqs_priv->name) - 1);
 
-	gpr_np = of_parse_phandle(np, "gpr", 0);
-	if (IS_ERR(gpr_np)) {
-		dev_err(&pdev->dev, "failed to get gpr node by phandle\n");
-		ret = PTR_ERR(gpr_np);
-		goto out;
-	}
-
-	mqs_priv->gpr = syscon_node_to_regmap(gpr_np);
-	if (IS_ERR(mqs_priv->gpr)) {
-		dev_err(&pdev->dev, "failed to get gpr regmap\n");
-		ret = PTR_ERR(mqs_priv->gpr);
-		goto out;
+	if (of_device_is_compatible(np, "fsl,imx8qm-mqs"))
+		mqs_priv->use_gpr = false;
+	else
+		mqs_priv->use_gpr = true;
+
+	if (mqs_priv->use_gpr) {
+		gpr_np = of_parse_phandle(np, "gpr", 0);
+		if (IS_ERR(gpr_np)) {
+			dev_err(&pdev->dev, "failed to get gpr node by phandle\n");
+			ret = PTR_ERR(gpr_np);
+			goto out;
+		}
+
+		mqs_priv->gpr = syscon_node_to_regmap(gpr_np);
+		if (IS_ERR(mqs_priv->gpr)) {
+			dev_err(&pdev->dev, "failed to get gpr regmap\n");
+			ret = PTR_ERR(mqs_priv->gpr);
+			goto out;
+		}
+	} else {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		regs = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(regs))
+			return PTR_ERR(regs);
+
+		mqs_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
+				"core", regs, &fsl_mqs_regmap_config);
+		if (IS_ERR(mqs_priv->regmap)) {
+			dev_err(&pdev->dev, "failed to init regmap: %ld\n",
+					PTR_ERR(mqs_priv->regmap));
+			return PTR_ERR(mqs_priv->regmap);
+		}
+
+		mqs_priv->ipg = devm_clk_get(&pdev->dev, "core");
+		if (IS_ERR(mqs_priv->ipg)) {
+			dev_err(&pdev->dev, "failed to get the clock: %ld\n",
+					PTR_ERR(mqs_priv->ipg));
+			goto out;
+		}
 	}
 
 	mqs_priv->mclk = devm_clk_get(&pdev->dev, "mclk");
@@ -246,6 +328,7 @@ static const struct dev_pm_ops fsl_mqs_pm_ops = {
 };
 
 static const struct of_device_id fsl_mqs_dt_ids[] = {
+	{ .compatible = "fsl,imx8qm-mqs", },
 	{ .compatible = "fsl,imx6sx-mqs", },
 	{}
 };