xref: /rk3399_ARM-atf/plat/imx/common/imx_clock.c (revision 9a207532f8216bf83fed0891fed9ed0bc72ca450)
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  */
6*09d40e0eSAntonio Nino Diaz 
782e35083SBryan O'Donoghue #include <stdint.h>
882e35083SBryan O'Donoghue #include <stdbool.h>
9*09d40e0eSAntonio Nino Diaz 
10*09d40e0eSAntonio Nino Diaz #include <arch.h>
11*09d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
12*09d40e0eSAntonio Nino Diaz 
1382e35083SBryan O'Donoghue #include <imx_regs.h>
1482e35083SBryan O'Donoghue #include <imx_clock.h>
1582e35083SBryan O'Donoghue 
imx_clock_target_set(unsigned int id,uint32_t val)1682e35083SBryan O'Donoghue void imx_clock_target_set(unsigned int id, uint32_t val)
1782e35083SBryan O'Donoghue {
1882e35083SBryan O'Donoghue 	struct ccm *ccm = ((struct ccm *)CCM_BASE);
1982e35083SBryan O'Donoghue 	uintptr_t addr;
2082e35083SBryan O'Donoghue 
2182e35083SBryan O'Donoghue 	if (id > CCM_ROOT_CTRL_NUM)
2282e35083SBryan O'Donoghue 		return;
2382e35083SBryan O'Donoghue 
2482e35083SBryan O'Donoghue 	addr = (uintptr_t)&ccm->ccm_root_ctrl[id].ccm_target_root;
2582e35083SBryan O'Donoghue 	mmio_write_32(addr, val);
2682e35083SBryan O'Donoghue }
2782e35083SBryan O'Donoghue 
imx_clock_target_clr(unsigned int id,uint32_t val)2882e35083SBryan O'Donoghue void imx_clock_target_clr(unsigned int id, uint32_t val)
2982e35083SBryan O'Donoghue {
3082e35083SBryan O'Donoghue 	struct ccm *ccm = ((struct ccm *)CCM_BASE);
3182e35083SBryan O'Donoghue 	uintptr_t addr;
3282e35083SBryan O'Donoghue 
3382e35083SBryan O'Donoghue 	if (id > CCM_ROOT_CTRL_NUM)
3482e35083SBryan O'Donoghue 		return;
3582e35083SBryan O'Donoghue 
3682e35083SBryan O'Donoghue 	addr = (uintptr_t)&ccm->ccm_root_ctrl[id].ccm_target_root_clr;
3782e35083SBryan O'Donoghue 	mmio_write_32(addr, val);
3882e35083SBryan O'Donoghue }
3982e35083SBryan O'Donoghue 
imx_clock_gate_enable(unsigned int id,bool enable)4082e35083SBryan O'Donoghue void imx_clock_gate_enable(unsigned int id, bool enable)
4182e35083SBryan O'Donoghue {
4282e35083SBryan O'Donoghue 	struct ccm *ccm = ((struct ccm *)CCM_BASE);
4382e35083SBryan O'Donoghue 	uintptr_t addr;
4482e35083SBryan O'Donoghue 
4582e35083SBryan O'Donoghue 	if (id > CCM_CLK_GATE_CTRL_NUM)
4682e35083SBryan O'Donoghue 		return;
4782e35083SBryan O'Donoghue 
4882e35083SBryan O'Donoghue 	/* TODO: add support for more than DOMAIN0 clocks */
4982e35083SBryan O'Donoghue 	if (enable)
5082e35083SBryan O'Donoghue 		addr = (uintptr_t)&ccm->ccm_clk_gate_ctrl[id].ccm_ccgr_set;
5182e35083SBryan O'Donoghue 	else
5282e35083SBryan O'Donoghue 		addr = (uintptr_t)&ccm->ccm_clk_gate_ctrl[id].ccm_ccgr_clr;
5382e35083SBryan O'Donoghue 
5482e35083SBryan O'Donoghue 	mmio_write_32(addr, CCM_CCGR_SETTING0_DOM_CLK_ALWAYS);
5582e35083SBryan O'Donoghue }
56dcd54e9bSBryan O'Donoghue 
imx_clock_enable_uart(unsigned int uart_id,uint32_t uart_clk_en_bits)57dcd54e9bSBryan O'Donoghue void imx_clock_enable_uart(unsigned int uart_id, uint32_t uart_clk_en_bits)
58dcd54e9bSBryan O'Donoghue {
59dcd54e9bSBryan O'Donoghue 	unsigned int ccm_trgt_id = CCM_TRT_ID_UART1_CLK_ROOT + uart_id;
60dcd54e9bSBryan O'Donoghue 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_UART1 + uart_id;
61dcd54e9bSBryan O'Donoghue 
62dcd54e9bSBryan O'Donoghue 	/* Check for error */
63dcd54e9bSBryan O'Donoghue 	if (uart_id > MXC_MAX_UART_NUM)
64dcd54e9bSBryan O'Donoghue 		return;
65dcd54e9bSBryan O'Donoghue 
66dcd54e9bSBryan O'Donoghue 	/* Set target register values */
67dcd54e9bSBryan O'Donoghue 	imx_clock_target_set(ccm_trgt_id, uart_clk_en_bits);
68dcd54e9bSBryan O'Donoghue 
69dcd54e9bSBryan O'Donoghue 	/* Enable the clock gate */
70dcd54e9bSBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_id, true);
71dcd54e9bSBryan O'Donoghue }
72dcd54e9bSBryan O'Donoghue 
imx_clock_disable_uart(unsigned int uart_id)73dcd54e9bSBryan O'Donoghue void imx_clock_disable_uart(unsigned int uart_id)
74dcd54e9bSBryan O'Donoghue {
75dcd54e9bSBryan O'Donoghue 	unsigned int ccm_trgt_id = CCM_TRT_ID_UART1_CLK_ROOT + uart_id;
76dcd54e9bSBryan O'Donoghue 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_UART1 + uart_id;
77dcd54e9bSBryan O'Donoghue 
78dcd54e9bSBryan O'Donoghue 	/* Check for error */
79dcd54e9bSBryan O'Donoghue 	if (uart_id > MXC_MAX_UART_NUM)
80dcd54e9bSBryan O'Donoghue 		return;
81dcd54e9bSBryan O'Donoghue 
82dcd54e9bSBryan O'Donoghue 	/* Disable the clock gate */
83dcd54e9bSBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_id, false);
84dcd54e9bSBryan O'Donoghue 
85dcd54e9bSBryan O'Donoghue 	/* Clear the target */
86dcd54e9bSBryan O'Donoghue 	imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF);
87dcd54e9bSBryan O'Donoghue }
8814cf32aaSJun Nie 
imx_clock_enable_usdhc(unsigned int usdhc_id,uint32_t usdhc_clk_en_bits)8914cf32aaSJun Nie void imx_clock_enable_usdhc(unsigned int usdhc_id, uint32_t usdhc_clk_en_bits)
9014cf32aaSJun Nie {
9114cf32aaSJun Nie 	unsigned int ccm_trgt_id = CCM_TRT_ID_USDHC1_CLK_ROOT + usdhc_id;
9214cf32aaSJun Nie 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_USBHDC1 + usdhc_id;
9314cf32aaSJun Nie 
9414cf32aaSJun Nie 	/* Check for error */
9514cf32aaSJun Nie 	if (usdhc_id > MXC_MAX_USDHC_NUM)
9614cf32aaSJun Nie 		return;
9714cf32aaSJun Nie 
9814cf32aaSJun Nie 	/* Set target register values */
9914cf32aaSJun Nie 	imx_clock_target_set(ccm_trgt_id, usdhc_clk_en_bits);
10014cf32aaSJun Nie 
10114cf32aaSJun Nie 	/* Enable the clock gate */
10214cf32aaSJun Nie 	imx_clock_gate_enable(ccm_ccgr_id, true);
10314cf32aaSJun Nie }
104bbdcdd04SBryan O'Donoghue 
imx_clock_enable_wdog(unsigned int wdog_id)105bbdcdd04SBryan O'Donoghue void imx_clock_enable_wdog(unsigned int wdog_id)
106bbdcdd04SBryan O'Donoghue {
107bbdcdd04SBryan O'Donoghue 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id;
108bbdcdd04SBryan O'Donoghue 
109bbdcdd04SBryan O'Donoghue 	/* Check for error */
110bbdcdd04SBryan O'Donoghue 	if (wdog_id > MXC_MAX_WDOG_NUM)
111bbdcdd04SBryan O'Donoghue 		return;
112bbdcdd04SBryan O'Donoghue 
113bbdcdd04SBryan O'Donoghue 	/* Enable the clock gate */
114bbdcdd04SBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_id, true);
115bbdcdd04SBryan O'Donoghue }
116bbdcdd04SBryan O'Donoghue 
imx_clock_disable_wdog(unsigned int wdog_id)117bbdcdd04SBryan O'Donoghue void imx_clock_disable_wdog(unsigned int wdog_id)
118bbdcdd04SBryan O'Donoghue {
119bbdcdd04SBryan O'Donoghue 	unsigned int ccm_trgt_id = CCM_TRT_ID_WDOG_CLK_ROOT;
120bbdcdd04SBryan O'Donoghue 	unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id;
121bbdcdd04SBryan O'Donoghue 
122bbdcdd04SBryan O'Donoghue 	/* Check for error */
123bbdcdd04SBryan O'Donoghue 	if (wdog_id > MXC_MAX_WDOG_NUM)
124bbdcdd04SBryan O'Donoghue 		return;
125bbdcdd04SBryan O'Donoghue 
126bbdcdd04SBryan O'Donoghue 	/* Disable the clock gate */
127bbdcdd04SBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_id, false);
128bbdcdd04SBryan O'Donoghue 
129bbdcdd04SBryan O'Donoghue 	/* Clear the target */
130bbdcdd04SBryan O'Donoghue 	imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF);
131bbdcdd04SBryan O'Donoghue }
132bbdcdd04SBryan O'Donoghue 
imx_clock_set_wdog_clk_root_bits(uint32_t wdog_clk_root_en_bits)133bbdcdd04SBryan O'Donoghue void imx_clock_set_wdog_clk_root_bits(uint32_t wdog_clk_root_en_bits)
134bbdcdd04SBryan O'Donoghue {
135bbdcdd04SBryan O'Donoghue 	/* Enable the common clock root just once */
136bbdcdd04SBryan O'Donoghue 	imx_clock_target_set(CCM_TRT_ID_WDOG_CLK_ROOT, wdog_clk_root_en_bits);
137bbdcdd04SBryan O'Donoghue }
1386176a4e5SBryan O'Donoghue 
imx_clock_enable_usb(unsigned int ccm_ccgr_usb_id)1396176a4e5SBryan O'Donoghue void imx_clock_enable_usb(unsigned int ccm_ccgr_usb_id)
1406176a4e5SBryan O'Donoghue {
1416176a4e5SBryan O'Donoghue 	/* Enable the clock gate */
1426176a4e5SBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_usb_id, true);
1436176a4e5SBryan O'Donoghue }
1446176a4e5SBryan O'Donoghue 
imx_clock_disable_usb(unsigned int ccm_ccgr_usb_id)1456176a4e5SBryan O'Donoghue void imx_clock_disable_usb(unsigned int ccm_ccgr_usb_id)
1466176a4e5SBryan O'Donoghue {
1476176a4e5SBryan O'Donoghue 	/* Disable the clock gate */
1486176a4e5SBryan O'Donoghue 	imx_clock_gate_enable(ccm_ccgr_usb_id, false);
1496176a4e5SBryan O'Donoghue }
1506176a4e5SBryan O'Donoghue 
imx_clock_set_usb_clk_root_bits(uint32_t usb_clk_root_en_bits)1516176a4e5SBryan O'Donoghue void imx_clock_set_usb_clk_root_bits(uint32_t usb_clk_root_en_bits)
1526176a4e5SBryan O'Donoghue {
1536176a4e5SBryan O'Donoghue 	/* Enable the common clock root just once */
1546176a4e5SBryan O'Donoghue 	imx_clock_target_set(CCM_TRT_ID_USB_HSIC_CLK_ROOT, usb_clk_root_en_bits);
1556176a4e5SBryan O'Donoghue }
156