mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-05 19:10:13 +00:00
90496afc27
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>
92 lines
2.2 KiB
C
92 lines
2.2 KiB
C
// 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;
|
|
}
|
|
}
|