blob: 4cb6817a8ef47be4a38e5e48059f50dee7bc382b [file] [log] [blame]
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#ifndef __MESON_CLK_PLL_H
#define __MESON_CLK_PLL_H
#include <asm/io.h>
#include <linux/bitops.h>
#include <common.h>
#include <linux/arm-smccc.h>
//#include <linux/delay.h>
#include <asm/arch/timer.h>
#define PLL_ENABLE BIT(28)
#define PLL_RESET BIT(29)
#define PLL_LOCK BIT(31)
#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
#define CLRPMASK(width, shift) (~SETPMASK(width, shift))
#define PARM_GET(width, shift, reg) \
(((reg) & SETPMASK(width, shift)) >> (shift))
#define PARM_SET(width, shift, reg, val) \
(((reg) & CLRPMASK(width, shift)) | (val << (shift)))
#define MESON_PARM_APPLICABLE(p) (!!((p)->width))
struct pll_params_table {
u16 m;
u16 n;
u16 od;
};
#define PLL_PARAMS(_m, _n, _od) \
{ \
.m = (_m), \
.n = (_n), \
.od = (_od), \
}
#define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
struct parm {
uint32_t reg;
uint8_t shift;
uint8_t width;
};
struct reg_sequence {
unsigned int reg;
unsigned int def;
unsigned int mask;
unsigned int delay_us;
};
struct meson_clk_pll_data {
char name[16];
struct parm m;
struct parm n;
struct parm rst;
struct parm l;
struct parm frac;
struct parm od;
struct parm en;
const struct reg_sequence *init_regs;
unsigned int init_count;
unsigned int *def_rate;
unsigned int def_cnt;
const struct pll_params_table *table;
unsigned int smc_id;
u8 flags;
u8 secid_disable;
u8 secid;
u8 clkmsr_id;
u8 clkmsr_div16_en;
};
static inline unsigned int meson_parm_read(struct parm *p)
{
unsigned int val;
val = readl(p->reg);
return PARM_GET(p->width, p->shift, val);
}
static inline void meson_parm_write(struct parm *p,
unsigned int val)
{
unsigned int tmp;
tmp = readl(p->reg);
tmp &= CLRPMASK(p->width, p->shift);
tmp |= val << p->shift;
writel(tmp, p->reg);
}
/* mpll data structure */
struct meson_clk_mpll_data {
char name[8];
struct parm sdm;
struct parm sdm_en;
struct parm n2;
struct parm ssen;
struct parm misc;
struct parm en;
unsigned int *def_rate;
unsigned int def_cnt;
const struct reg_sequence *init_regs;
unsigned int init_count;
u8 flags;
u8 clkmsr_id;
};
#define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0)
#define CLK_MESON_MPLL_SPREAD_SPECTRUM BIT(1)
int meson_pll_set_rate(struct meson_clk_pll_data *pll, unsigned long rate);
int meson_pll_set_one_rate(struct meson_clk_pll_data *pll, unsigned long rate);
void meson_pll_test(struct meson_clk_pll_data *pll);
void meson_pll_test_one(struct meson_clk_pll_data *pll);
int meson_secure_pll_set_rate(struct meson_clk_pll_data *pll, unsigned long rate);
void meson_secure_pll_test(struct meson_clk_pll_data *pll);
void meson_secure_pll_disable(struct meson_clk_pll_data *pll);
void meson_clk_pll_disable(struct meson_clk_pll_data *pll);
void meson_switch_cpu_clk(unsigned int smc_id, unsigned int secid, unsigned int flag);
int meson_mpll_set_rate(struct meson_clk_mpll_data *mpll,
unsigned long rate);
void meson_mpll_test(struct meson_clk_mpll_data *pll);
void one_pll_test(struct meson_clk_pll_data **pll, int pll_cnt,
struct meson_clk_mpll_data **mpll, int mpll_cnt, char *arg);
#endif /* __MESON_CLK_PLL_H */