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 #ifdef CONFIG_TI_EDMA3 128 void enable_edma3_clocks(void) 129 { 130 u32 *const clk_domains_edma3[] = { 131 0 132 }; 133 134 u32 *const clk_modules_explicit_en_edma3[] = { 135 &cmper->tpccclkctrl, 136 &cmper->tptc0clkctrl, 137 0 138 }; 139 140 do_enable_clocks(clk_domains_edma3, 141 clk_modules_explicit_en_edma3, 142 1); 143 } 144 145 void disable_edma3_clocks(void) 146 { 147 u32 *const clk_domains_edma3[] = { 148 0 149 }; 150 151 u32 *const clk_modules_disable_edma3[] = { 152 &cmper->tpccclkctrl, 153 &cmper->tptc0clkctrl, 154 0 155 }; 156 157 do_disable_clocks(clk_domains_edma3, 158 clk_modules_disable_edma3, 159 1); 160 } 161 #endif 162 163 #if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP) 164 void enable_usb_clocks(int index) 165 { 166 u32 *usbclkctrl = 0; 167 u32 *usbphyocp2scpclkctrl = 0; 168 169 if (index == 0) { 170 usbclkctrl = &cmper->usb0clkctrl; 171 usbphyocp2scpclkctrl = &cmper->usbphyocp2scp0clkctrl; 172 setbits_le32(&cmper->usb0clkctrl, 173 USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960); 174 setbits_le32(&cmwkup->usbphy0clkctrl, 175 USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K); 176 } else if (index == 1) { 177 usbclkctrl = &cmper->usb1clkctrl; 178 usbphyocp2scpclkctrl = &cmper->usbphyocp2scp1clkctrl; 179 setbits_le32(&cmper->usb1clkctrl, 180 USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960); 181 setbits_le32(&cmwkup->usbphy1clkctrl, 182 USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K); 183 } 184 185 u32 *const clk_domains_usb[] = { 186 0 187 }; 188 189 u32 *const clk_modules_explicit_en_usb[] = { 190 usbclkctrl, 191 usbphyocp2scpclkctrl, 192 0 193 }; 194 195 do_enable_clocks(clk_domains_usb, clk_modules_explicit_en_usb, 1); 196 } 197 198 void disable_usb_clocks(int index) 199 { 200 u32 *usbclkctrl = 0; 201 u32 *usbphyocp2scpclkctrl = 0; 202 203 if (index == 0) { 204 usbclkctrl = &cmper->usb0clkctrl; 205 usbphyocp2scpclkctrl = &cmper->usbphyocp2scp0clkctrl; 206 clrbits_le32(&cmper->usb0clkctrl, 207 USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960); 208 clrbits_le32(&cmwkup->usbphy0clkctrl, 209 USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K); 210 } else if (index == 1) { 211 usbclkctrl = &cmper->usb1clkctrl; 212 usbphyocp2scpclkctrl = &cmper->usbphyocp2scp1clkctrl; 213 clrbits_le32(&cmper->usb1clkctrl, 214 USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960); 215 clrbits_le32(&cmwkup->usbphy1clkctrl, 216 USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K); 217 } 218 219 u32 *const clk_domains_usb[] = { 220 0 221 }; 222 223 u32 *const clk_modules_disable_usb[] = { 224 usbclkctrl, 225 usbphyocp2scpclkctrl, 226 0 227 }; 228 229 do_disable_clocks(clk_domains_usb, clk_modules_disable_usb, 1); 230 } 231 #endif 232