[prev in list] [next in list] [prev in thread] [next in thread]
List: uclinux-dev
Subject: Re: [uClinux-dev] [PATCH] m68knommu: add basic mmu-less m548x support
From: Greg Ungerer <gerg () snapgear ! com>
Date: 2010-09-17 6:23:12
Message-ID: 4C930950.2090100 () snapgear ! com
[Download RAW message or body]
Hi Philippe,
On 06/09/10 23:34, Philippe De Muyter wrote:
> Add a very basic mmu-less support for coldfire m548x family. This is perhaps
> also valid for m547x family. The port comprises the serial, tick timer and
> reboot support. The gpio part compiles but is empty. This gives a functional
> albeit limited linux for the m548x coldfire family. This has been tested
> on a Freescale M548xEVB Lite board with a M5484 processor and the default
> dbug monitor.
>
> Signed-off-by: Philippe De Muyter<phdm@macqel.be>
Overall looks ok.
I don't particularly like the MCF_REG32 and friends macros,
or their use. (I know m532xsim.h uses it too - and I plan
on cleaning that out at some point in the future).
I would much prefer clean address defines, and use of
raw_readl/readl/raw_writel/writel/etc - just like the clock
code in this patch does (sltimers.c).
Regards
Greg
> diff --git a/arch/m68k/include/asm/cacheflush_no.h \
> b/arch/m68k/include/asm/cacheflush_no.h index 89f1956..7085bd5 100644
> --- a/arch/m68k/include/asm/cacheflush_no.h
> +++ b/arch/m68k/include/asm/cacheflush_no.h
> @@ -29,7 +29,7 @@
>
> static inline void __flush_cache_all(void)
> {
> -#ifdef CONFIG_M5407
> +#if defined(CONFIG_M5407) || defined(CONFIG_M548x)
> /*
> * Use cpushl to push and invalidate all cache lines.
> * Gas doesn't seem to know how to generate the ColdFire
> diff --git a/arch/m68k/include/asm/coldfire.h b/arch/m68k/include/asm/coldfire.h
> index 83a9fa4..3b0a34d 100644
> --- a/arch/m68k/include/asm/coldfire.h
> +++ b/arch/m68k/include/asm/coldfire.h
> @@ -32,7 +32,9 @@
> */
> #define MCF_MBAR 0x10000000
> #define MCF_MBAR2 0x80000000
> -#if defined(CONFIG_M520x)
> +#if defined(CONFIG_M548x)
> +#define MCF_IPSBAR MCF_MBAR
> +#elif defined(CONFIG_M520x)
> #define MCF_IPSBAR 0xFC000000
> #else
> #define MCF_IPSBAR 0x40000000
> diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h
> index 283214d..1b57adb 100644
> --- a/arch/m68k/include/asm/gpio.h
> +++ b/arch/m68k/include/asm/gpio.h
> @@ -36,7 +36,8 @@
> */
> #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
> defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
> - defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
> + defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
> + defined(CONFIG_M532x) || defined(CONFIG_M548x)
>
> /* These parts have GPIO organized by 8 bit ports */
>
> @@ -136,6 +137,8 @@ static inline u32 __mcf_gpio_ppdr(unsigned gpio)
> #endif
> else
> return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
> +#else
> + return 0;
> #endif
> }
>
> @@ -173,6 +176,8 @@ static inline u32 __mcf_gpio_podr(unsigned gpio)
> #endif
> else
> return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
> +#else
> + return 0;
> #endif
> }
>
> diff --git a/arch/m68k/include/asm/m548xgpt.h b/arch/m68k/include/asm/m548xgpt.h
> new file mode 100644
> index 0000000..bc7f9eb
> --- /dev/null
> +++ b/arch/m68k/include/asm/m548xgpt.h
> @@ -0,0 +1,88 @@
> +/*
> + * File: m548xgpt.h
> + * Purpose: Register and bit definitions for the MCF548X
> + *
> + * Notes:
> + *
> + */
> +
> +#ifndef m548xgpt_h
> +#define m548xgpt_h
> +
> +/*********************************************************************
> +*
> +* General Purpose Timers (GPT)
> +*
> +*********************************************************************/
> +
> +/* Register read/write macros */
> +#define MCF_GPT_GMS0 MCF_REG32(0x000800)
> +#define MCF_GPT_GCIR0 MCF_REG32(0x000804)
> +#define MCF_GPT_GPWM0 MCF_REG32(0x000808)
> +#define MCF_GPT_GSR0 MCF_REG32(0x00080C)
> +#define MCF_GPT_GMS1 MCF_REG32(0x000810)
> +#define MCF_GPT_GCIR1 MCF_REG32(0x000814)
> +#define MCF_GPT_GPWM1 MCF_REG32(0x000818)
> +#define MCF_GPT_GSR1 MCF_REG32(0x00081C)
> +#define MCF_GPT_GMS2 MCF_REG32(0x000820)
> +#define MCF_GPT_GCIR2 MCF_REG32(0x000824)
> +#define MCF_GPT_GPWM2 MCF_REG32(0x000828)
> +#define MCF_GPT_GSR2 MCF_REG32(0x00082C)
> +#define MCF_GPT_GMS3 MCF_REG32(0x000830)
> +#define MCF_GPT_GCIR3 MCF_REG32(0x000834)
> +#define MCF_GPT_GPWM3 MCF_REG32(0x000838)
> +#define MCF_GPT_GSR3 MCF_REG32(0x00083C)
> +#define MCF_GPT_GMS(x) MCF_REG32(0x000800+((x)*0x010))
> +#define MCF_GPT_GCIR(x) MCF_REG32(0x000804+((x)*0x010))
> +#define MCF_GPT_GPWM(x) MCF_REG32(0x000808+((x)*0x010))
> +#define MCF_GPT_GSR(x) MCF_REG32(0x00080C+((x)*0x010))
> +
> +/* Bit definitions and macros for MCF_GPT_GMS */
> +#define MCF_GPT_GMS_TMS(x) (((x)&0x00000007)<<0)
> +#define MCF_GPT_GMS_GPIO(x) (((x)&0x00000003)<<4)
> +#define MCF_GPT_GMS_IEN (0x00000100)
> +#define MCF_GPT_GMS_OD (0x00000200)
> +#define MCF_GPT_GMS_SC (0x00000400)
> +#define MCF_GPT_GMS_CE (0x00001000)
> +#define MCF_GPT_GMS_WDEN (0x00008000)
> +#define MCF_GPT_GMS_ICT(x) (((x)&0x00000003)<<16)
> +#define MCF_GPT_GMS_OCT(x) (((x)&0x00000003)<<20)
> +#define MCF_GPT_GMS_OCPW(x) (((x)&0x000000FF)<<24)
> +#define MCF_GPT_GMS_OCT_FRCLOW (0x00000000)
> +#define MCF_GPT_GMS_OCT_PULSEHI (0x00100000)
> +#define MCF_GPT_GMS_OCT_PULSELO (0x00200000)
> +#define MCF_GPT_GMS_OCT_TOGGLE (0x00300000)
> +#define MCF_GPT_GMS_ICT_ANY (0x00000000)
> +#define MCF_GPT_GMS_ICT_RISE (0x00010000)
> +#define MCF_GPT_GMS_ICT_FALL (0x00020000)
> +#define MCF_GPT_GMS_ICT_PULSE (0x00030000)
> +#define MCF_GPT_GMS_GPIO_INPUT (0x00000000)
> +#define MCF_GPT_GMS_GPIO_OUTLO (0x00000020)
> +#define MCF_GPT_GMS_GPIO_OUTHI (0x00000030)
> +#define MCF_GPT_GMS_TMS_DISABLE (0x00000000)
> +#define MCF_GPT_GMS_TMS_INCAPT (0x00000001)
> +#define MCF_GPT_GMS_TMS_OUTCAPT (0x00000002)
> +#define MCF_GPT_GMS_TMS_PWM (0x00000003)
> +#define MCF_GPT_GMS_TMS_GPIO (0x00000004)
> +
> +/* Bit definitions and macros for MCF_GPT_GCIR */
> +#define MCF_GPT_GCIR_CNT(x) (((x)&0x0000FFFF)<<0)
> +#define MCF_GPT_GCIR_PRE(x) (((x)&0x0000FFFF)<<16)
> +
> +/* Bit definitions and macros for MCF_GPT_GPWM */
> +#define MCF_GPT_GPWM_LOAD (0x00000001)
> +#define MCF_GPT_GPWM_PWMOP (0x00000100)
> +#define MCF_GPT_GPWM_WIDTH(x) (((x)&0x0000FFFF)<<16)
> +
> +/* Bit definitions and macros for MCF_GPT_GSR */
> +#define MCF_GPT_GSR_CAPT (0x00000001)
> +#define MCF_GPT_GSR_COMP (0x00000002)
> +#define MCF_GPT_GSR_PWMP (0x00000004)
> +#define MCF_GPT_GSR_TEXP (0x00000008)
> +#define MCF_GPT_GSR_PIN (0x00000100)
> +#define MCF_GPT_GSR_OVF(x) (((x)&0x00000007)<<12)
> +#define MCF_GPT_GSR_CAPTURE(x) (((x)&0x0000FFFF)<<16)
> +
> +/********************************************************************/
> +
> +#endif /* m548xgpt_h */
> diff --git a/arch/m68k/include/asm/m548xsim.h b/arch/m68k/include/asm/m548xsim.h
> new file mode 100644
> index 0000000..c2fc4f7
> --- /dev/null
> +++ b/arch/m68k/include/asm/m548xsim.h
> @@ -0,0 +1,59 @@
> +/*
> + * m548xsim.h -- ColdFire 547x/548x System Integration Unit support.
> + */
> +
> +#ifndef m548xsim_h
> +#define m548xsim_h
> +
> +#define MCF_REG32(x) *(volatile unsigned long *)(MCF_MBAR+(x))
> +#define MCF_REG16(x) *(volatile unsigned short *)(MCF_MBAR+(x))
> +#define MCF_REG08(x) *(volatile unsigned char *)(MCF_MBAR+(x))
> +
> +#define MCFINT_VECBASE 64
> +
> +/*
> + * Interrupt Controller Registers
> + */
> +#define MCFICM_INTC0 0x0700 /* Base for Interrupt Ctrl 0 */
> +#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */
> +#define MCFINTC_IPRL 0x04 /* Interrupt pending 1-31 */
> +#define MCFINTC_IMRH 0x08 /* Interrupt mask 32-63 */
> +#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */
> +#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */
> +#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */
> +#define MCFINTC_IRLR 0x18 /* */
> +#define MCFINTC_IACKL 0x19 /* */
> +#define MCFINTC_ICR0 0x40 /* Base ICR register */
> +
> +/*
> + * Define system peripheral IRQ usage.
> + */
> +#define MCF_IRQ_TIMER (64 + 54) /* Slice Timer 0 */
> +#define MCF_IRQ_PROFILER (64 + 53) /* Slice Timer 1 */
> +
> +/*
> + * Generic GPIO support
> + */
> +#define MCFGPIO_PIN_MAX 0 /* I am too lazy to count */
> +#define MCFGPIO_IRQ_MAX -1
> +#define MCFGPIO_IRQ_VECBASE -1
> +
> +/*
> + * Some PSC related definitions
> + */
> +#define MCF_PAR_PSCn(x) MCF_REG08(0x000A4F-((x)&0x3))
> +#define MCF_PAR_SDA (0x0008)
> +#define MCF_PAR_SCL (0x0004)
> +#define MCF_PAR_PSC_TXD (0x04)
> +#define MCF_PAR_PSC_RXD (0x08)
> +#define MCF_PAR_PSC_RTS(x) (((x)&0x03)<<4)
> +#define MCF_PAR_PSC_CTS(x) (((x)&0x03)<<6)
> +#define MCF_PAR_PSC_CTS_GPIO (0x00)
> +#define MCF_PAR_PSC_CTS_BCLK (0x80)
> +#define MCF_PAR_PSC_CTS_CTS (0xC0)
> +#define MCF_PAR_PSC_RTS_GPIO (0x00)
> +#define MCF_PAR_PSC_RTS_FSYNC (0x20)
> +#define MCF_PAR_PSC_RTS_RTS (0x30)
> +#define MCF_PAR_PSC_CANRX (0x40)
> +
> +#endif /* m548xsim_h */
> diff --git a/arch/m68k/include/asm/mcfcache.h b/arch/m68k/include/asm/mcfcache.h
> index c042634..f49dfc0 100644
> --- a/arch/m68k/include/asm/mcfcache.h
> +++ b/arch/m68k/include/asm/mcfcache.h
> @@ -107,7 +107,7 @@
> .endm
> #endif /* CONFIG_M532x */
>
> -#if defined(CONFIG_M5407)
> +#if defined(CONFIG_M5407) || defined(CONFIG_M548x)
> /*
> * Version 4 cores have a true harvard style separate instruction
> * and data cache. Invalidate and enable cache, also enable write
> diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h
> index 9c70a67..6901fd6 100644
> --- a/arch/m68k/include/asm/mcfsim.h
> +++ b/arch/m68k/include/asm/mcfsim.h
> @@ -41,6 +41,8 @@
> #elif defined(CONFIG_M5407)
> #include<asm/m5407sim.h>
> #include<asm/mcfintc.h>
> +#elif defined(CONFIG_M548x)
> +#include<asm/m548xsim.h>
> #endif
>
> /****************************************************************************/
> diff --git a/arch/m68k/include/asm/mcfslt.h b/arch/m68k/include/asm/mcfslt.h
> new file mode 100644
> index 0000000..d0d0ecb
> --- /dev/null
> +++ b/arch/m68k/include/asm/mcfslt.h
> @@ -0,0 +1,44 @@
> +/****************************************************************************/
> +
> +/*
> + * mcfslt.h -- ColdFire internal Slice (SLT) timer support defines.
> + *
> + * (C) Copyright 2004, Greg Ungerer (gerg@snapgear.com)
> + * (C) Copyright 2009, Philippe De Muyter (phdm@macqel.be)
> + */
> +
> +/****************************************************************************/
> +#ifndef mcfslt_h
> +#define mcfslt_h
> +/****************************************************************************/
> +
> +/*
> + * Get address specific defines for the 547x.
> + */
> +#define MCFSLT_TIMER0 0x900 /* Base address of TIMER0 */
> +#define MCFSLT_TIMER1 0x910 /* Base address of TIMER1 */
> +
> +
> +/*
> + * Define the SLT timer register set addresses.
> + */
> +#define MCFSLT_STCNT 0x00 /* Terminal count */
> +#define MCFSLT_SCR 0x04 /* Control */
> +#define MCFSLT_SCNT 0x08 /* Current count */
> +#define MCFSLT_SSR 0x0C /* Status */
> +
> +/*
> + * Bit definitions for the SCR control register.
> + */
> +#define MCFSLT_SCR_RUN 0x04000000 /* Run mode (continuous) */
> +#define MCFSLT_SCR_IEN 0x02000000 /* Interrupt enable */
> +#define MCFSLT_SCR_TEN 0x01000000 /* Timer enable */
> +
> +/*
> + * Bit definitions for the SSR status register.
> + */
> +#define MCFSLT_SSR_BE 0x02000000 /* Bus error condition */
> +#define MCFSLT_SSR_TE 0x01000000 /* Timeout condition */
> +
> +/****************************************************************************/
> +#endif /* mcfslt_h */
> diff --git a/arch/m68k/include/asm/mcfuart.h b/arch/m68k/include/asm/mcfuart.h
> index 01a8716..af16f3b 100644
> --- a/arch/m68k/include/asm/mcfuart.h
> +++ b/arch/m68k/include/asm/mcfuart.h
> @@ -47,6 +47,11 @@
> #define MCFUART_BASE1 0xfc060000 /* Base address of UART1 */
> #define MCFUART_BASE2 0xfc064000 /* Base address of UART2 */
> #define MCFUART_BASE3 0xfc068000 /* Base address of UART3 */
> +#elif defined(CONFIG_M548x)
> +#define MCFUART_BASE1 0x8600 /* on M548x */
> +#define MCFUART_BASE2 0x8700 /* on M548x */
> +#define MCFUART_BASE3 0x8800 /* on M548x */
> +#define MCFUART_BASE4 0x8900 /* on M548x */
> #endif
>
>
> diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
> index 2609c39..e9db45e 100644
> --- a/arch/m68knommu/Kconfig
> +++ b/arch/m68knommu/Kconfig
> @@ -171,6 +171,11 @@ config M5407
> help
> Motorola ColdFire 5407 processor support.
>
> +config M548x
> + bool "MCF548x"
> + help
> + Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support.
> +
> endchoice
>
> config M527x
> @@ -181,7 +186,7 @@ config M527x
>
> config COLDFIRE
> bool
> - depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x \
> || M5307 || M532x || M5407) + depends on (M5206 || M5206e || M520x || M523x || \
> M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407 || M548x) select \
> GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB
> default y
> diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
> index 1404257..026ef16 100644
> --- a/arch/m68knommu/Makefile
> +++ b/arch/m68knommu/Makefile
> @@ -25,6 +25,7 @@ platform-$(CONFIG_M528x) := 528x
> platform-$(CONFIG_M5307) := 5307
> platform-$(CONFIG_M532x) := 532x
> platform-$(CONFIG_M5407) := 5407
> +platform-$(CONFIG_M548x) := 548x
> PLATFORM := $(platform-y)
>
> board-$(CONFIG_PILOT) := pilot
> @@ -73,6 +74,7 @@ cpuclass-$(CONFIG_M528x) := coldfire
> cpuclass-$(CONFIG_M5307) := coldfire
> cpuclass-$(CONFIG_M532x) := coldfire
> cpuclass-$(CONFIG_M5407) := coldfire
> +cpuclass-$(CONFIG_M548x) := coldfire
> cpuclass-$(CONFIG_M68328) := 68328
> cpuclass-$(CONFIG_M68EZ328) := 68328
> cpuclass-$(CONFIG_M68VZ328) := 68328
> @@ -100,6 +102,7 @@ cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307)
> cflags-$(CONFIG_M5307) := $(call cc-option,-m5307,-m5200)
> cflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307)
> cflags-$(CONFIG_M5407) := $(call cc-option,-m5407,-m5200)
> +cflags-$(CONFIG_M548x) := $(call cc-option,-m5407,-m5200)
> cflags-$(CONFIG_M68328) := -m68000
> cflags-$(CONFIG_M68EZ328) := -m68000
> cflags-$(CONFIG_M68VZ328) := -m68000
> diff --git a/arch/m68knommu/platform/548x/Makefile \
> b/arch/m68knommu/platform/548x/Makefile new file mode 100644
> index 0000000..e6035e7
> --- /dev/null
> +++ b/arch/m68knommu/platform/548x/Makefile
> @@ -0,0 +1,18 @@
> +#
> +# Makefile for the m68knommu linux kernel.
> +#
> +
> +#
> +# If you want to play with the HW breakpoints then you will
> +# need to add define this, which will give you a stack backtrace
> +# on the console port whenever a DBG interrupt occurs. You have to
> +# set up you HW breakpoints to trigger a DBG interrupt:
> +#
> +# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
> +# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
> +#
> +
> +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
> +
> +obj-y := config.o
> +
> diff --git a/arch/m68knommu/platform/548x/config.c \
> b/arch/m68knommu/platform/548x/config.c new file mode 100644
> index 0000000..3b05d74
> --- /dev/null
> +++ b/arch/m68knommu/platform/548x/config.c
> @@ -0,0 +1,110 @@
> +/***************************************************************************/
> +
> +/*
> + * linux/arch/m68knommu/platform/548x/config.c
> + *
> + * Copyright (C) 2010, Philippe De Muyter<phdm@macqel.be>
> + */
> +
> +/***************************************************************************/
> +
> +#include<linux/kernel.h>
> +#include<linux/param.h>
> +#include<linux/init.h>
> +#include<linux/interrupt.h>
> +#include<linux/io.h>
> +#include<asm/machdep.h>
> +#include<asm/coldfire.h>
> +#include<asm/m548xsim.h>
> +#include<asm/mcfuart.h>
> +#include<asm/m548xgpt.h>
> +
> +/***************************************************************************/
> +
> +static struct mcf_platform_uart m548x_uart_platform[] = {
> + {
> + .mapbase = MCF_MBAR + MCFUART_BASE1,
> + .irq = 64 + 35,
> + },
> + {
> + .mapbase = MCF_MBAR + MCFUART_BASE2,
> + .irq = 64 + 34,
> + },
> + {
> + .mapbase = MCF_MBAR + MCFUART_BASE3,
> + .irq = 64 + 33,
> + },
> + {
> + .mapbase = MCF_MBAR + MCFUART_BASE4,
> + .irq = 64 + 32,
> + },
> +};
> +
> +static struct platform_device m548x_uart = {
> + .name = "mcfuart",
> + .id = 0,
> + .dev.platform_data = m548x_uart_platform,
> +};
> +
> +static struct platform_device *m548x_devices[] __initdata = {
> + &m548x_uart,
> +};
> +
> +
> +/***************************************************************************/
> +
> +static void __init m548x_uart_init_line(int line, int irq)
> +{
> + int rts_cts;
> +
> + /* enable io pins */
> + switch(line)
> + {
> + case 0 : rts_cts = 0; break;
> + case 1 : rts_cts = MCF_PAR_PSC_RTS_RTS; break;
> + case 2 : rts_cts = MCF_PAR_PSC_RTS_RTS | MCF_PAR_PSC_CTS_CTS; break;
> + case 3 : rts_cts = 0; break;
> + }
> + MCF_PAR_PSCn(line) = MCF_PAR_PSC_TXD | rts_cts | MCF_PAR_PSC_RXD;
> +}
> +
> +static void __init m548x_uarts_init(void)
> +{
> + const int nrlines = ARRAY_SIZE(m548x_uart_platform);
> + int line;
> +
> + for (line = 0; (line< nrlines); line++)
> + m548x_uart_init_line(line, m548x_uart_platform[line].irq);
> +}
> +
> +/***************************************************************************/
> +
> +static void mcf548x_reset(void)
> +{
> + /* disable interrupts and enable the watchdog */
> + asm("movew #0x2700, %sr\n");
> + MCF_GPT_GMS0 = 0;
> + MCF_GPT_GCIR0 = MCF_GPT_GCIR_CNT(1);
> + MCF_GPT_GMS0 = MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS(4);
> +}
> +
> +/***************************************************************************/
> +
> +void __init config_BSP(char *commandp, int size)
> +{
> + mach_reset = mcf548x_reset;
> + m548x_uarts_init();
> +}
> +
> +/***************************************************************************/
> +
> +static int __init init_BSP(void)
> +{
> +
> + platform_add_devices(m548x_devices, ARRAY_SIZE(m548x_devices));
> + return 0;
> +}
> +
> +arch_initcall(init_BSP);
> +
> +/***************************************************************************/
> diff --git a/arch/m68knommu/platform/coldfire/Makefile \
> b/arch/m68knommu/platform/coldfire/Makefile index f72a0e5..df62171 100644
> --- a/arch/m68knommu/platform/coldfire/Makefile
> +++ b/arch/m68knommu/platform/coldfire/Makefile
> @@ -26,6 +26,7 @@ obj-$(CONFIG_M528x) += pit.o intc-2.o
> obj-$(CONFIG_M5307) += timers.o intc.o
> obj-$(CONFIG_M532x) += timers.o intc-simr.o
> obj-$(CONFIG_M5407) += timers.o intc.o
> +obj-$(CONFIG_M548x) += sltimers.o intc-2.o
>
> obj-y += pinmux.o gpio.o
> extra-y := head.o
> diff --git a/arch/m68knommu/platform/coldfire/sltimers.c \
> b/arch/m68knommu/platform/coldfire/sltimers.c new file mode 100644
> index 0000000..986d4cb
> --- /dev/null
> +++ b/arch/m68knommu/platform/coldfire/sltimers.c
> @@ -0,0 +1,160 @@
> +/***************************************************************************/
> +
> +/*
> + * sltimers.c -- generic ColdFire slice timer support.
> + *
> + * Copyright (C) 2009-2010, Philippe De Muyter<phdm@macqel.be>
> + * based on
> + * timers.c -- generic ColdFire hardware timer support.
> + * Copyright (C) 1999-2008, Greg Ungerer<gerg@snapgear.com>
> + */
> +
> +/***************************************************************************/
> +
> +#include<linux/kernel.h>
> +#include<linux/init.h>
> +#include<linux/sched.h>
> +#include<linux/interrupt.h>
> +#include<linux/irq.h>
> +#include<linux/profile.h>
> +#include<linux/clocksource.h>
> +#include<asm/io.h>
> +#include<asm/traps.h>
> +#include<asm/machdep.h>
> +#include<asm/coldfire.h>
> +#include<asm/mcfslt.h>
> +#include<asm/mcfsim.h>
> +
> +/***************************************************************************/
> +
> +/*
> + * By default use Slice Timer 0 as the system clock timer.
> + */
> +#define TA(a) (MCF_MBAR + MCFSLT_TIMER0 + (a))
> +
> +void coldfire_profile_init(void);
> +
> +static u32 mcfslt_cycles_per_jiffy;
> +static u32 mcfslt_cnt;
> +
> +/***************************************************************************/
> +
> +static irqreturn_t mcfslt_tick(int irq, void *dummy)
> +{
> + /* Reset Slice Timer 0 */
> + __raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, TA(MCFSLT_SSR));
> + mcfslt_cnt += mcfslt_cycles_per_jiffy;
> + return arch_timer_interrupt(irq, dummy);
> +}
> +
> +/***************************************************************************/
> +
> +static struct irqaction mcfslt_timer_irq = {
> + .name = "timer",
> + .flags = IRQF_DISABLED | IRQF_TIMER,
> + .handler = mcfslt_tick,
> +};
> +
> +/***************************************************************************/
> +
> +static cycle_t mcfslt_read_clk(struct clocksource *cs)
> +{
> + unsigned long flags;
> + u32 cycles;
> + u16 scnt;
> +
> + local_irq_save(flags);
> + scnt = __raw_readl(TA(MCFSLT_SCNT));
> + cycles = mcfslt_cnt;
> + local_irq_restore(flags);
> +
> + /* substract because slice timers count down */
> + return cycles - scnt;
> +}
> +
> +/***************************************************************************/
> +
> +static struct clocksource mcfslt_clk = {
> + .name = "slt",
> + .rating = 250,
> + .read = mcfslt_read_clk,
> + .shift = 20,
> + .mask = CLOCKSOURCE_MASK(32),
> + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +/***************************************************************************/
> +
> +void hw_timer_init(void)
> +{
> + mcfslt_cycles_per_jiffy = MCF_BUSCLK / HZ;
> + /*
> + * The coldfire slice timer (SLT) runs from STCNT to 0 included,
> + * then STCNT again and so on. It counts thus actually
> + * STCNT + 1 steps for 1 tick, not STCNT. So if you want
> + * n cycles, initialize STCNT with n - 1.
> + */
> + __raw_writel(mcfslt_cycles_per_jiffy - 1, TA(MCFSLT_STCNT));
> + __raw_writel(MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN,
> + TA(MCFSLT_SCR));
> + /* initialize mcfslt_cnt knowing that slice timers count down */
> + mcfslt_cnt = mcfslt_cycles_per_jiffy;
> +
> + setup_irq(MCF_IRQ_TIMER,&mcfslt_timer_irq);
> +
> + mcfslt_clk.mult = clocksource_hz2mult(MCF_BUSCLK, mcfslt_clk.shift);
> + clocksource_register(&mcfslt_clk);
> +}
> +
> +/***************************************************************************/
> +#ifdef CONFIG_HIGHPROFILE
> +/***************************************************************************/
> +
> +/*
> + * By default use Slice Timer 1 as the profiler clock timer.
> + */
> +#define PA(a) (MCF_MBAR + MCFSLT_TIMER1 + (a))
> +
> +/*
> + * Choose a reasonably fast profile timer. Make it an odd value to
> + * try and get good coverage of kernel operations.
> + */
> +#define PROFILEHZ 1013
> +
> +/*
> + * Use the other timer to provide high accuracy profiling info.
> + */
> +irqreturn_t coldfire_profile_tick(int irq, void *dummy)
> +{
> + /* Reset Slice Timer 1 */
> + __raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, PA(MCFSLT_SSR));
> + if (current->pid)
> + profile_tick(CPU_PROFILING);
> + return IRQ_HANDLED;
> +}
> +
> +/***************************************************************************/
> +
> +static struct irqaction coldfire_profile_irq = {
> + .name = "profile timer",
> + .flags = IRQF_DISABLED | IRQF_TIMER,
> + .handler = coldfire_profile_tick,
> +};
> +
> +void coldfire_profile_init(void)
> +{
> + printk(KERN_INFO "PROFILE: lodging TIMER 1 @ %dHz as profile timer\n",
> + PROFILEHZ);
> +
> + setup_irq(MCF_IRQ_PROFILER,&coldfire_profile_irq);
> +
> + /* Set up TIMER 2 as high speed profile clock */
> + __raw_writel(MCF_BUSCLK / PROFILEHZ - 1, PA(MCFSLT_STCNT));
> + __raw_writel(MCFSLT_SCR_RUN | MCFSLT_SCR_IEN | MCFSLT_SCR_TEN,
> + PA(MCFSLT_SCR));
> +
> +}
> +
> +/***************************************************************************/
> +#endif /* CONFIG_HIGHPROFILE */
> +/***************************************************************************/
> _______________________________________________
> uClinux-dev mailing list
> uClinux-dev@uclinux.org
> http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
> This message was resent by uclinux-dev@uclinux.org
> To unsubscribe see:
> http://mailman.uclinux.org/mailman/options/uclinux-dev
>
--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close FAX: +61 7 3217 5323
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic