static void exynos_set_cpufreq(const struct cpu_freq *freqreq) { struct cpu_info *ci; uint32_t regval; int M, P, S; int cii; M = freqreq->M; P = freqreq->P; S = freqreq->S; regval = __SHIFTIN(M, PLL_CON0_M) | __SHIFTIN(P, PLL_CON0_P) | __SHIFTIN(S, PLL_CON0_S); /* enable PPL and write config */ regval |= PLL_CON0_ENABLE; bus_space_write_4(&armv7_generic_bs_tag, exynos_cmu_apll_bsh, PLL_CON0_OFFSET, regval); /* update our cycle counter i.e. our CPU frequency for all CPUs */ for (CPU_INFO_FOREACH(cii, ci)) { ci->ci_data.cpu_cc_freq = exynos_get_cpufreq(); } }
static int sysctl_cpufreq_current(SYSCTLFN_ARGS) { struct sysctlnode node = *rnode; uint32_t freq; freq = exynos_get_cpufreq() / (1000*1000); node.sysctl_data = &freq; return sysctl_lookup(SYSCTLFN_CALL(&node)); }
static int sysctl_cpufreq_target(SYSCTLFN_ARGS) { struct sysctlnode node; uint32_t t, curfreq, minfreq, maxfreq; int i, best_i, diff; int error; curfreq = exynos_get_cpufreq() / (1000*1000); t = *(int *)rnode->sysctl_data; if (t == 0) t = curfreq; node = *rnode; node.sysctl_data = &t; error = sysctl_lookup(SYSCTLFN_CALL(&node)); if (error || newp == NULL) return error; minfreq = cpu_freq_settings[0].freq; maxfreq = cpu_freq_settings[ncpu_freq_settings-1].freq; if ((t < minfreq) || (t > maxfreq)) return EINVAL; if (t == curfreq) { *(int *)rnode->sysctl_data = t; return 0; } diff = maxfreq; best_i = -1; for (i = 0; i < ncpu_freq_settings; i++) { if (abs(t - cpu_freq_settings[i].freq) <= diff) { diff = labs(t - cpu_freq_settings[i].freq); best_i = i; } } if (best_i < 0) return EINVAL; exynos_set_cpufreq(&cpu_freq_settings[best_i]); *(int *)rnode->sysctl_data = t; return 0; }
u_int initarm(void *arg) { const struct pmap_devmap const *devmap; bus_addr_t rambase; const psize_t ram_reserve = 0x200000; psize_t ram_size; /* allocate/map our basic memory mapping */ switch (EXYNOS_PRODUCT_FAMILY(exynos_soc_id)) { #if defined(EXYNOS4) case EXYNOS4_PRODUCT_FAMILY: devmap = e4_devmap; rambase = EXYNOS4_SDRAM_PBASE; break; #endif #if defined(EXYNOS5) case EXYNOS5_PRODUCT_FAMILY: devmap = e5_devmap; rambase = EXYNOS5_SDRAM_PBASE; break; #endif default: /* Won't work, but... */ panic("Unknown product family %llx", EXYNOS_PRODUCT_FAMILY(exynos_soc_id)); } pmap_devmap_register(devmap); /* bootstrap soc. uart_address is determined in odroid_start */ paddr_t uart_address = armreg_tpidruro_read(); exynos_bootstrap(EXYNOS_CORE_VBASE, EXYNOS_IOPHYSTOVIRT(uart_address)); /* set up CPU / MMU / TLB functions */ if (set_cpufuncs()) panic("cpu not recognized!"); /* get normal console working */ consinit(); #ifdef KGDB kgdb_port_init(); #endif #ifdef VERBOSE_INIT_ARM printf("\nuboot arg = %#"PRIxPTR", %#"PRIxPTR", %#"PRIxPTR", %#"PRIxPTR"\n", uboot_args[0], uboot_args[1], uboot_args[2], uboot_args[3]); printf("Exynos SoC ID %08x\n", exynos_soc_id); printf("initarm: cbar=%#x\n", armreg_cbar_read()); #endif /* determine cpu0 clock rate */ exynos_clocks_bootstrap(); #ifdef VERBOSE_INIT_ARM printf("CPU0 now running on %"PRIu64" Mhz\n", exynos_get_cpufreq()/(1000*1000)); #endif #if NARML2CC > 0 if (CPU_ID_CORTEX_A9_P(curcpu()->ci_arm_cpuid)) { /* probe and enable the PL310 L2CC */ const bus_space_handle_t pl310_bh = EXYNOS_IOPHYSTOVIRT(armreg_cbar_read()); #ifdef ARM_TRUSTZONE_FIRMWARE exynos4_l2cc_init(); #endif arml2cc_init(&exynos_bs_tag, pl310_bh, 0x2000); } #endif cpu_reset_address = exynos_wdt_reset; #ifdef VERBOSE_INIT_ARM printf("\nNetBSD/evbarm (odroid) booting ...\n"); #endif #ifdef BOOT_ARGS char mi_bootargs[] = BOOT_ARGS; parse_mi_bootargs(mi_bootargs); #endif boot_args = bootargs; parse_mi_bootargs(boot_args); exynos_extract_mac_adress(); /* * Determine physical memory by looking at the PoP package. This PoP * package ID seems to be only available on Exynos4 * * First assume the default 2Gb of memory, dictated by mapping too */ ram_size = (psize_t) 0xC0000000 - 0x40000000; #if defined(EXYNOS4) switch (exynos_pop_id) { case EXYNOS_PACKAGE_ID_2_GIG: KASSERT(ram_size <= 2UL*1024*1024*1024); break; default: printf("Unknown PoP package id 0x%08x, assuming 1Gb\n", exynos_pop_id); ram_size = (psize_t) 0x10000000; } #endif /* Fake bootconfig structure for the benefit of pmap.c. */ bootconfig.dramblocks = 1; bootconfig.dram[0].address = rambase; bootconfig.dram[0].pages = ram_size / PAGE_SIZE; #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS const bool mapallmem_p = true; #ifndef PMAP_NEED_ALLOC_POOLPAGE if (ram_size > KERNEL_VM_BASE - KERNEL_BASE) { printf("%s: dropping RAM size from %luMB to %uMB\n", __func__, (unsigned long) (ram_size >> 20), (KERNEL_VM_BASE - KERNEL_BASE) >> 20); ram_size = KERNEL_VM_BASE - KERNEL_BASE; }