xref: /rk3399_ARM-atf/plat/imx/common/imx_clock.c (revision bbdcdd044a662de7a1b33b02eb2ccd81596b6420)
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 }
101*bbdcdd04SBryan O'Donoghue 
102*bbdcdd04SBryan O'Donoghue void imx_clock_enable_wdog(unsigned int wdog_id)
103*bbdcdd04SBryan O'Donoghue {
104*bbdcdd04SBryan O'Donoghue 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id;
105*bbdcdd04SBryan O'Donoghue 
106*bbdcdd04SBryan O'Donoghue 	/* Check for error */
107*bbdcdd04SBryan O'Donoghue 	if (wdog_id > MXC_MAX_WDOG_NUM)
108*bbdcdd04SBryan O'Donoghue 		return;
109*bbdcdd04SBryan O'Donoghue 
110*bbdcdd04SBryan O'Donoghue 	/* Enable the clock gate */
111*bbdcdd04SBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_id, true);
112*bbdcdd04SBryan O'Donoghue }
113*bbdcdd04SBryan O'Donoghue 
114*bbdcdd04SBryan O'Donoghue void imx_clock_disable_wdog(unsigned int wdog_id)
115*bbdcdd04SBryan O'Donoghue {
116*bbdcdd04SBryan O'Donoghue 	unsigned int ccm_trgt_id = CCM_TRT_ID_WDOG_CLK_ROOT;
117*bbdcdd04SBryan O'Donoghue 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id;
118*bbdcdd04SBryan O'Donoghue 
119*bbdcdd04SBryan O'Donoghue 	/* Check for error */
120*bbdcdd04SBryan O'Donoghue 	if (wdog_id > MXC_MAX_WDOG_NUM)
121*bbdcdd04SBryan O'Donoghue 		return;
122*bbdcdd04SBryan O'Donoghue 
123*bbdcdd04SBryan O'Donoghue 	/* Disable the clock gate */
124*bbdcdd04SBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_id, false);
125*bbdcdd04SBryan O'Donoghue 
126*bbdcdd04SBryan O'Donoghue 	/* Clear the target */
127*bbdcdd04SBryan O'Donoghue 	imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF);
128*bbdcdd04SBryan O'Donoghue }
129*bbdcdd04SBryan O'Donoghue 
130*bbdcdd04SBryan O'Donoghue void imx_clock_set_wdog_clk_root_bits(uint32_t wdog_clk_root_en_bits)
131*bbdcdd04SBryan O'Donoghue {
132*bbdcdd04SBryan O'Donoghue 	/* Enable the common clock root just once */
133*bbdcdd04SBryan O'Donoghue 	imx_clock_target_set(CCM_TRT_ID_WDOG_CLK_ROOT, wdog_clk_root_en_bits);
134*bbdcdd04SBryan O'Donoghue }
135