Skip to content

Commit

Permalink
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
Browse files Browse the repository at this point in the history
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (103 commits)
  ARM: 5719/1: [AT91] Fix AC97 breakage
  ARM: 5721/1: MMCI enable the use of a regulator
  ARM: 5720/1: Move MMCI header to amba include dir
  ARM: 5718/1: Sane busids for RealView board components
  ARM: 5715/1: Make kprobes unregistration SMP safe
  ARM: 5711/1: locomo.c: CodingStyle cleanups
  ARM: 5710/1: at91: add AC97 support to at91sam9rl and at91sam9rlek board
  ARM: 5709/1: at91: add AC97 support to at91sam9g45 series and at91sam9m10g45ek board
  ARM: 5621/1: at91/dmaengine: integration of at_hdmac driver in at91sam9g45 series
  ARM: 5620/1: at91/dmaengine: integration of at_hdmac driver in at91sam9rl
  ARM: Add support for checking access permissions on prefetch aborts
  ARM: Separate out access error checking
  ARM: Ensure correct might_sleep() check in pagefault path
  ARM: Update page fault handling for new OOM techniques
  ARM: Provide definitions and helpers for decoding the FSR register
  ARM: 5712/1: SA1100: initialise spinlock in DMA code
  ARM: s3c: fix check of index into s3c_gpios[]
  ARM: spitz: fix touchscreen max presure
  ARM: STMP3xxx: deallocation with negative index of descriptors[]
  Thumb-2: Correctly handle undefined instructions in the kernel
  ...
  • Loading branch information
Linus Torvalds committed Sep 25, 2009
2 parents f25f60b + baea7b9 commit d9fbd9a
Show file tree
Hide file tree
Showing 153 changed files with 7,834 additions and 3,746 deletions.
145 changes: 145 additions & 0 deletions Documentation/arm/tcm.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
ARM TCM (Tightly-Coupled Memory) handling in Linux
----
Written by Linus Walleij <linus.walleij@stericsson.com>

Some ARM SoC:s have a so-called TCM (Tightly-Coupled Memory).
This is usually just a few (4-64) KiB of RAM inside the ARM
processor.

Due to being embedded inside the CPU The TCM has a
Harvard-architecture, so there is an ITCM (instruction TCM)
and a DTCM (data TCM). The DTCM can not contain any
instructions, but the ITCM can actually contain data.
The size of DTCM or ITCM is minimum 4KiB so the typical
minimum configuration is 4KiB ITCM and 4KiB DTCM.

ARM CPU:s have special registers to read out status, physical
location and size of TCM memories. arch/arm/include/asm/cputype.h
defines a CPUID_TCM register that you can read out from the
system control coprocessor. Documentation from ARM can be found
at http://infocenter.arm.com, search for "TCM Status Register"
to see documents for all CPUs. Reading this register you can
determine if ITCM (bit 0) and/or DTCM (bit 16) is present in the
machine.

