From: 黄涛 Date: Fri, 21 Mar 2014 10:07:09 +0000 (+0800) Subject: ARM: rockchip: fix rk3288 smp and timer support X-Git-Tag: firefly_0821_release~5923 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=256eee054f3703b8d4ef09b358c37f520a20fdad;p=firefly-linux-kernel-4.4.55.git ARM: rockchip: fix rk3288 smp and timer support --- diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 44a64d75ab15..c7cd9feea8c2 100755 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -41,7 +41,6 @@ compatible = "arm,cortex-a15"; reg = <0x500>; }; -/* cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a15"; @@ -57,7 +56,6 @@ compatible = "arm,cortex-a15"; reg = <0x503>; }; -*/ }; gic: interrupt-controller@ffc01000 { @@ -187,6 +185,34 @@ }; */ + timer@ff6b0000 { + compatible = "rockchip,timer"; + reg = <0xff6b0000 0x20>; + interrupts = ; + rockchip,percpu = <0>; + }; + + timer@ff6b0020 { + compatible = "rockchip,timer"; + reg = <0xff6b0020 0x20>; + interrupts = ; + rockchip,percpu = <1>; + }; + + timer@ff6b0040 { + compatible = "rockchip,timer"; + reg = <0xff6b0040 0x20>; + interrupts = ; + rockchip,percpu = <2>; + }; + + timer@ff6b0060 { + compatible = "rockchip,timer"; + reg = <0xff6b0060 0x20>; + interrupts = ; + rockchip,percpu = <3>; + }; + timer@ff810000 { compatible = "rockchip,timer"; reg = <0xff810000 0x20>; diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index d0358a372ae6..9444a1c5e541 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -147,8 +147,21 @@ static void __init rockchip_a9_smp_prepare_cpus(unsigned int max_cpus) static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) { + unsigned int i, cpu; + unsigned long scuctlr; + if (scu_a9_has_base()) return rockchip_a9_smp_prepare_cpus(max_cpus); + + asm("mrc p15, 1, %0, c9, c0, 4" : "=r" (scuctlr)); + ncores = (scuctlr & 3) + 1; + cpu = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 0); + /* Make sure that all cores except myself are really off */ + for (i = 0; i < ncores; i++) { + if (i == cpu) + continue; + rockchip_pmu_ops.set_power_domain(PD_CPU_0 + i, false); + } } struct smp_operations rockchip_smp_ops __initdata = { diff --git a/arch/arm/mach-rockchip/rk3288.c b/arch/arm/mach-rockchip/rk3288.c index 1ee73bb90e51..f493c5718cb8 100755 --- a/arch/arm/mach-rockchip/rk3288.c +++ b/arch/arm/mach-rockchip/rk3288.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -45,6 +46,8 @@ #define RK3288_SERVICE_DEVICE(name) \ RK_DEVICE(RK3288_SERVICE_##name##_VIRT, RK3288_SERVICE_##name##_PHYS, RK3288_SERVICE_##name##_SIZE) +#define RK3288_IMEM_VIRT (RK_BOOTRAM_VIRT + SZ_32K) + static struct map_desc rk3288_io_desc[] __initdata = { RK3288_DEVICE(CRU), RK3288_DEVICE(GRF), @@ -73,10 +76,10 @@ static struct map_desc rk3288_io_desc[] __initdata = { RK_DEVICE(RK_GPIO_VIRT(7), RK3288_GPIO7_PHYS, RK3288_GPIO_SIZE), RK_DEVICE(RK_GPIO_VIRT(8), RK3288_GPIO8_PHYS, RK3288_GPIO_SIZE), RK_DEVICE(RK_DEBUG_UART_VIRT, RK3288_UART_DBG_PHYS, RK3288_UART_SIZE), - RK_DEVICE(RK_GIC_VIRT, RK3288_GIC_DIST_PHYS, RK3288_GIC_DIST_SIZE), - RK_DEVICE(RK_GIC_VIRT+RK3288_GIC_DIST_SIZE, RK3288_GIC_DIST_PHYS+RK3288_GIC_DIST_SIZE, RK3288_GIC_CPU_SIZE), - RK_DEVICE(RK_BOOTRAM_VIRT, RK3288_BOOTRAM_PHYS, RK3288_BOOTRAM_SIZE), - + RK_DEVICE(RK_GIC_VIRT, RK3288_GIC_DIST_PHYS, RK3288_GIC_DIST_SIZE), + RK_DEVICE(RK_GIC_VIRT + RK3288_GIC_DIST_SIZE, RK3288_GIC_DIST_PHYS + RK3288_GIC_DIST_SIZE, RK3288_GIC_CPU_SIZE), + RK_DEVICE(RK_BOOTRAM_VIRT, RK3288_BOOTRAM_PHYS, RK3288_BOOTRAM_SIZE), + RK_DEVICE(RK3288_IMEM_VIRT, RK3288_IMEM_PHYS, SZ_4K), }; static void __init rk3288_boot_mode_init(void) @@ -96,16 +99,16 @@ static void __init rk3288_boot_mode_init(void) static void usb_uart_init(void) { - u32 soc_status2; + u32 soc_status2; writel_relaxed(0x00c00000, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3); #ifdef CONFIG_RK_USB_UART - soc_status2 = (readl_relaxed(RK_GRF_VIRT + RK3288_GRF_SOC_STATUS2)); - if(!(soc_status2 & (1<<14)) && (soc_status2 & (1<<17))) - { - writel_relaxed(0x00040004, RK_GRF_VIRT + RK3288_GRF_UOC0_CON2); //software control usb phy enable + soc_status2 = (readl_relaxed(RK_GRF_VIRT + RK3288_GRF_SOC_STATUS2)); + if(!(soc_status2 & (1<<14)) && (soc_status2 & (1<<17))) + { + writel_relaxed(0x00040004, RK_GRF_VIRT + RK3288_GRF_UOC0_CON2); //software control usb phy enable writel_relaxed(0x003f002a, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3); //usb phy enter suspend writel_relaxed(0x00c000c0, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3); - } + } #endif // end of CONFIG_RK_USB_UART } @@ -121,12 +124,6 @@ static void __init rk3288_dt_map_io(void) /* rkpwm is used instead of old pwm */ writel_relaxed(0x00010001, RK_GRF_VIRT + RK3288_GRF_SOC_CON2); -#ifdef CONFIG_SMP - /* enable fast boot */ - writel_relaxed(0x01000100, RK_SGRF_VIRT + RK3288_SGRF_SOC_CON0); - writel_relaxed(virt_to_phys(secondary_startup), RK_SGRF_VIRT + RK3288_SGRF_FAST_BOOT_ADDR); -#endif - rk3288_boot_mode_init(); } @@ -302,6 +299,11 @@ static int rk3288_pmu_set_power_domain(enum pmu_power_domain pd, bool on) rk3288_pmu_set_idle_request(IDLE_REQ_HEVC, false); RESTORE_QOS(hevc_r_qos, HEVC_R); RESTORE_QOS(hevc_w_qos, HEVC_W); + } else if (pd >= PD_CPU_1 && pd <= PD_CPU_3) { + udelay(10); + writel_relaxed(virt_to_phys(secondary_startup), RK3288_IMEM_VIRT + 8); + writel_relaxed(0xDEADBEAF, RK3288_IMEM_VIRT + 4); + dsb_sev(); } } @@ -391,8 +393,8 @@ arch_initcall(rk3288_pie_init); static void __init rk3288_init_suspend(void) { return; - rockchip_suspend_init(); - rkpm_pie_init(); - rk3288_suspend_init(); + rockchip_suspend_init(); + rkpm_pie_init(); + rk3288_suspend_init(); } #endif