1 /* 2 * clock_am43xx.c 3 * 4 * clocks for AM43XX based boards 5 * Derived from AM33XX based boards 6 * 7 * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ 8 * 9 * SPDX-License-Identifier: GPL-2.0+ 10 */ 11 12 #include <common.h> 13 #include <asm/arch/cpu.h> 14 #include <asm/arch/clock.h> 15 #include <asm/arch/hardware.h> 16 #include <asm/arch/sys_proto.h> 17 #include <asm/io.h> 18 19 struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; 20 struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP; 21 struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; 22 23 const struct dpll_regs dpll_mpu_regs = { 24 .cm_clkmode_dpll = CM_WKUP + 0x560, 25 .cm_idlest_dpll = CM_WKUP + 0x564, 26 .cm_clksel_dpll = CM_WKUP + 0x56c, 27 .cm_div_m2_dpll = CM_WKUP + 0x570, 28 }; 29 30 const struct dpll_regs dpll_core_regs = { 31 .cm_clkmode_dpll = CM_WKUP + 0x520, 32 .cm_idlest_dpll = CM_WKUP + 0x524, 33 .cm_clksel_dpll = CM_WKUP + 0x52C, 34 .cm_div_m4_dpll = CM_WKUP + 0x538, 35 .cm_div_m5_dpll = CM_WKUP + 0x53C, 36 .cm_div_m6_dpll = CM_WKUP + 0x540, 37 }; 38 39 const struct dpll_regs dpll_per_regs = { 40 .cm_clkmode_dpll = CM_WKUP + 0x5E0, 41 .cm_idlest_dpll = CM_WKUP + 0x5E4, 42 .cm_clksel_dpll = CM_WKUP + 0x5EC, 43 .cm_div_m2_dpll = CM_WKUP + 0x5F0, 44 }; 45 46 const struct dpll_regs dpll_ddr_regs = { 47 .cm_clkmode_dpll = CM_WKUP + 0x5A0, 48 .cm_idlest_dpll = CM_WKUP + 0x5A4, 49 .cm_clksel_dpll = CM_WKUP + 0x5AC, 50 .cm_div_m2_dpll = CM_WKUP + 0x5B0, 51 .cm_div_m4_dpll = CM_WKUP + 0x5B8, 52 }; 53 54 void setup_clocks_for_console(void) 55 { 56 u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED; 57 58 /* Do not add any spl_debug prints in this function */ 59 clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, 60 CD_CLKCTRL_CLKTRCTRL_SW_WKUP << 61 CD_CLKCTRL_CLKTRCTRL_SHIFT); 62 63 /* Enable UART0 */ 64 clrsetbits_le32(&cmwkup->wkup_uart0ctrl, 65 MODULE_CLKCTRL_MODULEMODE_MASK, 66 MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << 67 MODULE_CLKCTRL_MODULEMODE_SHIFT); 68 69 while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) || 70 (idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) { 71 clkctrl = readl(&cmwkup->wkup_uart0ctrl); 72 idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >> 73 MODULE_CLKCTRL_IDLEST_SHIFT; 74 } 75 } 76 77 void enable_basic_clocks(void) 78 { 79 u32 *const clk_domains[] = { 80 &cmper->l3clkstctrl, 81 &cmper->l3sclkstctrl, 82 &cmper->l4lsclkstctrl, 83 &cmwkup->wkclkstctrl, 84 &cmper->emifclkstctrl, 85 0 86 }; 87 88 u32 *const clk_modules_explicit_en[] = { 89 &cmper->l3clkctrl, 90 &cmper->l4lsclkctrl, 91 &cmper->l4fwclkctrl, 92 &cmwkup->wkl4wkclkctrl, 93 &cmper->l3instrclkctrl, 94 &cmper->l4hsclkctrl, 95 &cmwkup->wkgpio0clkctrl, 96 &cmwkup->wkctrlclkctrl, 97 &cmper->timer2clkctrl, 98 &cmper->gpmcclkctrl, 99 &cmper->elmclkctrl, 100 &cmper->mmc0clkctrl, 101 &cmper->mmc1clkctrl, 102 &cmwkup->wkup_i2c0ctrl, 103 &cmper->gpio1clkctrl, 104 &cmper->gpio2clkctrl, 105 &cmper->gpio3clkctrl, 106 &cmper->gpio4clkctrl, 107 &cmper->gpio5clkctrl, 108 &cmper->i2c1clkctrl, 109 &cmper->cpgmac0clkctrl, 110 &cmper->emiffwclkctrl, 111 &cmper->emifclkctrl, 112 &cmper->otfaemifclkctrl, 113 &cmper->qspiclkctrl, 114 &cmper->spi0clkctrl, 115 0 116 }; 117 118 do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); 119 120 /* Select the Master osc clk as Timer2 clock source */ 121 writel(0x1, &cmdpll->clktimer2clk); 122 123 /* For OPP100 the mac clock should be /5. */ 124 writel(0x4, &cmdpll->clkselmacclk); 125 } 126 127 void rtc_only_enable_basic_clocks(void) 128 { 129 u32 *const clk_domains[] = { 130 &cmper->emifclkstctrl, 131 0 132 }; 133 134 u32 *const clk_modules_explicit_en[] = { 135 &cmper->gpio5clkctrl, 136 &cmper->emiffwclkctrl, 137 &cmper->emifclkctrl, 138 &cmper->otfaemifclkctrl, 139 0 140 }; 141 142 do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); 143 144 /* Select the Master osc clk as Timer2 clock source */ 145 writel(0x1, &cmdpll->clktimer2clk); 146 } 147 148 #ifdef CONFIG_TI_EDMA3 149 void enable_edma3_clocks(void) 150 { 151 u32 *const clk_domains_edma3[] = { 152 0 153 }; 154 155 u32 *const clk_modules_explicit_en_edma3[] = { 156 &cmper->tpccclkctrl, 157 &cmper->tptc0clkctrl, 158 0 159 }; 160 161 do_enable_clocks(clk_domains_edma3, 162 clk_modules_explicit_en_edma3, 163 1); 164 } 165 166 void disable_edma3_clocks(void) 167 { 168 u32 *const clk_domains_edma3[] = { 169 0 170 }; 171 172 u32 *const clk_modules_disable_edma3[] = { 173 &cmper->tpccclkctrl, 174 &cmper->tptc0clkctrl, 175 0 176 }; 177 178 do_disable_clocks(clk_domains_edma3, 179 clk_modules_disable_edma3, 180 1); 181 } 182 #endif 183 184 #if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) 185 void enable_usb_clocks(int index) 186 { 187 u32 *usbclkctrl = 0; 188 u32 *usbphyocp2scpclkctrl = 0; 189 190 if (index == 0) { 191 usbclkctrl = &cmper->usb0clkctrl; 192 usbphyocp2scpclkctrl = &cmper->usbphyocp2scp0clkctrl; 193 setbits_le32(&cmper->usb0clkctrl, 194 USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960); 195 setbits_le32(&cmwkup->usbphy0clkctrl, 196 USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K); 197 } else if (index == 1) { 198 usbclkctrl = &cmper->usb1clkctrl; 199 usbphyocp2scpclkctrl = &cmper->usbphyocp2scp1clkctrl; 200 setbits_le32(&cmper->usb1clkctrl, 201 USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960); 202 setbits_le32(&cmwkup->usbphy1clkctrl, 203 USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K); 204 } 205 206 u32 *const clk_domains_usb[] = { 207 0 208 }; 209 210 u32 *const clk_modules_explicit_en_usb[] = { 211 usbclkctrl, 212 usbphyocp2scpclkctrl, 213 0 214 }; 215 216 do_enable_clocks(clk_domains_usb, clk_modules_explicit_en_usb, 1); 217 } 218 219 void disable_usb_clocks(int index) 220 { 221 u32 *usbclkctrl = 0; 222 u32 *usbphyocp2scpclkctrl = 0; 223 224 if (index == 0) { 225 usbclkctrl = &cmper->usb0clkctrl; 226 usbphyocp2scpclkctrl = &cmper->usbphyocp2scp0clkctrl; 227 clrbits_le32(&cmper->usb0clkctrl, 228 USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960); 229 clrbits_le32(&cmwkup->usbphy0clkctrl, 230 USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K); 231 } else if (index == 1) { 232 usbclkctrl = &cmper->usb1clkctrl; 233 usbphyocp2scpclkctrl = &cmper->usbphyocp2scp1clkctrl; 234 clrbits_le32(&cmper->usb1clkctrl, 235 USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960); 236 clrbits_le32(&cmwkup->usbphy1clkctrl, 237 USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K); 238 } 239 240 u32 *const clk_domains_usb[] = { 241 0 242 }; 243 244 u32 *const clk_modules_disable_usb[] = { 245 usbclkctrl, 246 usbphyocp2scpclkctrl, 247 0 248 }; 249 250 do_disable_clocks(clk_domains_usb, clk_modules_disable_usb, 1); 251 } 252 #endif 253