Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 225961
b: refs/heads/master
c: ef6c844
h: refs/heads/master
i:
  225959: 2e608f0
v: v3
  • Loading branch information
Haojian Zhuang authored and Eric Miao committed Dec 20, 2010
1 parent 35ca6a1 commit 45e70a4
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a79a9ad94acdbd0106491f5a444167636562460f
refs/heads/master: ef6c84454f8567d4968c210d7d194fb711ed3739
4 changes: 2 additions & 2 deletions trunk/arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -999,8 +999,8 @@ source arch/arm/mm/Kconfig

config IWMMXT
bool "Enable iWMMXt support"
depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
default y if PXA27x || PXA3xx || ARCH_MMP
depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4
default y if PXA27x || PXA3xx || PXA95x || ARCH_MMP
help
Enable support for iWMMXt context switching at run time if
running on a CPU that supports it.
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/arm/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o
obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o
obj-$(CONFIG_IWMMXT) += iwmmxt.o
obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
Expand Down
55 changes: 42 additions & 13 deletions trunk/arch/arm/kernel/iwmmxt.S
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>

#if defined(CONFIG_CPU_PJ4)
#define PJ4(code...) code
#define XSC(code...)
#else
#define PJ4(code...)
#define XSC(code...) code
#endif

#define MMX_WR0 (0x00)
#define MMX_WR1 (0x08)
#define MMX_WR2 (0x10)
Expand Down Expand Up @@ -58,11 +66,17 @@

ENTRY(iwmmxt_task_enable)

mrc p15, 0, r2, c15, c1, 0
tst r2, #0x3 @ CP0 and CP1 accessible?
XSC(mrc p15, 0, r2, c15, c1, 0)
PJ4(mrc p15, 0, r2, c1, c0, 2)
@ CP0 and CP1 accessible?
XSC(tst r2, #0x3)
PJ4(tst r2, #0xf)
movne pc, lr @ if so no business here
orr r2, r2, #0x3 @ enable access to CP0 and CP1
mcr p15, 0, r2, c15, c1, 0
@ enable access to CP0 and CP1
XSC(orr r2, r2, #0x3)
XSC(mcr p15, 0, r2, c15, c1, 0)
PJ4(orr r2, r2, #0xf)
PJ4(mcr p15, 0, r2, c1, c0, 2)

ldr r3, =concan_owner
add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area
Expand Down Expand Up @@ -179,17 +193,26 @@ ENTRY(iwmmxt_task_disable)
teqne r1, r2 @ or specified one?
bne 1f @ no: quit

mrc p15, 0, r4, c15, c1, 0
orr r4, r4, #0x3 @ enable access to CP0 and CP1
mcr p15, 0, r4, c15, c1, 0
@ enable access to CP0 and CP1
XSC(mrc p15, 0, r4, c15, c1, 0)
XSC(orr r4, r4, #0xf)
XSC(mcr p15, 0, r4, c15, c1, 0)
PJ4(mrc p15, 0, r4, c1, c0, 2)
PJ4(orr r4, r4, #0x3)
PJ4(mcr p15, 0, r4, c1, c0, 2)

mov r0, #0 @ nothing to load
str r0, [r3] @ no more current owner
mrc p15, 0, r2, c2, c0, 0
mov r2, r2 @ cpwait
bl concan_save

bic r4, r4, #0x3 @ disable access to CP0 and CP1
mcr p15, 0, r4, c15, c1, 0
@ disable access to CP0 and CP1
XSC(bic r4, r4, #0x3)
XSC(mcr p15, 0, r4, c15, c1, 0)
PJ4(bic r4, r4, #0xf)
PJ4(mcr p15, 0, r4, c1, c0, 2)

mrc p15, 0, r2, c2, c0, 0
mov r2, r2 @ cpwait

Expand Down Expand Up @@ -277,8 +300,11 @@ ENTRY(iwmmxt_task_restore)
*/
ENTRY(iwmmxt_task_switch)

mrc p15, 0, r1, c15, c1, 0
tst r1, #0x3 @ CP0 and CP1 accessible?
XSC(mrc p15, 0, r1, c15, c1, 0)
PJ4(mrc p15, 0, r1, c1, c0, 2)
@ CP0 and CP1 accessible?
XSC(tst r1, #0x3)
PJ4(tst r1, #0xf)
bne 1f @ yes: block them for next task

ldr r2, =concan_owner
Expand All @@ -287,8 +313,11 @@ ENTRY(iwmmxt_task_switch)
teq r2, r3 @ next task owns it?
movne pc, lr @ no: leave Concan disabled

1: eor r1, r1, #3 @ flip Concan access
mcr p15, 0, r1, c15, c1, 0
1: @ flip Conan access
XSC(eor r1, r1, #0x3)
XSC(mcr p15, 0, r1, c15, c1, 0)
PJ4(eor r1, r1, #0xf)
PJ4(mcr p15, 0, r1, c1, c0, 2)

mrc p15, 0, r1, c2, c0, 0
sub pc, lr, r1, lsr #32 @ cpwait and return
Expand Down
94 changes: 94 additions & 0 deletions trunk/arch/arm/kernel/pj4-cp0.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* linux/arch/arm/kernel/pj4-cp0.c
*
* PJ4 iWMMXt coprocessor context switching and handling
*
* Copyright (c) 2010 Marvell International Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/io.h>
#include <asm/thread_notify.h>

static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
{
struct thread_info *thread = t;

switch (cmd) {
case THREAD_NOTIFY_FLUSH:
/*
* flush_thread() zeroes thread->fpstate, so no need
* to do anything here.
*
* FALLTHROUGH: Ensure we don't try to overwrite our newly
* initialised state information on the first fault.
*/

case THREAD_NOTIFY_EXIT:
iwmmxt_task_release(thread);
break;

case THREAD_NOTIFY_SWITCH:
iwmmxt_task_switch(thread);
break;
}

return NOTIFY_DONE;
}

static struct notifier_block iwmmxt_notifier_block = {
.notifier_call = iwmmxt_do,
};


static u32 __init pj4_cp_access_read(void)
{
u32 value;

__asm__ __volatile__ (
"mrc p15, 0, %0, c1, c0, 2\n\t"
: "=r" (value));
return value;
}

static void __init pj4_cp_access_write(u32 value)
{
u32 temp;

__asm__ __volatile__ (
"mcr p15, 0, %1, c1, c0, 2\n\t"
"mrc p15, 0, %0, c1, c0, 2\n\t"
"mov %0, %0\n\t"
"sub pc, pc, #4\n\t"
: "=r" (temp) : "r" (value));
}


/*
* Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
* switch code handle iWMMXt context switching.
*/
static int __init pj4_cp0_init(void)
{
u32 cp_access;

cp_access = pj4_cp_access_read() & ~0xf;
pj4_cp_access_write(cp_access);

printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n");
elf_hwcap |= HWCAP_IWMMXT;
thread_register_notifier(&iwmmxt_notifier_block);

return 0;
}

late_initcall(pj4_cp0_init);

0 comments on commit 45e70a4

Please sign in to comment.