1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <commonlib/helpers.h>
6 #include <device/mmio.h>
11 /* Clock Branch Operations */
12 static bool clock_is_off(u32
*cbcr_addr
)
14 return (read32(cbcr_addr
) & CLK_CTL_OFF_BMSK
);
17 enum cb_err
clock_enable_vote(void *cbcr_addr
, void *vote_addr
,
22 setbits32(vote_addr
, BIT(vote_bit
));
24 /* Ensure clock is enabled */
26 if (!clock_is_off(cbcr_addr
))
30 printk(BIOS_ERR
, "Failed to enable clock, register val: 0x%x\n",
35 enum cb_err
clock_enable(void *cbcr_addr
)
39 /* Set clock enable bit */
40 setbits32(cbcr_addr
, BIT(CLK_CTL_EN_SHFT
));
42 /* Ensure clock is enabled */
44 if (!clock_is_off(cbcr_addr
))
48 printk(BIOS_ERR
, "Failed to enable clock, register val: 0x%x\n",
53 /* Clock Block Reset Operations */
54 void clock_reset_bcr(void *bcr_addr
, bool assert)
57 setbits32(bcr_addr
, BIT(CLK_CTL_BCR_BLK_SHFT
));
59 clrbits32(bcr_addr
, BIT(CLK_CTL_BCR_BLK_SHFT
));
62 /* Clock GDSC Operations */
63 enum cb_err
enable_and_poll_gdsc_status(void *gdscr_addr
)
65 if (read32(gdscr_addr
) & CLK_CTL_OFF_BMSK
)
68 clrbits32(gdscr_addr
, BIT(GDSC_ENABLE_BIT
));
70 /* Ensure gdsc is enabled */
71 if (!wait_us(100, (read32(gdscr_addr
) & CLK_CTL_OFF_BMSK
)))
77 /* Clock Root clock Generator with MND Operations */
78 static void clock_configure_mnd(struct clock_rcg
*clk
, uint32_t m
, uint32_t n
,
81 struct clock_rcg_mnd
*mnd
= (struct clock_rcg_mnd
*)clk
;
83 setbits32(&clk
->rcg_cfg
,
84 RCG_MODE_DUAL_EDGE
<< CLK_CTL_CFG_MODE_SHFT
);
86 write32(&mnd
->m
, m
& CLK_CTL_RCG_MND_BMSK
);
87 write32(&mnd
->n
, ~(n
-m
) & CLK_CTL_RCG_MND_BMSK
);
88 write32(&mnd
->d_2
, ~(d_2
) & CLK_CTL_RCG_MND_BMSK
);
91 /* Clock Root clock Generator Operations */
92 enum cb_err
clock_configure(struct clock_rcg
*clk
,
93 struct clock_freq_config
*clk_cfg
, uint32_t hz
,
96 uint32_t reg_val
, idx
;
98 for (idx
= 0; idx
< num_perfs
; idx
++)
99 if (hz
== clk_cfg
[idx
].hz
)
102 /* Verify we matched an entry. If not, throw error. */
103 if (idx
>= num_perfs
)
104 die("Failed to find a matching clock frequency (%d hz) for %p!\n",
107 reg_val
= (clk_cfg
[idx
].src
<< CLK_CTL_CFG_SRC_SEL_SHFT
) |
108 (clk_cfg
[idx
].div
<< CLK_CTL_CFG_SRC_DIV_SHFT
);
110 /* Set clock config */
111 write32(&clk
->rcg_cfg
, reg_val
);
113 if (clk_cfg
[idx
].m
!= 0)
114 clock_configure_mnd(clk
, clk_cfg
[idx
].m
, clk_cfg
[idx
].n
,
117 /* Commit config to RCG */
118 setbits32(&clk
->rcg_cmd
, BIT(CLK_CTL_CMD_UPDATE_SHFT
));
123 /* Clock Root clock Generator with DFS Operations */
124 void clock_configure_dfsr_table(int qup
, struct clock_freq_config
*clk_cfg
,
127 struct qupv3_clock
*qup_clk
;
128 unsigned int idx
, s
= qup
% QUP_WRAP1_S0
;
131 qup_clk
= qup
< QUP_WRAP1_S0
?
132 &gcc
->qup_wrap0_s
[s
] : &gcc
->qup_wrap1_s
[s
];
134 clrsetbits32(&qup_clk
->dfsr_clk
.cmd_dfsr
,
135 BIT(CLK_CTL_CMD_RCG_SW_CTL_SHFT
),
136 BIT(CLK_CTL_CMD_DFSR_SHFT
));
138 for (idx
= 0; idx
< num_perfs
; idx
++) {
139 reg_val
= (clk_cfg
[idx
].src
<< CLK_CTL_CFG_SRC_SEL_SHFT
) |
140 (clk_cfg
[idx
].div
<< CLK_CTL_CFG_SRC_DIV_SHFT
);
142 write32(&qup_clk
->dfsr_clk
.perf_dfsr
[idx
], reg_val
);
144 if (clk_cfg
[idx
].m
== 0)
147 setbits32(&qup_clk
->dfsr_clk
.perf_dfsr
[idx
],
148 RCG_MODE_DUAL_EDGE
<< CLK_CTL_CFG_MODE_SHFT
);
150 reg_val
= clk_cfg
[idx
].m
& CLK_CTL_RCG_MND_BMSK
;
151 write32(&qup_clk
->dfsr_clk
.perf_m_dfsr
[idx
], reg_val
);
153 reg_val
= ~(clk_cfg
[idx
].n
- clk_cfg
[idx
].m
)
154 & CLK_CTL_RCG_MND_BMSK
;
155 write32(&qup_clk
->dfsr_clk
.perf_n_dfsr
[idx
], reg_val
);
157 reg_val
= ~(clk_cfg
[idx
].d_2
) & CLK_CTL_RCG_MND_BMSK
;
158 write32(&qup_clk
->dfsr_clk
.perf_d_dfsr
[idx
], reg_val
);
162 /* General Purpose PLL configuration and enable Operations */
163 enum cb_err
clock_configure_enable_gpll(struct alpha_pll_reg_val_config
*cfg
,
164 bool enable
, int br_enable
)
167 write32(cfg
->reg_l
, cfg
->l_val
);
170 write32(cfg
->reg_cal_l
, cfg
->cal_l_val
);
173 write32(cfg
->reg_alpha
, cfg
->alpha_val
);
175 if (cfg
->user_ctl_val
)
176 write32(cfg
->reg_user_ctl
, cfg
->user_ctl_val
);
178 if (cfg
->user_ctl_hi_val
)
179 write32(cfg
->reg_user_ctl_hi
, cfg
->user_ctl_hi_val
);
181 if (cfg
->user_ctl_hi1_val
)
182 write32(cfg
->reg_user_ctl_hi1
, cfg
->user_ctl_hi1_val
);
184 if (cfg
->config_ctl_val
)
185 write32(cfg
->reg_config_ctl
, cfg
->config_ctl_val
);
187 if (cfg
->config_ctl_hi_val
)
188 write32(cfg
->reg_config_ctl_hi
, cfg
->config_ctl_hi_val
);
190 if (cfg
->config_ctl_hi1_val
)
191 write32(cfg
->reg_config_ctl_hi1
, cfg
->config_ctl_hi1_val
);
194 setbits32(cfg
->reg_mode
, BIT(PLL_FSM_EN_SHFT
));
197 setbits32(cfg
->reg_opmode
, BIT(PLL_STANDBY_MODE
));
200 * H/W requires a 1us delay between placing PLL in STANDBY and
201 * de-asserting the reset.
204 setbits32(cfg
->reg_mode
, BIT(PLL_RESET_N_SHFT
));
207 * H/W requires a 10us delay between de-asserting the reset and
208 * enabling the PLL branch bit.
211 setbits32(cfg
->reg_apcs_pll_br_en
, BIT(br_enable
));
213 /* Wait for Lock Detection */
214 if (!wait_us(100, read32(cfg
->reg_mode
) & PLL_LOCK_DET_BMSK
)) {
215 printk(BIOS_ERR
, "PLL did not lock!\n");
223 enum cb_err
agera_pll_enable(struct alpha_pll_reg_val_config
*cfg
)
225 setbits32(cfg
->reg_mode
, BIT(PLL_BYPASSNL_SHFT
));
228 * H/W requires a 5us delay between disabling the bypass and
229 * de-asserting the reset.
232 setbits32(cfg
->reg_mode
, BIT(PLL_RESET_SHFT
));
234 if (!wait_us(100, read32(cfg
->reg_mode
) & PLL_LOCK_DET_BMSK
)) {
235 printk(BIOS_ERR
, "CPU PLL did not lock!\n");
239 setbits32(cfg
->reg_mode
, BIT(PLL_OUTCTRL_SHFT
));
244 enum cb_err
zonda_pll_enable(struct alpha_pll_reg_val_config
*cfg
)
246 setbits32(cfg
->reg_mode
, BIT(PLL_BYPASSNL_SHFT
));
249 * H/W requires a 1us delay between disabling the bypass and
250 * de-asserting the reset.
253 setbits32(cfg
->reg_mode
, BIT(PLL_RESET_SHFT
));
254 setbits32(cfg
->reg_opmode
, PLL_RUN_MODE
);
256 if (!wait_us(100, read32(cfg
->reg_mode
) & PLL_LOCK_DET_BMSK
)) {
257 printk(BIOS_ERR
, "CPU PLL did not lock!\n");
261 setbits32(cfg
->reg_user_ctl
, PLL_USERCTL_BMSK
);
262 setbits32(cfg
->reg_mode
, BIT(PLL_OUTCTRL_SHFT
));
267 /* Bring subsystem out of RESET */
268 void clock_reset_subsystem(u32
*misc
, u32 shft
)
270 clrbits32(misc
, BIT(shft
));