1 1.41 jmcneill /* $NetBSD: exynos_soc.c,v 1.41 2022/10/29 13:29:46 jmcneill Exp $ */ 2 1.20 skrll 3 1.1 matt /*- 4 1.1 matt * Copyright (c) 2014 The NetBSD Foundation, Inc. 5 1.1 matt * All rights reserved. 6 1.1 matt * 7 1.1 matt * This code is derived from software contributed to The NetBSD Foundation 8 1.1 matt * by Reinoud Zandijk. 9 1.1 matt * 10 1.1 matt * Redistribution and use in source and binary forms, with or without 11 1.1 matt * modification, are permitted provided that the following conditions 12 1.1 matt * are met: 13 1.1 matt * 1. Redistributions of source code must retain the above copyright 14 1.1 matt * notice, this list of conditions and the following disclaimer. 15 1.1 matt * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 matt * notice, this list of conditions and the following disclaimer in the 17 1.1 matt * documentation and/or other materials provided with the distribution. 18 1.1 matt * 19 1.1 matt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 matt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 matt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 matt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 matt * POSSIBILITY OF SUCH DAMAGE. 30 1.1 matt */ 31 1.1 matt 32 1.34 skrll #include "opt_arm_debug.h" 33 1.1 matt #include "opt_exynos.h" 34 1.1 matt 35 1.1 matt #include <sys/cdefs.h> 36 1.41 jmcneill __KERNEL_RCSID(1, "$NetBSD: exynos_soc.c,v 1.41 2022/10/29 13:29:46 jmcneill Exp $"); 37 1.1 matt 38 1.1 matt #include <sys/param.h> 39 1.1 matt #include <sys/bus.h> 40 1.1 matt #include <sys/cpu.h> 41 1.1 matt #include <sys/device.h> 42 1.1 matt 43 1.1 matt #include <prop/proplib.h> 44 1.1 matt 45 1.1 matt #include <net/if.h> 46 1.1 matt #include <net/if_ether.h> 47 1.1 matt 48 1.1 matt #include <arm/locore.h> 49 1.1 matt 50 1.1 matt #include <arm/mainbus/mainbus.h> 51 1.1 matt #include <arm/cortex/mpcore_var.h> 52 1.1 matt 53 1.1 matt #include <arm/samsung/exynos_reg.h> 54 1.1 matt #include <arm/samsung/exynos_var.h> 55 1.14 matt #include <arm/samsung/mct_reg.h> 56 1.1 matt #include <arm/samsung/smc.h> 57 1.1 matt 58 1.1 matt #include <arm/cortex/pl310_var.h> 59 1.1 matt #include <arm/cortex/pl310_reg.h> 60 1.1 matt 61 1.41 jmcneill #include <evbarm/fdt/platform.h> 62 1.41 jmcneill 63 1.41 jmcneill #define EXYNOS_CORE_VBASE KERNEL_IO_VBASE 64 1.1 matt 65 1.1 matt 66 1.1 matt /* these variables are retrieved in start.S and stored in .data */ 67 1.1 matt uint32_t exynos_soc_id = 0; 68 1.1 matt uint32_t exynos_pop_id = 0; 69 1.1 matt 70 1.16 reinoud /* cpu frequencies */ 71 1.16 reinoud struct cpu_freq { 72 1.16 reinoud uint64_t freq; 73 1.16 reinoud int P; 74 1.16 reinoud int M; 75 1.26 skrll int S; 76 1.16 reinoud }; 77 1.16 reinoud 78 1.16 reinoud 79 1.32 jmcneill #ifdef SOC_EXYNOS4 80 1.35 skrll int exynos4_l2cc_init(void); 81 1.35 skrll 82 1.16 reinoud const struct cpu_freq cpu_freq_settings_exynos4[] = { 83 1.16 reinoud { 200, 3, 100, 2}, 84 1.16 reinoud { 300, 4, 200, 2}, 85 1.16 reinoud { 400, 3, 100, 1}, 86 1.16 reinoud { 500, 3, 125, 1}, 87 1.16 reinoud { 600, 4, 200, 1}, 88 1.16 reinoud { 700, 3, 175, 1}, 89 1.16 reinoud { 800, 3, 100, 0}, 90 1.16 reinoud { 900, 4, 150, 0}, 91 1.16 reinoud {1000, 3, 125, 0}, 92 1.16 reinoud {1100, 6, 275, 0}, 93 1.16 reinoud {1200, 4, 200, 0}, 94 1.16 reinoud {1300, 6, 325, 0}, 95 1.16 reinoud {1400, 3, 175, 0}, 96 1.16 reinoud {1600, 3, 200, 0}, 97 1.24 reinoud // {1704, 3, 213, 0}, 98 1.24 reinoud // {1800, 4, 300, 0}, 99 1.24 reinoud // {1920, 3, 240, 0}, 100 1.24 reinoud // {2000, 3, 250, 0}, 101 1.16 reinoud }; 102 1.16 reinoud #endif 103 1.16 reinoud 104 1.16 reinoud 105 1.32 jmcneill #ifdef SOC_EXYNOS5 106 1.24 reinoud #define EXYNOS5_DEFAULT_ENTRY 7 107 1.16 reinoud const struct cpu_freq cpu_freq_settings_exynos5[] = { 108 1.16 reinoud { 200, 3, 100, 2}, 109 1.16 reinoud { 333, 4, 222, 2}, 110 1.16 reinoud { 400, 3, 100, 1}, 111 1.16 reinoud { 533, 12, 533, 1}, 112 1.16 reinoud { 600, 4, 200, 1}, 113 1.16 reinoud { 667, 7, 389, 1}, 114 1.16 reinoud { 800, 3, 100, 0}, 115 1.24 reinoud { 900, 4, 150, 0}, 116 1.16 reinoud {1000, 3, 125, 0}, 117 1.16 reinoud {1066, 12, 533, 0}, 118 1.16 reinoud {1200, 3, 150, 0}, 119 1.16 reinoud {1400, 3, 175, 0}, 120 1.16 reinoud {1600, 3, 200, 0}, 121 1.16 reinoud }; 122 1.16 reinoud #endif 123 1.16 reinoud 124 1.16 reinoud static struct cpu_freq const *cpu_freq_settings = NULL; 125 1.16 reinoud static int ncpu_freq_settings = 0; 126 1.16 reinoud 127 1.16 reinoud static int cpu_freq_target = 0; 128 1.24 reinoud #define NFRQS 18 129 1.16 reinoud static char sysctl_cpu_freqs_txt[NFRQS*5]; 130 1.16 reinoud 131 1.21 reinoud bus_space_handle_t exynos_core_bsh; 132 1.21 reinoud bus_space_handle_t exynos_audiocore_bsh; 133 1.21 reinoud 134 1.21 reinoud bus_space_handle_t exynos_wdt_bsh; 135 1.21 reinoud bus_space_handle_t exynos_pmu_bsh; 136 1.21 reinoud bus_space_handle_t exynos_cmu_bsh; 137 1.21 reinoud bus_space_handle_t exynos_cmu_apll_bsh; 138 1.22 reinoud bus_space_handle_t exynos_sysreg_bsh; 139 1.21 reinoud 140 1.21 reinoud 141 1.16 reinoud static int sysctl_cpufreq_target(SYSCTLFN_ARGS); 142 1.16 reinoud static int sysctl_cpufreq_current(SYSCTLFN_ARGS); 143 1.16 reinoud 144 1.1 matt #ifdef ARM_TRUSTZONE_FIRMWARE 145 1.2 reinoud int 146 1.1 matt exynos_do_idle(void) 147 1.1 matt { 148 1.1 matt exynos_smc(SMC_CMD_SLEEP, 0, 0, 0); 149 1.1 matt 150 1.1 matt return 0; 151 1.1 matt } 152 1.1 matt 153 1.1 matt 154 1.2 reinoud int 155 1.1 matt exynos_set_cpu_boot_addr(int cpu, vaddr_t boot_addr) 156 1.1 matt { 157 1.2 reinoud /* XXX we need to map in iRAM space for this XXX */ 158 1.1 matt return 0; 159 1.1 matt } 160 1.1 matt 161 1.1 matt 162 1.2 reinoud int 163 1.1 matt exynos_cpu_boot(int cpu) 164 1.1 matt { 165 1.1 matt exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0); 166 1.1 matt 167 1.1 matt return 0; 168 1.1 matt } 169 1.1 matt 170 1.1 matt 171 1.32 jmcneill #ifdef SOC_EXYNOS4 172 1.1 matt /* 173 1.17 snj * The latency values used below are `magic' and probably chosen empirically. 174 1.1 matt * For the 4210 variant the data latency is lower, a 0x110. This is currently 175 1.1 matt * not enforced. 176 1.1 matt * 177 1.1 matt * The prefetch values are also different for the revision 0 of the 178 1.1 matt * Exynos4412, but why? 179 1.1 matt */ 180 1.1 matt 181 1.2 reinoud int 182 1.23 reinoud exynos4_l2cc_init(void) 183 1.1 matt { 184 1.1 matt const uint32_t tag_latency = 0x110; 185 1.2 reinoud const uint32_t data_latency = IS_EXYNOS4410_P() ? 0x110 : 0x120; 186 1.1 matt const uint32_t prefetch4412 = /* 0111 0001 0000 0000 0000 0000 0000 0111 */ 187 1.1 matt PREFETCHCTL_DBLLINEF_EN | 188 1.1 matt PREFETCHCTL_INSTRPREF_EN | 189 1.1 matt PREFETCHCTL_DATAPREF_EN | 190 1.1 matt PREFETCHCTL_PREF_DROP_EN | 191 1.1 matt PREFETCHCTL_PREFETCH_OFFSET_7; 192 1.1 matt const uint32_t prefetch4412_r0 = /* 0011 0000 0000 0000 0000 0000 0000 0111 */ 193 1.1 matt PREFETCHCTL_INSTRPREF_EN | 194 1.1 matt PREFETCHCTL_DATAPREF_EN | 195 1.1 matt PREFETCHCTL_PREFETCH_OFFSET_7; 196 1.1 matt const uint32_t aux_val = /* 0111 1100 0100 0111 0000 0000 0000 0001 */ 197 1.1 matt AUXCTL_EARLY_BRESP_EN | 198 1.1 matt AUXCTL_I_PREFETCH | 199 1.1 matt AUXCTL_D_PREFETCH | 200 1.1 matt AUXCTL_NS_INT_ACC_CTL | 201 1.1 matt AUXCTL_NS_INT_LOCK_EN | 202 1.1 matt AUXCTL_SHARED_ATT_OVR | 203 1.1 matt AUXCTL_WAY_SIZE_RSVD7 << 16 | /* why rsvd7 ??? */ 204 1.1 matt AUXCTL_FULL_LINE_WR0; 205 1.1 matt const uint32_t aux_keepmask = /* 1100 0010 0000 0000 1111 1111 1111 1111 */ 206 1.1 matt AUXCTL_RSVD31 | 207 1.1 matt AUXCTL_EARLY_BRESP_EN | 208 1.1 matt AUXCTL_CACHE_REPL_RR | 209 1.1 matt 210 1.1 matt AUXCTL_SH_ATTR_INV_ENA| 211 1.1 matt AUXCTL_EXCL_CACHE_CFG | 212 1.1 matt AUXCTL_ST_BUF_DEV_LIM_EN | 213 1.1 matt AUXCTL_HIPRO_SO_DEV_EN | 214 1.1 matt AUXCTL_FULL_LINE_WR0 | 215 1.1 matt 0xffff; 216 1.1 matt uint32_t prefetch; 217 1.1 matt 218 1.1 matt /* check the bitmaps are the same as the linux implementation uses */ 219 1.1 matt KASSERT(prefetch4412 == 0x71000007); 220 1.1 matt KASSERT(prefetch4412_r0 == 0x30000007); 221 1.1 matt KASSERT(aux_val == 0x7C470001); 222 1.1 matt KASSERT(aux_keepmask == 0xC200FFFF); 223 1.1 matt 224 1.2 reinoud if (IS_EXYNOS4412_R0_P()) 225 1.1 matt prefetch = prefetch4412_r0; 226 1.1 matt else 227 1.1 matt prefetch = prefetch4412; /* newer than >= r1_0 */ 228 1.1 matt ; 229 1.1 matt 230 1.1 matt exynos_smc(SMC_CMD_L2X0SETUP1, tag_latency, data_latency, prefetch); 231 1.1 matt exynos_smc(SMC_CMD_L2X0SETUP2, 232 1.1 matt POWERCTL_DYNCLKGATE | POWERCTL_STANDBY, 233 1.1 matt aux_val, aux_keepmask); 234 1.1 matt exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0); 235 1.1 matt exynos_smc(SMC_CMD_L2X0CTRL, 1, 0, 0); 236 1.1 matt 237 1.1 matt return 0; 238 1.1 matt } 239 1.23 reinoud #endif 240 1.2 reinoud #endif /* ARM_TRUSTZONE_FIRMWARE */ 241 1.1 matt 242 1.1 matt 243 1.1 matt void 244 1.16 reinoud exynos_sysctl_cpufreq_init(void) 245 1.16 reinoud { 246 1.16 reinoud const struct sysctlnode *node, *cpunode, *freqnode; 247 1.16 reinoud char *cpos; 248 1.16 reinoud int i, val; 249 1.16 reinoud int error; 250 1.16 reinoud 251 1.16 reinoud memset(sysctl_cpu_freqs_txt, (int) ' ', sizeof(sysctl_cpu_freqs_txt)); 252 1.16 reinoud cpos = sysctl_cpu_freqs_txt; 253 1.16 reinoud for (i = 0; i < ncpu_freq_settings; i++) { 254 1.16 reinoud val = cpu_freq_settings[i].freq; 255 1.16 reinoud snprintf(cpos, 6, "%d ", val); 256 1.16 reinoud cpos += (val < 1000) ? 4 : 5; 257 1.16 reinoud } 258 1.16 reinoud *cpos = 0; 259 1.16 reinoud 260 1.16 reinoud error = sysctl_createv(NULL, 0, NULL, &node, 261 1.16 reinoud CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, 262 1.16 reinoud NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL); 263 1.16 reinoud if (error) 264 1.16 reinoud printf("couldn't create `machdep' node\n"); 265 1.16 reinoud 266 1.16 reinoud error = sysctl_createv(NULL, 0, &node, &cpunode, 267 1.16 reinoud 0, CTLTYPE_NODE, "cpu", NULL, 268 1.16 reinoud NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 269 1.16 reinoud if (error) 270 1.16 reinoud printf("couldn't create `cpu' node\n"); 271 1.16 reinoud 272 1.16 reinoud error = sysctl_createv(NULL, 0, &cpunode, &freqnode, 273 1.16 reinoud 0, CTLTYPE_NODE, "frequency", NULL, 274 1.16 reinoud NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 275 1.16 reinoud if (error) 276 1.16 reinoud printf("couldn't create `frequency' node\n"); 277 1.16 reinoud 278 1.16 reinoud error = sysctl_createv(NULL, 0, &freqnode, &node, 279 1.16 reinoud CTLFLAG_READWRITE, CTLTYPE_INT, "target", NULL, 280 1.16 reinoud sysctl_cpufreq_target, 0, &cpu_freq_target, 0, 281 1.16 reinoud CTL_CREATE, CTL_EOL); 282 1.16 reinoud if (error) 283 1.16 reinoud printf("couldn't create `target' node\n"); 284 1.16 reinoud 285 1.16 reinoud error = sysctl_createv(NULL, 0, &freqnode, &node, 286 1.16 reinoud 0, CTLTYPE_INT, "current", NULL, 287 1.16 reinoud sysctl_cpufreq_current, 0, NULL, 0, 288 1.16 reinoud CTL_CREATE, CTL_EOL); 289 1.16 reinoud if (error) 290 1.16 reinoud printf("couldn't create `current' node\n"); 291 1.16 reinoud 292 1.16 reinoud error = sysctl_createv(NULL, 0, &freqnode, &node, 293 1.16 reinoud CTLFLAG_READONLY, CTLTYPE_STRING, "available", NULL, 294 1.16 reinoud NULL, 0, sysctl_cpu_freqs_txt, 0, 295 1.16 reinoud CTL_CREATE, CTL_EOL); 296 1.16 reinoud if (error) 297 1.16 reinoud printf("couldn't create `available' node\b"); 298 1.16 reinoud } 299 1.16 reinoud 300 1.16 reinoud 301 1.16 reinoud uint64_t 302 1.16 reinoud exynos_get_cpufreq(void) 303 1.16 reinoud { 304 1.16 reinoud uint32_t regval; 305 1.16 reinoud uint32_t freq; 306 1.16 reinoud 307 1.31 marty regval = bus_space_read_4(&armv7_generic_bs_tag, exynos_cmu_apll_bsh, 308 1.21 reinoud PLL_CON0_OFFSET); 309 1.16 reinoud freq = PLL_FREQ(EXYNOS_F_IN_FREQ, regval); 310 1.16 reinoud 311 1.16 reinoud return freq; 312 1.16 reinoud } 313 1.16 reinoud 314 1.16 reinoud 315 1.16 reinoud static void 316 1.16 reinoud exynos_set_cpufreq(const struct cpu_freq *freqreq) 317 1.16 reinoud { 318 1.18 reinoud struct cpu_info *ci; 319 1.16 reinoud uint32_t regval; 320 1.16 reinoud int M, P, S; 321 1.18 reinoud int cii; 322 1.16 reinoud 323 1.16 reinoud M = freqreq->M; 324 1.16 reinoud P = freqreq->P; 325 1.16 reinoud S = freqreq->S; 326 1.16 reinoud 327 1.16 reinoud regval = __SHIFTIN(M, PLL_CON0_M) | 328 1.16 reinoud __SHIFTIN(P, PLL_CON0_P) | 329 1.16 reinoud __SHIFTIN(S, PLL_CON0_S); 330 1.16 reinoud 331 1.16 reinoud /* enable PPL and write config */ 332 1.16 reinoud regval |= PLL_CON0_ENABLE; 333 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, exynos_cmu_apll_bsh, PLL_CON0_OFFSET, 334 1.21 reinoud regval); 335 1.18 reinoud 336 1.18 reinoud /* update our cycle counter i.e. our CPU frequency for all CPUs */ 337 1.18 reinoud for (CPU_INFO_FOREACH(cii, ci)) { 338 1.18 reinoud ci->ci_data.cpu_cc_freq = exynos_get_cpufreq(); 339 1.18 reinoud } 340 1.16 reinoud } 341 1.16 reinoud 342 1.16 reinoud 343 1.16 reinoud static int 344 1.16 reinoud sysctl_cpufreq_target(SYSCTLFN_ARGS) 345 1.16 reinoud { 346 1.16 reinoud struct sysctlnode node; 347 1.16 reinoud uint32_t t, curfreq, minfreq, maxfreq; 348 1.16 reinoud int i, best_i, diff; 349 1.16 reinoud int error; 350 1.16 reinoud 351 1.16 reinoud curfreq = exynos_get_cpufreq() / (1000*1000); 352 1.16 reinoud t = *(int *)rnode->sysctl_data; 353 1.16 reinoud if (t == 0) 354 1.16 reinoud t = curfreq; 355 1.16 reinoud 356 1.16 reinoud node = *rnode; 357 1.16 reinoud node.sysctl_data = &t; 358 1.16 reinoud error = sysctl_lookup(SYSCTLFN_CALL(&node)); 359 1.16 reinoud if (error || newp == NULL) 360 1.16 reinoud return error; 361 1.16 reinoud 362 1.16 reinoud minfreq = cpu_freq_settings[0].freq; 363 1.16 reinoud maxfreq = cpu_freq_settings[ncpu_freq_settings-1].freq; 364 1.16 reinoud 365 1.16 reinoud if ((t < minfreq) || (t > maxfreq)) 366 1.16 reinoud return EINVAL; 367 1.16 reinoud 368 1.16 reinoud if (t == curfreq) { 369 1.16 reinoud *(int *)rnode->sysctl_data = t; 370 1.16 reinoud return 0; 371 1.16 reinoud } 372 1.16 reinoud 373 1.16 reinoud diff = maxfreq; 374 1.16 reinoud best_i = -1; 375 1.16 reinoud for (i = 0; i < ncpu_freq_settings; i++) { 376 1.16 reinoud if (abs(t - cpu_freq_settings[i].freq) <= diff) { 377 1.16 reinoud diff = labs(t - cpu_freq_settings[i].freq); 378 1.16 reinoud best_i = i; 379 1.16 reinoud } 380 1.16 reinoud } 381 1.16 reinoud if (best_i < 0) 382 1.16 reinoud return EINVAL; 383 1.16 reinoud 384 1.16 reinoud exynos_set_cpufreq(&cpu_freq_settings[best_i]); 385 1.16 reinoud 386 1.16 reinoud *(int *)rnode->sysctl_data = t; 387 1.16 reinoud return 0; 388 1.16 reinoud } 389 1.16 reinoud 390 1.16 reinoud 391 1.16 reinoud static int 392 1.16 reinoud sysctl_cpufreq_current(SYSCTLFN_ARGS) 393 1.16 reinoud { 394 1.16 reinoud struct sysctlnode node = *rnode; 395 1.16 reinoud uint32_t freq; 396 1.16 reinoud 397 1.16 reinoud freq = exynos_get_cpufreq() / (1000*1000); 398 1.16 reinoud node.sysctl_data = &freq; 399 1.16 reinoud 400 1.16 reinoud return sysctl_lookup(SYSCTLFN_CALL(&node)); 401 1.16 reinoud } 402 1.16 reinoud 403 1.16 reinoud 404 1.19 reinoud #ifdef VERBOSE_INIT_ARM 405 1.38 skrll #define VPRINTF(...) printf(__VA_ARGS__) 406 1.38 skrll 407 1.19 reinoud #define DUMP_PLL(v, var) \ 408 1.19 reinoud reg = EXYNOS##v##_CMU_##var + PLL_CON0_OFFSET;\ 409 1.31 marty regval = bus_space_read_4(&armv7_generic_bs_tag, exynos_cmu_bsh, reg); \ 410 1.19 reinoud freq = PLL_FREQ(EXYNOS_F_IN_FREQ, regval); \ 411 1.19 reinoud printf("%8s at %d Mhz\n", #var, freq/(1000*1000)); 412 1.19 reinoud 413 1.19 reinoud 414 1.19 reinoud static void 415 1.19 reinoud exynos_dump_clocks(void) 416 1.19 reinoud { 417 1.19 reinoud uint32_t reg = 0; 418 1.19 reinoud uint32_t regval; 419 1.19 reinoud uint32_t freq; 420 1.19 reinoud 421 1.19 reinoud printf("Initial PLL settings\n"); 422 1.32 jmcneill #ifdef SOC_EXYNOS4 423 1.21 reinoud DUMP_PLL(4, APLL); 424 1.21 reinoud DUMP_PLL(4, MPLL); 425 1.21 reinoud DUMP_PLL(4, EPLL); 426 1.21 reinoud DUMP_PLL(4, VPLL); 427 1.19 reinoud #endif 428 1.32 jmcneill #ifdef SOC_EXYNOS5 429 1.21 reinoud DUMP_PLL(5, APLL); 430 1.21 reinoud DUMP_PLL(5, MPLL); 431 1.25 reinoud DUMP_PLL(5, KPLL); 432 1.25 reinoud DUMP_PLL(5, DPLL); 433 1.21 reinoud DUMP_PLL(5, VPLL); 434 1.21 reinoud DUMP_PLL(5, CPLL); 435 1.21 reinoud DUMP_PLL(5, GPLL); 436 1.21 reinoud DUMP_PLL(5, BPLL); 437 1.19 reinoud #endif 438 1.19 reinoud } 439 1.19 reinoud #undef DUMP_PLL 440 1.38 skrll #else 441 1.38 skrll #define VPRINTF(...) __nothing 442 1.19 reinoud #endif 443 1.19 reinoud 444 1.19 reinoud 445 1.21 reinoud /* XXX clock stuff needs major work XXX */ 446 1.21 reinoud 447 1.21 reinoud void 448 1.32 jmcneill exynos_init_clkout_for_usb(void) 449 1.32 jmcneill { 450 1.32 jmcneill /* Select XUSBXTI as source for CLKOUT */ 451 1.32 jmcneill bus_space_write_4(&armv7_generic_bs_tag, exynos_pmu_bsh, 452 1.32 jmcneill EXYNOS_PMU_DEBUG_CLKOUT, 0x1000); 453 1.32 jmcneill } 454 1.32 jmcneill 455 1.32 jmcneill 456 1.32 jmcneill void 457 1.21 reinoud exynos_clocks_bootstrap(void) 458 1.21 reinoud { 459 1.16 reinoud KASSERT(ncpu_freq_settings != 0); 460 1.16 reinoud KASSERT(ncpu_freq_settings < NFRQS); 461 1.24 reinoud int fsel; 462 1.16 reinoud 463 1.19 reinoud #ifdef VERBOSE_INIT_ARM 464 1.19 reinoud exynos_dump_clocks(); 465 1.19 reinoud #endif 466 1.19 reinoud 467 1.24 reinoud /* set (max) cpufreq */ 468 1.24 reinoud fsel = ncpu_freq_settings-1; 469 1.24 reinoud 470 1.32 jmcneill #ifdef SOC_EXYNOS5 471 1.24 reinoud /* XXX BUGFIX selecting freq on E5 goes wrong for now XXX */ 472 1.24 reinoud fsel = EXYNOS5_DEFAULT_ENTRY; 473 1.24 reinoud #endif 474 1.24 reinoud 475 1.24 reinoud exynos_set_cpufreq(&cpu_freq_settings[fsel]); 476 1.21 reinoud 477 1.21 reinoud /* set external USB frequency to XCLKOUT */ 478 1.21 reinoud exynos_init_clkout_for_usb(); 479 1.16 reinoud } 480 1.16 reinoud 481 1.16 reinoud 482 1.16 reinoud void 483 1.37 skrll exynos_bootstrap(int soc) 484 1.1 matt { 485 1.5 reinoud int error; 486 1.11 reinoud size_t core_size, audiocore_size; 487 1.21 reinoud bus_addr_t audiocore_pbase; 488 1.21 reinoud bus_addr_t audiocore_vbase __diagused; 489 1.21 reinoud bus_addr_t exynos_wdt_offset; 490 1.21 reinoud bus_addr_t exynos_pmu_offset; 491 1.22 reinoud bus_addr_t exynos_sysreg_offset; 492 1.21 reinoud bus_addr_t exynos_cmu_apll_offset; 493 1.21 reinoud 494 1.37 skrll switch (soc) { 495 1.32 jmcneill #ifdef SOC_EXYNOS4 496 1.37 skrll case 4: 497 1.37 skrll core_size = EXYNOS4_CORE_SIZE; 498 1.37 skrll audiocore_size = EXYNOS4_AUDIOCORE_SIZE; 499 1.37 skrll audiocore_pbase = EXYNOS4_AUDIOCORE_PBASE; 500 1.37 skrll audiocore_vbase = EXYNOS4_AUDIOCORE_VBASE; 501 1.37 skrll exynos_wdt_offset = EXYNOS4_WDT_OFFSET; 502 1.37 skrll exynos_pmu_offset = EXYNOS4_PMU_OFFSET; 503 1.37 skrll exynos_sysreg_offset = EXYNOS4_SYSREG_OFFSET; 504 1.37 skrll exynos_cmu_apll_offset = EXYNOS4_CMU_APLL; 505 1.37 skrll 506 1.37 skrll cpu_freq_settings = cpu_freq_settings_exynos4; 507 1.37 skrll ncpu_freq_settings = __arraycount(cpu_freq_settings_exynos4); 508 1.37 skrll break; 509 1.11 reinoud #endif 510 1.32 jmcneill #ifdef SOC_EXYNOS5 511 1.37 skrll case 5: 512 1.37 skrll core_size = EXYNOS5_CORE_SIZE; 513 1.37 skrll audiocore_size = EXYNOS5_AUDIOCORE_SIZE; 514 1.37 skrll audiocore_pbase = EXYNOS5_AUDIOCORE_PBASE; 515 1.37 skrll audiocore_vbase = EXYNOS5_AUDIOCORE_VBASE; 516 1.37 skrll exynos_wdt_offset = EXYNOS5_WDT_OFFSET; 517 1.37 skrll exynos_pmu_offset = EXYNOS5_PMU_OFFSET; 518 1.37 skrll exynos_sysreg_offset = EXYNOS5_SYSREG_OFFSET; 519 1.37 skrll exynos_cmu_apll_offset = EXYNOS5_CMU_APLL; 520 1.37 skrll 521 1.37 skrll cpu_freq_settings = cpu_freq_settings_exynos5; 522 1.37 skrll ncpu_freq_settings = __arraycount(cpu_freq_settings_exynos5); 523 1.37 skrll break; 524 1.11 reinoud #endif 525 1.37 skrll default: 526 1.37 skrll panic("%s: unknown soc version", __func__); 527 1.37 skrll } 528 1.1 matt 529 1.1 matt /* map in the exynos io registers */ 530 1.31 marty error = bus_space_map(&armv7_generic_bs_tag, EXYNOS_CORE_PBASE, 531 1.5 reinoud core_size, 0, &exynos_core_bsh); 532 1.1 matt if (error) 533 1.11 reinoud panic("%s: failed to map in Exynos SFR registers: %d", 534 1.1 matt __func__, error); 535 1.39 skrll KASSERT(exynos_core_bsh == EXYNOS_CORE_VBASE); 536 1.7 reinoud 537 1.31 marty error = bus_space_map(&armv7_generic_bs_tag, audiocore_pbase, 538 1.11 reinoud audiocore_size, 0, &exynos_audiocore_bsh); 539 1.11 reinoud if (error) 540 1.11 reinoud panic("%s: failed to map in Exynos audio SFR registers: %d", 541 1.11 reinoud __func__, error); 542 1.12 reinoud KASSERT(exynos_audiocore_bsh == audiocore_vbase); 543 1.11 reinoud 544 1.21 reinoud /* map in commonly used subregions and common used register banks */ 545 1.31 marty error = bus_space_subregion(&armv7_generic_bs_tag, exynos_core_bsh, 546 1.21 reinoud exynos_wdt_offset, EXYNOS_BLOCK_SIZE, &exynos_wdt_bsh); 547 1.21 reinoud if (error) 548 1.21 reinoud panic("%s: failed to subregion wdt registers: %d", 549 1.21 reinoud __func__, error); 550 1.21 reinoud 551 1.31 marty error = bus_space_subregion(&armv7_generic_bs_tag, exynos_core_bsh, 552 1.21 reinoud exynos_pmu_offset, EXYNOS_BLOCK_SIZE, &exynos_pmu_bsh); 553 1.21 reinoud if (error) 554 1.21 reinoud panic("%s: failed to subregion pmu registers: %d", 555 1.21 reinoud __func__, error); 556 1.21 reinoud 557 1.21 reinoud exynos_cmu_bsh = exynos_core_bsh; 558 1.31 marty bus_space_subregion(&armv7_generic_bs_tag, exynos_core_bsh, 559 1.22 reinoud exynos_sysreg_offset, EXYNOS_BLOCK_SIZE, 560 1.22 reinoud &exynos_sysreg_bsh); 561 1.22 reinoud if (error) 562 1.22 reinoud panic("%s: failed to subregion sysreg registers: %d", 563 1.22 reinoud __func__, error); 564 1.22 reinoud 565 1.31 marty error = bus_space_subregion(&armv7_generic_bs_tag, exynos_cmu_bsh, 566 1.21 reinoud exynos_cmu_apll_offset, 0xfff, &exynos_cmu_apll_bsh); 567 1.21 reinoud if (error) 568 1.21 reinoud panic("%s: failed to subregion cmu apll registers: %d", 569 1.21 reinoud __func__, error); 570 1.21 reinoud 571 1.11 reinoud /* gpio bootstrapping delayed */ 572 1.1 matt } 573 1.1 matt 574 1.1 matt 575 1.1 matt void 576 1.1 matt exynos_device_register(device_t self, void *aux) 577 1.1 matt { 578 1.1 matt if (device_is_a(self, "armperiph") 579 1.1 matt && device_is_a(device_parent(self), "mainbus")) { 580 1.1 matt /* 581 1.1 matt * XXX KLUDGE ALERT XXX 582 1.1 matt * The iot mainbus supplies is completely wrong since it scales 583 1.17 snj * addresses by 2. The simplest remedy is to replace with our 584 1.23 reinoud * bus space used for the armcore registers (which armperiph uses). 585 1.1 matt */ 586 1.1 matt struct mainbus_attach_args * const mb = aux; 587 1.31 marty mb->mb_iot = &armv7_generic_bs_tag; 588 1.1 matt return; 589 1.1 matt } 590 1.1 matt if (device_is_a(self, "armgic") 591 1.1 matt && device_is_a(device_parent(self), "armperiph")) { 592 1.1 matt /* 593 1.1 matt * The Exynos4420 armgic is located at a different location! 594 1.1 matt */ 595 1.1 matt 596 1.1 matt extern uint32_t exynos_soc_id; 597 1.6 reinoud 598 1.1 matt switch (EXYNOS_PRODUCT_ID(exynos_soc_id)) { 599 1.32 jmcneill #ifdef SOC_EXYNOS5 600 1.1 matt case 0xe5410: 601 1.6 reinoud /* offsets not changed on matt's request */ 602 1.1 matt #if 0 603 1.6 reinoud mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE; 604 1.1 matt mpcaa->mpcaa_off1 = EXYNOS5_GIC_IOP_DISTRIBUTOR_OFFSET; 605 1.1 matt mpcaa->mpcaa_off2 = EXYNOS5_GIC_IOP_CONTROLLER_OFFSET; 606 1.1 matt #endif 607 1.1 matt break; 608 1.28 marty case 0xe5422: { 609 1.28 marty struct mpcore_attach_args * const mpcaa = aux; 610 1.28 marty 611 1.28 marty mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE; 612 1.28 marty mpcaa->mpcaa_off1 = EXYNOS5_GIC_IOP_DISTRIBUTOR_OFFSET; 613 1.28 marty mpcaa->mpcaa_off2 = EXYNOS5_GIC_IOP_CONTROLLER_OFFSET; 614 1.28 marty break; 615 1.28 marty } 616 1.1 matt #endif 617 1.32 jmcneill #ifdef SOC_EXYNOS4 618 1.1 matt case 0xe4410: 619 1.12 reinoud case 0xe4412: { 620 1.12 reinoud struct mpcore_attach_args * const mpcaa = aux; 621 1.12 reinoud 622 1.1 matt mpcaa->mpcaa_memh = EXYNOS_CORE_VBASE; 623 1.1 matt mpcaa->mpcaa_off1 = EXYNOS4_GIC_DISTRIBUTOR_OFFSET; 624 1.1 matt mpcaa->mpcaa_off2 = EXYNOS4_GIC_CNTR_OFFSET; 625 1.1 matt break; 626 1.12 reinoud } 627 1.1 matt #endif 628 1.1 matt default: 629 1.1 matt panic("%s: unknown SoC product id %#x", __func__, 630 1.1 matt (u_int)EXYNOS_PRODUCT_ID(exynos_soc_id)); 631 1.1 matt } 632 1.1 matt return; 633 1.1 matt } 634 1.10 reinoud if (device_is_a(self, "armgtmr") || device_is_a(self, "mct")) { 635 1.32 jmcneill #ifdef SOC_EXYNOS5 636 1.13 matt /* 637 1.13 matt * The global timer is dependent on the MCT running. 638 1.13 matt */ 639 1.13 matt bus_size_t o = EXYNOS5_MCT_OFFSET + MCT_G_TCON; 640 1.31 marty uint32_t v = bus_space_read_4(&armv7_generic_bs_tag, exynos_core_bsh, 641 1.14 matt o); 642 1.13 matt v |= G_TCON_START; 643 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, exynos_core_bsh, o, v); 644 1.13 matt #endif 645 1.1 matt /* 646 1.10 reinoud * The frequencies of the timers are the reference 647 1.1 matt * frequency. 648 1.1 matt */ 649 1.1 matt prop_dictionary_set_uint32(device_properties(self), 650 1.10 reinoud "frequency", EXYNOS_F_IN_FREQ); 651 1.1 matt return; 652 1.1 matt } 653 1.1 matt } 654 1.1 matt 655 1.9 reinoud 656 1.9 reinoud void 657 1.9 reinoud exynos_device_register_post_config(device_t self, void *aux) 658 1.9 reinoud { 659 1.9 reinoud } 660 1.9 reinoud 661 1.23 reinoud void 662 1.23 reinoud exynos_usb_soc_powerup(void) 663 1.23 reinoud { 664 1.23 reinoud /* XXX 5422 XXX */ 665 1.23 reinoud } 666 1.23 reinoud 667 1.23 reinoud 668 1.23 reinoud /* 669 1.23 reinoud * USB Phy SoC dependent handling 670 1.23 reinoud */ 671 1.23 reinoud 672 1.23 reinoud /* XXX 5422 not handled since its unknown how it handles this XXX*/ 673 1.23 reinoud static void 674 1.23 reinoud exynos_usb2_set_isolation(bool on) 675 1.23 reinoud { 676 1.23 reinoud uint32_t en_mask, regval; 677 1.23 reinoud bus_addr_t reg; 678 1.23 reinoud 679 1.23 reinoud /* enable PHY */ 680 1.23 reinoud reg = EXYNOS_PMU_USB_PHY_CTRL; 681 1.23 reinoud 682 1.23 reinoud if (IS_EXYNOS5_P() || IS_EXYNOS4410_P()) { 683 1.23 reinoud /* set usbhost mode */ 684 1.23 reinoud regval = on ? 0 : USB20_PHY_HOST_LINK_EN; 685 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, exynos_sysreg_bsh, 686 1.23 reinoud EXYNOS5_SYSREG_USB20_PHY_TYPE, regval); 687 1.23 reinoud reg = EXYNOS_PMU_USBHOST_PHY_CTRL; 688 1.23 reinoud } 689 1.23 reinoud 690 1.23 reinoud /* do enable PHY */ 691 1.23 reinoud en_mask = PMU_PHY_ENABLE; 692 1.31 marty regval = bus_space_read_4(&armv7_generic_bs_tag, exynos_pmu_bsh, reg); 693 1.23 reinoud regval = on ? regval & ~en_mask : regval | en_mask; 694 1.23 reinoud 695 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, exynos_pmu_bsh, 696 1.23 reinoud reg, regval); 697 1.23 reinoud 698 1.23 reinoud if (IS_EXYNOS4X12_P()) { 699 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, exynos_pmu_bsh, 700 1.23 reinoud EXYNOS_PMU_USB_HSIC_1_PHY_CTRL, regval); 701 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, exynos_pmu_bsh, 702 1.23 reinoud EXYNOS_PMU_USB_HSIC_2_PHY_CTRL, regval); 703 1.23 reinoud } 704 1.23 reinoud } 705 1.23 reinoud 706 1.23 reinoud 707 1.32 jmcneill #ifdef SOC_EXYNOS4 708 1.23 reinoud static void 709 1.23 reinoud exynos4_usb2phy_enable(bus_space_handle_t usb2phy_bsh) 710 1.23 reinoud { 711 1.23 reinoud uint32_t phypwr, rstcon, clkreg; 712 1.23 reinoud 713 1.23 reinoud /* write clock value */ 714 1.23 reinoud clkreg = FSEL_CLKSEL_24M; 715 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 716 1.23 reinoud USB_PHYCLK, clkreg); 717 1.23 reinoud 718 1.23 reinoud /* set device and host to normal */ 719 1.31 marty phypwr = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, 720 1.23 reinoud USB_PHYPWR); 721 1.23 reinoud 722 1.23 reinoud /* enable analog, enable otg, unsleep phy0 (host) */ 723 1.23 reinoud phypwr &= ~PHYPWR_NORMAL_MASK_PHY0; 724 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 725 1.23 reinoud USB_PHYPWR, phypwr); 726 1.23 reinoud 727 1.23 reinoud if (IS_EXYNOS4X12_P()) { 728 1.23 reinoud /* enable hsic0 (host), enable hsic1 and phy1 (otg) */ 729 1.31 marty phypwr = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, 730 1.23 reinoud USB_PHYPWR); 731 1.23 reinoud phypwr &= ~(PHYPWR_NORMAL_MASK_HSIC0 | 732 1.23 reinoud PHYPWR_NORMAL_MASK_HSIC1 | 733 1.23 reinoud PHYPWR_NORMAL_MASK_PHY1); 734 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 735 1.23 reinoud USB_PHYPWR, phypwr); 736 1.23 reinoud } 737 1.23 reinoud 738 1.23 reinoud /* reset both phy and link of device */ 739 1.31 marty rstcon = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, 740 1.23 reinoud USB_RSTCON); 741 1.23 reinoud rstcon |= RSTCON_DEVPHY_SWRST; 742 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 743 1.23 reinoud USB_RSTCON, rstcon); 744 1.23 reinoud DELAY(10000); 745 1.23 reinoud rstcon &= ~RSTCON_DEVPHY_SWRST; 746 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 747 1.23 reinoud USB_RSTCON, rstcon); 748 1.23 reinoud 749 1.23 reinoud if (IS_EXYNOS4X12_P()) { 750 1.23 reinoud /* reset both phy and link of host */ 751 1.31 marty rstcon = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, 752 1.23 reinoud USB_RSTCON); 753 1.23 reinoud rstcon |= RSTCON_HOSTPHY_SWRST | RSTCON_HOSTPHYLINK_SWRST; 754 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 755 1.23 reinoud USB_RSTCON, rstcon); 756 1.23 reinoud DELAY(10000); 757 1.23 reinoud rstcon &= ~(RSTCON_HOSTPHY_SWRST | RSTCON_HOSTPHYLINK_SWRST); 758 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 759 1.23 reinoud USB_RSTCON, rstcon); 760 1.23 reinoud } 761 1.23 reinoud 762 1.23 reinoud /* wait for everything to be initialized */ 763 1.23 reinoud DELAY(80000); 764 1.23 reinoud } 765 1.23 reinoud #endif 766 1.23 reinoud 767 1.23 reinoud 768 1.32 jmcneill #ifdef SOC_EXYNOS5 769 1.23 reinoud static void 770 1.23 reinoud exynos5410_usb2phy_enable(bus_space_handle_t usb2phy_bsh) 771 1.23 reinoud { 772 1.23 reinoud uint32_t phyhost; //, phyotg; 773 1.27 skrll uint32_t phyhsic; 774 1.27 skrll uint32_t ehcictrl, ohcictrl; 775 1.23 reinoud 776 1.23 reinoud /* host configuration: */ 777 1.31 marty phyhost = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, 778 1.27 skrll USB_PHY_HOST_CTRL0); 779 1.23 reinoud 780 1.23 reinoud /* host phy reference clock; assumption its 24 MHz now */ 781 1.23 reinoud phyhost &= ~HOST_CTRL0_FSEL_MASK; 782 1.27 skrll phyhost |= __SHIFTIN(FSEL_CLKSEL_24M, HOST_CTRL0_FSEL_MASK); 783 1.23 reinoud 784 1.23 reinoud /* enable normal mode of operation */ 785 1.23 reinoud phyhost &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP); 786 1.23 reinoud 787 1.23 reinoud /* host phy reset */ 788 1.23 reinoud phyhost &= ~(HOST_CTRL0_PHY_SWRST | HOST_CTRL0_PHY_SWRST_ALL | 789 1.27 skrll HOST_CTRL0_SIDDQ | HOST_CTRL0_FORCESUSPEND | 790 1.27 skrll HOST_CTRL0_FORCESLEEP); 791 1.26 skrll 792 1.23 reinoud /* host link reset */ 793 1.27 skrll phyhost |= HOST_CTRL0_LINK_SWRST | HOST_CTRL0_UTMI_SWRST | 794 1.27 skrll HOST_CTRL0_COMMONON_N; 795 1.23 reinoud /* do the reset */ 796 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HOST_CTRL0, 797 1.27 skrll phyhost); 798 1.23 reinoud DELAY(10000); 799 1.27 skrll 800 1.23 reinoud phyhost &= ~(HOST_CTRL0_LINK_SWRST | HOST_CTRL0_UTMI_SWRST); 801 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HOST_CTRL0, 802 1.27 skrll phyhost); 803 1.27 skrll 804 1.27 skrll /* HSIC control */ 805 1.27 skrll phyhsic = 806 1.27 skrll __SHIFTIN(HSIC_CTRL_REFCLKDIV_12, HSIC_CTRL_REFCLKDIV_MASK) | 807 1.27 skrll __SHIFTIN(HSIC_CTRL_REFCLKSEL_DEFAULT, HSIC_CTRL_REFCLKSEL_MASK) | 808 1.27 skrll HSIC_CTRL_PHY_SWRST; 809 1.27 skrll 810 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HSIC_CTRL1, 811 1.27 skrll phyhsic); 812 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HSIC_CTRL2, 813 1.27 skrll phyhsic); 814 1.27 skrll DELAY(10); 815 1.27 skrll 816 1.27 skrll phyhsic &= ~HSIC_CTRL_PHY_SWRST; 817 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HSIC_CTRL1, 818 1.27 skrll phyhsic); 819 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, USB_PHY_HSIC_CTRL2, 820 1.27 skrll phyhsic); 821 1.27 skrll DELAY(80); 822 1.23 reinoud 823 1.23 reinoud #if 0 824 1.23 reinoud /* otg configuration: */ 825 1.31 marty phyotg = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, 826 1.23 reinoud USB_PHY_OTG_SYS); 827 1.23 reinoud 828 1.40 andvar /* otg phy reference clock: assumption its 24 Mhz now */ 829 1.23 reinoud phyotg &= ~OTG_SYS_FSEL_MASK; 830 1.23 reinoud phyotg |= __SHIFTIN(OTG_SYS_FSEL_MASK, FSEL_CLKSEL_24M); 831 1.23 reinoud 832 1.23 reinoud /* enable normal mode of operation */ 833 1.23 reinoud phyotg &= ~(OTG_SYS_FORCESUSPEND | OTG_SYS_FORCESLEEP | 834 1.23 reinoud OTG_SYS_SIDDQ_UOTG | OTG_SYS_REFCLKSEL_MASK | 835 1.23 reinoud OTG_SYS_COMMON_ON); 836 1.23 reinoud 837 1.23 reinoud /* OTG phy and link reset */ 838 1.23 reinoud phyotg |= OTG_SYS_PHY0_SWRST | OTG_SYS_PHYLINK_SWRST | 839 1.23 reinoud OTG_SYS_OTGDISABLE | OTG_SYS_REFCLKSEL_MASK; 840 1.23 reinoud 841 1.23 reinoud /* do the reset */ 842 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 843 1.23 reinoud USB_PHY_OTG_SYS, phyotg); 844 1.23 reinoud DELAY(10000); 845 1.23 reinoud phyotg &= ~(OTG_SYS_PHY0_SWRST | OTG_SYS_LINK_SWRST_UOTG | 846 1.23 reinoud OTG_SYS_PHYLINK_SWRST); 847 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 848 1.23 reinoud USB_PHY_OTG_SYS, phyotg); 849 1.23 reinoud #endif 850 1.23 reinoud 851 1.23 reinoud /* enable EHCI DMA burst: */ 852 1.31 marty ehcictrl = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, 853 1.27 skrll USB_PHY_HOST_EHCICTRL); 854 1.23 reinoud ehcictrl |= HOST_EHCICTRL_ENA_INCRXALIGN | 855 1.27 skrll HOST_EHCICTRL_ENA_INCR4 | HOST_EHCICTRL_ENA_INCR8 | 856 1.27 skrll HOST_EHCICTRL_ENA_INCR16; 857 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 858 1.27 skrll USB_PHY_HOST_EHCICTRL, ehcictrl); 859 1.27 skrll 860 1.27 skrll /* Set OHCI suspend */ 861 1.31 marty ohcictrl = bus_space_read_4(&armv7_generic_bs_tag, usb2phy_bsh, 862 1.27 skrll USB_PHY_HOST_OHCICTRL); 863 1.27 skrll ohcictrl |= HOST_OHCICTRL_SUSPLGCY; 864 1.31 marty bus_space_write_4(&armv7_generic_bs_tag, usb2phy_bsh, 865 1.27 skrll USB_PHY_HOST_OHCICTRL, ohcictrl); 866 1.23 reinoud } 867 1.23 reinoud 868 1.23 reinoud 869 1.23 reinoud static void 870 1.23 reinoud exynos5422_usb2phy_enable(bus_space_handle_t usb2phy_bsh) 871 1.23 reinoud { 872 1.23 reinoud aprint_error("%s not implemented\n", __func__); 873 1.23 reinoud } 874 1.23 reinoud #endif 875 1.23 reinoud 876 1.23 reinoud 877 1.23 reinoud void 878 1.23 reinoud exynos_usb_phy_init(bus_space_handle_t usb2phy_bsh) 879 1.23 reinoud { 880 1.23 reinoud /* disable phy isolation */ 881 1.23 reinoud exynos_usb2_set_isolation(false); 882 1.23 reinoud 883 1.32 jmcneill #ifdef SOC_EXYNOS4 884 1.23 reinoud exynos4_usb2phy_enable(usb2phy_bsh); 885 1.23 reinoud #endif 886 1.32 jmcneill #ifdef SOC_EXYNOS5 887 1.23 reinoud if (IS_EXYNOS5410_P()) { 888 1.23 reinoud exynos5410_usb2phy_enable(usb2phy_bsh); 889 1.23 reinoud /* TBD: USB3 phy init */ 890 1.23 reinoud } else if (IS_EXYNOS5422_P()) { 891 1.23 reinoud exynos5422_usb2phy_enable(usb2phy_bsh); 892 1.23 reinoud /* TBD: USB3 phy init */ 893 1.23 reinoud } 894 1.23 reinoud #endif 895 1.23 reinoud } 896 1.23 reinoud 897 1.23 reinoud 898