1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2004 Texas Instruments. 4 * Copyright (C) 2009 David Brownell 5 */ 6 7 #include <common.h> 8 #include <netdev.h> 9 #include <asm/arch/hardware.h> 10 #include <asm/io.h> 11 12 DECLARE_GLOBAL_DATA_PTR; 13 14 /* offsets from PLL controller base */ 15 #define PLLC_PLLCTL 0x100 16 #define PLLC_PLLM 0x110 17 #define PLLC_PREDIV 0x114 18 #define PLLC_PLLDIV1 0x118 19 #define PLLC_PLLDIV2 0x11c 20 #define PLLC_PLLDIV3 0x120 21 #define PLLC_POSTDIV 0x128 22 #define PLLC_BPDIV 0x12c 23 #define PLLC_PLLDIV4 0x160 24 #define PLLC_PLLDIV5 0x164 25 #define PLLC_PLLDIV6 0x168 26 #define PLLC_PLLDIV7 0x16c 27 #define PLLC_PLLDIV8 0x170 28 #define PLLC_PLLDIV9 0x174 29 30 /* SOC-specific pll info */ 31 #ifdef CONFIG_SOC_DM355 32 #define ARM_PLLDIV PLLC_PLLDIV1 33 #define DDR_PLLDIV PLLC_PLLDIV1 34 #endif 35 36 #ifdef CONFIG_SOC_DM644X 37 #define ARM_PLLDIV PLLC_PLLDIV2 38 #define DSP_PLLDIV PLLC_PLLDIV1 39 #define DDR_PLLDIV PLLC_PLLDIV2 40 #endif 41 42 #ifdef CONFIG_SOC_DM646X 43 #define DSP_PLLDIV PLLC_PLLDIV1 44 #define ARM_PLLDIV PLLC_PLLDIV2 45 #define DDR_PLLDIV PLLC_PLLDIV1 46 #endif 47 48 #ifdef CONFIG_SOC_DA8XX 49 unsigned int sysdiv[9] = { 50 PLLC_PLLDIV1, PLLC_PLLDIV2, PLLC_PLLDIV3, PLLC_PLLDIV4, PLLC_PLLDIV5, 51 PLLC_PLLDIV6, PLLC_PLLDIV7, PLLC_PLLDIV8, PLLC_PLLDIV9 52 }; 53 54 int clk_get(enum davinci_clk_ids id) 55 { 56 int pre_div; 57 int pllm; 58 int post_div; 59 int pll_out; 60 unsigned int pll_base; 61 62 pll_out = CONFIG_SYS_OSCIN_FREQ; 63 64 if (id == DAVINCI_AUXCLK_CLKID) 65 goto out; 66 67 if ((id >> 16) == 1) 68 pll_base = (unsigned int)davinci_pllc1_regs; 69 else 70 pll_base = (unsigned int)davinci_pllc0_regs; 71 72 id &= 0xFFFF; 73 74 /* 75 * Lets keep this simple. Combining operations can result in 76 * unexpected approximations 77 */ 78 pre_div = (readl(pll_base + PLLC_PREDIV) & 79 DAVINCI_PLLC_DIV_MASK) + 1; 80 pllm = readl(pll_base + PLLC_PLLM) + 1; 81 82 pll_out /= pre_div; 83 pll_out *= pllm; 84 85 if (id == DAVINCI_PLLM_CLKID) 86 goto out; 87 88 post_div = (readl(pll_base + PLLC_POSTDIV) & 89 DAVINCI_PLLC_DIV_MASK) + 1; 90 91 pll_out /= post_div; 92 93 if (id == DAVINCI_PLLC_CLKID) 94 goto out; 95 96 pll_out /= (readl(pll_base + sysdiv[id - 1]) & 97 DAVINCI_PLLC_DIV_MASK) + 1; 98 99 out: 100 return pll_out; 101 } 102 103 int set_cpu_clk_info(void) 104 { 105 gd->bd->bi_arm_freq = clk_get(DAVINCI_ARM_CLKID) / 1000000; 106 /* DDR PHY uses an x2 input clock */ 107 gd->bd->bi_ddr_freq = cpu_is_da830() ? 0 : 108 (clk_get(DAVINCI_DDR_CLKID) / 1000000); 109 gd->bd->bi_dsp_freq = 0; 110 return 0; 111 } 112 113 #else /* CONFIG_SOC_DA8XX */ 114 115 static unsigned pll_div(volatile void *pllbase, unsigned offset) 116 { 117 u32 div; 118 119 div = REG(pllbase + offset); 120 return (div & BIT(15)) ? (1 + (div & 0x1f)) : 1; 121 } 122 123 static inline unsigned pll_prediv(volatile void *pllbase) 124 { 125 #ifdef CONFIG_SOC_DM355 126 /* this register read seems to fail on pll0 */ 127 if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) 128 return 8; 129 else 130 return pll_div(pllbase, PLLC_PREDIV); 131 #elif defined(CONFIG_SOC_DM365) 132 return pll_div(pllbase, PLLC_PREDIV); 133 #endif 134 return 1; 135 } 136 137 static inline unsigned pll_postdiv(volatile void *pllbase) 138 { 139 #if defined(CONFIG_SOC_DM355) || defined(CONFIG_SOC_DM365) 140 return pll_div(pllbase, PLLC_POSTDIV); 141 #elif defined(CONFIG_SOC_DM6446) 142 if (pllbase == (volatile void *)DAVINCI_PLL_CNTRL0_BASE) 143 return pll_div(pllbase, PLLC_POSTDIV); 144 #endif 145 return 1; 146 } 147 148 static unsigned pll_sysclk_mhz(unsigned pll_addr, unsigned div) 149 { 150 volatile void *pllbase = (volatile void *) pll_addr; 151 #ifdef CONFIG_SOC_DM646X 152 unsigned base = CONFIG_REFCLK_FREQ / 1000; 153 #else 154 unsigned base = CONFIG_SYS_HZ_CLOCK / 1000; 155 #endif 156 157 /* the PLL might be bypassed */ 158 if (readl(pllbase + PLLC_PLLCTL) & BIT(0)) { 159 base /= pll_prediv(pllbase); 160 #if defined(CONFIG_SOC_DM365) 161 base *= 2 * (readl(pllbase + PLLC_PLLM) & 0x0ff); 162 #else 163 base *= 1 + (REG(pllbase + PLLC_PLLM) & 0x0ff); 164 #endif 165 base /= pll_postdiv(pllbase); 166 } 167 return DIV_ROUND_UP(base, 1000 * pll_div(pllbase, div)); 168 } 169 170 #ifdef DAVINCI_DM6467EVM 171 unsigned int davinci_arm_clk_get() 172 { 173 return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV) * 1000000; 174 } 175 #endif 176 177 #if defined(CONFIG_SOC_DM365) 178 unsigned int davinci_clk_get(unsigned int div) 179 { 180 return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, div) * 1000000; 181 } 182 #endif 183 184 int set_cpu_clk_info(void) 185 { 186 unsigned int pllbase = DAVINCI_PLL_CNTRL0_BASE; 187 #if defined(CONFIG_SOC_DM365) 188 pllbase = DAVINCI_PLL_CNTRL1_BASE; 189 #endif 190 gd->bd->bi_arm_freq = pll_sysclk_mhz(pllbase, ARM_PLLDIV); 191 192 #ifdef DSP_PLLDIV 193 gd->bd->bi_dsp_freq = 194 pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, DSP_PLLDIV); 195 #else 196 gd->bd->bi_dsp_freq = 0; 197 #endif 198 199 pllbase = DAVINCI_PLL_CNTRL1_BASE; 200 #if defined(CONFIG_SOC_DM365) 201 pllbase = DAVINCI_PLL_CNTRL0_BASE; 202 #endif 203 gd->bd->bi_ddr_freq = pll_sysclk_mhz(pllbase, DDR_PLLDIV) / 2; 204 205 return 0; 206 } 207 208 #endif /* !CONFIG_SOC_DA8XX */ 209 210 /* 211 * Initializes on-chip ethernet controllers. 212 * to override, implement board_eth_init() 213 */ 214 int cpu_eth_init(bd_t *bis) 215 { 216 #if defined(CONFIG_DRIVER_TI_EMAC) 217 davinci_emac_initialize(); 218 #endif 219 return 0; 220 } 221