Merge tag 'arm-soc/for-4.15/drivers-part2' of http://github.com/Broadcom/stblinux into next/drivers

Pull "Broadcom drivers changes for 4.15 (part 2)" from Florian Fainelli:

This pull request contains Broadcom ARM/ARM64/MIPS SoCs changes for 4.15
(second part), please pull the following:

- Markus updates the Broadcom STB DPFE driver to avoid loading the firmware when
  unnecessary to accomodate for specific platform restrictions

- Florian adds support for the Broadcom Hurricane 2 SoC iProc PLL clock needed
  to get the proper CPU clock frequency

* tag 'arm-soc/for-4.15/drivers-part2' of http://github.com/Broadcom/stblinux:
  clk: bcm: Add Broadcom Hurricane 2 clock support
  memory: brcmstb: dpfe: skip downloading firmware when possible
  memory: brcmstb: dpfe: introduce is_dcpu_enabled()
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig
index 1d9187d..4c4bd85 100644
--- a/drivers/clk/bcm/Kconfig
+++ b/drivers/clk/bcm/Kconfig
@@ -30,6 +30,15 @@
 	help
 	  Enable common clock framework support for the Broadcom Cygnus SoC
 
+config CLK_BCM_HR2
+	bool "Broadcom Hurricane 2 clock support"
+	depends on ARCH_BCM_HR2 || COMPILE_TEST
+	select COMMON_CLK_IPROC
+	default ARCH_BCM_HR2
+	help
+	  Enable common clock framework support for the Broadcom Hurricane 2
+	  SoC
+
 config CLK_BCM_NSP
 	bool "Broadcom Northstar/Northstar Plus clock support"
 	depends on ARCH_BCM_5301X || ARCH_BCM_NSP || COMPILE_TEST
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile
index a0c14fa..7551441 100644
--- a/drivers/clk/bcm/Makefile
+++ b/drivers/clk/bcm/Makefile
@@ -8,6 +8,7 @@
 obj-$(CONFIG_ARCH_BCM2835)	+= clk-bcm2835-aux.o
 obj-$(CONFIG_ARCH_BCM_53573)	+= clk-bcm53573-ilp.o
 obj-$(CONFIG_CLK_BCM_CYGNUS)	+= clk-cygnus.o
+obj-$(CONFIG_CLK_BCM_HR2)	+= clk-hr2.o
 obj-$(CONFIG_CLK_BCM_NSP)	+= clk-nsp.o
 obj-$(CONFIG_CLK_BCM_NS2)	+= clk-ns2.o
 obj-$(CONFIG_CLK_BCM_SR)	+= clk-sr.o
diff --git a/drivers/clk/bcm/clk-hr2.c b/drivers/clk/bcm/clk-hr2.c
new file mode 100644
index 0000000..f7c5b73
--- /dev/null
+++ b/drivers/clk/bcm/clk-hr2.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "clk-iproc.h"
+
+static void __init hr2_armpll_init(struct device_node *node)
+{
+	iproc_armpll_setup(node);
+}
+CLK_OF_DECLARE(hr2_armpll, "brcm,hr2-armpll", hr2_armpll_init);
diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c
index 21242c4..0a7bdbe 100644
--- a/drivers/memory/brcmstb_dpfe.c
+++ b/drivers/memory/brcmstb_dpfe.c
@@ -202,17 +202,26 @@ static const u32 dpfe_commands[DPFE_CMD_MAX][MSG_FIELD_MAX] = {
 	},
 };
 
+static bool is_dcpu_enabled(void __iomem *regs)
+{
+	u32 val;
+
+	val = readl_relaxed(regs + REG_DCPU_RESET);
+
+	return !(val & DCPU_RESET_MASK);
+}
+
 static void __disable_dcpu(void __iomem *regs)
 {
 	u32 val;
 
-	/* Check if DCPU is running */
+	if (!is_dcpu_enabled(regs))
+		return;
+
+	/* Put DCPU in reset if it's running. */
 	val = readl_relaxed(regs + REG_DCPU_RESET);
-	if (!(val & DCPU_RESET_MASK)) {
-		/* Put DCPU in reset */
-		val |= (1 << DCPU_RESET_SHIFT);
-		writel_relaxed(val, regs + REG_DCPU_RESET);
-	}
+	val |= (1 << DCPU_RESET_SHIFT);
+	writel_relaxed(val, regs + REG_DCPU_RESET);
 }
 
 static void __enable_dcpu(void __iomem *regs)
@@ -422,13 +431,25 @@ static int brcmstb_dpfe_download_firmware(struct platform_device *pdev,
 	const void *fw_blob;
 	int ret;
 
+	priv = platform_get_drvdata(pdev);
+
+	/*
+	 * Skip downloading the firmware if the DCPU is already running and
+	 * responding to commands.
+	 */
+	if (is_dcpu_enabled(priv->regs)) {
+		u32 response[MSG_FIELD_MAX];
+
+		ret = __send_command(priv, DPFE_CMD_GET_INFO, response);
+		if (!ret)
+			return 0;
+	}
+
 	ret = request_firmware(&fw, FIRMWARE_NAME, dev);
 	/* request_firmware() prints its own error messages. */
 	if (ret)
 		return ret;
 
-	priv = platform_get_drvdata(pdev);
-
 	ret = __verify_firmware(init, fw);
 	if (ret)
 		return -EFAULT;