1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <commonlib/helpers.h>
5 #include <device/mmio.h>
9 static struct clock_freq_config qspi_core_cfg
[] = {
11 .hz
= SRC_XO_HZ
, /* 19.2KHz */
12 .src
= SRC_XO_19_2MHZ
,
13 .div
= QCOM_CLOCK_DIV(1),
17 .src
= SRC_GPLL0_EVEN_300MHZ
,
18 .div
= QCOM_CLOCK_DIV(3),
22 .src
= SRC_GPLL0_EVEN_300MHZ
,
23 .div
= QCOM_CLOCK_DIV(2),
26 .hz
= GPLL0_EVEN_HZ
, /* 300MHz */
27 .src
= SRC_GPLL0_EVEN_300MHZ
,
28 .div
= QCOM_CLOCK_DIV(1),
32 static struct clock_freq_config qupv3_wrap_cfg
[] = {
34 .hz
= SRC_XO_HZ
, /* 19.2KHz */
35 .src
= SRC_XO_19_2MHZ
,
36 .div
= QCOM_CLOCK_DIV(1),
40 .src
= SRC_GPLL0_EVEN_300MHZ
,
41 .div
= QCOM_CLOCK_DIV(1),
48 .src
= SRC_GPLL0_EVEN_300MHZ
,
49 .div
= QCOM_CLOCK_DIV(1),
56 .src
= SRC_GPLL0_EVEN_300MHZ
,
57 .div
= QCOM_CLOCK_DIV(1),
64 .src
= SRC_GPLL0_EVEN_300MHZ
,
65 .div
= QCOM_CLOCK_DIV(1),
72 .src
= SRC_GPLL0_EVEN_300MHZ
,
73 .div
= QCOM_CLOCK_DIV(3),
76 .hz
= SRC_XO_HZ
, /* 19.2KHz */
77 .src
= SRC_XO_19_2MHZ
,
78 .div
= QCOM_CLOCK_DIV(1),
81 .hz
= SRC_XO_HZ
, /* 19.2KHz */
82 .src
= SRC_XO_19_2MHZ
,
83 .div
= QCOM_CLOCK_DIV(1),
87 static struct clock_rcg_mnd
*mdss_clock
[MDSS_CLK_COUNT
] = {
88 [MDSS_CLK_ESC0
] = &mdss
->esc0
,
89 [MDSS_CLK_PCLK0
] = &mdss
->pclk0
,
90 [MDSS_CLK_BYTE0
] = &mdss
->byte0
,
91 [MDSS_CLK_BYTE0_INTF
] = &mdss
->byte0
,
94 static u32
*mdss_cbcr
[MDSS_CLK_COUNT
] = {
95 [MDSS_CLK_ESC0
] = &mdss
->esc0_cbcr
,
96 [MDSS_CLK_PCLK0
] = &mdss
->pclk0_cbcr
,
97 [MDSS_CLK_BYTE0
] = &mdss
->byte0_cbcr
,
98 [MDSS_CLK_BYTE0_INTF
] = &mdss
->byte0_intf_cbcr
,
101 static int clock_configure_gpll0(void)
103 struct alpha_pll_reg_val_config gpll0_cfg
= {0};
105 gpll0_cfg
.reg_user_ctl_hi
= &gcc
->gpll0
.user_ctl_u
;
106 gpll0_cfg
.user_ctl_hi_val
= 1 << SCALE_FREQ_SHFT
;
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
);
114 return clock_configure_enable_gpll(&gpll0_cfg
, false, 0);
117 void clock_configure_qspi(uint32_t hz
)
119 clock_configure(&gcc
->qspi_core
,
121 ARRAY_SIZE(qspi_core_cfg
));
122 clock_enable(&gcc
->qspi_cnoc_ahb_cbcr
);
123 clock_enable(&gcc
->qspi_core_cbcr
);
126 void clock_configure_dfsr(int qup
)
128 clock_configure_dfsr_table(qup
, qupv3_wrap_cfg
,
129 ARRAY_SIZE(qupv3_wrap_cfg
));
132 void clock_enable_qup(int qup
)
134 int s
= qup
% QUP_WRAP1_S0
;
135 int clk_en_off
= qup
< QUP_WRAP1_S0
?
136 QUPV3_WRAP0_CLK_ENA_S(s
) : QUPV3_WRAP1_CLK_ENA_S(s
);
137 struct qupv3_clock
*qup_clk
= qup
< QUP_WRAP1_S0
?
138 &gcc
->qup_wrap0_s
[s
] : &gcc
->qup_wrap1_s
[s
];
140 clock_enable_vote(&qup_clk
->cbcr
, &gcc
->apcs_clk_br_en1
,
144 static enum cb_err
pll_init_and_set(struct sc7180_apss_clock
*apss
, u32 l_val
)
146 struct alpha_pll_reg_val_config pll_cfg
= {0};
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
;
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
) |
160 write32(&apss
->pll
.config_ctl_u1
, 0x0);
161 pll_cfg
.reg_l
= &apss
->pll
.l
;
162 pll_cfg
.l_val
= l_val
;
164 ret
= clock_configure_enable_gpll(&pll_cfg
, false, 0);
165 if (ret
!= CB_SUCCESS
)
168 pll_cfg
.reg_mode
= &apss
->pll
.mode
;
169 ret
= agera_pll_enable(&pll_cfg
);
170 if (ret
!= CB_SUCCESS
)
173 gfmux_val
= read32(&apss
->cfg_gfmux
) & ~GFMUX_SRC_SEL_BMSK
;
174 gfmux_val
|= APCS_SRC_EARLY
;
175 write32(&apss
->cfg_gfmux
, gfmux_val
);
180 static void speed_up_boot_cpu(void)
183 if (!pll_init_and_set(apss_silver
, L_VAL_1516P8MHz
))
184 printk(BIOS_DEBUG
, "Silver Frequency bumped to 1.5168(GHz)\n");
187 if (!pll_init_and_set(apss_l3
, L_VAL_1209P6MHz
))
188 printk(BIOS_DEBUG
, "L3 Frequency bumped to 1.2096(GHz)\n");
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
)
195 struct clock_freq_config mdss_clk_cfg
;
197 if (clk_type
>= MDSS_CLK_COUNT
)
200 /* Initialize it with received arguments */
202 mdss_clk_cfg
.src
= source
;
205 * Update half_divider passed from display, this is to accommodate
206 * the transition to common clock driver.
208 * client is expected to provide 2n divider value,
209 * as the divider value in register is in form "2n-1"
211 mdss_clk_cfg
.div
= divider
? ((divider
* 2) - 1) : 0;
214 mdss_clk_cfg
.d_2
= d_2
;
216 return clock_configure((struct clock_rcg
*)mdss_clock
[clk_type
],
217 &mdss_clk_cfg
, 0, 1);
220 int mdss_clock_enable(enum mdss_clock clk_type
)
222 if (clk_type
>= MDSS_CLK_COUNT
)
226 return clock_enable(mdss_cbcr
[clk_type
]);
229 void clock_init(void)
231 clock_configure_gpll0();
233 clock_enable_vote(&gcc
->qup_wrap0_core_2x_cbcr
,
234 &gcc
->apcs_clk_br_en1
,
235 QUPV3_WRAP0_CORE_2X_CLK_ENA
);
236 clock_enable_vote(&gcc
->qup_wrap0_core_cbcr
,
237 &gcc
->apcs_clk_br_en1
,
238 QUPV3_WRAP0_CORE_CLK_ENA
);
239 clock_enable_vote(&gcc
->qup_wrap0_m_ahb_cbcr
,
240 &gcc
->apcs_clk_br_en1
,
241 QUPV3_WRAP_0_M_AHB_CLK_ENA
);
242 clock_enable_vote(&gcc
->qup_wrap0_s_ahb_cbcr
,
243 &gcc
->apcs_clk_br_en1
,
244 QUPV3_WRAP_0_S_AHB_CLK_ENA
);
246 clock_enable_vote(&gcc
->qup_wrap1_core_2x_cbcr
,
247 &gcc
->apcs_clk_br_en1
,
248 QUPV3_WRAP1_CORE_2X_CLK_ENA
);
249 clock_enable_vote(&gcc
->qup_wrap1_core_cbcr
,
250 &gcc
->apcs_clk_br_en1
,
251 QUPV3_WRAP1_CORE_CLK_ENA
);
252 clock_enable_vote(&gcc
->qup_wrap1_m_ahb_cbcr
,
253 &gcc
->apcs_clk_br_en1
,
254 QUPV3_WRAP_1_M_AHB_CLK_ENA
);
255 clock_enable_vote(&gcc
->qup_wrap1_s_ahb_cbcr
,
256 &gcc
->apcs_clk_br_en1
,
257 QUPV3_WRAP_1_S_AHB_CLK_ENA
);