From 1e0228fd20aa46ac1f02cffee946cdd4ffaf8b96 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 28 Feb 2017 12:08:20 +0000 Subject: hw/arm/exynos: Fix Linux kernel division by zero for PLLs Without any clock controller, the Linux kernel was hitting division by zero during boot or with clk_summary: [ 0.000000] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 0.000000] [] (show_stack) from [] (dump_stack+0x88/0x9c) [ 0.000000] [] (dump_stack) from [] (Ldiv0+0x8/0x10) [ 0.000000] [] (Ldiv0) from [] (samsung_pll45xx_recalc_rate+0x58/0x74) [ 0.000000] [] (samsung_pll45xx_recalc_rate) from [] (clk_register+0x39c/0x63c) [ 0.000000] [] (clk_register) from [] (samsung_clk_register_pll+0x2e0/0x3d4) [ 0.000000] [] (samsung_clk_register_pll) from [] (exynos4_clk_init+0x1b0/0x5e4) [ 0.000000] [] (exynos4_clk_init) from [] (of_clk_init+0x17c/0x210) [ 0.000000] [] (of_clk_init) from [] (time_init+0x24/0x2c) [ 0.000000] [] (time_init) from [] (start_kernel+0x24c/0x38c) [ 0.000000] [] (start_kernel) from [<4020807c>] (0x4020807c) Provide stub for clock controller returning reset values for PLLs. Signed-off-by: Krzysztof Kozlowski Message-id: 20170226200142.31169-1-krzk@kernel.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/exynos4210.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'hw/arm/exynos4210.c') diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index be3c96d21e..a0ecbe8c1f 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu-common.h" +#include "qemu/log.h" #include "cpu.h" #include "hw/boards.h" #include "sysemu/sysemu.h" @@ -74,6 +75,9 @@ /* PMU SFR base address */ #define EXYNOS4210_PMU_BASE_ADDR 0x10020000 +/* Clock controller SFR base address */ +#define EXYNOS4210_CLK_BASE_ADDR 0x10030000 + /* Display controllers (FIMD) */ #define EXYNOS4210_FIMD0_BASE_ADDR 0x11C00000 @@ -297,6 +301,8 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem, */ sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL); + sysbus_create_simple("exynos4210.clk", EXYNOS4210_CLK_BASE_ADDR, NULL); + /* PWM */ sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR, s->irq_table[exynos4210_get_irq(22, 0)], -- cgit 1.4.1 From f3a6339a5bbc160d327299c67bb68c6d07fa4a61 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 28 Feb 2017 12:08:20 +0000 Subject: hw/arm/exynos: Fix proper mapping of CPUs by providing real cluster ID The Exynos4210 has cluster ID 0x9 in its MPIDR register (raw value 0x8000090x). If this cluster ID is not provided, then Linux kernel cannot map DeviceTree nodes to MPIDR values resulting in kernel warning and lack of any secondary CPUs: DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map ... smp: Bringing up secondary CPUs ... smp: Brought up 1 node, 1 CPU SMP: Total of 1 processors activated (24.00 BogoMIPS). Provide a cluster ID so Linux will see proper MPIDR and will try to bring the secondary CPU online. Signed-off-by: Krzysztof Kozlowski Message-id: 20170226200142.31169-2-krzk@kernel.org Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/exynos4210.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'hw/arm/exynos4210.c') diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index a0ecbe8c1f..1d2b50cc4e 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -142,6 +142,16 @@ void exynos4210_write_secondary(ARMCPU *cpu, info->smp_loader_start); } +static uint64_t exynos4210_calc_affinity(int cpu) +{ + uint64_t mp_affinity; + + /* Exynos4210 has 0x9 as cluster ID */ + mp_affinity = (0x9 << ARM_AFF1_SHIFT) | cpu; + + return mp_affinity; +} + Exynos4210State *exynos4210_init(MemoryRegion *system_mem, unsigned long ram_size) { @@ -167,6 +177,8 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem, } s->cpu[n] = ARM_CPU(cpuobj); + object_property_set_int(cpuobj, exynos4210_calc_affinity(n), + "mp-affinity", &error_abort); object_property_set_int(cpuobj, EXYNOS4210_SMP_PRIVATE_BASE_ADDR, "reset-cbar", &error_abort); object_property_set_bool(cpuobj, true, "realized", &error_fatal); -- cgit 1.4.1