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