diff options
Diffstat (limited to 'arch/c6x/include/asm')
42 files changed, 2283 insertions, 0 deletions
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild new file mode 100644 index 00000000000..8dbdce8421b --- /dev/null +++ b/arch/c6x/include/asm/Kbuild @@ -0,0 +1,61 @@ + +generic-y += atomic.h +generic-y += auxvec.h +generic-y += barrier.h +generic-y += bitsperlong.h +generic-y += bugs.h +generic-y += cputime.h +generic-y += current.h +generic-y += device.h +generic-y += div64.h +generic-y += dma.h +generic-y += emergency-restart.h +generic-y += errno.h +generic-y += exec.h +generic-y += fb.h +generic-y += fcntl.h +generic-y += futex.h +generic-y += hash.h +generic-y += hw_irq.h +generic-y += io.h +generic-y += ioctl.h +generic-y += ioctls.h +generic-y += ipcbuf.h +generic-y += irq_regs.h +generic-y += kdebug.h +generic-y += kmap_types.h +generic-y += local.h +generic-y += mcs_spinlock.h +generic-y += mman.h +generic-y += mmu.h +generic-y += mmu_context.h +generic-y += msgbuf.h +generic-y += param.h +generic-y += pci.h +generic-y += percpu.h +generic-y += pgalloc.h +generic-y += poll.h +generic-y += posix_types.h +generic-y += preempt.h +generic-y += resource.h +generic-y += scatterlist.h +generic-y += segment.h +generic-y += sembuf.h +generic-y += shmbuf.h +generic-y += shmparam.h +generic-y += siginfo.h +generic-y += signal.h +generic-y += socket.h +generic-y += sockios.h +generic-y += stat.h +generic-y += statfs.h +generic-y += termbits.h +generic-y += termios.h +generic-y += tlbflush.h +generic-y += topology.h +generic-y += trace_clock.h +generic-y += types.h +generic-y += ucontext.h +generic-y += user.h +generic-y += vga.h +generic-y += xor.h diff --git a/arch/c6x/include/asm/asm-offsets.h b/arch/c6x/include/asm/asm-offsets.h new file mode 100644 index 00000000000..d370ee36a18 --- /dev/null +++ b/arch/c6x/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include <generated/asm-offsets.h> diff --git a/arch/c6x/include/asm/bitops.h b/arch/c6x/include/asm/bitops.h new file mode 100644 index 00000000000..f0ab012401b --- /dev/null +++ b/arch/c6x/include/asm/bitops.h @@ -0,0 +1,98 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_BITOPS_H +#define _ASM_C6X_BITOPS_H + +#ifdef __KERNEL__ + +#include <linux/bitops.h> +#include <asm/byteorder.h> +#include <asm/barrier.h> + +/* + * We are lucky, DSP is perfect for bitops: do it in 3 cycles + */ + +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + * Note __ffs(0) = undef, __ffs(1) = 0, __ffs(0x80000000) = 31. + * + */ +static inline unsigned long __ffs(unsigned long x) +{ +	asm (" bitr  .M1  %0,%0\n" +	     " nop\n" +	     " lmbd  .L1  1,%0,%0\n" +	     : "+a"(x)); + +	return x; +} + +/* + * ffz - find first zero in word. + * @word: The word to search + * + * Undefined if no zero exists, so code should check against ~0UL first. + */ +#define ffz(x) __ffs(~(x)) + +/** + * fls - find last (most-significant) bit set + * @x: the word to search + * + * This is defined the same way as ffs. + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. + */ +static inline int fls(int x) +{ +	if (!x) +		return 0; + +	asm (" lmbd  .L1  1,%0,%0\n" : "+a"(x)); + +	return 32 - x; +} + +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + * Note ffs(0) = 0, ffs(1) = 1, ffs(0x80000000) = 32. + */ +static inline int ffs(int x) +{ +	if (!x) +		return 0; + +	return __ffs(x) + 1; +} + +#include <asm-generic/bitops/__fls.h> +#include <asm-generic/bitops/fls64.h> +#include <asm-generic/bitops/find.h> + +#include <asm-generic/bitops/sched.h> +#include <asm-generic/bitops/hweight.h> +#include <asm-generic/bitops/lock.h> + +#include <asm-generic/bitops/atomic.h> +#include <asm-generic/bitops/non-atomic.h> +#include <asm-generic/bitops/le.h> +#include <asm-generic/bitops/ext2-atomic.h> + +#endif /* __KERNEL__ */ +#endif /* _ASM_C6X_BITOPS_H */ diff --git a/arch/c6x/include/asm/bug.h b/arch/c6x/include/asm/bug.h new file mode 100644 index 00000000000..8d59933dd6f --- /dev/null +++ b/arch/c6x/include/asm/bug.h @@ -0,0 +1,23 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_BUG_H +#define _ASM_C6X_BUG_H + +#include <linux/linkage.h> +#include <asm-generic/bug.h> + +struct pt_regs; + +extern void die(char *str, struct pt_regs *fp, int nr); +extern asmlinkage int process_exception(struct pt_regs *regs); +extern asmlinkage void enable_exception(void); + +#endif /* _ASM_C6X_BUG_H */ diff --git a/arch/c6x/include/asm/cache.h b/arch/c6x/include/asm/cache.h new file mode 100644 index 00000000000..86648c083bb --- /dev/null +++ b/arch/c6x/include/asm/cache.h @@ -0,0 +1,97 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2005, 2006, 2009, 2010, 2012 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_CACHE_H +#define _ASM_C6X_CACHE_H + +#include <linux/irqflags.h> +#include <linux/init.h> + +/* + * Cache line size + */ +#define L1D_CACHE_SHIFT   6 +#define L1D_CACHE_BYTES   (1 << L1D_CACHE_SHIFT) + +#define L1P_CACHE_SHIFT   5 +#define L1P_CACHE_BYTES   (1 << L1P_CACHE_SHIFT) + +#define L2_CACHE_SHIFT    7 +#define L2_CACHE_BYTES    (1 << L2_CACHE_SHIFT) + +/* + * L2 used as cache + */ +#define L2MODE_SIZE	  L2MODE_256K_CACHE + +/* + * For practical reasons the L1_CACHE_BYTES defines should not be smaller than + * the L2 line size + */ +#define L1_CACHE_SHIFT        L2_CACHE_SHIFT +#define L1_CACHE_BYTES        (1 << L1_CACHE_SHIFT) + +#define L2_CACHE_ALIGN_LOW(x) \ +	(((x) & ~(L2_CACHE_BYTES - 1))) +#define L2_CACHE_ALIGN_UP(x) \ +	(((x) + (L2_CACHE_BYTES - 1)) & ~(L2_CACHE_BYTES - 1)) +#define L2_CACHE_ALIGN_CNT(x) \ +	(((x) + (sizeof(int) - 1)) & ~(sizeof(int) - 1)) + +#define ARCH_DMA_MINALIGN	L1_CACHE_BYTES +#define ARCH_SLAB_MINALIGN	L1_CACHE_BYTES + +/* + * This is the granularity of hardware cacheability control. + */ +#define CACHEABILITY_ALIGN	0x01000000 + +/* + * Align a physical address to MAR regions + */ +#define CACHE_REGION_START(v) \ +	(((u32) (v)) & ~(CACHEABILITY_ALIGN - 1)) +#define CACHE_REGION_END(v) \ +	(((u32) (v) + (CACHEABILITY_ALIGN - 1)) & ~(CACHEABILITY_ALIGN - 1)) + +extern void __init c6x_cache_init(void); + +extern void enable_caching(unsigned long start, unsigned long end); +extern void disable_caching(unsigned long start, unsigned long end); + +extern void L1_cache_off(void); +extern void L1_cache_on(void); + +extern void L1P_cache_global_invalidate(void); +extern void L1D_cache_global_invalidate(void); +extern void L1D_cache_global_writeback(void); +extern void L1D_cache_global_writeback_invalidate(void); +extern void L2_cache_set_mode(unsigned int mode); +extern void L2_cache_global_writeback_invalidate(void); +extern void L2_cache_global_writeback(void); + +extern void L1P_cache_block_invalidate(unsigned int start, unsigned int end); +extern void L1D_cache_block_invalidate(unsigned int start, unsigned int end); +extern void L1D_cache_block_writeback_invalidate(unsigned int start, +						 unsigned int end); +extern void L1D_cache_block_writeback(unsigned int start, unsigned int end); +extern void L2_cache_block_invalidate(unsigned int start, unsigned int end); +extern void L2_cache_block_writeback(unsigned int start, unsigned int end); +extern void L2_cache_block_writeback_invalidate(unsigned int start, +						unsigned int end); +extern void L2_cache_block_invalidate_nowait(unsigned int start, +					     unsigned int end); +extern void L2_cache_block_writeback_nowait(unsigned int start, +					    unsigned int end); + +extern void L2_cache_block_writeback_invalidate_nowait(unsigned int start, +						       unsigned int end); + +#endif /* _ASM_C6X_CACHE_H */ diff --git a/arch/c6x/include/asm/cacheflush.h b/arch/c6x/include/asm/cacheflush.h new file mode 100644 index 00000000000..df5db90dbe5 --- /dev/null +++ b/arch/c6x/include/asm/cacheflush.h @@ -0,0 +1,65 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_CACHEFLUSH_H +#define _ASM_C6X_CACHEFLUSH_H + +#include <linux/spinlock.h> + +#include <asm/setup.h> +#include <asm/cache.h> +#include <asm/mman.h> +#include <asm/page.h> +#include <asm/string.h> + +/* + * virtually-indexed cache management (our cache is physically indexed) + */ +#define flush_cache_all()			do {} while (0) +#define flush_cache_mm(mm)			do {} while (0) +#define flush_cache_dup_mm(mm)			do {} while (0) +#define flush_cache_range(mm, start, end)	do {} while (0) +#define flush_cache_page(vma, vmaddr, pfn)	do {} while (0) +#define flush_cache_vmap(start, end)		do {} while (0) +#define flush_cache_vunmap(start, end)		do {} while (0) +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 +#define flush_dcache_page(page)			do {} while (0) +#define flush_dcache_mmap_lock(mapping)		do {} while (0) +#define flush_dcache_mmap_unlock(mapping)	do {} while (0) + +/* + * physically-indexed cache management + */ +#define flush_icache_range(s, e)				  \ +do {								  \ +		L1D_cache_block_writeback((s), (e));		  \ +		L1P_cache_block_invalidate((s), (e));		  \ +} while (0) + +#define flush_icache_page(vma, page)					  \ +do {								  \ +	if ((vma)->vm_flags & PROT_EXEC)				  \ +		L1D_cache_block_writeback_invalidate(page_address(page),  \ +			(unsigned long) page_address(page) + PAGE_SIZE)); \ +		L1P_cache_block_invalidate(page_address(page),		  \ +			(unsigned long) page_address(page) + PAGE_SIZE)); \ +} while (0) + + +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ +do {						     \ +	memcpy(dst, src, len);			     \ +	flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \ +} while (0) + +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ +	memcpy(dst, src, len) + +#endif /* _ASM_C6X_CACHEFLUSH_H */ diff --git a/arch/c6x/include/asm/checksum.h b/arch/c6x/include/asm/checksum.h new file mode 100644 index 00000000000..7246816d6e4 --- /dev/null +++ b/arch/c6x/include/asm/checksum.h @@ -0,0 +1,34 @@ +/* + *  Copyright (C) 2011 Texas Instruments Incorporated + *  Author: Mark Salter <msalter@redhat.com> + * + *  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. + */ +#ifndef _ASM_C6X_CHECKSUM_H +#define _ASM_C6X_CHECKSUM_H + +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, +		   unsigned short proto, __wsum sum) +{ +	unsigned long long tmp; + +	asm ("add     .d1   %1,%5,%1\n" +	     "|| addu .l1   %3,%4,%0\n" +	     "addu    .l1   %2,%0,%0\n" +#ifndef CONFIG_CPU_BIG_ENDIAN +	     "|| shl  .s1   %1,8,%1\n" +#endif +	     "addu    .l1   %1,%0,%0\n" +	     "add     .l1   %P0,%p0,%2\n" +	     : "=&a"(tmp), "+a"(len), "+a"(sum) +	     : "a" (saddr), "a" (daddr), "a" (proto)); +	return sum; +} +#define csum_tcpudp_nofold csum_tcpudp_nofold + +#include <asm-generic/checksum.h> + +#endif /* _ASM_C6X_CHECKSUM_H */ diff --git a/arch/c6x/include/asm/clkdev.h b/arch/c6x/include/asm/clkdev.h new file mode 100644 index 00000000000..76a070b1c2e --- /dev/null +++ b/arch/c6x/include/asm/clkdev.h @@ -0,0 +1,22 @@ +#ifndef _ASM_CLKDEV_H +#define _ASM_CLKDEV_H + +#include <linux/slab.h> + +struct clk; + +static inline int __clk_get(struct clk *clk) +{ +	return 1; +} + +static inline void __clk_put(struct clk *clk) +{ +} + +static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) +{ +	return kzalloc(size, GFP_KERNEL); +} + +#endif /* _ASM_CLKDEV_H */ diff --git a/arch/c6x/include/asm/clock.h b/arch/c6x/include/asm/clock.h new file mode 100644 index 00000000000..bcf42b2b4b1 --- /dev/null +++ b/arch/c6x/include/asm/clock.h @@ -0,0 +1,148 @@ +/* + * TI C64X clock definitions + * + * Copyright (C) 2010, 2011 Texas Instruments. + * Contributed by: Mark Salter <msalter@redhat.com> + * + * Copied heavily from arm/mach-davinci/clock.h, so: + * + * Copyright (C) 2006-2007 Texas Instruments. + * Copyright (C) 2008-2009 Deep Root Systems, LLC + * + * 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. + */ + +#ifndef _ASM_C6X_CLOCK_H +#define _ASM_C6X_CLOCK_H + +#ifndef __ASSEMBLER__ + +#include <linux/list.h> + +/* PLL/Reset register offsets */ +#define PLLCTL		0x100 +#define PLLM		0x110 +#define PLLPRE		0x114 +#define PLLDIV1		0x118 +#define PLLDIV2		0x11c +#define PLLDIV3		0x120 +#define PLLPOST		0x128 +#define PLLCMD		0x138 +#define PLLSTAT		0x13c +#define PLLALNCTL	0x140 +#define PLLDCHANGE	0x144 +#define PLLCKEN		0x148 +#define PLLCKSTAT	0x14c +#define PLLSYSTAT	0x150 +#define PLLDIV4		0x160 +#define PLLDIV5		0x164 +#define PLLDIV6		0x168 +#define PLLDIV7		0x16c +#define PLLDIV8		0x170 +#define PLLDIV9		0x174 +#define PLLDIV10	0x178 +#define PLLDIV11	0x17c +#define PLLDIV12	0x180 +#define PLLDIV13	0x184 +#define PLLDIV14	0x188 +#define PLLDIV15	0x18c +#define PLLDIV16	0x190 + +/* PLLM register bits */ +#define PLLM_PLLM_MASK	0xff +#define PLLM_VAL(x)	((x) - 1) + +/* PREDIV register bits */ +#define PLLPREDIV_EN	BIT(15) +#define PLLPREDIV_VAL(x) ((x) - 1) + +/* PLLCTL register bits */ +#define PLLCTL_PLLEN	BIT(0) +#define PLLCTL_PLLPWRDN	BIT(1) +#define PLLCTL_PLLRST	BIT(3) +#define PLLCTL_PLLDIS	BIT(4) +#define PLLCTL_PLLENSRC	BIT(5) +#define PLLCTL_CLKMODE	BIT(8) + +/* PLLCMD register bits */ +#define PLLCMD_GOSTAT	BIT(0) + +/* PLLSTAT register bits */ +#define PLLSTAT_GOSTAT	BIT(0) + +/* PLLDIV register bits */ +#define PLLDIV_EN	BIT(15) +#define PLLDIV_RATIO_MASK 0x1f +#define PLLDIV_RATIO(x) ((x) - 1) + +struct pll_data; + +struct clk { +	struct list_head	node; +	struct module		*owner; +	const char		*name; +	unsigned long		rate; +	int			usecount; +	u32			flags; +	struct clk		*parent; +	struct list_head	children;	/* list of children */ +	struct list_head	childnode;	/* parent's child list node */ +	struct pll_data		*pll_data; +	u32			div; +	unsigned long (*recalc) (struct clk *); +	int (*set_rate) (struct clk *clk, unsigned long rate); +	int (*round_rate) (struct clk *clk, unsigned long rate); +}; + +/* Clock flags: SoC-specific flags start at BIT(16) */ +#define ALWAYS_ENABLED		BIT(1) +#define CLK_PLL			BIT(2) /* PLL-derived clock */ +#define PRE_PLL			BIT(3) /* source is before PLL mult/div */ +#define FIXED_DIV_PLL		BIT(4) /* fixed divisor from PLL */ +#define FIXED_RATE_PLL		BIT(5) /* fixed ouput rate PLL */ + +#define MAX_PLL_SYSCLKS 16 + +struct pll_data { +	void __iomem *base; +	u32 num; +	u32 flags; +	u32 input_rate; +	u32 bypass_delay; /* in loops */ +	u32 reset_delay;  /* in loops */ +	u32 lock_delay;   /* in loops */ +	struct clk sysclks[MAX_PLL_SYSCLKS + 1]; +}; + +/* pll_data flag bit */ +#define PLL_HAS_PRE	BIT(0) +#define PLL_HAS_MUL	BIT(1) +#define PLL_HAS_POST	BIT(2) + +#define CLK(dev, con, ck)	\ +	{			\ +		.dev_id = dev,	\ +		.con_id = con,	\ +		.clk = ck,	\ +	}			\ + +extern void c6x_clks_init(struct clk_lookup *clocks); +extern int clk_register(struct clk *clk); +extern void clk_unregister(struct clk *clk); +extern void c64x_setup_clocks(void); + +extern struct pll_data c6x_soc_pll1; + +extern struct clk clkin1; +extern struct clk c6x_core_clk; +extern struct clk c6x_i2c_clk; +extern struct clk c6x_watchdog_clk; +extern struct clk c6x_mcbsp1_clk; +extern struct clk c6x_mcbsp2_clk; +extern struct clk c6x_mdio_clk; + +#endif + +#endif /* _ASM_C6X_CLOCK_H */ diff --git a/arch/c6x/include/asm/cmpxchg.h b/arch/c6x/include/asm/cmpxchg.h new file mode 100644 index 00000000000..b27c8cefb8c --- /dev/null +++ b/arch/c6x/include/asm/cmpxchg.h @@ -0,0 +1,68 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_CMPXCHG_H +#define _ASM_C6X_CMPXCHG_H + +#include <linux/irqflags.h> + +/* + * Misc. functions + */ +static inline unsigned int __xchg(unsigned int x, volatile void *ptr, int size) +{ +	unsigned int tmp; +	unsigned long flags; + +	local_irq_save(flags); + +	switch (size) { +	case 1: +		tmp = 0; +		tmp = *((unsigned char *) ptr); +		*((unsigned char *) ptr) = (unsigned char) x; +		break; +	case 2: +		tmp = 0; +		tmp = *((unsigned short *) ptr); +		*((unsigned short *) ptr) = x; +		break; +	case 4: +		tmp = 0; +		tmp = *((unsigned int *) ptr); +		*((unsigned int *) ptr) = x; +		break; +	} +	local_irq_restore(flags); +	return tmp; +} + +#define xchg(ptr, x) \ +	((__typeof__(*(ptr)))__xchg((unsigned int)(x), (void *) (ptr), \ +				    sizeof(*(ptr)))) +#define tas(ptr)    xchg((ptr), 1) + + +#include <asm-generic/cmpxchg-local.h> + +/* + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make + * them available. + */ +#define cmpxchg_local(ptr, o, n)					\ +	((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr),		\ +						     (unsigned long)(o), \ +						     (unsigned long)(n), \ +						     sizeof(*(ptr)))) +#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) + +#include <asm-generic/cmpxchg.h> + +#endif /* _ASM_C6X_CMPXCHG_H */ diff --git a/arch/c6x/include/asm/delay.h b/arch/c6x/include/asm/delay.h new file mode 100644 index 00000000000..f314c2e9eb5 --- /dev/null +++ b/arch/c6x/include/asm/delay.h @@ -0,0 +1,67 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_DELAY_H +#define _ASM_C6X_DELAY_H + +#include <linux/kernel.h> + +extern unsigned int ticks_per_ns_scaled; + +static inline void __delay(unsigned long loops) +{ +	uint32_t tmp; + +	/* 6 cycles per loop */ +	asm volatile ("        mv    .s1  %0,%1\n" +		      "0: [%1] b     .s1  0b\n" +		      "        add   .l1  -6,%0,%0\n" +		      "        cmplt .l1  1,%0,%1\n" +		      "        nop   3\n" +		      : "+a"(loops), "=A"(tmp)); +} + +static inline void _c6x_tickdelay(unsigned int x) +{ +	uint32_t cnt, endcnt; + +	asm volatile ("        mvc   .s2   TSCL,%0\n" +		      "        add   .s2x  %0,%1,%2\n" +		      " ||     mvk   .l2   1,B0\n" +		      "0: [B0] b     .s2   0b\n" +		      "        mvc   .s2   TSCL,%0\n" +		      "        sub   .s2   %0,%2,%0\n" +		      "        cmpgt .l2   0,%0,B0\n" +		      "        nop   2\n" +		      : "=b"(cnt), "+a"(x), "=b"(endcnt) : : "B0"); +} + +/* use scaled math to avoid slow division */ +#define C6X_NDELAY_SCALE 10 + +static inline void _ndelay(unsigned int n) +{ +	_c6x_tickdelay((ticks_per_ns_scaled * n) >> C6X_NDELAY_SCALE); +} + +static inline void _udelay(unsigned int n) +{ +	while (n >= 10) { +		_ndelay(10000); +		n -= 10; +	} +	while (n-- > 0) +		_ndelay(1000); +} + +#define udelay(x) _udelay((unsigned int)(x)) +#define ndelay(x) _ndelay((unsigned int)(x)) + +#endif /* _ASM_C6X_DELAY_H */ diff --git a/arch/c6x/include/asm/dma-mapping.h b/arch/c6x/include/asm/dma-mapping.h new file mode 100644 index 00000000000..88bd0d899bd --- /dev/null +++ b/arch/c6x/include/asm/dma-mapping.h @@ -0,0 +1,107 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot <aurelien.jacquiot@ti.com> + * + *  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. + * + */ +#ifndef _ASM_C6X_DMA_MAPPING_H +#define _ASM_C6X_DMA_MAPPING_H + +#include <linux/dma-debug.h> +#include <asm-generic/dma-coherent.h> + +#define dma_supported(d, m)	1 + +static inline int dma_set_mask(struct device *dev, u64 dma_mask) +{ +	if (!dev->dma_mask || !dma_supported(dev, dma_mask)) +		return -EIO; + +	*dev->dma_mask = dma_mask; + +	return 0; +} + +/* + * DMA errors are defined by all-bits-set in the DMA address. + */ +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ +	debug_dma_mapping_error(dev, dma_addr); +	return dma_addr == ~0; +} + +extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, +				 size_t size, enum dma_data_direction dir); + +extern void dma_unmap_single(struct device *dev, dma_addr_t handle, +			     size_t size, enum dma_data_direction dir); + +extern int dma_map_sg(struct device *dev, struct scatterlist *sglist, +		      int nents, enum dma_data_direction direction); + +extern void dma_unmap_sg(struct device *dev, struct scatterlist *sglist, +			 int nents, enum dma_data_direction direction); + +static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, +				      unsigned long offset, size_t size, +				      enum dma_data_direction dir) +{ +	dma_addr_t handle; + +	handle = dma_map_single(dev, page_address(page) + offset, size, dir); + +	debug_dma_map_page(dev, page, offset, size, dir, handle, false); + +	return handle; +} + +static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, +		size_t size, enum dma_data_direction dir) +{ +	dma_unmap_single(dev, handle, size, dir); + +	debug_dma_unmap_page(dev, handle, size, dir, false); +} + +extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, +				    size_t size, enum dma_data_direction dir); + +extern void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, +				       size_t size, +				       enum dma_data_direction dir); + +extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, +				int nents, enum dma_data_direction dir); + +extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, +				   int nents, enum dma_data_direction dir); + +extern void coherent_mem_init(u32 start, u32 size); +extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); +extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t); + +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f)) +#define dma_free_noncoherent(d, s, v, h)  dma_free_coherent((d), (s), (v), (h)) + +/* Not supported for now */ +static inline int dma_mmap_coherent(struct device *dev, +				    struct vm_area_struct *vma, void *cpu_addr, +				    dma_addr_t dma_addr, size_t size) +{ +	return -EINVAL; +} + +static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt, +				  void *cpu_addr, dma_addr_t dma_addr, +				  size_t size) +{ +	return -EINVAL; +} + +#endif	/* _ASM_C6X_DMA_MAPPING_H */ diff --git a/arch/c6x/include/asm/dscr.h b/arch/c6x/include/asm/dscr.h new file mode 100644 index 00000000000..561ba833204 --- /dev/null +++ b/arch/c6x/include/asm/dscr.h @@ -0,0 +1,34 @@ +/* + *  Copyright (C) 2011 Texas Instruments Incorporated + *  Author: Mark Salter <msalter@redhat.com> + * + *  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. + * + */ +#ifndef _ASM_C6X_DSCR_H +#define _ASM_C6X_DSCR_H + +enum dscr_devstate_t { +	DSCR_DEVSTATE_ENABLED, +	DSCR_DEVSTATE_DISABLED, +}; + +/* + * Set the device state of the device with the given ID. + * + * Individual drivers should use this to enable or disable the + * hardware device. The devid used to identify the device being + * controlled should be a property in the device's tree node. + */ +extern void dscr_set_devstate(int devid, enum dscr_devstate_t state); + +/* + * Assert or de-assert an RMII reset. + */ +extern void dscr_rmii_reset(int id, int assert); + +extern void dscr_probe(void); + +#endif /* _ASM_C6X_DSCR_H */ diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h new file mode 100644 index 00000000000..9a4dfc5eb24 --- /dev/null +++ b/arch/c6x/include/asm/elf.h @@ -0,0 +1,123 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_ELF_H +#define _ASM_C6X_ELF_H + +/* + * ELF register definitions.. + */ +#include <asm/ptrace.h> + +typedef unsigned long elf_greg_t; +typedef unsigned long elf_fpreg_t; + +#define ELF_NGREG  58 +#define ELF_NFPREG 1 + +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x)->e_machine == EM_TI_C6000) + +#define elf_check_fdpic(x) (1) +#define elf_check_const_displacement(x) (0) + +#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map, _interp_map, _dynamic_addr) \ +do {								\ +	_regs->b4	= (_exec_map);				\ +	_regs->a6	= (_interp_map);			\ +	_regs->b6	= (_dynamic_addr);			\ +} while (0) + +#define ELF_FDPIC_CORE_EFLAGS	0 + +#define ELF_CORE_COPY_FPREGS(...) 0 /* No FPU regs to copy */ + +/* + * These are used to set parameters in the core dumps. + */ +#ifdef __LITTLE_ENDIAN__ +#define ELF_DATA	ELFDATA2LSB +#else +#define ELF_DATA	ELFDATA2MSB +#endif + +#define ELF_CLASS	ELFCLASS32 +#define ELF_ARCH	EM_TI_C6000 + +/* Nothing for now. Need to setup DP... */ +#define ELF_PLAT_INIT(_r) + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE	4096 + +#define ELF_CORE_COPY_REGS(_dest, _regs)		\ +	memcpy((char *) &_dest, (char *) _regs,		\ +	sizeof(struct pt_regs)); + +/* This yields a mask that user programs can use to figure out what +   instruction set this cpu supports.  */ + +#define ELF_HWCAP	(0) + +/* This yields a string that ld.so will use to load implementation +   specific libraries for optimization.  This is more specific in +   intent than poking at uname or /proc/cpuinfo.  */ + +#define ELF_PLATFORM  (NULL) + +/* C6X specific section types */ +#define SHT_C6000_UNWIND	0x70000001 +#define SHT_C6000_PREEMPTMAP	0x70000002 +#define SHT_C6000_ATTRIBUTES	0x70000003 + +/* C6X specific DT_ tags */ +#define DT_C6000_DSBT_BASE	0x70000000 +#define DT_C6000_DSBT_SIZE	0x70000001 +#define DT_C6000_PREEMPTMAP	0x70000002 +#define DT_C6000_DSBT_INDEX	0x70000003 + +/* C6X specific relocs */ +#define R_C6000_NONE		0 +#define R_C6000_ABS32		1 +#define R_C6000_ABS16		2 +#define R_C6000_ABS8		3 +#define R_C6000_PCR_S21		4 +#define R_C6000_PCR_S12		5 +#define R_C6000_PCR_S10		6 +#define R_C6000_PCR_S7		7 +#define R_C6000_ABS_S16		8 +#define R_C6000_ABS_L16		9 +#define R_C6000_ABS_H16		10 +#define R_C6000_SBR_U15_B	11 +#define R_C6000_SBR_U15_H	12 +#define R_C6000_SBR_U15_W	13 +#define R_C6000_SBR_S16		14 +#define R_C6000_SBR_L16_B	15 +#define R_C6000_SBR_L16_H	16 +#define R_C6000_SBR_L16_W	17 +#define R_C6000_SBR_H16_B	18 +#define R_C6000_SBR_H16_H	19 +#define R_C6000_SBR_H16_W	20 +#define R_C6000_SBR_GOT_U15_W	21 +#define R_C6000_SBR_GOT_L16_W	22 +#define R_C6000_SBR_GOT_H16_W	23 +#define R_C6000_DSBT_INDEX	24 +#define R_C6000_PREL31		25 +#define R_C6000_COPY		26 +#define R_C6000_ALIGN		253 +#define R_C6000_FPHEAD		254 +#define R_C6000_NOCMP		255 + +#endif /*_ASM_C6X_ELF_H */ diff --git a/arch/c6x/include/asm/ftrace.h b/arch/c6x/include/asm/ftrace.h new file mode 100644 index 00000000000..3701958d3d1 --- /dev/null +++ b/arch/c6x/include/asm/ftrace.h @@ -0,0 +1,6 @@ +#ifndef _ASM_C6X_FTRACE_H +#define _ASM_C6X_FTRACE_H + +/* empty */ + +#endif /* _ASM_C6X_FTRACE_H */ diff --git a/arch/c6x/include/asm/hardirq.h b/arch/c6x/include/asm/hardirq.h new file mode 100644 index 00000000000..9621954f98f --- /dev/null +++ b/arch/c6x/include/asm/hardirq.h @@ -0,0 +1,20 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ + +#ifndef _ASM_C6X_HARDIRQ_H +#define _ASM_C6X_HARDIRQ_H + +extern void ack_bad_irq(int irq); +#define ack_bad_irq ack_bad_irq + +#include <asm-generic/hardirq.h> + +#endif /* _ASM_C6X_HARDIRQ_H */ diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h new file mode 100644 index 00000000000..1324e62bd4e --- /dev/null +++ b/arch/c6x/include/asm/irq.h @@ -0,0 +1,53 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  Large parts taken directly from powerpc. + * + *  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. + */ +#ifndef _ASM_C6X_IRQ_H +#define _ASM_C6X_IRQ_H + +#include <linux/irqdomain.h> +#include <linux/threads.h> +#include <linux/list.h> +#include <linux/radix-tree.h> +#include <asm/percpu.h> + +#define irq_canonicalize(irq)  (irq) + +/* + * The C64X+ core has 16 IRQ vectors. One each is used by Reset and NMI. Two + * are reserved. The remaining 12 vectors are used to route SoC interrupts. + * These interrupt vectors are prioritized with IRQ 4 having the highest + * priority and IRQ 15 having the lowest. + * + * The C64x+ megamodule provides a PIC which combines SoC IRQ sources into a + * single core IRQ vector. There are four combined sources, each of which + * feed into one of the 12 general interrupt vectors. The remaining 8 vectors + * can each route a single SoC interrupt directly. + */ +#define NR_PRIORITY_IRQS 16 + +/* Total number of virq in the platform */ +#define NR_IRQS		256 + +/* This number is used when no interrupt has been assigned */ +#define NO_IRQ		0 + +extern void __init init_pic_c64xplus(void); + +extern void init_IRQ(void); + +struct pt_regs; + +extern asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs); + +extern unsigned long irq_err_count; + +#endif /* _ASM_C6X_IRQ_H */ diff --git a/arch/c6x/include/asm/irqflags.h b/arch/c6x/include/asm/irqflags.h new file mode 100644 index 00000000000..2c71d5634ec --- /dev/null +++ b/arch/c6x/include/asm/irqflags.h @@ -0,0 +1,72 @@ +/* + *  C6X IRQ flag handling + * + * Copyright (C) 2010 Texas Instruments Incorporated + * Written by Mark Salter (msalter@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_IRQFLAGS_H +#define _ASM_IRQFLAGS_H + +#ifndef __ASSEMBLY__ + +/* read interrupt enabled status */ +static inline unsigned long arch_local_save_flags(void) +{ +	unsigned long flags; + +	asm volatile (" mvc .s2 CSR,%0\n" : "=b"(flags)); +	return flags; +} + +/* set interrupt enabled status */ +static inline void arch_local_irq_restore(unsigned long flags) +{ +	asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags) : "memory"); +} + +/* unconditionally enable interrupts */ +static inline void arch_local_irq_enable(void) +{ +	unsigned long flags = arch_local_save_flags(); +	flags |= 1; +	arch_local_irq_restore(flags); +} + +/* unconditionally disable interrupts */ +static inline void arch_local_irq_disable(void) +{ +	unsigned long flags = arch_local_save_flags(); +	flags &= ~1; +	arch_local_irq_restore(flags); +} + +/* get status and disable interrupts */ +static inline unsigned long arch_local_irq_save(void) +{ +	unsigned long flags; + +	flags = arch_local_save_flags(); +	arch_local_irq_restore(flags & ~1); +	return flags; +} + +/* test flags */ +static inline int arch_irqs_disabled_flags(unsigned long flags) +{ +	return (flags & 1) == 0; +} + +/* test hardware interrupt enable bit */ +static inline int arch_irqs_disabled(void) +{ +	return arch_irqs_disabled_flags(arch_local_save_flags()); +} + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_IRQFLAGS_H */ diff --git a/arch/c6x/include/asm/linkage.h b/arch/c6x/include/asm/linkage.h new file mode 100644 index 00000000000..376925c47d5 --- /dev/null +++ b/arch/c6x/include/asm/linkage.h @@ -0,0 +1,30 @@ +#ifndef _ASM_C6X_LINKAGE_H +#define _ASM_C6X_LINKAGE_H + +#ifdef __ASSEMBLER__ + +#define __ALIGN		.align 2 +#define __ALIGN_STR	".align 2" + +#ifndef __DSBT__ +#define ENTRY(name)		\ +	.global name @		\ +	__ALIGN @		\ +name: +#else +#define ENTRY(name)		\ +	.global name @		\ +	.hidden name @		\ +	__ALIGN @		\ +name: +#endif + +#define ENDPROC(name)		\ +	.type name, @function @	\ +	.size name, . - name + +#endif + +#include <asm-generic/linkage.h> + +#endif /* _ASM_C6X_LINKAGE_H */ diff --git a/arch/c6x/include/asm/megamod-pic.h b/arch/c6x/include/asm/megamod-pic.h new file mode 100644 index 00000000000..eca0a867803 --- /dev/null +++ b/arch/c6x/include/asm/megamod-pic.h @@ -0,0 +1,9 @@ +#ifndef _C6X_MEGAMOD_PIC_H +#define _C6X_MEGAMOD_PIC_H + +#ifdef __KERNEL__ + +extern void __init megamod_pic_init(void); + +#endif /* __KERNEL__ */ +#endif /* _C6X_MEGAMOD_PIC_H */ diff --git a/arch/c6x/include/asm/module.h b/arch/c6x/include/asm/module.h new file mode 100644 index 00000000000..5c7269c7ef7 --- /dev/null +++ b/arch/c6x/include/asm/module.h @@ -0,0 +1,23 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  Updated for 2.6.34 by: Mark Salter (msalter@redhat.com) + * + *  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. + */ +#ifndef _ASM_C6X_MODULE_H +#define _ASM_C6X_MODULE_H + +#include <asm-generic/module.h> + +struct loaded_sections { +	unsigned int new_vaddr; +	unsigned int loaded; +}; + +#endif /* _ASM_C6X_MODULE_H */ diff --git a/arch/c6x/include/asm/mutex.h b/arch/c6x/include/asm/mutex.h new file mode 100644 index 00000000000..7a7248e0462 --- /dev/null +++ b/arch/c6x/include/asm/mutex.h @@ -0,0 +1,6 @@ +#ifndef _ASM_C6X_MUTEX_H +#define _ASM_C6X_MUTEX_H + +#include <asm-generic/mutex-null.h> + +#endif /* _ASM_C6X_MUTEX_H */ diff --git a/arch/c6x/include/asm/page.h b/arch/c6x/include/asm/page.h new file mode 100644 index 00000000000..d18e2b0c7ae --- /dev/null +++ b/arch/c6x/include/asm/page.h @@ -0,0 +1,11 @@ +#ifndef _ASM_C6X_PAGE_H +#define _ASM_C6X_PAGE_H + +#define VM_DATA_DEFAULT_FLAGS \ +	(VM_READ | VM_WRITE | \ +	((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ +		 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#include <asm-generic/page.h> + +#endif /* _ASM_C6X_PAGE_H */ diff --git a/arch/c6x/include/asm/pgtable.h b/arch/c6x/include/asm/pgtable.h new file mode 100644 index 00000000000..c0eed5b1886 --- /dev/null +++ b/arch/c6x/include/asm/pgtable.h @@ -0,0 +1,77 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_PGTABLE_H +#define _ASM_C6X_PGTABLE_H + +#include <asm-generic/4level-fixup.h> + +#include <asm/setup.h> +#include <asm/page.h> + +/* + * All 32bit addresses are effectively valid for vmalloc... + * Sort of meaningless for non-VM targets. + */ +#define	VMALLOC_START	0 +#define	VMALLOC_END	0xffffffff + +#define pgd_present(pgd)	(1) +#define pgd_none(pgd)		(0) +#define pgd_bad(pgd)		(0) +#define pgd_clear(pgdp) +#define kern_addr_valid(addr) (1) + +#define pmd_offset(a, b)	((void *)0) +#define pmd_none(x)		(!pmd_val(x)) +#define pmd_present(x)		(pmd_val(x)) +#define pmd_clear(xp)		do { set_pmd(xp, __pmd(0)); } while (0) +#define pmd_bad(x)		(pmd_val(x) & ~PAGE_MASK) + +#define PAGE_NONE		__pgprot(0)    /* these mean nothing to NO_MM */ +#define PAGE_SHARED		__pgprot(0)    /* these mean nothing to NO_MM */ +#define PAGE_COPY		__pgprot(0)    /* these mean nothing to NO_MM */ +#define PAGE_READONLY	        __pgprot(0)    /* these mean nothing to NO_MM */ +#define PAGE_KERNEL		__pgprot(0)    /* these mean nothing to NO_MM */ +#define pgprot_noncached(prot)	(prot) + +extern void paging_init(void); + +#define __swp_type(x)		(0) +#define __swp_offset(x)		(0) +#define __swp_entry(typ, off)	((swp_entry_t) { ((typ) | ((off) << 7)) }) +#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x)	((pte_t) { (x).val }) + +static inline int pte_file(pte_t pte) +{ +	return 0; +} + +#define set_pte(pteptr, pteval) (*(pteptr) = pteval) +#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#define ZERO_PAGE(vaddr)	virt_to_page(empty_zero_page) +extern unsigned long empty_zero_page; + +#define swapper_pg_dir ((pgd_t *) 0) + +/* + * No page table caches to initialise + */ +#define pgtable_cache_init()   do { } while (0) + +#include <asm-generic/pgtable.h> + +#endif /* _ASM_C6X_PGTABLE_H */ diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h new file mode 100644 index 00000000000..b9eb3da7f27 --- /dev/null +++ b/arch/c6x/include/asm/processor.h @@ -0,0 +1,136 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  Updated for 2.6.34: Mark Salter <msalter@redhat.com> + * + *  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. + */ +#ifndef _ASM_C6X_PROCESSOR_H +#define _ASM_C6X_PROCESSOR_H + +#include <asm/ptrace.h> +#include <asm/page.h> +#include <asm/current.h> + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr()			\ +({						\ +	void *__pc;				\ +	asm("mvc .S2 pce1,%0\n" : "=b"(__pc));	\ +	__pc;					\ +}) + +/* + * User space process size. This is mostly meaningless for NOMMU + * but some C6X processors may have RAM addresses up to 0xFFFFFFFF. + * Since calls like mmap() can return an address or an error, we + * have to allow room for error returns when code does something + * like: + * + *       addr = do_mmap(...) + *       if ((unsigned long)addr >= TASK_SIZE) + *            ... its an error code, not an address ... + * + * Here, we allow for 4096 error codes which means we really can't + * use the last 4K page on systems with RAM extending all the way + * to the end of the 32-bit address space. + */ +#define TASK_SIZE	0xFFFFF000 + +/* + * This decides where the kernel will search for a free chunk of vm + * space during mmap's. We won't be using it + */ +#define TASK_UNMAPPED_BASE	0 + +struct thread_struct { +	unsigned long long b15_14; +	unsigned long long a15_14; +	unsigned long long b13_12; +	unsigned long long a13_12; +	unsigned long long b11_10; +	unsigned long long a11_10; +	unsigned long long ricl_icl; +	unsigned long  usp;		/* user stack pointer */ +	unsigned long  pc;		/* kernel pc */ +	unsigned long  wchan; +}; + +#define INIT_THREAD					\ +{							\ +	.usp = 0,					\ +	.wchan = 0,					\ +} + +#define INIT_MMAP { \ +	&init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, \ +	NULL, NULL } + +#define task_pt_regs(task) \ +	((struct pt_regs *)(THREAD_START_SP + task_stack_page(task)) - 1) + +#define alloc_kernel_stack()	__get_free_page(GFP_KERNEL) +#define free_kernel_stack(page) free_page((page)) + + +/* Forward declaration, a strange C thing */ +struct task_struct; + +extern void start_thread(struct pt_regs *regs, unsigned int pc, +			 unsigned long usp); + +/* Free all resources held by a thread. */ +static inline void release_thread(struct task_struct *dead_task) +{ +} + +#define copy_segments(tsk, mm)		do { } while (0) +#define release_segments(mm)		do { } while (0) + +/* + * saved PC of a blocked thread. + */ +#define thread_saved_pc(tsk) (task_pt_regs(tsk)->pc) + +/* + * saved kernel SP and DP of a blocked thread. + */ +#ifdef _BIG_ENDIAN +#define thread_saved_ksp(tsk) \ +	(*(unsigned long *)&(tsk)->thread.b15_14) +#define thread_saved_dp(tsk) \ +	(*(((unsigned long *)&(tsk)->thread.b15_14) + 1)) +#else +#define thread_saved_ksp(tsk) \ +	(*(((unsigned long *)&(tsk)->thread.b15_14) + 1)) +#define thread_saved_dp(tsk) \ +	(*(unsigned long *)&(tsk)->thread.b15_14) +#endif + +extern unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(task)	(task_pt_regs(task)->pc) +#define KSTK_ESP(task)	(task_pt_regs(task)->sp) + +#define cpu_relax()		do { } while (0) + +extern const struct seq_operations cpuinfo_op; + +/* Reset the board */ +#define HARD_RESET_NOW() + +extern unsigned int c6x_core_freq; + + +extern void (*c6x_restart)(void); +extern void (*c6x_halt)(void); + +#endif /* ASM_C6X_PROCESSOR_H */ diff --git a/arch/c6x/include/asm/procinfo.h b/arch/c6x/include/asm/procinfo.h new file mode 100644 index 00000000000..c139d1e71f8 --- /dev/null +++ b/arch/c6x/include/asm/procinfo.h @@ -0,0 +1,28 @@ +/* + *  Copyright (C) 2010 Texas Instruments Incorporated + *  Author: Mark Salter (msalter@redhat.com) + * + * + * 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. + */ +#ifndef _ASM_C6X_PROCINFO_H +#define _ASM_C6X_PROCINFO_H + +#ifdef __KERNEL__ + +struct proc_info_list { +	unsigned int		cpu_val; +	unsigned int		cpu_mask; +	const char		*arch_name; +	const char		*elf_name; +	unsigned int		elf_hwcap; +}; + +#else	/* __KERNEL__ */ +#include <asm/elf.h> +#warning "Please include asm/elf.h instead" +#endif	/* __KERNEL__ */ + +#endif	/* _ASM_C6X_PROCINFO_H */ diff --git a/arch/c6x/include/asm/ptrace.h b/arch/c6x/include/asm/ptrace.h new file mode 100644 index 00000000000..76da6ad6610 --- /dev/null +++ b/arch/c6x/include/asm/ptrace.h @@ -0,0 +1,35 @@ +/* + *  Copyright (C) 2004, 2006, 2009, 2010 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  Updated for 2.6.34: Mark Salter <msalter@redhat.com> + * + *  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. + */ +#ifndef _ASM_C6X_PTRACE_H +#define _ASM_C6X_PTRACE_H + +#include <uapi/asm/ptrace.h> + +#ifndef __ASSEMBLY__ +#ifdef _BIG_ENDIAN +#else +#endif + +#include <linux/linkage.h> + +#define user_mode(regs)	((((regs)->tsr) & 0x40) != 0) + +#define instruction_pointer(regs) ((regs)->pc) +#define profile_pc(regs) instruction_pointer(regs) +#define user_stack_pointer(regs) ((regs)->sp) + +extern void show_regs(struct pt_regs *); + +extern asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs); +extern asmlinkage void syscall_trace_exit(struct pt_regs *regs); + +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_C6X_PTRACE_H */ diff --git a/arch/c6x/include/asm/sections.h b/arch/c6x/include/asm/sections.h new file mode 100644 index 00000000000..f703989d837 --- /dev/null +++ b/arch/c6x/include/asm/sections.h @@ -0,0 +1,12 @@ +#ifndef _ASM_C6X_SECTIONS_H +#define _ASM_C6X_SECTIONS_H + +#include <asm-generic/sections.h> + +extern char _vectors_start[]; +extern char _vectors_end[]; + +extern char _data_lma[]; +extern char _fdt_start[], _fdt_end[]; + +#endif /* _ASM_C6X_SECTIONS_H */ diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h new file mode 100644 index 00000000000..696804475f5 --- /dev/null +++ b/arch/c6x/include/asm/setup.h @@ -0,0 +1,31 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_SETUP_H +#define _ASM_C6X_SETUP_H + +#include <uapi/asm/setup.h> + +#ifndef __ASSEMBLY__ +extern int c6x_add_memory(phys_addr_t start, unsigned long size); + +extern unsigned long ram_start; +extern unsigned long ram_end; + +extern int c6x_num_cores; +extern unsigned int c6x_silicon_rev; +extern unsigned int c6x_devstat; +extern unsigned char c6x_fuse_mac[6]; + +extern void machine_init(unsigned long dt_ptr); +extern void time_init(void); + +#endif /* !__ASSEMBLY__ */ +#endif /* _ASM_C6X_SETUP_H */ diff --git a/arch/c6x/include/asm/soc.h b/arch/c6x/include/asm/soc.h new file mode 100644 index 00000000000..43f50159e59 --- /dev/null +++ b/arch/c6x/include/asm/soc.h @@ -0,0 +1,35 @@ +/* + * Miscellaneous SoC-specific hooks. + * + * Copyright (C) 2011 Texas Instruments Incorporated + * + * Author: Mark Salter <msalter@redhat.com> + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +#ifndef _ASM_C6X_SOC_H +#define _ASM_C6X_SOC_H + +struct soc_ops { +	/* Return active exception event or -1 if none */ +	int		(*get_exception)(void); + +	/* Assert an event */ +	void		(*assert_event)(unsigned int evt); +}; + +extern struct soc_ops soc_ops; + +extern int soc_get_exception(void); +extern void soc_assert_event(unsigned int event); +extern int soc_mac_addr(unsigned int index, u8 *addr); + +/* + * for mmio on SoC devices. regs are always same byte order as cpu. + */ +#define soc_readl(addr)    __raw_readl(addr) +#define soc_writel(b, addr) __raw_writel((b), (addr)) + +#endif /* _ASM_C6X_SOC_H */ diff --git a/arch/c6x/include/asm/special_insns.h b/arch/c6x/include/asm/special_insns.h new file mode 100644 index 00000000000..59672bca841 --- /dev/null +++ b/arch/c6x/include/asm/special_insns.h @@ -0,0 +1,63 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_SPECIAL_INSNS_H +#define _ASM_C6X_SPECIAL_INSNS_H + + +#define get_creg(reg) \ +	({ unsigned int __x; \ +	   asm volatile ("mvc .s2 " #reg ",%0\n" : "=b"(__x)); __x; }) + +#define set_creg(reg, v) \ +	do { unsigned int __x = (unsigned int)(v); \ +		asm volatile ("mvc .s2 %0," #reg "\n" : : "b"(__x)); \ +	} while (0) + +#define or_creg(reg, n) \ +	do { unsigned __x, __n = (unsigned)(n);		  \ +		asm volatile ("mvc .s2 " #reg ",%0\n"	  \ +			      "or  .l2 %1,%0,%0\n"	  \ +			      "mvc .s2 %0," #reg "\n"	  \ +			      "nop\n"			  \ +			      : "=&b"(__x) : "b"(__n));	  \ +	} while (0) + +#define and_creg(reg, n) \ +	do { unsigned __x, __n = (unsigned)(n);		  \ +		asm volatile ("mvc .s2 " #reg ",%0\n"	  \ +			      "and .l2 %1,%0,%0\n"	  \ +			      "mvc .s2 %0," #reg "\n"	  \ +			      "nop\n"    \ +			      : "=&b"(__x) : "b"(__n));	  \ +	} while (0) + +#define get_coreid() (get_creg(DNUM) & 0xff) + +/* Set/get IST */ +#define set_ist(x)	set_creg(ISTP, x) +#define get_ist()       get_creg(ISTP) + +/* + * Exception management + */ +#define disable_exception() +#define get_except_type()        get_creg(EFR) +#define ack_exception(type)      set_creg(ECR, 1 << (type)) +#define get_iexcept()            get_creg(IERR) +#define set_iexcept(mask)        set_creg(IERR, (mask)) + +#define _extu(x, s, e)							\ +	({      unsigned int __x;					\ +		asm volatile ("extu .S2 %3,%1,%2,%0\n" :		\ +			      "=b"(__x) : "n"(s), "n"(e), "b"(x));	\ +	       __x; }) + +#endif /* _ASM_C6X_SPECIAL_INSNS_H */ diff --git a/arch/c6x/include/asm/string.h b/arch/c6x/include/asm/string.h new file mode 100644 index 00000000000..b21517c80a1 --- /dev/null +++ b/arch/c6x/include/asm/string.h @@ -0,0 +1,21 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_STRING_H +#define _ASM_C6X_STRING_H + +#include <asm/page.h> +#include <linux/linkage.h> + +asmlinkage extern void *memcpy(void *to, const void *from, size_t n); + +#define __HAVE_ARCH_MEMCPY + +#endif /* _ASM_C6X_STRING_H */ diff --git a/arch/c6x/include/asm/switch_to.h b/arch/c6x/include/asm/switch_to.h new file mode 100644 index 00000000000..af6c71fe75e --- /dev/null +++ b/arch/c6x/include/asm/switch_to.h @@ -0,0 +1,33 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_SWITCH_TO_H +#define _ASM_C6X_SWITCH_TO_H + +#include <linux/linkage.h> + +#define prepare_to_switch()    do { } while (0) + +struct task_struct; +struct thread_struct; +asmlinkage void *__switch_to(struct thread_struct *prev, +			     struct thread_struct *next, +			     struct task_struct *tsk); + +#define switch_to(prev, next, last)				\ +	do {							\ +		current->thread.wchan = (u_long) __builtin_return_address(0); \ +		(last) = __switch_to(&(prev)->thread,		\ +				     &(next)->thread, (prev));	\ +		mb();						\ +		current->thread.wchan = 0;			\ +	} while (0) + +#endif /* _ASM_C6X_SWITCH_TO_H */ diff --git a/arch/c6x/include/asm/syscall.h b/arch/c6x/include/asm/syscall.h new file mode 100644 index 00000000000..ae2be315ee9 --- /dev/null +++ b/arch/c6x/include/asm/syscall.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter <msalter@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __ASM_C6X_SYSCALL_H +#define __ASM_C6X_SYSCALL_H + +#include <linux/err.h> +#include <linux/sched.h> + +static inline int syscall_get_nr(struct task_struct *task, +				 struct pt_regs *regs) +{ +	return regs->b0; +} + +static inline void syscall_rollback(struct task_struct *task, +				    struct pt_regs *regs) +{ +	/* do nothing */ +} + +static inline long syscall_get_error(struct task_struct *task, +				     struct pt_regs *regs) +{ +	return IS_ERR_VALUE(regs->a4) ? regs->a4 : 0; +} + +static inline long syscall_get_return_value(struct task_struct *task, +					    struct pt_regs *regs) +{ +	return regs->a4; +} + +static inline void syscall_set_return_value(struct task_struct *task, +					    struct pt_regs *regs, +					    int error, long val) +{ +	regs->a4 = error ?: val; +} + +static inline void syscall_get_arguments(struct task_struct *task, +					 struct pt_regs *regs, unsigned int i, +					 unsigned int n, unsigned long *args) +{ +	switch (i) { +	case 0: +		if (!n--) +			break; +		*args++ = regs->a4; +	case 1: +		if (!n--) +			break; +		*args++ = regs->b4; +	case 2: +		if (!n--) +			break; +		*args++ = regs->a6; +	case 3: +		if (!n--) +			break; +		*args++ = regs->b6; +	case 4: +		if (!n--) +			break; +		*args++ = regs->a8; +	case 5: +		if (!n--) +			break; +		*args++ = regs->b8; +	case 6: +		if (!n--) +			break; +	default: +		BUG(); +	} +} + +static inline void syscall_set_arguments(struct task_struct *task, +					 struct pt_regs *regs, +					 unsigned int i, unsigned int n, +					 const unsigned long *args) +{ +	switch (i) { +	case 0: +		if (!n--) +			break; +		regs->a4 = *args++; +	case 1: +		if (!n--) +			break; +		regs->b4 = *args++; +	case 2: +		if (!n--) +			break; +		regs->a6 = *args++; +	case 3: +		if (!n--) +			break; +		regs->b6 = *args++; +	case 4: +		if (!n--) +			break; +		regs->a8 = *args++; +	case 5: +		if (!n--) +			break; +		regs->a9 = *args++; +	case 6: +		if (!n) +			break; +	default: +		BUG(); +	} +} + +#endif /* __ASM_C6X_SYSCALLS_H */ diff --git a/arch/c6x/include/asm/syscalls.h b/arch/c6x/include/asm/syscalls.h new file mode 100644 index 00000000000..df3d05feb15 --- /dev/null +++ b/arch/c6x/include/asm/syscalls.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated + * Author: Mark Salter <msalter@redhat.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT.  See the GNU General Public License for + * more details. + */ + +#ifndef __ASM_C6X_SYSCALLS_H +#define __ASM_C6X_SYSCALLS_H + +#include <linux/compiler.h> +#include <linux/linkage.h> +#include <linux/types.h> + +/* The array of function pointers for syscalls. */ +extern void *sys_call_table[]; + +/* The following are trampolines in entry.S to handle 64-bit arguments */ +extern long sys_pread_c6x(unsigned int fd, char __user *buf, +			  size_t count, off_t pos_low, off_t pos_high); +extern long sys_pwrite_c6x(unsigned int fd, const char __user *buf, +			   size_t count, off_t pos_low, off_t pos_high); +extern long sys_truncate64_c6x(const char __user *path, +			       off_t length_low, off_t length_high); +extern long sys_ftruncate64_c6x(unsigned int fd, +			       off_t length_low, off_t length_high); +extern long sys_fadvise64_c6x(int fd, u32 offset_lo, u32 offset_hi, +			      u32 len, int advice); +extern long sys_fadvise64_64_c6x(int fd, u32 offset_lo, u32 offset_hi, +				u32 len_lo, u32 len_hi, int advice); +extern long sys_fallocate_c6x(int fd, int mode, +			      u32 offset_lo, u32 offset_hi, +			      u32 len_lo, u32 len_hi); +extern int sys_cache_sync(unsigned long s, unsigned long e); + +#include <asm-generic/syscalls.h> + +#endif /* __ASM_C6X_SYSCALLS_H */ diff --git a/arch/c6x/include/asm/thread_info.h b/arch/c6x/include/asm/thread_info.h new file mode 100644 index 00000000000..d4e9ef87076 --- /dev/null +++ b/arch/c6x/include/asm/thread_info.h @@ -0,0 +1,105 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  Updated for 2.6.3x: Mark Salter <msalter@redhat.com> + * + *  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. + */ +#ifndef _ASM_C6X_THREAD_INFO_H +#define _ASM_C6X_THREAD_INFO_H + +#ifdef __KERNEL__ + +#include <asm/page.h> + +#ifdef CONFIG_4KSTACKS +#define THREAD_SIZE		4096 +#define THREAD_SHIFT		12 +#define THREAD_SIZE_ORDER	0 +#else +#define THREAD_SIZE		8192 +#define THREAD_SHIFT		13 +#define THREAD_SIZE_ORDER	1 +#endif + +#define THREAD_START_SP		(THREAD_SIZE - 8) + +#ifndef __ASSEMBLY__ + +typedef struct { +	unsigned long seg; +} mm_segment_t; + +/* + * low level task data. + */ +struct thread_info { +	struct task_struct	*task;		/* main task structure */ +	struct exec_domain	*exec_domain;	/* execution domain */ +	unsigned long		flags;		/* low level flags */ +	int			cpu;		/* cpu we're on */ +	int			preempt_count;	/* 0 = preemptable, <0 = BUG */ +	mm_segment_t		addr_limit;	/* thread address space */ +	struct restart_block	restart_block; +}; + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ +#define INIT_THREAD_INFO(tsk)			\ +{						\ +	.task		= &tsk,			\ +	.exec_domain	= &default_exec_domain,	\ +	.flags		= 0,			\ +	.cpu		= 0,			\ +	.preempt_count	= INIT_PREEMPT_COUNT,	\ +	.addr_limit	= KERNEL_DS,		\ +	.restart_block	= {			\ +		.fn = do_no_restart_syscall,	\ +	},					\ +} + +#define init_thread_info	(init_thread_union.thread_info) +#define init_stack		(init_thread_union.stack) + +/* get the thread information struct of current task */ +static inline __attribute__((const)) +struct thread_info *current_thread_info(void) +{ +	struct thread_info *ti; +	asm volatile (" clr   .s2 B15,0,%1,%0\n" +		      : "=b" (ti) +		      : "Iu5" (THREAD_SHIFT - 1)); +	return ti; +} + +#define get_thread_info(ti)	get_task_struct((ti)->task) +#define put_thread_info(ti)	put_task_struct((ti)->task) +#endif /* __ASSEMBLY__ */ + +/* + * thread information flag bit numbers + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#define TIF_SYSCALL_TRACE	0	/* syscall trace active */ +#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */ +#define TIF_SIGPENDING		2	/* signal pending */ +#define TIF_NEED_RESCHED	3	/* rescheduling necessary */ +#define TIF_RESTORE_SIGMASK	4	/* restore signal mask in do_signal() */ + +#define TIF_MEMDIE		17	/* OOM killer killed process */ + +#define TIF_WORK_MASK		0x00007FFE /* work on irq/exception return */ +#define TIF_ALLWORK_MASK	0x00007FFF /* work on any return to u-space */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_C6X_THREAD_INFO_H */ diff --git a/arch/c6x/include/asm/timer64.h b/arch/c6x/include/asm/timer64.h new file mode 100644 index 00000000000..bbe27bb9887 --- /dev/null +++ b/arch/c6x/include/asm/timer64.h @@ -0,0 +1,6 @@ +#ifndef _C6X_TIMER64_H +#define _C6X_TIMER64_H + +extern void __init timer64_init(void); + +#endif /* _C6X_TIMER64_H */ diff --git a/arch/c6x/include/asm/timex.h b/arch/c6x/include/asm/timex.h new file mode 100644 index 00000000000..508c3ec971f --- /dev/null +++ b/arch/c6x/include/asm/timex.h @@ -0,0 +1,33 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  Modified for 2.6.34: Mark Salter <msalter@redhat.com> + * + *  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. + */ +#ifndef _ASM_C6X_TIMEX_H +#define _ASM_C6X_TIMEX_H + +#define CLOCK_TICK_RATE ((1000 * 1000000UL) / 6) + +/* 64-bit timestamp */ +typedef unsigned long long cycles_t; + +static inline cycles_t get_cycles(void) +{ +	unsigned l, h; + +	asm volatile (" dint\n" +		      " mvc .s2 TSCL,%0\n" +		      " mvc .s2 TSCH,%1\n" +		      " rint\n" +		      : "=b"(l), "=b"(h)); +	return ((cycles_t)h << 32) | l; +} + +#endif /* _ASM_C6X_TIMEX_H */ diff --git a/arch/c6x/include/asm/tlb.h b/arch/c6x/include/asm/tlb.h new file mode 100644 index 00000000000..8709e5e29d2 --- /dev/null +++ b/arch/c6x/include/asm/tlb.h @@ -0,0 +1,8 @@ +#ifndef _ASM_C6X_TLB_H +#define _ASM_C6X_TLB_H + +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + +#include <asm-generic/tlb.h> + +#endif /* _ASM_C6X_TLB_H */ diff --git a/arch/c6x/include/asm/traps.h b/arch/c6x/include/asm/traps.h new file mode 100644 index 00000000000..62124d7b1b5 --- /dev/null +++ b/arch/c6x/include/asm/traps.h @@ -0,0 +1,36 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2011 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + *  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. + */ +#ifndef _ASM_C6X_TRAPS_H +#define _ASM_C6X_TRAPS_H + +#define EXCEPT_TYPE_NXF   31	   /* NMI */ +#define EXCEPT_TYPE_EXC   30	   /* external exception */ +#define EXCEPT_TYPE_IXF   1	   /* internal exception */ +#define EXCEPT_TYPE_SXF   0	   /* software exception */ + +#define EXCEPT_CAUSE_LBX  (1 << 7) /* loop buffer exception */ +#define EXCEPT_CAUSE_PRX  (1 << 6) /* privilege exception */ +#define EXCEPT_CAUSE_RAX  (1 << 5) /* resource access exception */ +#define EXCEPT_CAUSE_RCX  (1 << 4) /* resource conflict exception */ +#define EXCEPT_CAUSE_OPX  (1 << 3) /* opcode exception */ +#define EXCEPT_CAUSE_EPX  (1 << 2) /* execute packet exception */ +#define EXCEPT_CAUSE_FPX  (1 << 1) /* fetch packet exception */ +#define EXCEPT_CAUSE_IFX  (1 << 0) /* instruction fetch exception */ + +struct exception_info { +	char *kernel_str; +	int  signo; +	int  code; +}; + +extern int (*c6x_nmi_handler)(struct pt_regs *regs); + +#endif /* _ASM_C6X_TRAPS_H */ diff --git a/arch/c6x/include/asm/uaccess.h b/arch/c6x/include/asm/uaccess.h new file mode 100644 index 00000000000..453dd263bee --- /dev/null +++ b/arch/c6x/include/asm/uaccess.h @@ -0,0 +1,107 @@ +/* + *  Copyright (C) 2011 Texas Instruments Incorporated + *  Author: Mark Salter <msalter@redhat.com> + * + *  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. + */ +#ifndef _ASM_C6X_UACCESS_H +#define _ASM_C6X_UACCESS_H + +#include <linux/types.h> +#include <linux/compiler.h> +#include <linux/string.h> + +#ifdef CONFIG_ACCESS_CHECK +#define __access_ok _access_ok +#endif + +/* + * __copy_from_user/copy_to_user are based on ones in asm-generic/uaccess.h + * + * C6X supports unaligned 32 and 64 bit loads and stores. + */ +static inline __must_check long __copy_from_user(void *to, +		const void __user *from, unsigned long n) +{ +	u32 tmp32; +	u64 tmp64; + +	if (__builtin_constant_p(n)) { +		switch (n) { +		case 1: +			*(u8 *)to = *(u8 __force *)from; +			return 0; +		case 4: +			asm volatile ("ldnw .d1t1 *%2,%0\n" +				      "nop  4\n" +				      "stnw .d1t1 %0,*%1\n" +				      : "=&a"(tmp32) +				      : "A"(to), "a"(from) +				      : "memory"); +			return 0; +		case 8: +			asm volatile ("ldndw .d1t1 *%2,%0\n" +				      "nop   4\n" +				      "stndw .d1t1 %0,*%1\n" +				      : "=&a"(tmp64) +				      : "a"(to), "a"(from) +				      : "memory"); +			return 0; +		default: +			break; +		} +	} + +	memcpy(to, (const void __force *)from, n); +	return 0; +} + +static inline __must_check long __copy_to_user(void __user *to, +		const void *from, unsigned long n) +{ +	u32 tmp32; +	u64 tmp64; + +	if (__builtin_constant_p(n)) { +		switch (n) { +		case 1: +			*(u8 __force *)to = *(u8 *)from; +			return 0; +		case 4: +			asm volatile ("ldnw .d1t1 *%2,%0\n" +				      "nop  4\n" +				      "stnw .d1t1 %0,*%1\n" +				      : "=&a"(tmp32) +				      : "a"(to), "a"(from) +				      : "memory"); +			return 0; +		case 8: +			asm volatile ("ldndw .d1t1 *%2,%0\n" +				      "nop   4\n" +				      "stndw .d1t1 %0,*%1\n" +				      : "=&a"(tmp64) +				      : "a"(to), "a"(from) +				      : "memory"); +			return 0; +		default: +			break; +		} +	} + +	memcpy((void __force *)to, from, n); +	return 0; +} + +#define __copy_to_user   __copy_to_user +#define __copy_from_user __copy_from_user + +extern int _access_ok(unsigned long addr, unsigned long size); +#ifdef CONFIG_ACCESS_CHECK +#define __access_ok _access_ok +#endif + +#include <asm-generic/uaccess.h> + +#endif /* _ASM_C6X_UACCESS_H */ diff --git a/arch/c6x/include/asm/unaligned.h b/arch/c6x/include/asm/unaligned.h new file mode 100644 index 00000000000..b976cb740ea --- /dev/null +++ b/arch/c6x/include/asm/unaligned.h @@ -0,0 +1,170 @@ +/* + *  Port on Texas Instruments TMS320C6x architecture + * + *  Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated + *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + *  Rewritten for 2.6.3x: Mark Salter <msalter@redhat.com> + * + *  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. + */ +#ifndef _ASM_C6X_UNALIGNED_H +#define _ASM_C6X_UNALIGNED_H + +#include <linux/swab.h> + +/* + * The C64x+ can do unaligned word and dword accesses in hardware + * using special load/store instructions. + */ + +static inline u16 get_unaligned_le16(const void *p) +{ +	const u8 *_p = p; +	return _p[0] | _p[1] << 8; +} + +static inline u16 get_unaligned_be16(const void *p) +{ +	const u8 *_p = p; +	return _p[0] << 8 | _p[1]; +} + +static inline void put_unaligned_le16(u16 val, void *p) +{ +	u8 *_p = p; +	_p[0] = val; +	_p[1] = val >> 8; +} + +static inline void put_unaligned_be16(u16 val, void *p) +{ +	u8 *_p = p; +	_p[0] = val >> 8; +	_p[1] = val; +} + +static inline u32 get_unaligned32(const void *p) +{ +	u32 val = (u32) p; +	asm (" ldnw	.d1t1	*%0,%0\n" +	     " nop     4\n" +	     : "+a"(val)); +	return val; +} + +static inline void put_unaligned32(u32 val, void *p) +{ +	asm volatile (" stnw	.d2t1	%0,*%1\n" +		      : : "a"(val), "b"(p) : "memory"); +} + +static inline u64 get_unaligned64(const void *p) +{ +	u64 val; +	asm volatile (" ldndw	.d1t1	*%1,%0\n" +		      " nop     4\n" +		      : "=a"(val) : "a"(p)); +	return val; +} + +static inline void put_unaligned64(u64 val, const void *p) +{ +	asm volatile (" stndw	.d2t1	%0,*%1\n" +		      : : "a"(val), "b"(p) : "memory"); +} + +#ifdef CONFIG_CPU_BIG_ENDIAN + +#define get_unaligned_le32(p)	 __swab32(get_unaligned32(p)) +#define get_unaligned_le64(p)	 __swab64(get_unaligned64(p)) +#define get_unaligned_be32(p)	 get_unaligned32(p) +#define get_unaligned_be64(p)	 get_unaligned64(p) +#define put_unaligned_le32(v, p) put_unaligned32(__swab32(v), (p)) +#define put_unaligned_le64(v, p) put_unaligned64(__swab64(v), (p)) +#define put_unaligned_be32(v, p) put_unaligned32((v), (p)) +#define put_unaligned_be64(v, p) put_unaligned64((v), (p)) +#define get_unaligned	__get_unaligned_be +#define put_unaligned	__put_unaligned_be + +#else + +#define get_unaligned_le32(p)	 get_unaligned32(p) +#define get_unaligned_le64(p)	 get_unaligned64(p) +#define get_unaligned_be32(p)	 __swab32(get_unaligned32(p)) +#define get_unaligned_be64(p)	 __swab64(get_unaligned64(p)) +#define put_unaligned_le32(v, p) put_unaligned32((v), (p)) +#define put_unaligned_le64(v, p) put_unaligned64((v), (p)) +#define put_unaligned_be32(v, p) put_unaligned32(__swab32(v), (p)) +#define put_unaligned_be64(v, p) put_unaligned64(__swab64(v), (p)) +#define get_unaligned	__get_unaligned_le +#define put_unaligned	__put_unaligned_le + +#endif + +/* + * Cause a link-time error if we try an unaligned access other than + * 1,2,4 or 8 bytes long + */ +extern int __bad_unaligned_access_size(void); + +#define __get_unaligned_le(ptr) (typeof(*(ptr)))({			\ +	sizeof(*(ptr)) == 1 ? *(ptr) :					\ +	  (sizeof(*(ptr)) == 2 ? get_unaligned_le16((ptr)) :		\ +	     (sizeof(*(ptr)) == 4 ? get_unaligned_le32((ptr)) :		\ +		(sizeof(*(ptr)) == 8 ? get_unaligned_le64((ptr)) :	\ +		   __bad_unaligned_access_size())));			\ +	}) + +#define __get_unaligned_be(ptr) (__force typeof(*(ptr)))({	\ +	sizeof(*(ptr)) == 1 ? *(ptr) :					\ +	  (sizeof(*(ptr)) == 2 ? get_unaligned_be16((ptr)) :		\ +	     (sizeof(*(ptr)) == 4 ? get_unaligned_be32((ptr)) :		\ +		(sizeof(*(ptr)) == 8 ? get_unaligned_be64((ptr)) :	\ +		   __bad_unaligned_access_size())));			\ +	}) + +#define __put_unaligned_le(val, ptr) ({					\ +	void *__gu_p = (ptr);						\ +	switch (sizeof(*(ptr))) {					\ +	case 1:								\ +		*(u8 *)__gu_p = (__force u8)(val);			\ +		break;							\ +	case 2:								\ +		put_unaligned_le16((__force u16)(val), __gu_p);		\ +		break;							\ +	case 4:								\ +		put_unaligned_le32((__force u32)(val), __gu_p);		\ +		break;							\ +	case 8:								\ +		put_unaligned_le64((__force u64)(val), __gu_p);		\ +		break;							\ +	default:							\ +		__bad_unaligned_access_size();				\ +		break;							\ +	}								\ +	(void)0; }) + +#define __put_unaligned_be(val, ptr) ({					\ +	void *__gu_p = (ptr);						\ +	switch (sizeof(*(ptr))) {					\ +	case 1:								\ +		*(u8 *)__gu_p = (__force u8)(val);			\ +		break;							\ +	case 2:								\ +		put_unaligned_be16((__force u16)(val), __gu_p);		\ +		break;							\ +	case 4:								\ +		put_unaligned_be32((__force u32)(val), __gu_p);		\ +		break;							\ +	case 8:								\ +		put_unaligned_be64((__force u64)(val), __gu_p);		\ +		break;							\ +	default:							\ +		__bad_unaligned_access_size();				\ +		break;							\ +	}								\ +	(void)0; }) + +#endif /* _ASM_C6X_UNALIGNED_H */  | 
