msm: pil-q6v5: Update clock calls to fix MSS PIL with full bootchain

LPASS and MSS have different requirements related to the order that
their clocks are enable/disabled and resets are asserted/de-asserted.
Currently, this causes 'clock stuck off' warnings in the kernel logs
when MSS is booted multiple times.

Fix this by reordering the MSS clock calls so that the core_clk reset
is de-asserted prior to enabling its iface_clk. Because doing this
would break LPASS (which requires iface_clk to be on for the core_clk
reset de-assertion to work), we are forced to separate the MSS and
LPASS clock sequences into separate functions and move them into their
respective PIL files.

MSS PIL also requires an additional clock that is added as part of
this fixup. The gcc_mss_q6_bimc_axi_clk is needed for the MSS Q6
to access memory.

Change-Id: Id877781f201a7267f72b52045ed2b87ebf7b4e05
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 56be717..6a30940 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -74,6 +74,55 @@
 	return regulator_disable(drv->vreg);
 }
 
+static int pil_mss_enable_clks(struct q6v5_data *drv)
+{
+	int ret;
+
+	ret = clk_prepare_enable(drv->ahb_clk);
+	if (ret)
+		goto err_ahb_clk;
+	ret = clk_reset(drv->core_clk, CLK_RESET_DEASSERT);
+	if (ret)
+		goto err_reset;
+	ret = clk_prepare_enable(drv->core_clk);
+	if (ret)
+		goto err_core_clk;
+	ret = clk_prepare_enable(drv->axi_clk);
+	if (ret)
+		goto err_axi_clk;
+	ret = clk_prepare_enable(drv->reg_clk);
+	if (ret)
+		goto err_reg_clk;
+	ret = clk_prepare_enable(drv->rom_clk);
+	if (ret)
+		goto err_rom_clk;
+
+	return 0;
+
+err_rom_clk:
+	clk_disable_unprepare(drv->reg_clk);
+err_reg_clk:
+	clk_disable_unprepare(drv->axi_clk);
+err_axi_clk:
+	clk_disable_unprepare(drv->core_clk);
+err_core_clk:
+	clk_reset(drv->core_clk, CLK_RESET_ASSERT);
+err_reset:
+	clk_disable_unprepare(drv->ahb_clk);
+err_ahb_clk:
+	return ret;
+}
+
+static void pil_mss_disable_clks(struct q6v5_data *drv)
+{
+	clk_disable_unprepare(drv->rom_clk);
+	clk_disable_unprepare(drv->reg_clk);
+	clk_disable_unprepare(drv->axi_clk);
+	clk_disable_unprepare(drv->core_clk);
+	clk_reset(drv->core_clk, CLK_RESET_ASSERT);
+	clk_disable_unprepare(drv->ahb_clk);
+}
+
 static int wait_for_mba_ready(struct device *dev)
 {
 	struct q6v5_data *drv = dev_get_drvdata(dev);
@@ -123,11 +172,11 @@
 	 */
 	if (drv->is_booted == false) {
 		pil_mss_power_up(pil->dev);
-		pil_q6v5_enable_clks(pil);
+		pil_mss_enable_clks(drv);
 	}
 	pil_q6v5_shutdown(pil);
 
-	pil_q6v5_disable_clks(pil);
+	pil_mss_disable_clks(drv);
 	pil_mss_power_down(pil->dev);
 
 	writel_relaxed(1, drv->restart_reg);
@@ -155,7 +204,7 @@
 	if (ret)
 		goto err_power;
 
-	ret = pil_q6v5_enable_clks(pil);
+	ret = pil_mss_enable_clks(drv);
 	if (ret)
 		goto err_clks;
 
@@ -190,7 +239,7 @@
 err_auth:
 	pil_q6v5_shutdown(pil);
 err_q6v5_reset:
-	pil_q6v5_disable_clks(pil);
+	pil_mss_disable_clks(drv);
 err_clks:
 	pil_mss_power_down(pil->dev);
 err_power:
@@ -259,9 +308,25 @@
 		return ret;
 	}
 
-	drv->ss_clk = devm_clk_get(&pdev->dev, "mem_clk");
-	if (IS_ERR(drv->ss_clk))
-		return PTR_ERR(drv->ss_clk);
+	drv->ahb_clk = devm_clk_get(&pdev->dev, "iface_clk");
+	if (IS_ERR(drv->ahb_clk))
+		return PTR_ERR(drv->ahb_clk);
+
+	drv->core_clk = devm_clk_get(&pdev->dev, "core_clk");
+	if (IS_ERR(drv->core_clk))
+		return PTR_ERR(drv->core_clk);
+
+	drv->axi_clk = devm_clk_get(&pdev->dev, "bus_clk");
+	if (IS_ERR(drv->axi_clk))
+		return PTR_ERR(drv->axi_clk);
+
+	drv->reg_clk = devm_clk_get(&pdev->dev, "reg_clk");
+	if (IS_ERR(drv->reg_clk))
+		return PTR_ERR(drv->reg_clk);
+
+	drv->rom_clk = devm_clk_get(&pdev->dev, "mem_clk");
+	if (IS_ERR(drv->rom_clk))
+		return PTR_ERR(drv->rom_clk);
 
 	drv->pil = msm_pil_register(desc);
 	if (IS_ERR(drv->pil))