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