aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorDzmitry Sankouski <dsankouski@gmail.com>2021-10-17 13:44:30 +0300
committerTom Rini <trini@konsulko.com>2021-10-31 08:46:44 -0400
commit90496afc27525a9da373f94e84b99bcfd313f2ec (patch)
tree7aafc4646cabc5eac40e6072d118940857ee58b7 /arch
parent7964c30541dfb3411c7aeec94af483185ee58c28 (diff)
downloadu-boot-90496afc27525a9da373f94e84b99bcfd313f2ec.zip
u-boot-90496afc27525a9da373f94e84b99bcfd313f2ec.tar.gz
u-boot-90496afc27525a9da373f94e84b99bcfd313f2ec.tar.bz2
clocks: qcom: add clocks for SDM845 debug uart
Allows to change clock frequency of debug uart, thus supporting wide range of baudrates. Enable / disable functionality is not implemented yet. In most use cases of SDM845 (i.e. mobile phones and tablets) it's not needed, because qualcomm first stage bootloader leaves it initialized, and on the other hand there's no possibility to replace signed first stage bootloader with u-boot. Signed-off-by: Dzmitry Sankouski <dsankouski@gmail.com> Cc: Ramon Fried <rfried.dev@gmail.com> Cc: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-snapdragon/clock-sdm845.c92
-rw-r--r--arch/arm/mach-snapdragon/clock-snapdragon.c1
-rw-r--r--arch/arm/mach-snapdragon/clock-snapdragon.h3
3 files changed, 95 insertions, 1 deletions
diff --git a/arch/arm/mach-snapdragon/clock-sdm845.c b/arch/arm/mach-snapdragon/clock-sdm845.c
new file mode 100644
index 0000000..9572639
--- /dev/null
+++ b/arch/arm/mach-snapdragon/clock-sdm845.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Clock drivers for Qualcomm SDM845
+ *
+ * (C) Copyright 2017 Jorge Ramirez Ortiz <jorge.ramirez-ortiz@linaro.org>
+ * (C) Copyright 2021 Dzmitry Sankouski <dsankouski@gmail.com>
+ *
+ * Based on Little Kernel driver, simplified
+ */
+
+#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"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+struct freq_tbl {
+ uint freq;
+ uint src;
+ u8 pre_div;
+ u16 m;
+ u16 n;
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+ F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
+ F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
+ F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
+ F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
+ F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
+ F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
+ F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
+ F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
+ F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
+ F(100000000, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0),
+ F(102400000, CFG_CLK_SRC_GPLL0_EVEN, 1, 128, 375),
+ F(112000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 28, 75),
+ F(117964800, CFG_CLK_SRC_GPLL0_EVEN, 1, 6144, 15625),
+ F(120000000, CFG_CLK_SRC_GPLL0_EVEN, 2.5, 0, 0),
+ F(128000000, CFG_CLK_SRC_GPLL0, 1, 16, 75),
+ { }
+};
+
+static const struct bcr_regs uart2_regs = {
+ .cfg_rcgr = SE9_UART_APPS_CFG_RCGR,
+ .cmd_rcgr = SE9_UART_APPS_CMD_RCGR,
+ .M = SE9_UART_APPS_M,
+ .N = SE9_UART_APPS_N,
+ .D = SE9_UART_APPS_D,
+};
+
+const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, uint rate)
+{
+ if (!f)
+ return NULL;
+
+ if (!f->freq)
+ return f;
+
+ for (; f->freq; f++)
+ if (rate <= f->freq)
+ return f;
+
+ /* Default to our fastest rate */
+ return f - 1;
+}
+
+static int clk_init_uart(struct msm_clk_priv *priv, uint rate)
+{
+ const struct freq_tbl *freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
+
+ clk_rcg_set_rate_mnd(priv->base, &uart2_regs,
+ freq->pre_div, freq->m, freq->n, freq->src);
+
+ return 0;
+}
+
+ulong msm_set_rate(struct clk *clk, ulong rate)
+{
+ struct msm_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case 0x58: /*UART2*/
+ return clk_init_uart(priv, rate);
+ default:
+ return 0;
+ }
+}
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/arch/arm/mach-snapdragon/clock-snapdragon.c
index 2b76371..3deb08a 100644
--- a/arch/arm/mach-snapdragon/clock-snapdragon.c
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.c
@@ -135,6 +135,7 @@ static const struct udevice_id msm_clk_ids[] = {
{ .compatible = "qcom,gcc-apq8016" },
{ .compatible = "qcom,gcc-msm8996" },
{ .compatible = "qcom,gcc-apq8096" },
+ { .compatible = "qcom,gcc-sdm845" },
{ }
};
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/arch/arm/mach-snapdragon/clock-snapdragon.h
index 58fab40..2ac53b5 100644
--- a/arch/arm/mach-snapdragon/clock-snapdragon.h
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * Qualcomm APQ8016, APQ8096
+ * Qualcomm APQ8016, APQ8096, SDM845
*
* (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
*/
@@ -9,6 +9,7 @@
#define CFG_CLK_SRC_CXO (0 << 8)
#define CFG_CLK_SRC_GPLL0 (1 << 8)
+#define CFG_CLK_SRC_GPLL0_EVEN (6 << 8)
#define CFG_CLK_SRC_MASK (7 << 8)
struct pll_vote_clk {