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

Reply via email to