clocks: qcom: Add clock driver for QCS404 SoC
Currently this clock driver initializes clocks for UART and eMMC. Along
with this import "qcom,gcc-qcs404.h" header from Linux mainline to
support DT bindings.
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/arch/arm/mach-snapdragon/clock-qcs404.c
new file mode 100644
index 0000000..bb8a6fe
--- /dev/null
+++ b/arch/arm/mach-snapdragon/clock-qcs404.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Clock drivers for Qualcomm QCS404
+ *
+ * (C) Copyright 2022 Sumit Garg <sumit.garg@linaro.org>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include "clock-snapdragon.h"
+
+#include <dt-bindings/clock/qcom,gcc-qcs404.h>
+
+/* GPLL0 clock control registers */
+#define GPLL0_STATUS_ACTIVE BIT(31)
+
+static struct vote_clk gcc_blsp1_ahb_clk = {
+ .cbcr_reg = BLSP1_AHB_CBCR,
+ .ena_vote = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .vote_bit = BIT(10) | BIT(5) | BIT(4),
+};
+
+static const struct bcr_regs uart2_regs = {
+ .cfg_rcgr = BLSP1_UART2_APPS_CFG_RCGR,
+ .cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR,
+ .M = BLSP1_UART2_APPS_M,
+ .N = BLSP1_UART2_APPS_N,
+ .D = BLSP1_UART2_APPS_D,
+};
+
+static const struct bcr_regs sdc_regs = {
+ .cfg_rcgr = SDCC_CFG_RCGR(1),
+ .cmd_rcgr = SDCC_CMD_RCGR(1),
+ .M = SDCC_M(1),
+ .N = SDCC_N(1),
+ .D = SDCC_D(1),
+};
+
+static struct pll_vote_clk gpll0_vote_clk = {
+ .status = GPLL0_STATUS,
+ .status_bit = GPLL0_STATUS_ACTIVE,
+ .ena_vote = APCS_GPLL_ENA_VOTE,
+ .vote_bit = BIT(0),
+};
+
+ulong msm_set_rate(struct clk *clk, ulong rate)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case GCC_BLSP1_UART2_APPS_CLK:
+ /* UART: 115200 */
+ clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 0, 12, 125,
+ CFG_CLK_SRC_CXO);
+ clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
+ break;
+ case GCC_BLSP1_AHB_CLK:
+ clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk);
+ break;
+ case GCC_SDCC1_APPS_CLK:
+ /* SDCC1: 200MHz */
+ clk_rcg_set_rate_mnd(priv->base, &sdc_regs, 4, 0, 0,
+ CFG_CLK_SRC_GPLL0);
+ clk_enable_gpll0(priv->base, &gpll0_vote_clk);
+ clk_enable_cbc(priv->base + SDCC_APPS_CBCR(1));
+ break;
+ case GCC_SDCC1_AHB_CLK:
+ clk_enable_cbc(priv->base + SDCC_AHB_CBCR(1));
+ break;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/arch/arm/mach-snapdragon/clock-snapdragon.c
index 3deb08a..5652d2f 100644
--- a/arch/arm/mach-snapdragon/clock-snapdragon.c
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.c
@@ -136,6 +136,7 @@
{ .compatible = "qcom,gcc-msm8996" },
{ .compatible = "qcom,gcc-apq8096" },
{ .compatible = "qcom,gcc-sdm845" },
+ { .compatible = "qcom,gcc-qcs404" },
{ }
};
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h b/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h
new file mode 100644
index 0000000..4dc96b9
--- /dev/null
+++ b/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Qualcomm QCS404 sysmap
+ *
+ * (C) Copyright 2022 Sumit Garg <sumit.garg@linaro.org>
+ */
+#ifndef _MACH_SYSMAP_QCS404_H
+#define _MACH_SYSMAP_QCS404_H
+
+#define GICD_BASE (0x0b000000)
+#define GICC_BASE (0x0b002000)
+
+/* Clocks: (from CLK_CTL_BASE) */
+#define GPLL0_STATUS (0x21000)
+#define APCS_GPLL_ENA_VOTE (0x45000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004)
+
+/* BLSP1 AHB clock (root clock for BLSP) */
+#define BLSP1_AHB_CBCR 0x1008
+
+/* Uart clock control registers */
+#define BLSP1_UART2_BCR (0x3028)
+#define BLSP1_UART2_APPS_CBCR (0x302C)
+#define BLSP1_UART2_APPS_CMD_RCGR (0x3034)
+#define BLSP1_UART2_APPS_CFG_RCGR (0x3038)
+#define BLSP1_UART2_APPS_M (0x303C)
+#define BLSP1_UART2_APPS_N (0x3040)
+#define BLSP1_UART2_APPS_D (0x3044)
+
+/* SD controller clock control registers */
+#define SDCC_BCR(n) (((n) * 0x1000) + 0x41000)
+#define SDCC_CMD_RCGR(n) (((n) * 0x1000) + 0x41004)
+#define SDCC_CFG_RCGR(n) (((n) * 0x1000) + 0x41008)
+#define SDCC_M(n) (((n) * 0x1000) + 0x4100C)
+#define SDCC_N(n) (((n) * 0x1000) + 0x41010)
+#define SDCC_D(n) (((n) * 0x1000) + 0x41014)
+#define SDCC_APPS_CBCR(n) (((n) * 0x1000) + 0x41018)
+#define SDCC_AHB_CBCR(n) (((n) * 0x1000) + 0x4101C)
+
+#endif