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