int amptimer_match(struct device *parent, void *cfdata, void *aux) { if ((cpufunc_id() & CPU_ID_CORTEX_A9_MASK) == CPU_ID_CORTEX_A9) return (1); return 0; }
int cortexmatch(struct device *parent, void *cfdata, void *aux) { struct mainbus_attach_args *ma = aux; struct cfdata *cf = (struct cfdata *)cfdata; int cputype = cpufunc_id(); if (strcmp(cf->cf_driver->cd_name, ma->ma_name) != 0) return (0); if ((cputype & CPU_ID_CORTEX_A7_MASK) == CPU_ID_CORTEX_A7 || (cputype & CPU_ID_CORTEX_A9_MASK) == CPU_ID_CORTEX_A9 || (cputype & CPU_ID_CORTEX_A15_MASK) == CPU_ID_CORTEX_A15 || (cputype & CPU_ID_CORTEX_A17_MASK) == CPU_ID_CORTEX_A17) { if (armv7_periphbase()) return (1); } return (0); }
void platform_mp_start_ap(void) { uint32_t reg, *src, *dst, cpu_num, div_val, cputype; vm_offset_t pmu_boot_off; /* * Initialization procedure depends on core revision, * in this step CHIP ID is checked to choose proper procedure */ cputype = cpufunc_id(); cputype &= CPU_ID_CPU_MASK; /* * Set the PA of CPU0 Boot Address Redirect register used in * mptramp according to the actual SoC registers' base address. */ pmu_boot_off = (CPU_PMU(0) - MV_BASE) + CPU_PMU_BOOT; mptramp_pmu_boot = fdt_immr_pa + pmu_boot_off; dst = pmap_mapdev(0xffff0000, PAGE_SIZE); for (src = (uint32_t *)mptramp; src < (uint32_t *)mptramp_end; src++, dst++) { *dst = *src; } pmap_unmapdev((vm_offset_t)dst, PAGE_SIZE); if (cputype == CPU_ID_MV88SV584X_V7) { /* Core rev A0 */ div_val = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1); div_val &= 0x3f; for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ ) { reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1); reg &= CPU_DIVCLK_MASK(cpu_num); reg |= div_val << (cpu_num * 8); write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg); } } else { /* Core rev Z1 */ div_val = 0x01; if (mp_ncpus > 1) { reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0); reg &= CPU_DIVCLK_MASK(3); reg |= div_val << 24; write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL0, reg); } for (cpu_num = 2; cpu_num < mp_ncpus; cpu_num++ ) { reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1); reg &= CPU_DIVCLK_MASK(cpu_num); reg |= div_val << (cpu_num * 8); write_cpu_clkdiv(CPU_DIVCLK_CTRL2_RATIO_FULL1, reg); } } reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0); reg |= ((0x1 << (mp_ncpus - 1)) - 1) << 21; write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg); reg = read_cpu_clkdiv(CPU_DIVCLK_CTRL0); reg |= 0x01000000; write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg); DELAY(100); reg &= ~(0xf << 21); write_cpu_clkdiv(CPU_DIVCLK_CTRL0, reg); DELAY(100); bus_space_write_4(fdtbus_bs_tag, MV_BASE, CPU_RESUME_CONTROL, 0); for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ ) bus_space_write_4(fdtbus_bs_tag, CPU_PMU(cpu_num), CPU_PMU_BOOT, pmap_kextract((vm_offset_t)mpentry)); cpu_idcache_wbinv_all(); for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ ) bus_space_write_4(fdtbus_bs_tag, MP, MP_SW_RESET(cpu_num), 0); /* XXX: Temporary workaround for hangup after releasing AP's */ wmb(); DELAY(10); armadaxp_init_coher_fabric(); }