xref: /rk3399_ARM-atf/plat/imx/common/imx_clock.c (revision 14cf32aaa72fabb13f60e85c2a4c8bf9422c22ec)
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 }
85*14cf32aaSJun Nie 
86*14cf32aaSJun Nie void imx_clock_enable_usdhc(unsigned int usdhc_id, uint32_t usdhc_clk_en_bits)
87*14cf32aaSJun Nie {
88*14cf32aaSJun Nie 	unsigned int ccm_trgt_id = CCM_TRT_ID_USDHC1_CLK_ROOT + usdhc_id;
89*14cf32aaSJun Nie 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_USBHDC1 + usdhc_id;
90*14cf32aaSJun Nie 
91*14cf32aaSJun Nie 	/* Check for error */
92*14cf32aaSJun Nie 	if (usdhc_id > MXC_MAX_USDHC_NUM)
93*14cf32aaSJun Nie 		return;
94*14cf32aaSJun Nie 
95*14cf32aaSJun Nie 	/* Set target register values */
96*14cf32aaSJun Nie 	imx_clock_target_set(ccm_trgt_id, usdhc_clk_en_bits);
97*14cf32aaSJun Nie 
98*14cf32aaSJun Nie 	/* Enable the clock gate */
99*14cf32aaSJun Nie 	imx_clock_gate_enable(ccm_ccgr_id, true);
100*14cf32aaSJun Nie }
101