1 /* 2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stdint.h> 8 #include <stdbool.h> 9 10 #include <arch.h> 11 #include <lib/mmio.h> 12 13 #include <imx_regs.h> 14 #include <imx_clock.h> 15 16 void imx_clock_target_set(unsigned int id, uint32_t val) 17 { 18 struct ccm *ccm = ((struct ccm *)CCM_BASE); 19 uintptr_t addr; 20 21 if (id > CCM_ROOT_CTRL_NUM) 22 return; 23 24 addr = (uintptr_t)&ccm->ccm_root_ctrl[id].ccm_target_root; 25 mmio_write_32(addr, val); 26 } 27 28 void imx_clock_target_clr(unsigned int id, uint32_t val) 29 { 30 struct ccm *ccm = ((struct ccm *)CCM_BASE); 31 uintptr_t addr; 32 33 if (id > CCM_ROOT_CTRL_NUM) 34 return; 35 36 addr = (uintptr_t)&ccm->ccm_root_ctrl[id].ccm_target_root_clr; 37 mmio_write_32(addr, val); 38 } 39 40 void imx_clock_gate_enable(unsigned int id, bool enable) 41 { 42 struct ccm *ccm = ((struct ccm *)CCM_BASE); 43 uintptr_t addr; 44 45 if (id > CCM_CLK_GATE_CTRL_NUM) 46 return; 47 48 /* TODO: add support for more than DOMAIN0 clocks */ 49 if (enable) 50 addr = (uintptr_t)&ccm->ccm_clk_gate_ctrl[id].ccm_ccgr_set; 51 else 52 addr = (uintptr_t)&ccm->ccm_clk_gate_ctrl[id].ccm_ccgr_clr; 53 54 mmio_write_32(addr, CCM_CCGR_SETTING0_DOM_CLK_ALWAYS); 55 } 56 57 void imx_clock_enable_uart(unsigned int uart_id, uint32_t uart_clk_en_bits) 58 { 59 unsigned int ccm_trgt_id = CCM_TRT_ID_UART1_CLK_ROOT + uart_id; 60 unsigned int ccm_ccgr_id = CCM_CCGR_ID_UART1 + uart_id; 61 62 /* Check for error */ 63 if (uart_id > MXC_MAX_UART_NUM) 64 return; 65 66 /* Set target register values */ 67 imx_clock_target_set(ccm_trgt_id, uart_clk_en_bits); 68 69 /* Enable the clock gate */ 70 imx_clock_gate_enable(ccm_ccgr_id, true); 71 } 72 73 void imx_clock_disable_uart(unsigned int uart_id) 74 { 75 unsigned int ccm_trgt_id = CCM_TRT_ID_UART1_CLK_ROOT + uart_id; 76 unsigned int ccm_ccgr_id = CCM_CCGR_ID_UART1 + uart_id; 77 78 /* Check for error */ 79 if (uart_id > MXC_MAX_UART_NUM) 80 return; 81 82 /* Disable the clock gate */ 83 imx_clock_gate_enable(ccm_ccgr_id, false); 84 85 /* Clear the target */ 86 imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF); 87 } 88 89 void imx_clock_enable_usdhc(unsigned int usdhc_id, uint32_t usdhc_clk_en_bits) 90 { 91 unsigned int ccm_trgt_id = CCM_TRT_ID_USDHC1_CLK_ROOT + usdhc_id; 92 unsigned int ccm_ccgr_id = CCM_CCGR_ID_USBHDC1 + usdhc_id; 93 94 /* Check for error */ 95 if (usdhc_id > MXC_MAX_USDHC_NUM) 96 return; 97 98 /* Set target register values */ 99 imx_clock_target_set(ccm_trgt_id, usdhc_clk_en_bits); 100 101 /* Enable the clock gate */ 102 imx_clock_gate_enable(ccm_ccgr_id, true); 103 } 104 105 void imx_clock_enable_wdog(unsigned int wdog_id) 106 { 107 unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id; 108 109 /* Check for error */ 110 if (wdog_id > MXC_MAX_WDOG_NUM) 111 return; 112 113 /* Enable the clock gate */ 114 imx_clock_gate_enable(ccm_ccgr_id, true); 115 } 116 117 void imx_clock_disable_wdog(unsigned int wdog_id) 118 { 119 unsigned int ccm_trgt_id = CCM_TRT_ID_WDOG_CLK_ROOT; 120 unsigned int ccm_ccgr_id = CCM_CCGR_ID_WDOG1 + wdog_id; 121 122 /* Check for error */ 123 if (wdog_id > MXC_MAX_WDOG_NUM) 124 return; 125 126 /* Disable the clock gate */ 127 imx_clock_gate_enable(ccm_ccgr_id, false); 128 129 /* Clear the target */ 130 imx_clock_target_clr(ccm_trgt_id, 0xFFFFFFFF); 131 } 132 133 void imx_clock_set_wdog_clk_root_bits(uint32_t wdog_clk_root_en_bits) 134 { 135 /* Enable the common clock root just once */ 136 imx_clock_target_set(CCM_TRT_ID_WDOG_CLK_ROOT, wdog_clk_root_en_bits); 137 } 138 139 void imx_clock_enable_usb(unsigned int ccm_ccgr_usb_id) 140 { 141 /* Enable the clock gate */ 142 imx_clock_gate_enable(ccm_ccgr_usb_id, true); 143 } 144 145 void imx_clock_disable_usb(unsigned int ccm_ccgr_usb_id) 146 { 147 /* Disable the clock gate */ 148 imx_clock_gate_enable(ccm_ccgr_usb_id, false); 149 } 150 151 void imx_clock_set_usb_clk_root_bits(uint32_t usb_clk_root_en_bits) 152 { 153 /* Enable the common clock root just once */ 154 imx_clock_target_set(CCM_TRT_ID_USB_HSIC_CLK_ROOT, usb_clk_root_en_bits); 155 } 156