summaryrefslogtreecommitdiff
path: root/plat/imx/common/imx_clock.c
blob: 743de553ab8d82d0d41efabcd523564227f92e3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdint.h>
#include <stdbool.h>

#include <arch.h>
#include <lib/mmio.h>

#include <imx_regs.h>
#include <imx_clock.h>

void imx_clock_target_set(unsigned int id, uint32_t val)
{
	struct ccm *ccm = ((struct ccm *)CCM_BASE);
	uintptr_t addr;

	if (id > CCM_ROOT_CTRL_NUM)
		return;

	addr = (uintptr_t)&ccm->ccm_root_ctrl[id].ccm_target_root;
	mmio_write_32(addr, val);
}

void imx_clock_target_clr(unsigned int id, uint32_t val)
{
	struct ccm *ccm = ((struct ccm *)CCM_BASE);
	uintptr_t addr;

	if (id > CCM_ROOT_CTRL_NUM)
		return;

	addr = (uintptr_t)&ccm->ccm_root_ctrl[id].ccm_target_root_clr;
	mmio_write_32(addr, val);
}

void imx_clock_gate_enable(unsigned int id, bool enable)
{
	struct ccm *ccm = ((struct ccm *)CCM_BASE);
	uintptr_t addr;

	if (id > CCM_CLK_GATE_CTRL_NUM)
		return;

	/* TODO: add support for more than DOMAIN0 clocks */
	if (enable)
		addr = (uintptr_t)&ccm->ccm_clk_gate_ctrl[id].ccm_ccgr_set;
	else
		addr = (uintptr_t)&ccm->ccm_clk_gate_ctrl[id].ccm_ccgr_clr;

	mmio_write_32(addr, CCM_CCGR_SETTING0_DOM_CLK_ALWAYS);
}

void imx_clock_enable_uart(unsigned int uart_id, uint32_t uart_clk_en_bits)
{
	unsigned int ccm_trgt_id = CCM_TRT_ID_UART1_CLK_ROOT + uart_id;
	unsigned int ccm_ccgr_id = CCM_CCGR_ID_UART1 + uart_id;

	/* Check for error */
	if (uart_id > MXC_MAX_UART_NUM)
		return;

	/* Set target register values */
	imx_clock_target_set(ccm_trgt_id, uart_clk_en_bits);

	/* Enable the clock gate */
	imx_clock_gate_enable(ccm_ccgr_id, true);
}

void imx_clock_disable_uart(unsigned int uart_id)
{
	unsigned int ccm_trgt_id = CCM_TRT_ID_UART1_CLK_ROOT + uart_id;
	unsigned int ccm_ccgr_id = CCM_CCGR_ID_UART1 + uart_id;

	/* Check for error */
	if (uart_id > MXC_MAX_UART_NUM)
		return;

	/* Disable the clock gate */
	imx_clock_gate_enable(ccm_ccgr_id, false);

	/* Clear the target */
	imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF);
}

void imx_clock_enable_usdhc(unsigned int usdhc_id, uint32_t usdhc_clk_en_bits)
{
	unsigned int ccm_trgt_id = CCM_TRT_ID_USDHC1_CLK_ROOT + usdhc_id;
	unsigned int ccm_ccgr_id = CCM_CCGR_ID_USBHDC1 + usdhc_id;

	/* Check for error */
	if (usdhc_id > MXC_MAX_USDHC_NUM)
		return;

	/* Set target register values */
	imx_clock_target_set(ccm_trgt_id, usdhc_clk_en_bits);

	/* Enable the clock gate */
	imx_clock_gate_enable(ccm_ccgr_id, true);
}

void imx_clock_enable_wdog(unsigned int wdog_id)
{
	unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id;

	/* Check for error */
	if (wdog_id > MXC_MAX_WDOG_NUM)
		return;

	/* Enable the clock gate */
	imx_clock_gate_enable(ccm_ccgr_id, true);
}

void imx_clock_disable_wdog(unsigned int wdog_id)
{
	unsigned int ccm_trgt_id = CCM_TRT_ID_WDOG_CLK_ROOT;
	unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id;

	/* Check for error */
	if (wdog_id > MXC_MAX_WDOG_NUM)
		return;

	/* Disable the clock gate */
	imx_clock_gate_enable(ccm_ccgr_id, false);

	/* Clear the target */
	imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF);
}

void imx_clock_set_wdog_clk_root_bits(uint32_t wdog_clk_root_en_bits)
{
	/* Enable the common clock root just once */
	imx_clock_target_set(CCM_TRT_ID_WDOG_CLK_ROOT, wdog_clk_root_en_bits);
}

void imx_clock_enable_usb(unsigned int ccm_ccgr_usb_id)
{
	/* Enable the clock gate */
	imx_clock_gate_enable(ccm_ccgr_usb_id, true);
}

void imx_clock_disable_usb(unsigned int ccm_ccgr_usb_id)
{
	/* Disable the clock gate */
	imx_clock_gate_enable(ccm_ccgr_usb_id, false);
}

void imx_clock_set_usb_clk_root_bits(uint32_t usb_clk_root_en_bits)
{
	/* Enable the common clock root just once */
	imx_clock_target_set(CCM_TRT_ID_USB_HSIC_CLK_ROOT, usb_clk_root_en_bits);
}