commit: http://blackfin.uclinux.org/git/?p=linux-kernel;a=commitdiff;h=a8342a6c5895fab70b9773d951edae5537adbe3a branch: http://blackfin.uclinux.org/git/?p=linux-kernel;a=shortlog;h=refs/heads/2012R1
add ipi support for BF60x add coreb start stub coreb_start.S add BFIN_COREB menuconfig, cleanup Signed-off-by: Steven Miao <[email protected]> --- arch/blackfin/Kconfig | 9 +++ arch/blackfin/kernel/setup.c | 29 +++++++- arch/blackfin/mach-bf609/Makefile | 1 + arch/blackfin/mach-bf609/coreb_start.S | 105 ++++++++++++++++++++++++++++ arch/blackfin/mach-bf609/include/mach/pm.h | 9 ++- arch/blackfin/mach-bf609/pm.c | 64 ++++++++++++++++-- arch/blackfin/mach-common/ints-priority.c | 12 +++- 7 files changed, 215 insertions(+), 14 deletions(-) diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 31afa76..2f435e6 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -254,6 +254,15 @@ config HOTPLUG_CPU depends on SMP && HOTPLUG default y +comment "Core B Support" + +if !SMP +config BFIN_COREB + bool "Enable Core B loader" + depends on (BF561 || BF60x) + default y +endif + config BF_REV_MIN int default 0 if (BF51x || BF52x || (BF54x && !BF54xM)) || BF60x diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 0053e1b..0133bc0 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -179,6 +179,14 @@ void __init bfin_cache_init(void) bfin_setup_caches(0); } +#ifdef CONFIG_BFIN_COREB +static void core1_enable(void) +{ + bfin_write32(RCU0_SVECT1, 0xff600000); + bfin_write32(RCU0_CRCTL, 0); +} +#endif + void __init bfin_relocate_l1_mem(void) { unsigned long text_l1_len = (unsigned long)_text_l1_len; @@ -204,10 +212,27 @@ void __init bfin_relocate_l1_mem(void) blackfin_dma_early_init(); + +#ifdef CONFIG_BFIN_COREB + core1_enable(); + + if (L1_CODE_LENGTH && text_l1_len) + early_dma_memcpy((void *)0xFF600000, _text_l1_lma, + text_l1_len); + + bfin_write32(RCU0_CRCTL, 0x2); + + while (!(bfin_read32(RCU0_CRSTAT) & 0x2)) + continue; + + bfin_write32(RCU0_CRCTL, 0); +#endif + /* if necessary, copy L1 text to L1 instruction SRAM */ if (L1_CODE_LENGTH && text_l1_len) early_dma_memcpy(_stext_l1, _text_l1_lma, text_l1_len); + /* if necessary, copy L1 data to L1 data bank A SRAM */ if (L1_DATA_A_LENGTH && data_l1_len) early_dma_memcpy(_sdata_l1, _data_l1_lma, data_l1_len); @@ -541,8 +566,8 @@ static __init void parse_cmdline_early(char *cmdline_p) * [_rambase, _ramstart]: kernel image * [memory_start, memory_end]: dynamic memory managed by kernel * [memory_end, _ramend]: reserved memory - * [memory_mtd_start(memory_end), - * memory_mtd_start + mtd_size]: rootfs (if any) + * [memory_mtd_start(memory_end), + * memory_mtd_start + mtd_size]: rootfs (if any) * [_ramend - DMA_UNCACHED_REGION, * _ramend]: uncached DMA region * [_ramend, physical_mem_end]: memory not managed by kernel diff --git a/arch/blackfin/mach-bf609/Makefile b/arch/blackfin/mach-bf609/Makefile index 2a27f81..1bccf9e 100644 --- a/arch/blackfin/mach-bf609/Makefile +++ b/arch/blackfin/mach-bf609/Makefile @@ -4,3 +4,4 @@ obj-y := dma.o clock.o obj-$(CONFIG_PM) += pm.o hibernate.o +obj-$(CONFIG_BFIN_COREB) += coreb_start.o diff --git a/arch/blackfin/mach-bf609/coreb_start.S b/arch/blackfin/mach-bf609/coreb_start.S new file mode 100644 index 0000000..74e0270 --- /dev/null +++ b/arch/blackfin/mach-bf609/coreb_start.S @@ -0,0 +1,105 @@ +#include <linux/linkage.h> +#include <asm/blackfin.h> + +.section .l1.text.head + +/* Lay the initial stack into the L1 scratch area of Core B */ +#define INITIAL_STACK (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) + +ENTRY(_coreb_trampoline_start) + /* Set the SYSCFG register */ + R0 = 0x36; + SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/ + R0 = 0; + + /*Clear Out All the data and pointer Registers*/ + R1 = R0; + R2 = R0; + R3 = R0; + R4 = R0; + R5 = R0; + R6 = R0; + R7 = R0; + + P0 = R0; + P1 = R0; + P2 = R0; + P3 = R0; + P4 = R0; + P5 = R0; + + LC0 = r0; + LC1 = r0; + L0 = r0; + L1 = r0; + L2 = r0; + L3 = r0; + + /* Clear Out All the DAG Registers*/ + B0 = r0; + B1 = r0; + B2 = r0; + B3 = r0; + + I0 = r0; + I1 = r0; + I2 = r0; + I3 = r0; + + M0 = r0; + M1 = r0; + M2 = r0; + M3 = r0; + + /* Initialize stack pointer */ + sp.l = lo(INITIAL_STACK); + sp.h = hi(INITIAL_STACK); + fp = sp; + usp = sp; + + p1.h = HI(0xff700000); + p1.l = LO(0xff700000) + r0.l = 0xDEAD; + [p1] = r0; + + p0.l = lo(EVT15); + p0.h = hi(EVT15); + p1.l = _coreb_start; + p1.h = _coreb_start; + [p0] = p1; + csync; + + p0.l = lo(IMASK); + p0.h = hi(IMASK); + p1.l = IMASK_IVG15; + p1.h = 0x0; + [p0] = p1; + csync; + + raise 15; + + p0.l = .LWAIT_HERE; + p0.h = .LWAIT_HERE; + reti = p0; + nop;nop;nop; + rti; +.LWAIT_HERE: + jump .LWAIT_HERE; +ENDPROC(_coreb_trampoline_start) +ENTRY(_coreb_trampoline_end) + +ENTRY(_core1_evt11) + [--sp] = SYSCFG; + [--sp] = P0; /*orig_p0*/ + [--sp] = R0; /*orig_r0*/ + [--sp] = (R7:0,P5:0); + p0.h = _core1_evt_handle; + p0.l = _core1_evt_handle; + call (p0); + (R7:0,P5:0) = [SP++]; + sp += 8; /* Skip orig_r0/orig_p0 */ + csync; + SYSCFG = [sp++]; + csync; + rti; +ENDPROC(_core1_evt11) diff --git a/arch/blackfin/mach-bf609/include/mach/pm.h b/arch/blackfin/mach-bf609/include/mach/pm.h index 7bbb265..65c9ba0 100644 --- a/arch/blackfin/mach-bf609/include/mach/pm.h +++ b/arch/blackfin/mach-bf609/include/mach/pm.h @@ -11,9 +11,10 @@ #include <linux/suspend.h> -extern int bfin609_pm_enter(suspend_state_t state); -extern int bf609_pm_prepare(void); -extern void bf609_pm_finish(void); +int bfin609_pm_enter(suspend_state_t state); +int bf609_pm_prepare(void); +void bf609_pm_finish(void); -extern void bf609_hibernate(void); +void bf609_hibernate(void); +void bfin_sec_raise_irq(unsigned int sid); #endif diff --git a/arch/blackfin/mach-bf609/pm.c b/arch/blackfin/mach-bf609/pm.c index b76966e..f7fb905 100644 --- a/arch/blackfin/mach-bf609/pm.c +++ b/arch/blackfin/mach-bf609/pm.c @@ -118,6 +118,7 @@ struct STRUCT_ROM_SYSCTRL configvalues; uint32_t dactionflags; #define FUNC_ROM_SYSCONTROL 0xC8000080 +#define FUNC_ROM_MEMCPY 0xC8000024 __attribute__((l1_data)) static uint32_t (* const bfrom_SysControl)(uint32_t action_flags, struct STRUCT_ROM_SYSCTRL *settings, void *reserved) = (void *)FUNC_ROM_SYSCONTROL; @@ -203,11 +204,8 @@ void bfin_hibernate_syscontrol(void) bfin_write32(DPM0_RESTORE5, bfin_read32(DPM0_RESTORE5) | 4); } -#ifndef CONFIG_BF60x -# define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) -#else -# define SIC_SYSIRQ(irq) ((irq) - IVG15) -#endif +# define IRQ_SID(irq) ((irq) - IVG15) + void bfin_hibernate(unsigned long mask) { bfin_write32(DPM0_WAKE_EN, 0x10); @@ -315,6 +313,14 @@ static struct bfin_cpu_pm_fns bf609_cpu_pm = { static irqreturn_t test_isr(int irq, void *dev_id) { printk(KERN_DEBUG "gpio irq %d\n", irq); + if (irq == 231) + bfin_sec_raise_irq(IRQ_SID(IRQ_SOFT1)); + return IRQ_HANDLED; +} + +static irqreturn_t soft_isr(int irq, void *dev_id) +{ + printk(KERN_DEBUG "soft irq %d\n", irq); return IRQ_HANDLED; } @@ -329,6 +335,46 @@ static irqreturn_t dpm0_isr(int irq, void *dev_id) return IRQ_HANDLED; } +void core1_evt_handle(void) +{ + unsigned int sid = bfin_read_SEC_SCI(1, SEC_CSID); + + bfin_write_SEC_SCI(1, SEC_CSID, sid); + SSYNC(); + bfin_sec_raise_irq(IRQ_SID(IRQ_SOFT0)); + bfin_write32(SEC_END, sid); +} + +asmlinkage void core1_evt11(void); + +void coreb_start(void) +{ + unsigned long ilat; + unsigned long bfin_irq_flags; + unsigned int i = 0; + + /* enable interrupt */ + __asm__ ("[--sp] = reti;"); + + ilat = bfin_read_ILAT(); + CSYNC(); + bfin_write_ILAT(ilat); + CSYNC(); + + bfin_write_EVT11(core1_evt11 - L1_CODE_START + COREB_L1_CODE_START); + + SSYNC(); + bfin_irq_flags = IMASK_IVG11; + bfin_sti(bfin_irq_flags); + + while (1) { + if (i++ > 10000000) { + bfin_sec_raise_irq(IRQ_SID(IRQ_SOFT0)); + i = 0; + } + } +} + static int __init bf609_init_pm(void) { int irq; @@ -355,6 +401,14 @@ static int __init bf609_init_pm(void) if (error < 0) printk(KERN_DEBUG "Unable to get irq\n"); + error = request_irq(IRQ_SOFT0, soft_isr, IRQF_NO_SUSPEND, "software event", NULL); + if (error < 0) + printk(KERN_DEBUG "Unable to get irq\n"); + + error = request_irq(IRQ_SOFT1, soft_isr, IRQF_NO_SUSPEND, "software event", NULL); + if (error < 0) + printk(KERN_DEBUG "Unable to get irq\n"); + bfin_cpu_pm = &bf609_cpu_pm; return 0; } diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 2729cba..ea8279d 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -258,7 +258,9 @@ static void bfin_sec_set_ssi_coreid(unsigned int sid, unsigned int coreid) uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); reg_sctl &= ((uint32_t)~SEC_SCTL_CTG); - bfin_write_SEC_SCTL(sid, reg_sctl | ((coreid << 20) & SEC_SCTL_CTG)); + bfin_write_SEC_SCTL(sid, reg_sctl | ((coreid << 24) & SEC_SCTL_CTG)); + + pr_debug("sid %d %08x %08x\n", sid, bfin_read_SEC_SCTL(sid), reg_sctl | ((coreid << 24) & SEC_SCTL_CTG)); hard_local_irq_restore(flags); } @@ -310,7 +312,7 @@ static void bfin_sec_disable(struct irq_data *d) hard_local_irq_restore(flags); } -static void bfin_sec_raise_irq(unsigned int sid) +void bfin_sec_raise_irq(unsigned int sid) { unsigned long flags = hard_local_irq_save(); @@ -319,10 +321,11 @@ static void bfin_sec_raise_irq(unsigned int sid) hard_local_irq_restore(flags); } -static void init_software_driven_irq(void) +void init_software_driven_irq(void) { bfin_sec_set_ssi_coreid(34, 0); bfin_sec_set_ssi_coreid(35, 1); + bfin_sec_set_ssi_coreid(36, 0); bfin_sec_set_ssi_coreid(37, 1); } @@ -522,6 +525,7 @@ static struct irq_chip bfin_internal_irqchip = { static struct irq_chip bfin_sec_irqchip = { .name = "SEC", .irq_mask_ack = bfin_sec_mask_ack_irq, + .irq_ack = bfin_sec_mask_ack_irq, .irq_mask = bfin_sec_mask_ack_irq, .irq_unmask = bfin_sec_unmask_irq, .irq_eoi = bfin_sec_unmask_irq, @@ -1441,6 +1445,8 @@ int __init init_arch_irq(void) udelay(100); bfin_write_SEC_GCTL(SEC_GCTL_EN); bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); + bfin_write_SEC_SCI(1, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); + init_software_driven_irq(); register_syscore_ops(&sec_pm_syscore_ops); #endif
_______________________________________________ Linux-kernel-commits mailing list [email protected] https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits
