xref: /rk3399_ARM-atf/plat/imx/common/imx_clock.c (revision 6176a4e56b16fa28a914b72fa163929135463f8c)
182e35083SBryan O'Donoghue /*
282e35083SBryan O'Donoghue  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
382e35083SBryan O'Donoghue  *
482e35083SBryan O'Donoghue  * SPDX-License-Identifier: BSD-3-Clause
582e35083SBryan O'Donoghue  */
682e35083SBryan O'Donoghue #include <arch.h>
782e35083SBryan O'Donoghue #include <mmio.h>
882e35083SBryan O'Donoghue #include <stdint.h>
982e35083SBryan O'Donoghue #include <stdbool.h>
1082e35083SBryan O'Donoghue #include <imx_regs.h>
1182e35083SBryan O'Donoghue #include <imx_clock.h>
1282e35083SBryan O'Donoghue 
1382e35083SBryan O'Donoghue void imx_clock_target_set(unsigned int id, uint32_t val)
1482e35083SBryan O'Donoghue {
1582e35083SBryan O'Donoghue 	struct ccm *ccm = ((struct ccm *)CCM_BASE);
1682e35083SBryan O'Donoghue 	uintptr_t addr;
1782e35083SBryan O'Donoghue 
1882e35083SBryan O'Donoghue 	if (id > CCM_ROOT_CTRL_NUM)
1982e35083SBryan O'Donoghue 		return;
2082e35083SBryan O'Donoghue 
2182e35083SBryan O'Donoghue 	addr = (uintptr_t)&ccm->ccm_root_ctrl[id].ccm_target_root;
2282e35083SBryan O'Donoghue 	mmio_write_32(addr, val);
2382e35083SBryan O'Donoghue }
2482e35083SBryan O'Donoghue 
2582e35083SBryan O'Donoghue void imx_clock_target_clr(unsigned int id, uint32_t val)
2682e35083SBryan O'Donoghue {
2782e35083SBryan O'Donoghue 	struct ccm *ccm = ((struct ccm *)CCM_BASE);
2882e35083SBryan O'Donoghue 	uintptr_t addr;
2982e35083SBryan O'Donoghue 
3082e35083SBryan O'Donoghue 	if (id > CCM_ROOT_CTRL_NUM)
3182e35083SBryan O'Donoghue 		return;
3282e35083SBryan O'Donoghue 
3382e35083SBryan O'Donoghue 	addr = (uintptr_t)&ccm->ccm_root_ctrl[id].ccm_target_root_clr;
3482e35083SBryan O'Donoghue 	mmio_write_32(addr, val);
3582e35083SBryan O'Donoghue }
3682e35083SBryan O'Donoghue 
3782e35083SBryan O'Donoghue void imx_clock_gate_enable(unsigned int id, bool enable)
3882e35083SBryan O'Donoghue {
3982e35083SBryan O'Donoghue 	struct ccm *ccm = ((struct ccm *)CCM_BASE);
4082e35083SBryan O'Donoghue 	uintptr_t addr;
4182e35083SBryan O'Donoghue 
4282e35083SBryan O'Donoghue 	if (id > CCM_CLK_GATE_CTRL_NUM)
4382e35083SBryan O'Donoghue 		return;
4482e35083SBryan O'Donoghue 
4582e35083SBryan O'Donoghue 	/* TODO: add support for more than DOMAIN0 clocks */
4682e35083SBryan O'Donoghue 	if (enable)
4782e35083SBryan O'Donoghue 		addr = (uintptr_t)&ccm->ccm_clk_gate_ctrl[id].ccm_ccgr_set;
4882e35083SBryan O'Donoghue 	else
4982e35083SBryan O'Donoghue 		addr = (uintptr_t)&ccm->ccm_clk_gate_ctrl[id].ccm_ccgr_clr;
5082e35083SBryan O'Donoghue 
5182e35083SBryan O'Donoghue 	mmio_write_32(addr, CCM_CCGR_SETTING0_DOM_CLK_ALWAYS);
5282e35083SBryan O'Donoghue }
53dcd54e9bSBryan O'Donoghue 
54dcd54e9bSBryan O'Donoghue void imx_clock_enable_uart(unsigned int uart_id, uint32_t uart_clk_en_bits)
55dcd54e9bSBryan O'Donoghue {
56dcd54e9bSBryan O'Donoghue 	unsigned int ccm_trgt_id = CCM_TRT_ID_UART1_CLK_ROOT + uart_id;
57dcd54e9bSBryan O'Donoghue 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_UART1 + uart_id;
58dcd54e9bSBryan O'Donoghue 
59dcd54e9bSBryan O'Donoghue 	/* Check for error */
60dcd54e9bSBryan O'Donoghue 	if (uart_id > MXC_MAX_UART_NUM)
61dcd54e9bSBryan O'Donoghue 		return;
62dcd54e9bSBryan O'Donoghue 
63dcd54e9bSBryan O'Donoghue 	/* Set target register values */
64dcd54e9bSBryan O'Donoghue 	imx_clock_target_set(ccm_trgt_id, uart_clk_en_bits);
65dcd54e9bSBryan O'Donoghue 
66dcd54e9bSBryan O'Donoghue 	/* Enable the clock gate */
67dcd54e9bSBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_id, true);
68dcd54e9bSBryan O'Donoghue }
69dcd54e9bSBryan O'Donoghue 
70dcd54e9bSBryan O'Donoghue void imx_clock_disable_uart(unsigned int uart_id)
71dcd54e9bSBryan O'Donoghue {
72dcd54e9bSBryan O'Donoghue 	unsigned int ccm_trgt_id = CCM_TRT_ID_UART1_CLK_ROOT + uart_id;
73dcd54e9bSBryan O'Donoghue 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_UART1 + uart_id;
74dcd54e9bSBryan O'Donoghue 
75dcd54e9bSBryan O'Donoghue 	/* Check for error */
76dcd54e9bSBryan O'Donoghue 	if (uart_id > MXC_MAX_UART_NUM)
77dcd54e9bSBryan O'Donoghue 		return;
78dcd54e9bSBryan O'Donoghue 
79dcd54e9bSBryan O'Donoghue 	/* Disable the clock gate */
80dcd54e9bSBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_id, false);
81dcd54e9bSBryan O'Donoghue 
82dcd54e9bSBryan O'Donoghue 	/* Clear the target */
83dcd54e9bSBryan O'Donoghue 	imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF);
84dcd54e9bSBryan O'Donoghue }
8514cf32aaSJun Nie 
8614cf32aaSJun Nie void imx_clock_enable_usdhc(unsigned int usdhc_id, uint32_t usdhc_clk_en_bits)
8714cf32aaSJun Nie {
8814cf32aaSJun Nie 	unsigned int ccm_trgt_id = CCM_TRT_ID_USDHC1_CLK_ROOT + usdhc_id;
8914cf32aaSJun Nie 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_USBHDC1 + usdhc_id;
9014cf32aaSJun Nie 
9114cf32aaSJun Nie 	/* Check for error */
9214cf32aaSJun Nie 	if (usdhc_id > MXC_MAX_USDHC_NUM)
9314cf32aaSJun Nie 		return;
9414cf32aaSJun Nie 
9514cf32aaSJun Nie 	/* Set target register values */
9614cf32aaSJun Nie 	imx_clock_target_set(ccm_trgt_id, usdhc_clk_en_bits);
9714cf32aaSJun Nie 
9814cf32aaSJun Nie 	/* Enable the clock gate */
9914cf32aaSJun Nie 	imx_clock_gate_enable(ccm_ccgr_id, true);
10014cf32aaSJun Nie }
101bbdcdd04SBryan O'Donoghue 
102bbdcdd04SBryan O'Donoghue void imx_clock_enable_wdog(unsigned int wdog_id)
103bbdcdd04SBryan O'Donoghue {
104bbdcdd04SBryan O'Donoghue 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id;
105bbdcdd04SBryan O'Donoghue 
106bbdcdd04SBryan O'Donoghue 	/* Check for error */
107bbdcdd04SBryan O'Donoghue 	if (wdog_id > MXC_MAX_WDOG_NUM)
108bbdcdd04SBryan O'Donoghue 		return;
109bbdcdd04SBryan O'Donoghue 
110bbdcdd04SBryan O'Donoghue 	/* Enable the clock gate */
111bbdcdd04SBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_id, true);
112bbdcdd04SBryan O'Donoghue }
113bbdcdd04SBryan O'Donoghue 
114bbdcdd04SBryan O'Donoghue void imx_clock_disable_wdog(unsigned int wdog_id)
115bbdcdd04SBryan O'Donoghue {
116bbdcdd04SBryan O'Donoghue 	unsigned int ccm_trgt_id = CCM_TRT_ID_WDOG_CLK_ROOT;
117bbdcdd04SBryan O'Donoghue 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id;
118bbdcdd04SBryan O'Donoghue 
119bbdcdd04SBryan O'Donoghue 	/* Check for error */
120bbdcdd04SBryan O'Donoghue 	if (wdog_id > MXC_MAX_WDOG_NUM)
121bbdcdd04SBryan O'Donoghue 		return;
122bbdcdd04SBryan O'Donoghue 
123bbdcdd04SBryan O'Donoghue 	/* Disable the clock gate */
124bbdcdd04SBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_id, false);
125bbdcdd04SBryan O'Donoghue 
126bbdcdd04SBryan O'Donoghue 	/* Clear the target */
127bbdcdd04SBryan O'Donoghue 	imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF);
128bbdcdd04SBryan O'Donoghue }
129bbdcdd04SBryan O'Donoghue 
130bbdcdd04SBryan O'Donoghue void imx_clock_set_wdog_clk_root_bits(uint32_t wdog_clk_root_en_bits)
131bbdcdd04SBryan O'Donoghue {
132bbdcdd04SBryan O'Donoghue 	/* Enable the common clock root just once */
133bbdcdd04SBryan O'Donoghue 	imx_clock_target_set(CCM_TRT_ID_WDOG_CLK_ROOT, wdog_clk_root_en_bits);
134bbdcdd04SBryan O'Donoghue }
135*6176a4e5SBryan O'Donoghue 
136*6176a4e5SBryan O'Donoghue void imx_clock_enable_usb(unsigned int ccm_ccgr_usb_id)
137*6176a4e5SBryan O'Donoghue {
138*6176a4e5SBryan O'Donoghue 	/* Enable the clock gate */
139*6176a4e5SBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_usb_id, true);
140*6176a4e5SBryan O'Donoghue }
141*6176a4e5SBryan O'Donoghue 
142*6176a4e5SBryan O'Donoghue void imx_clock_disable_usb(unsigned int ccm_ccgr_usb_id)
143*6176a4e5SBryan O'Donoghue {
144*6176a4e5SBryan O'Donoghue 	/* Disable the clock gate */
145*6176a4e5SBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_usb_id, false);
146*6176a4e5SBryan O'Donoghue }
147*6176a4e5SBryan O'Donoghue 
148*6176a4e5SBryan O'Donoghue void imx_clock_set_usb_clk_root_bits(uint32_t usb_clk_root_en_bits)
149*6176a4e5SBryan O'Donoghue {
150*6176a4e5SBryan O'Donoghue 	/* Enable the common clock root just once */
151*6176a4e5SBryan O'Donoghue 	imx_clock_target_set(CCM_TRT_ID_USB_HSIC_CLK_ROOT, usb_clk_root_en_bits);
152*6176a4e5SBryan O'Donoghue }
153