mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-18 10:48:51 +00:00
93 lines
2.2 KiB
C
93 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;
|
||
|
}
|
||
|
}
|