8 #include <soc/addressmap.h>
52 #define PLL_DIVISORS(hz, _nr, _no) {\
53 .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
54 _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
55 (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
56 "divisors on line " STRINGIFY(__LINE__));
73 #define PLL_OD_MSK (0x0F)
75 #define PLL_NR_MSK (0x3F << 8)
76 #define PLL_NR_SHIFT (8)
79 #define PLL_NF_MSK (0x1FFF)
82 #define PLL_BWADJ_MSK (0x0FFF)
85 #define PLL_RESET_MSK (1 << 5)
86 #define PLL_RESET (1 << 5)
87 #define PLL_RESET_RESUME (0 << 5)
91 #define CORE_SEL_PLL_MSK (1 << 15)
92 #define CORE_SEL_APLL (0 << 15)
93 #define CORE_SEL_GPLL (1 << 15)
96 #define A12_DIV_SHIFT (8)
97 #define A12_DIV_MSK (0x1F << 8)
100 #define MP_DIV_SHIFT (4)
101 #define MP_DIV_MSK (0xF << 4)
104 #define M0_DIV_MSK (0xF)
108 #define PD_BUS_SEL_PLL_MSK (1 << 15)
109 #define PD_BUS_SEL_CPLL (0 << 15)
110 #define PD_BUS_SEL_GPLL (1 << 15)
115 #define PD_BUS_PCLK_DIV_SHIFT (12)
116 #define PD_BUS_PCLK_DIV_MSK (0x7 << 12)
121 #define PD_BUS_HCLK_DIV_SHIFT (8)
122 #define PD_BUS_HCLK_DIV_MSK (0x3 << 8)
127 #define PD_BUS_ACLK_DIV0_SHIFT (3)
128 #define PD_BUS_ACLK_DIV0_MASK (0x1f << 3)
129 #define PD_BUS_ACLK_DIV1_SHIFT (0)
130 #define PD_BUS_ACLK_DIV1_MASK (0x7 << 0)
134 #define PERI_SEL_PLL_MSK (1 << 15)
135 #define PERI_SEL_CPLL (0 << 15)
136 #define PERI_SEL_GPLL (1 << 15)
141 #define PERI_PCLK_DIV_SHIFT (12)
142 #define PERI_PCLK_DIV_MSK (0x7 << 12)
147 #define PERI_HCLK_DIV_SHIFT (8)
148 #define PERI_HCLK_DIV_MSK (0x3 << 8)
154 #define PERI_ACLK_DIV_SHIFT (0x0)
155 #define PERI_ACLK_DIV_MSK (0x1F)
158 #define L2_DIV_MSK (0x7)
160 #define ATCLK_DIV_MSK (0x1F << 4)
161 #define ATCLK_DIV_SHIFT (4)
163 #define PCLK_DBG_DIV_MSK (0x1F << 9)
164 #define PCLK_DBG_DIV_SHIFT (9)
166 #define APLL_MODE_MSK (0x3)
167 #define APLL_MODE_SLOW (0)
168 #define APLL_MODE_NORM (1)
170 #define DPLL_MODE_MSK (0x3 << 4)
171 #define DPLL_MODE_SLOW (0 << 4)
172 #define DPLL_MODE_NORM (1 << 4)
174 #define CPLL_MODE_MSK (0x3 << 8)
175 #define CPLL_MODE_SLOW (0 << 8)
176 #define CPLL_MODE_NORM (1 << 8)
178 #define GPLL_MODE_MSK (0x3 << 12)
179 #define GPLL_MODE_SLOW (0 << 12)
180 #define GPLL_MODE_NORM (1 << 12)
182 #define NPLL_MODE_MSK (0x3 << 14)
183 #define NPLL_MODE_SLOW (0 << 14)
184 #define NPLL_MODE_NORM (1 << 14)
186 #define SOCSTS_DPLL_LOCK (1 << 5)
187 #define SOCSTS_APLL_LOCK (1 << 6)
188 #define SOCSTS_CPLL_LOCK (1 << 7)
189 #define SOCSTS_GPLL_LOCK (1 << 8)
190 #define SOCSTS_NPLL_LOCK (1 << 9)
192 #define VCO_MAX_KHZ (2200 * (MHz/KHz))
193 #define VCO_MIN_KHZ (440 * (MHz/KHz))
194 #define OUTPUT_MAX_KHZ (2200 * (MHz/KHz))
195 #define OUTPUT_MIN_KHZ 27500
196 #define FREF_MAX_KHZ (2200 * (MHz/KHz))
197 #define FREF_MIN_KHZ 269
203 u32 output_khz = vco_khz / div->
no;
206 "NO = %d (VCO = %uKHz, output = %uKHz)\n",
207 pll_con, div->
nf, div->
nr, div->
no, vco_khz, output_khz);
210 (div->
no == 1 || !(div->
no % 2)));
355 dpll_cfg = (
struct pll_div){.
nf = 50, .nr = 2, .no = 2};
358 dpll_cfg = (
struct pll_div){.
nf = 400, .nr = 9, .no = 2};
361 dpll_cfg = (
struct pll_div){.
nf = 500, .nr = 9, .no = 2};
364 dpll_cfg = (
struct pll_div){.
nf = 100, .nr = 3, .no = 1};
367 die(
"Unsupported SDRAM frequency, add to clock.c!");
390 u32 phy_ctl_srstn_shift = 4 + 5 *
ch;
391 u32 ctl_psrstn_shift = 3 + 5 *
ch;
392 u32 ctl_srstn_shift = 2 + 5 *
ch;
393 u32 phy_psrstn_shift = 1 + 5 *
ch;
394 u32 phy_srstn_shift = 5 *
ch;
398 phy << phy_ctl_srstn_shift) |
399 RK_CLRSETBITS(1 << ctl_psrstn_shift, ctl << ctl_psrstn_shift) |
400 RK_CLRSETBITS(1 << ctl_srstn_shift, ctl << ctl_srstn_shift) |
401 RK_CLRSETBITS(1 << phy_psrstn_shift, phy << phy_psrstn_shift) |
402 RK_CLRSETBITS(1 << phy_srstn_shift, phy << phy_srstn_shift));
407 u32 phy_ctl_srstn_shift = 4 + 5 *
ch;
411 n << phy_ctl_srstn_shift));
416 int src_clk_div =
GPLL_HZ / hz;
418 assert((src_clk_div - 1 <= 127) && (src_clk_div * hz ==
GPLL_HZ));
424 1 << 7 | (src_clk_div - 1) << 0));
429 1 << 15 | (src_clk_div - 1) << 8));
434 1 << 7 | (src_clk_div - 1) << 0));
462 1 << 15 | 0 << 12 | 1 << 8 | 0 << 0));
467 d = (hz / v) & (0xffff);
488 assert((div - 1 <= 63) && (div * hz == 32 *
KHz));
497 u32 diff_khz, best_diff_khz;
498 const u32 max_nr = 1 << 6, max_nf = 1 << 12, max_no = 1 << 4;
501 u32 freq_khz = freq_hz /
KHz;
504 printk(
BIOS_ERR,
"%s: the frequency can not be 0 Hz\n", __func__);
518 vco_khz = freq_khz * no;
522 if (vco_khz < VCO_MIN_KHZ || vco_khz >
VCO_MAX_KHZ || no > max_no) {
524 " for Frequency (%uHz).\n", __func__, freq_hz);
530 best_diff_khz = vco_khz;
531 for (nr = 1; nr < max_nr && best_diff_khz; nr++) {
532 fref_khz = ref_khz / nr;
538 nf = vco_khz / fref_khz;
541 diff_khz = vco_khz - nf * fref_khz;
542 if (nf + 1 < max_nf && diff_khz > fref_khz / 2) {
544 diff_khz = fref_khz - diff_khz;
547 if (diff_khz >= best_diff_khz)
550 best_diff_khz = diff_khz;
555 if (best_diff_khz > 4 * (
MHz/
KHz)) {
557 "difference is %u Hz,exceed 4MHZ\n", __func__, freq_hz,
558 best_diff_khz *
KHz);
599 0 << 6 | (div - 1) << 0));
605 0 << 14 | (div - 1) << 8));
612 struct pll_div npll_config = {0};
640 (lcdc_div - 1) << 8 | 2 << 0));
646 (lcdc_div - 1) << 8 | 2 << 6));
static void write32(void *addr, uint32_t val)
static uint32_t read32(const void *addr)
#define assert(statement)
#define DIV_ROUND_UP(x, y)
#define printk(level,...)
void __noreturn die(const char *fmt,...)
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
static struct dramc_channel const ch[2]
static struct rk3288_grf_regs *const rk3288_grf
#define RK_CLRSETBITS(clr, set)
static int rkclk_set_pll(u32 *pll_con, const struct pll_div *div)
#define PLL_DIVISORS(hz, _nr, _no)
#define PD_BUS_ACLK_DIV0_MASK
#define PCLK_DBG_DIV_SHIFT
#define PERI_PCLK_DIV_MSK
void rkclk_ddr_phy_ctl_reset(u32 ch, u32 n)
static const struct pll_div apll_1800_cfg
void rkclk_configure_cpu(enum apll_frequencies apll_freq)
#define PD_BUS_PCLK_DIV_MSK
#define PERI_HCLK_DIV_SHIFT
void rkclk_ddr_reset(u32 ch, u32 ctl, u32 phy)
static struct rk3288_cru_reg *const cru_ptr
#define PD_BUS_ACLK_DIV1_MASK
int rkclk_was_watchdog_reset(void)
void rkclk_configure_tsadc(unsigned int hz)
unsigned int rkclk_i2c_clock_for_bus(unsigned int bus)
#define PERI_HCLK_DIV_MSK
void rkclk_configure_vop_aclk(u32 vop_id, u32 aclk_hz)
static int pll_para_config(u32 freq_hz, struct pll_div *div, u32 *ext_div)
void rkclk_configure_ddr(unsigned int hz)
void rkclk_configure_edp(void)
#define PD_BUS_ACLK_DIV0_SHIFT
static const struct pll_div cpll_init_cfg
static const struct pll_div apll_600_cfg
void rkclk_configure_i2s(unsigned int hz)
void rkclk_configure_spi(unsigned int bus, unsigned int hz)
static const struct pll_div * apll_cfgs[]
check_member(rk3288_cru_reg, cru_emmc_con[1], 0x021c)
static const struct pll_div apll_1416_cfg
#define PD_BUS_PCLK_DIV_SHIFT
#define PERI_PCLK_DIV_SHIFT
void rkclk_configure_hdmi(void)
#define PD_BUS_HCLK_DIV_MSK
#define PERI_ACLK_DIV_SHIFT
int rkclk_configure_vop_dclk(u32 vop_id, u32 dclk_hz)
#define PD_BUS_HCLK_DIV_SHIFT
static u32 clk_gcd(u32 a, u32 b)
void rkclk_configure_crypto(unsigned int hz)
static const struct pll_div gpll_init_cfg
#define PERI_ACLK_DIV_MSK
u32 cru_glb_srst_fst_value
u32 cru_glb_srst_snd_value