Exemple #1
0
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();
	}
}
Exemple #2
0
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));
}
Exemple #3
0
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;
	}