coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
clock.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <assert.h>
4 #include <commonlib/helpers.h>
5 #include <device/mmio.h>
6 #include <soc/clock.h>
7 #include <types.h>
8 
9 static struct clock_freq_config qspi_core_cfg[] = {
10  {
11  .hz = SRC_XO_HZ, /* 19.2KHz */
12  .src = SRC_XO_19_2MHZ,
13  .div = QCOM_CLOCK_DIV(1),
14  },
15  {
16  .hz = 100 * MHz,
17  .src = SRC_GPLL0_EVEN_300MHZ,
18  .div = QCOM_CLOCK_DIV(3),
19  },
20  {
21  .hz = 150 * MHz,
22  .src = SRC_GPLL0_EVEN_300MHZ,
23  .div = QCOM_CLOCK_DIV(2),
24  },
25  {
26  .hz = GPLL0_EVEN_HZ, /* 300MHz */
27  .src = SRC_GPLL0_EVEN_300MHZ,
28  .div = QCOM_CLOCK_DIV(1),
29  }
30 };
31 
32 static struct clock_freq_config qupv3_wrap_cfg[] = {
33  {
34  .hz = SRC_XO_HZ, /* 19.2KHz */
35  .src = SRC_XO_19_2MHZ,
36  .div = QCOM_CLOCK_DIV(1),
37  },
38  {
39  .hz = 32 * MHz,
40  .src = SRC_GPLL0_EVEN_300MHZ,
41  .div = QCOM_CLOCK_DIV(1),
42  .m = 8,
43  .n = 75,
44  .d_2 = 75,
45  },
46  {
47  .hz = 48 * MHz,
48  .src = SRC_GPLL0_EVEN_300MHZ,
49  .div = QCOM_CLOCK_DIV(1),
50  .m = 4,
51  .n = 25,
52  .d_2 = 25,
53  },
54  {
55  .hz = 64 * MHz,
56  .src = SRC_GPLL0_EVEN_300MHZ,
57  .div = QCOM_CLOCK_DIV(1),
58  .m = 16,
59  .n = 75,
60  .d_2 = 75,
61  },
62  {
63  .hz = 96 * MHz,
64  .src = SRC_GPLL0_EVEN_300MHZ,
65  .div = QCOM_CLOCK_DIV(1),
66  .m = 8,
67  .n = 25,
68  .d_2 = 25,
69  },
70  {
71  .hz = 100 * MHz,
72  .src = SRC_GPLL0_EVEN_300MHZ,
73  .div = QCOM_CLOCK_DIV(3),
74  },
75  {
76  .hz = SRC_XO_HZ, /* 19.2KHz */
77  .src = SRC_XO_19_2MHZ,
78  .div = QCOM_CLOCK_DIV(1),
79  },
80  {
81  .hz = SRC_XO_HZ, /* 19.2KHz */
82  .src = SRC_XO_19_2MHZ,
83  .div = QCOM_CLOCK_DIV(1),
84  },
85 };
86 
88  [MDSS_CLK_ESC0] = &mdss->esc0,
92 };
93 
99 };
100 
101 static int clock_configure_gpll0(void)
102 {
103  struct alpha_pll_reg_val_config gpll0_cfg = {0};
104 
105  gpll0_cfg.reg_user_ctl_hi = &gcc->gpll0.user_ctl_u;
106  gpll0_cfg.user_ctl_hi_val = 1 << SCALE_FREQ_SHFT;
107 
108  gpll0_cfg.reg_user_ctl = &gcc->gpll0.user_ctl;
109  gpll0_cfg.user_ctl_val = (1 << PLL_POST_DIV_EVEN_SHFT |
110  1 << PLL_PLLOUT_EVEN_SHFT |
111  1 << PLL_PLLOUT_MAIN_SHFT |
112  1 << PLL_PLLOUT_ODD_SHFT);
113 
114  return clock_configure_enable_gpll(&gpll0_cfg, false, 0);
115 }
116 
118 {
119  clock_configure(&gcc->qspi_core,
120  qspi_core_cfg, hz,
122  clock_enable(&gcc->qspi_cnoc_ahb_cbcr);
123  clock_enable(&gcc->qspi_core_cbcr);
124 }
125 
127 {
130 }
131 
133 {
134  int s = qup % QUP_WRAP1_S0;
135  int clk_en_off = qup < QUP_WRAP1_S0 ?
137  struct qupv3_clock *qup_clk = qup < QUP_WRAP1_S0 ?
138  &gcc->qup_wrap0_s[s] : &gcc->qup_wrap1_s[s];
139 
140  clock_enable_vote(&qup_clk->cbcr, &gcc->apcs_clk_br_en1,
141  clk_en_off);
142 }
143 
144 static enum cb_err pll_init_and_set(struct sc7180_apss_clock *apss, u32 l_val)
145 {
146  struct alpha_pll_reg_val_config pll_cfg = {0};
147  int ret;
148  u32 gfmux_val;
149 
150  pll_cfg.reg_config_ctl = &apss->pll.config_ctl_lo;
151  pll_cfg.reg_config_ctl_hi = &apss->pll.config_ctl_hi;
152  pll_cfg.reg_config_ctl_hi1 = &apss->pll.config_ctl_u1;
153 
154  pll_cfg.config_ctl_val = (0x2 << CTUNE_SHFT | 0x2 << K_I_SHFT |
155  0x5 << K_P_SHFT | 0x2 << PFA_MSB_SHFT |
156  0x2 << REF_CONT_SHFT);
157  pll_cfg.config_ctl_hi_val = (0x2 << CUR_ADJ_SHFT | BIT(DMET_SHFT) |
158  0xF << RES_SHFT);
159 
160  write32(&apss->pll.config_ctl_u1, 0x0);
161  pll_cfg.reg_l = &apss->pll.l;
162  pll_cfg.l_val = l_val;
163 
164  ret = clock_configure_enable_gpll(&pll_cfg, false, 0);
165  if (ret != CB_SUCCESS)
166  return CB_ERR;
167 
168  pll_cfg.reg_mode = &apss->pll.mode;
169  ret = agera_pll_enable(&pll_cfg);
170  if (ret != CB_SUCCESS)
171  return CB_ERR;
172 
173  gfmux_val = read32(&apss->cfg_gfmux) & ~GFMUX_SRC_SEL_BMSK;
174  gfmux_val |= APCS_SRC_EARLY;
175  write32(&apss->cfg_gfmux, gfmux_val);
176 
177  return CB_SUCCESS;
178 }
179 
180 static void speed_up_boot_cpu(void)
181 {
182  /* 1516.8 MHz */
184  printk(BIOS_DEBUG, "Silver Frequency bumped to 1.5168(GHz)\n");
185 
186  /* 1209.6 MHz */
188  printk(BIOS_DEBUG, "L3 Frequency bumped to 1.2096(GHz)\n");
189 }
190 
191 enum cb_err mdss_clock_configure(enum mdss_clock clk_type, uint32_t source,
192  uint32_t divider, uint32_t m,
193  uint32_t n, uint32_t d_2)
194 {
195  struct clock_freq_config mdss_clk_cfg;
196 
197  if (clk_type >= MDSS_CLK_COUNT)
198  return CB_ERR;
199 
200  /* Initialize it with received arguments */
201  mdss_clk_cfg.hz = 0;
202  mdss_clk_cfg.src = source;
203 
204  /*
205  * Update half_divider passed from display, this is to accommodate
206  * the transition to common clock driver.
207  *
208  * client is expected to provide 2n divider value,
209  * as the divider value in register is in form "2n-1"
210  */
211  mdss_clk_cfg.div = divider ? ((divider * 2) - 1) : 0;
212  mdss_clk_cfg.m = m;
213  mdss_clk_cfg.n = n;
214  mdss_clk_cfg.d_2 = d_2;
215 
216  return clock_configure((struct clock_rcg *)mdss_clock[clk_type],
217  &mdss_clk_cfg, 0, 1);
218 }
219 
220 int mdss_clock_enable(enum mdss_clock clk_type)
221 {
222  if (clk_type >= MDSS_CLK_COUNT)
223  return CB_ERR;
224 
225  /* Enable clock */
226  return clock_enable(mdss_cbcr[clk_type]);
227 }
228 
229 void clock_init(void)
230 {
232 
233  clock_enable_vote(&gcc->qup_wrap0_core_2x_cbcr,
234  &gcc->apcs_clk_br_en1,
236  clock_enable_vote(&gcc->qup_wrap0_core_cbcr,
237  &gcc->apcs_clk_br_en1,
239  clock_enable_vote(&gcc->qup_wrap0_m_ahb_cbcr,
240  &gcc->apcs_clk_br_en1,
242  clock_enable_vote(&gcc->qup_wrap0_s_ahb_cbcr,
243  &gcc->apcs_clk_br_en1,
245 
246  clock_enable_vote(&gcc->qup_wrap1_core_2x_cbcr,
247  &gcc->apcs_clk_br_en1,
249  clock_enable_vote(&gcc->qup_wrap1_core_cbcr,
250  &gcc->apcs_clk_br_en1,
252  clock_enable_vote(&gcc->qup_wrap1_m_ahb_cbcr,
253  &gcc->apcs_clk_br_en1,
255  clock_enable_vote(&gcc->qup_wrap1_s_ahb_cbcr,
256  &gcc->apcs_clk_br_en1,
259 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define MHz
Definition: helpers.h:80
cb_err
coreboot error codes
Definition: cb_err.h:15
@ CB_ERR
Generic error code.
Definition: cb_err.h:17
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
@ PLL_PLLOUT_EVEN_SHFT
Definition: clock_common.h:81
@ PLL_PLLOUT_MAIN_SHFT
Definition: clock_common.h:80
@ PLL_POST_DIV_EVEN_SHFT
Definition: clock_common.h:83
@ PLL_PLLOUT_ODD_SHFT
Definition: clock_common.h:82
#define QCOM_CLOCK_DIV(div)
Definition: clock_common.h:6
#define printk(level,...)
Definition: stdlib.h:16
#define BIT(nr)
Definition: ec_commands.h:45
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
void clock_init(void)
Definition: clock.c:539
enum cb_err clock_enable(void *cbcr_addr)
Definition: clock.c:35
void clock_configure_dfsr_table(int qup, struct clock_freq_config *clk_cfg, uint32_t num_perfs)
Definition: clock.c:124
enum cb_err clock_configure(struct clock_rcg *clk, struct clock_freq_config *clk_cfg, uint32_t hz, uint32_t num_perfs)
Definition: clock.c:92
enum cb_err clock_configure_enable_gpll(struct alpha_pll_reg_val_config *cfg, bool enable, int br_enable)
Definition: clock.c:163
enum cb_err agera_pll_enable(struct alpha_pll_reg_val_config *cfg)
Definition: clock.c:223
enum cb_err clock_enable_vote(void *cbcr_addr, void *vote_addr, uint32_t vote_bit)
Definition: clock.c:17
#define SRC_XO_19_2MHZ
Definition: clock.h:10
static struct qcs405_gcc *const gcc
Definition: clock.h:165
static struct clock_freq_config qupv3_wrap_cfg[]
Definition: clock.c:32
static enum cb_err pll_init_and_set(struct sc7180_apss_clock *apss, u32 l_val)
Definition: clock.c:144
static u32 * mdss_cbcr[MDSS_CLK_COUNT]
Definition: clock.c:94
int mdss_clock_enable(enum mdss_clock clk_type)
Definition: clock.c:220
enum cb_err mdss_clock_configure(enum mdss_clock clk_type, uint32_t source, uint32_t divider, uint32_t m, uint32_t n, uint32_t d_2)
Definition: clock.c:191
void clock_configure_qspi(uint32_t hz)
Definition: clock.c:117
void clock_enable_qup(int qup)
Definition: clock.c:132
static struct clock_freq_config qspi_core_cfg[]
Definition: clock.c:9
static void speed_up_boot_cpu(void)
Definition: clock.c:180
static int clock_configure_gpll0(void)
Definition: clock.c:101
void clock_configure_dfsr(int qup)
Definition: clock.c:126
@ QUP_WRAP1_S0
Definition: clock.h:138
#define QUPV3_WRAP1_CLK_ENA_S(idx)
Definition: clock.h:15
@ APCS_SRC_EARLY
Definition: clock.h:184
@ GFMUX_SRC_SEL_BMSK
Definition: clock.h:183
#define QUPV3_WRAP0_CLK_ENA_S(idx)
Definition: clock.h:14
@ REF_CONT_SHFT
Definition: clock.h:173
@ K_P_SHFT
Definition: clock.h:171
@ CTUNE_SHFT
Definition: clock.h:169
@ PFA_MSB_SHFT
Definition: clock.h:172
@ K_I_SHFT
Definition: clock.h:170
#define GPLL0_EVEN_HZ
Definition: clock.h:11
static struct sc7180_apss_clock *const apss_silver
Definition: clock.h:188
static struct sc7180_apss_clock *const apss_l3
Definition: clock.h:189
#define L_VAL_1516P8MHz
Definition: clock.h:35
mdss_clock
Definition: clock.h:123
@ MDSS_CLK_ESC0
Definition: clock.h:124
@ MDSS_CLK_COUNT
Definition: clock.h:128
@ MDSS_CLK_BYTE0
Definition: clock.h:126
@ MDSS_CLK_BYTE0_INTF
Definition: clock.h:127
@ MDSS_CLK_PCLK0
Definition: clock.h:125
@ SRC_GPLL0_EVEN_300MHZ
Definition: clock.h:31
#define SCALE_FREQ_SHFT
Definition: clock.h:39
static struct sc7180_disp_cc *const mdss
Definition: clock.h:190
#define L_VAL_1209P6MHz
Definition: clock.h:36
#define SRC_XO_HZ
Definition: clock.h:10
@ QUPV3_WRAP_1_S_AHB_CLK_ENA
Definition: clock.h:25
@ QUPV3_WRAP_1_M_AHB_CLK_ENA
Definition: clock.h:24
@ QUPV3_WRAP_0_S_AHB_CLK_ENA
Definition: clock.h:19
@ QUPV3_WRAP0_CORE_2X_CLK_ENA
Definition: clock.h:21
@ QUPV3_WRAP1_CORE_2X_CLK_ENA
Definition: clock.h:22
@ QUPV3_WRAP1_CORE_CLK_ENA
Definition: clock.h:23
@ QUPV3_WRAP_0_M_AHB_CLK_ENA
Definition: clock.h:18
@ QUPV3_WRAP0_CORE_CLK_ENA
Definition: clock.h:20
@ CUR_ADJ_SHFT
Definition: clock.h:177
@ RES_SHFT
Definition: clock.h:179
@ DMET_SHFT
Definition: clock.h:178
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
struct qcs405_gpll gpll0
Definition: clock.h:98
u32 user_ctl_u
Definition: clock.h:45
u32 user_ctl
Definition: clock.h:44
struct sc7180_apss_pll pll
Definition: clock.h:163
u32 config_ctl_lo
Definition: clock.h:151
u32 config_ctl_hi
Definition: clock.h:152
u32 config_ctl_u1
Definition: clock.h:153
struct clock_rcg_mnd byte0
Definition: clock.h:115
u32 byte0_cbcr
Definition: clock.h:108
struct clock_rcg_mnd pclk0
Definition: clock.h:113
u32 esc0_cbcr
Definition: clock.h:111
struct clock_rcg_mnd esc0
Definition: clock.h:117
u32 pclk0_cbcr
Definition: clock.h:106
u32 byte0_intf_cbcr
Definition: clock.h:109
#define s(param, src_bits, pmcreg, dst_bits)
#define m(clkreg, src_bits, pmcreg, dst_bits)