blob: 285dff8b4d6d2d1359b18c71f668e2b6d7db1978 [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (c) 2019 MediaTek Inc.
4 * Author: Pierre Lee <pierre.lee@mediatek.com>
5 */
6
7
8#ifndef __DRV_CLK_FHCTL_H
9#define __DRV_CLK_FHCTL_H
10
11#include <linux/clk-provider.h>
12#include <linux/clkdev.h>
13#include <linux/bitops.h>
14
15
16/************************************************
17 ********** register field **********
18 ************************************************/
19// REG_CFG mask
20#define MASK_FRDDSX_DYS GENMASK(23, 20)
21#define MASK_FRDDSX_DTS GENMASK(19, 16)
22#define FH_FHCTLX_CFG_PAUSE BIT(4)
23#define FH_SFSTRX_EN BIT(2)
24#define FH_FRDDSX_EN BIT(1)
25#define FH_FHCTLX_EN BIT(0)
26
27//REG_DDS mask
28#define FH_FHCTLX_PLL_TGL_ORG BIT(31)
29
30//FHCTLX_DVFS mask
31#define FH_FHCTLX_PLL_DVFS_TRI BIT(31)
32
33//XXPLL_CON1 mask (APMIXED)
34#define FH_XXPLL_CON_PCWCHG BIT(31)
35
36// Default DT/DF valude
37#define REG_CFG_DT_VAL 0x0
38#define REG_CFG_DF_VAL 0x9
39
40#define REG_HP_EN_APMIXEDSYS_CTR 0
41#define REG_HP_EN_FHCTL_CTR 1
42
43#define fh_set_field(reg, field, val) \
44do { \
45 unsigned int tv = readl(reg); \
46 tv &= ~(field); \
47 tv |= ((val) << (ffs(field) - 1)); \
48 writel(tv, reg); \
49} while (0)
50
51#define fh_get_field(reg, field, val) \
52do { \
53 unsigned int tv = readl(reg); \
54 val = ((tv & (field)) >> (ffs(field) - 1)); \
55} while (0)
56
57#define FH_REG_TR (void __iomem *)(0x104 +0x4)
58
59struct clk_mt_fhctl_regs {
60 /* Common reg */
61 void __iomem *reg_unitslope_en;
62 void __iomem *reg_hp_en;
63 void __iomem *reg_clk_con;
64 void __iomem *reg_rst_con;
65 void __iomem *reg_slope0;
66 void __iomem *reg_slope1;
67
68 /* For PLL specific */
69 void __iomem *reg_cfg;
70 void __iomem *reg_updnlmt;
71 void __iomem *reg_dds;
72 void __iomem *reg_dvfs;
73 void __iomem *reg_mon;
74 void __iomem *reg_con0;
75 void __iomem *reg_con_pcw;
76};
77
78struct clk_mt_fhctl_pll_data {
79 const char *pll_name;
80 int pll_id;
81 int pll_type;
82 int pll_default_ssc_rate;
83 unsigned int slope0_value;
84 unsigned int slope1_value;
85 unsigned int dds_mask;
86 unsigned int *hp_tbl;
87 unsigned int hp_tbl_size;
88 unsigned int dds_max; // for UT dds max value.
89 unsigned int dds_min; // for UT dds min value.
90};
91
92struct clk_mt_fhctl {
93 struct clk_mt_fhctl_pll_data *pll_data;
94 struct clk_mt_fhctl_regs *fh_regs;
95 const struct clk_mt_fhctl_hal_ops *hal_ops;
96 spinlock_t *lock;
97 struct list_head node;
98};
99
100struct clk_mt_fhctl_hal_ops {
101 int (*pll_init)(struct clk_mt_fhctl *fh);
102 int (*pll_unpause)(struct clk_mt_fhctl *fh);
103 int (*pll_pause)(struct clk_mt_fhctl *fh);
104 int (*pll_ssc_disable)(struct clk_mt_fhctl *fh);
105 int (*pll_ssc_enable)(struct clk_mt_fhctl *fh, int rate);
106 int (*pll_hopping)(struct clk_mt_fhctl *fh,
107 unsigned int new_dds, int postdiv);
108};
109
110struct fhctl_ipi_ops{
111 int (*ipi_init)(void);
112};
113
114struct mtk_fhctl {
115 struct device *dev;
116
117 /* set in fhctl probe */
118 void __iomem *fhctl_base;
119 void __iomem *apmixed_base;
120 void __iomem *reg_tr;
121 unsigned int pll_num;
122 int *idmap;
123
124 struct clk_mt_fhctl **fh_tbl;
125 const struct fhctl_ipi_ops *ipi_ops_p;
126 const struct mtk_fhctl_compatible *dev_comp;
127#if defined(CONFIG_DEBUG_FS)
128 struct dentry *debugfs_root;
129#endif
130};
131
132struct mtk_fhctl_compatible {
133 const u16 *common_regs;
134 const u16 *pll_regs;
135 const u16 *pll_con0_regs;
136 const char * const *pll_names;
137 unsigned int pll_apmix_pcw_offs;
138 unsigned int pll_num;
139 unsigned int pll_dds_reg_field_size;
140 unsigned int pll_slope0_reg_setting;
141 unsigned int pll_slope1_reg_setting;
142};
143
144enum FHCTL_PLL_PCW_OFFSET {
145 CON0_OFFS = 0x00,
146 CON1_OFFS = 0x04,
147 CON2_OFFS = 0x08,
148};
149
150enum FHCTL_COMMON_REGS_OFFSET {
151 OFFSET_UNITSLOPE_EN,
152 OFFSET_HP_EN,
153 OFFSET_CLK_CON,
154 OFFSET_RST_CON,
155 OFFSET_SLOPE0,
156 OFFSET_SLOPE1,
157 OFFSET_FHCTL_DSSC_CFG,
158};
159
160enum FHCTL_PLL_REGS_OFFSET {
161 OFFSET_CFG,
162 OFFSET_UPDNLMT,
163 OFFSET_DDS,
164 OFFSET_DVFS,
165 OFFSET_MON,
166 OFFSET_CON0,
167 OFFSET_CON1,
168};
169
170enum FHCTL_PLL_TYPE {
171 FH_PLL_TYPE_NOT_SUPPORT,
172 FH_PLL_TYPE_GENERAL,
173 FH_PLL_TYPE_CPU,
174 FH_PLL_TYPE_FORCE,
175};
176
177
178struct pll_status {
179 unsigned int pll_id;
180 unsigned int tx_id;
181 unsigned int target_dds;
182 unsigned int before_dds;
183 unsigned int after_dds;
184};
185
186
187#define FH_LOG_MAX_IPI_IDX 128 //max size
188
189struct clk_mt_fhctl *mtk_fh_get_fh_obj_tbl(struct mtk_fhctl *fhctl, int posi);
190extern const struct clk_mt_fhctl_hal_ops mt_fhctl_hal_ops;
191extern const struct fhctl_ipi_ops ipi_ops;
192extern struct mtk_ipi_device mcupm_ipidev;
193
194
195
196#endif /* __DRV_CLK_FHCTL_H */
197