if (IS_ERR(rstc) && read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
pr_err("%s: could not get reset control for core %d\n",
__func__, pd); return PTR_ERR(rstc);
}
/* *Weneedtosoftresetthecpuwhenweturnoffthecpupowerdomain, *orelsetheactiveprocessorsmightbestalledwhentheindividual *processorispowereddown.
*/ if (!IS_ERR(rstc) && !on)
reset_control_assert(rstc);
if (has_pmu) {
ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val); if (ret < 0) {
pr_err("%s: could not update power domain\n",
__func__); return ret;
}
ret = -1; while (ret != on) {
ret = pmu_power_domain_is_on(pd); if (ret < 0) {
pr_err("%s: could not read power domain state\n",
__func__); return ret;
}
}
}
if (!IS_ERR(rstc)) { if (on)
reset_control_deassert(rstc);
reset_control_put(rstc);
}
return0;
}
/* *HandlingofCPUcores
*/
staticint rockchip_boot_secondary(unsignedint cpu, struct task_struct *idle)
{ int ret;
if (!sram_base_addr || (has_pmu && !pmu)) {
pr_err("%s: sram or pmu missing for cpu boot\n", __func__); return -ENXIO;
}
if (cpu >= ncores) {
pr_err("%s: cpu %d outside maximum number of cpus %d\n",
__func__, cpu, ncores); return -ENXIO;
}
/* start the core */
ret = pmu_set_power_domain(0 + cpu, true); if (ret < 0) return ret;
if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) { /* *Wecommunicatewiththebootromtoactivethecpusother *thancpu0,afterablobofinitializecode,theywill *stayatwfestate,oncetheyareactivated,theywillcheck *themailbox: *sram_base_addr+4:0xdeadbeaf *sram_base_addr+8:startaddressforpc *Thecpu0needtowaittheothercpusotherthancpu0entering *thewfestate.Thewaittimeisaffectedbymanyaspects. *(e.g:cpufrequency,bootromfrequency,sramfrequency,...)
*/
mdelay(1); /* ensure the cpus other than cpu0 to startup */
ret = of_address_to_resource(node, 0, &res); if (ret < 0) {
pr_err("%s: could not get address for node %pOF\n",
__func__, node); return ret;
}
rsize = resource_size(&res); if (rsize < trampoline_sz) {
pr_err("%s: reserved block with size 0x%x is too small for trampoline size 0x%x\n",
__func__, rsize, trampoline_sz); return -EINVAL;
}
/* set the boot function for the sram code */
rockchip_boot_fn = __pa_symbol(secondary_startup);
/* copy the trampoline to sram, that runs during startup of the core */
memcpy_toio(sram_base_addr, &rockchip_secondary_trampoline, trampoline_sz);
flush_cache_all();
outer_clean_range(0, trampoline_sz);
pmu = syscon_regmap_lookup_by_phandle(node, "rockchip,pmu");
of_node_put(node); if (!IS_ERR(pmu)) return0;
pmu = syscon_regmap_lookup_by_compatible("rockchip,rk3066-pmu"); if (!IS_ERR(pmu)) return0;
/* fallback, create our own regmap for the pmu area */
pmu = NULL;
node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu"); if (!node) {
pr_err("%s: could not find pmu dt node\n", __func__); return -ENODEV;
}
pmu_base = of_iomap(node, 0);
of_node_put(node); if (!pmu_base) {
pr_err("%s: could not map pmu registers\n", __func__); return -ENOMEM;
}
pmu = regmap_init_mmio(NULL, pmu_base, &rockchip_pmu_regmap_config); if (IS_ERR(pmu)) { int ret = PTR_ERR(pmu);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.