There is further a TCM region register (search for "TCM Region
Registers" at the ARM site) that can report and modify the location
size of TCM memories at runtime. This is used to read out and modify
TCM location and size. Notice that this is not a MMU table: you
actually move the physical location of the TCM around. At the
place you put it, it will mask any underlying RAM from the
CPU so it is usually wise not to overlap any physical RAM with
the TCM. The TCM memory exists totally outside the MMU and will
override any MMU mappings.

Code executing inside the ITCM does not "see" any MMU mappings
and e.g. register accesses must be made to physical addresses.

TCM is used for a few things:

- FIQ and other interrupt handlers that need deterministic
timing and cannot wait for cache misses.

- Idle loops where all external RAM is set to self-refresh
retention mode, so only on-chip RAM is accessible by
the CPU and then we hang inside ITCM waiting for an
interrupt.

- Other operations which implies shutting off or reconfiguring
the external RAM controller.

There is an interface for using TCM on the ARM architecture
in <asm/tcm.h>. Using this interface it is possible to:

- Define the physical address and size of ITCM and DTCM.

- Tag functions to be compiled into ITCM.

- Tag data and constants to be allocated to DTCM and ITCM.

- Have the remaining TCM RAM added to a special
allocation pool with gen_pool_create() and gen_pool_add()
and provice tcm_alloc() and tcm_free() for this
memory. Such a heap is great for things like saving
device state when shutting off device power domains.

A machine that has TCM memory shall select HAVE_TCM in
arch/arm/Kconfig for itself, and then the
rest of the functionality will depend on the physical
location and size of ITCM and DTCM to be defined in
mach/memory.h for the machine. Code that needs to use
TCM shall #include <asm/tcm.h> If the TCM is not located
at the place given in memory.h it will be moved using
the TCM Region registers.

Functions to go into itcm can be tagged like this:
int __tcmfunc foo(int bar);

Variables to go into dtcm can be tagged like this:
int __tcmdata foo;

Constants can be tagged like this:
int __tcmconst foo;

To put assembler into TCM just use
.section ".tcm.text" or .section ".tcm.data"
respectively.

Example code:

#include <asm/tcm.h>

/* Uninitialized data */
static u32 __tcmdata tcmvar;
/* Initialized data */
static u32 __tcmdata tcmassigned = 0x2BADBABEU;
/* Constant */
static const u32 __tcmconst tcmconst = 0xCAFEBABEU;

static void __tcmlocalfunc tcm_to_tcm(void)
{
int i;
for (i = 0; i < 100; i++)
tcmvar ++;
}

static void __tcmfunc hello_tcm(void)
{
/* Some abstract code that runs in ITCM */
int i;
for (i = 0; i < 100; i++) {
tcmvar ++;
}
tcm_to_tcm();
}

static void __init test_tcm(void)
{
u32 *tcmem;
int i;

hello_tcm();
printk("Hello TCM executed from ITCM RAM\n");

printk("TCM variable from testrun: %u @ %p\n", tcmvar, &tcmvar);
tcmvar = 0xDEADBEEFU;
printk("TCM variable: 0x%x @ %p\n", tcmvar, &tcmvar);

printk("TCM assigned variable: 0x%x @ %p\n", tcmassigned, &tcmassigned);

printk("TCM constant: 0x%x @ %p\n", tcmconst, &tcmconst);

/* Allocate some TCM memory from the pool */
tcmem = tcm_alloc(20);
if (tcmem) {
printk("TCM Allocated 20 bytes of TCM @ %p\n", tcmem);
tcmem[0] = 0xDEADBEEFU;
tcmem[1] = 0x2BADBABEU;
tcmem[2] = 0xCAFEBABEU;
tcmem[3] = 0xDEADBEEFU;
tcmem[4] = 0x2BADBABEU;
for (i = 0; i < 5; i++)
printk("TCM tcmem[%d] = %08x\n", i, tcmem[i]);
tcm_free(tcmem, 20);
}
}
10 changes: 7 additions & 3 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ S: Maintained
ARM/INTEL IXP4XX ARM ARCHITECTURE
M: Imre Kaloz <kaloz@openwrt.org>
M: Krzysztof Halasa <khc@pm.waw.pl>
L: linux-arm-kernel@lists.infradead.org
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-ixp4xx/

Expand Down Expand Up @@ -740,18 +740,22 @@ M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
M: Dirk Opfer <dirk@opfer-online.de>
S: Maintained

ARM/PALMTX,PALMT5,PALMLD,PALMTE2 SUPPORT
M: Marek Vasut <marek.vasut@gmail.com>
ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT
P: Marek Vasut
M: marek.vasut@gmail.com
L: linux-arm-kernel@lists.infradead.org
W: http://hackndev.com
S: Maintained

ARM/PALM TREO 680 SUPPORT
M: Tomas Cech <sleep_walker@suse.cz>
L: linux-arm-kernel@lists.infradead.org
W: http://hackndev.com
S: Maintained

ARM/PALMZ72 SUPPORT
M: Sergey Lapin <slapin@ossfans.org>
L: linux-arm-kernel@lists.infradead.org
W: http://hackndev.com
S: Maintained

Expand Down
5 changes: 5 additions & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ config GENERIC_CLOCKEVENTS_BROADCAST
depends on GENERIC_CLOCKEVENTS
default y if SMP && !LOCAL_TIMERS

config HAVE_TCM
bool
select GENERIC_ALLOCATOR

config NO_IOPORT
bool

Expand Down Expand Up @@ -649,6 +653,7 @@ config ARCH_U300
bool "ST-Ericsson U300 Series"
depends on MMU
select CPU_ARM926T
select HAVE_TCM
select ARM_AMBA
select ARM_VIC
select GENERIC_TIME
Expand Down
17 changes: 7 additions & 10 deletions arch/arm/common/locomo.c
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,7 @@ void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir

spin_unlock_irqrestore(&lchip->lock, flags);
}
EXPORT_SYMBOL(locomo_gpio_set_dir);

