xref: /arm-trusted-firmware/plat/imx/common/imx_clock.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <stdint.h>
8*91f16700Schasinglulu #include <stdbool.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <arch.h>
11*91f16700Schasinglulu #include <lib/mmio.h>
12*91f16700Schasinglulu 
13*91f16700Schasinglulu #include <imx_regs.h>
14*91f16700Schasinglulu #include <imx_clock.h>
15*91f16700Schasinglulu 
16*91f16700Schasinglulu void imx_clock_target_set(unsigned int id, uint32_t val)
17*91f16700Schasinglulu {
18*91f16700Schasinglulu 	struct ccm *ccm = ((struct ccm *)CCM_BASE);
19*91f16700Schasinglulu 	uintptr_t addr;
20*91f16700Schasinglulu 
21*91f16700Schasinglulu 	if (id > CCM_ROOT_CTRL_NUM)
22*91f16700Schasinglulu 		return;
23*91f16700Schasinglulu 
24*91f16700Schasinglulu 	addr = (uintptr_t)&ccm->ccm_root_ctrl[id].ccm_target_root;
25*91f16700Schasinglulu 	mmio_write_32(addr, val);
26*91f16700Schasinglulu }
27*91f16700Schasinglulu 
28*91f16700Schasinglulu void imx_clock_target_clr(unsigned int id, uint32_t val)
29*91f16700Schasinglulu {
30*91f16700Schasinglulu 	struct ccm *ccm = ((struct ccm *)CCM_BASE);
31*91f16700Schasinglulu 	uintptr_t addr;
32*91f16700Schasinglulu 
33*91f16700Schasinglulu 	if (id > CCM_ROOT_CTRL_NUM)
34*91f16700Schasinglulu 		return;
35*91f16700Schasinglulu 
36*91f16700Schasinglulu 	addr = (uintptr_t)&ccm->ccm_root_ctrl[id].ccm_target_root_clr;
37*91f16700Schasinglulu 	mmio_write_32(addr, val);
38*91f16700Schasinglulu }
39*91f16700Schasinglulu 
40*91f16700Schasinglulu void imx_clock_gate_enable(unsigned int id, bool enable)
41*91f16700Schasinglulu {
42*91f16700Schasinglulu 	struct ccm *ccm = ((struct ccm *)CCM_BASE);
43*91f16700Schasinglulu 	uintptr_t addr;
44*91f16700Schasinglulu 
45*91f16700Schasinglulu 	if (id > CCM_CLK_GATE_CTRL_NUM)
46*91f16700Schasinglulu 		return;
47*91f16700Schasinglulu 
48*91f16700Schasinglulu 	/* TODO: add support for more than DOMAIN0 clocks */
49*91f16700Schasinglulu 	if (enable)
50*91f16700Schasinglulu 		addr = (uintptr_t)&ccm->ccm_clk_gate_ctrl[id].ccm_ccgr_set;
51*91f16700Schasinglulu 	else
52*91f16700Schasinglulu 		addr = (uintptr_t)&ccm->ccm_clk_gate_ctrl[id].ccm_ccgr_clr;
53*91f16700Schasinglulu 
54*91f16700Schasinglulu 	mmio_write_32(addr, CCM_CCGR_SETTING0_DOM_CLK_ALWAYS);
55*91f16700Schasinglulu }
56*91f16700Schasinglulu 
57*91f16700Schasinglulu void imx_clock_enable_uart(unsigned int uart_id, uint32_t uart_clk_en_bits)
58*91f16700Schasinglulu {
59*91f16700Schasinglulu 	unsigned int ccm_trgt_id = CCM_TRT_ID_UART1_CLK_ROOT + uart_id;
60*91f16700Schasinglulu 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_UART1 + uart_id;
61*91f16700Schasinglulu 
62*91f16700Schasinglulu 	/* Check for error */
63*91f16700Schasinglulu 	if (uart_id > MXC_MAX_UART_NUM)
64*91f16700Schasinglulu 		return;
65*91f16700Schasinglulu 
66*91f16700Schasinglulu 	/* Set target register values */
67*91f16700Schasinglulu 	imx_clock_target_set(ccm_trgt_id, uart_clk_en_bits);
68*91f16700Schasinglulu 
69*91f16700Schasinglulu 	/* Enable the clock gate */
70*91f16700Schasinglulu 	imx_clock_gate_enable(ccm_ccgr_id, true);
71*91f16700Schasinglulu }
72*91f16700Schasinglulu 
73*91f16700Schasinglulu void imx_clock_disable_uart(unsigned int uart_id)
74*91f16700Schasinglulu {
75*91f16700Schasinglulu 	unsigned int ccm_trgt_id = CCM_TRT_ID_UART1_CLK_ROOT + uart_id;
76*91f16700Schasinglulu 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_UART1 + uart_id;
77*91f16700Schasinglulu 
78*91f16700Schasinglulu 	/* Check for error */
79*91f16700Schasinglulu 	if (uart_id > MXC_MAX_UART_NUM)
80*91f16700Schasinglulu 		return;
81*91f16700Schasinglulu 
82*91f16700Schasinglulu 	/* Disable the clock gate */
83*91f16700Schasinglulu 	imx_clock_gate_enable(ccm_ccgr_id, false);
84*91f16700Schasinglulu 
85*91f16700Schasinglulu 	/* Clear the target */
86*91f16700Schasinglulu 	imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF);
87*91f16700Schasinglulu }
88*91f16700Schasinglulu 
89*91f16700Schasinglulu void imx_clock_enable_usdhc(unsigned int usdhc_id, uint32_t usdhc_clk_en_bits)
90*91f16700Schasinglulu {
91*91f16700Schasinglulu 	unsigned int ccm_trgt_id = CCM_TRT_ID_USDHC1_CLK_ROOT + usdhc_id;
92*91f16700Schasinglulu 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_USBHDC1 + usdhc_id;
93*91f16700Schasinglulu 
94*91f16700Schasinglulu 	/* Check for error */
95*91f16700Schasinglulu 	if (usdhc_id > MXC_MAX_USDHC_NUM)
96*91f16700Schasinglulu 		return;
97*91f16700Schasinglulu 
98*91f16700Schasinglulu 	/* Set target register values */
99*91f16700Schasinglulu 	imx_clock_target_set(ccm_trgt_id, usdhc_clk_en_bits);
100*91f16700Schasinglulu 
101*91f16700Schasinglulu 	/* Enable the clock gate */
102*91f16700Schasinglulu 	imx_clock_gate_enable(ccm_ccgr_id, true);
103*91f16700Schasinglulu }
104*91f16700Schasinglulu 
105*91f16700Schasinglulu void imx_clock_enable_wdog(unsigned int wdog_id)
106*91f16700Schasinglulu {
107*91f16700Schasinglulu 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id;
108*91f16700Schasinglulu 
109*91f16700Schasinglulu 	/* Check for error */
110*91f16700Schasinglulu 	if (wdog_id > MXC_MAX_WDOG_NUM)
111*91f16700Schasinglulu 		return;
112*91f16700Schasinglulu 
113*91f16700Schasinglulu 	/* Enable the clock gate */
114*91f16700Schasinglulu 	imx_clock_gate_enable(ccm_ccgr_id, true);
115*91f16700Schasinglulu }
116*91f16700Schasinglulu 
117*91f16700Schasinglulu void imx_clock_disable_wdog(unsigned int wdog_id)
118*91f16700Schasinglulu {
119*91f16700Schasinglulu 	unsigned int ccm_trgt_id = CCM_TRT_ID_WDOG_CLK_ROOT;
120*91f16700Schasinglulu 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id;
121*91f16700Schasinglulu 
122*91f16700Schasinglulu 	/* Check for error */
123*91f16700Schasinglulu 	if (wdog_id > MXC_MAX_WDOG_NUM)
124*91f16700Schasinglulu 		return;
125*91f16700Schasinglulu 
126*91f16700Schasinglulu 	/* Disable the clock gate */
127*91f16700Schasinglulu 	imx_clock_gate_enable(ccm_ccgr_id, false);
128*91f16700Schasinglulu 
129*91f16700Schasinglulu 	/* Clear the target */
130*91f16700Schasinglulu 	imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF);
131*91f16700Schasinglulu }
132*91f16700Schasinglulu 
133*91f16700Schasinglulu void imx_clock_set_wdog_clk_root_bits(uint32_t wdog_clk_root_en_bits)
134*91f16700Schasinglulu {
135*91f16700Schasinglulu 	/* Enable the common clock root just once */
136*91f16700Schasinglulu 	imx_clock_target_set(CCM_TRT_ID_WDOG_CLK_ROOT, wdog_clk_root_en_bits);
137*91f16700Schasinglulu }
138*91f16700Schasinglulu 
139*91f16700Schasinglulu void imx_clock_enable_usb(unsigned int ccm_ccgr_usb_id)
140*91f16700Schasinglulu {
141*91f16700Schasinglulu 	/* Enable the clock gate */
142*91f16700Schasinglulu 	imx_clock_gate_enable(ccm_ccgr_usb_id, true);
143*91f16700Schasinglulu }
144*91f16700Schasinglulu 
145*91f16700Schasinglulu void imx_clock_disable_usb(unsigned int ccm_ccgr_usb_id)
146*91f16700Schasinglulu {
147*91f16700Schasinglulu 	/* Disable the clock gate */
148*91f16700Schasinglulu 	imx_clock_gate_enable(ccm_ccgr_usb_id, false);
149*91f16700Schasinglulu }
150*91f16700Schasinglulu 
151*91f16700Schasinglulu void imx_clock_set_usb_clk_root_bits(uint32_t usb_clk_root_en_bits)
152*91f16700Schasinglulu {
153*91f16700Schasinglulu 	/* Enable the common clock root just once */
154*91f16700Schasinglulu 	imx_clock_target_set(CCM_TRT_ID_USB_HSIC_CLK_ROOT, usb_clk_root_en_bits);
155*91f16700Schasinglulu }
156