int locomo_gpio_read_level(struct device *dev, unsigned int bits)
{
Expand All @@ -882,6 +883,7 @@ int locomo_gpio_read_level(struct device *dev, unsigned int bits)
ret &= bits;
return ret;
}
EXPORT_SYMBOL(locomo_gpio_read_level);

int locomo_gpio_read_output(struct device *dev, unsigned int bits)
{
Expand All @@ -899,6 +901,7 @@ int locomo_gpio_read_output(struct device *dev, unsigned int bits)
ret &= bits;
return ret;
}
EXPORT_SYMBOL(locomo_gpio_read_output);

void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set)
{
Expand All @@ -920,6 +923,7 @@ void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set)

spin_unlock_irqrestore(&lchip->lock, flags);
}
EXPORT_SYMBOL(locomo_gpio_write);

static void locomo_m62332_sendbit(void *mapbase, int bit)
{
Expand Down Expand Up @@ -1084,13 +1088,12 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int

spin_unlock_irqrestore(&lchip->lock, flags);
}
EXPORT_SYMBOL(locomo_m62332_senddata);

/*
* Frontlight control
*/

static struct locomo *locomo_chip_driver(struct locomo_dev *ldev);

void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf)
{
unsigned long flags;
Expand Down Expand Up @@ -1182,11 +1185,13 @@ int locomo_driver_register(struct locomo_driver *driver)
driver->drv.bus = &locomo_bus_type;
return driver_register(&driver->drv);
}
EXPORT_SYMBOL(locomo_driver_register);

void locomo_driver_unregister(struct locomo_driver *driver)
{
driver_unregister(&driver->drv);
}
EXPORT_SYMBOL(locomo_driver_unregister);

static int __init locomo_init(void)
{
Expand All @@ -1208,11 +1213,3 @@ module_exit(locomo_exit);
MODULE_DESCRIPTION("Sharp LoCoMo core driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");

EXPORT_SYMBOL(locomo_driver_register);
EXPORT_SYMBOL(locomo_driver_unregister);
EXPORT_SYMBOL(locomo_gpio_set_dir);
EXPORT_SYMBOL(locomo_gpio_read_level);
EXPORT_SYMBOL(locomo_gpio_read_output);
EXPORT_SYMBOL(locomo_gpio_write);
EXPORT_SYMBOL(locomo_m62332_senddata);
1 change: 1 addition & 0 deletions arch/arm/common/vic.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/list.h>
#include <linux/io.h>
#include <linux/sysdev.h>
#include <linux/device.h>
#include <linux/amba/bus.h>

#include <asm/mach/irq.h>
Expand Down
Loading

0 comments on commit d9fbd9a

Please sign in to comment.