Skip to content

Commit

Permalink
[ARM] 3567/2: arm: base support for Hilscher netX
Browse files Browse the repository at this point in the history
Patch from Sascha Hauer

This patch adds the base support for Hilscher's netX network
processors.

Signed-off-by: Robert Schwebel <r.schwebel@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Sascha Hauer authored and Russell King committed Jun 19, 2006
1 parent 3095faf commit bb6d8c8
Show file tree
Hide file tree
Showing 20 changed files with 768 additions and 2 deletions.
8 changes: 8 additions & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,12 @@ config ARCH_PNX4008
help
This enables support for Philips PNX4008 mobile platform.

config ARCH_NETX
bool "Hilscher NetX based"
select ARM_VIC
help
This enables support for systems based on the Hilscher NetX Soc

endchoice

source "arch/arm/mach-clps711x/Kconfig"
Expand Down Expand Up @@ -319,6 +325,8 @@ source "arch/arm/mach-realview/Kconfig"

source "arch/arm/mach-at91rm9200/Kconfig"

source "arch/arm/mach-netx/Kconfig"

# Definitions to make life easier
config ARCH_ACORN
bool
Expand Down
1 change: 1 addition & 0 deletions arch/arm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ endif
machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200
machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_PNX4008) := pnx4008
machine-$(CONFIG_ARCH_NETX) := netx

ifeq ($(CONFIG_ARCH_EBSA110),y)
# This is what happens if you forget the IOCS16 line.
Expand Down
11 changes: 11 additions & 0 deletions arch/arm/mach-netx/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).

# Object file lists.

obj-y += time.o generic.o

2 changes: 2 additions & 0 deletions arch/arm/mach-netx/Makefile.boot
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
zreladdr-y := 0x80008000

193 changes: 193 additions & 0 deletions arch/arm/mach-netx/generic.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/*
* arch/arm/mach-netx/generic.c
*
* Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
* 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.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <linux/device.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <asm/hardware.h>
#include <asm/mach/map.h>
#include <asm/hardware/vic.h>
#include <asm/io.h>
#include <asm/arch/netx-regs.h>
#include <asm/mach/irq.h>

static struct map_desc netx_io_desc[] __initdata = {
{
.virtual = NETX_IO_VIRT,
.pfn = __phys_to_pfn(NETX_IO_PHYS),
.length = NETX_IO_SIZE,
.type = MT_DEVICE
}
};

void __init netx_map_io(void)
{
iotable_init(netx_io_desc, ARRAY_SIZE(netx_io_desc));
}

static struct resource netx_rtc_resources[] = {
[0] = {
.start = 0x00101200,
.end = 0x00101220,
.flags = IORESOURCE_MEM,
},
};

static struct platform_device netx_rtc_device = {
.name = "netx-rtc",
.id = 0,
.num_resources = ARRAY_SIZE(netx_rtc_resources),
.resource = netx_rtc_resources,
};

static struct platform_device *devices[] __initdata = {
&netx_rtc_device,
};

#if 0
#define DEBUG_IRQ(fmt...) printk(fmt)
#else
#define DEBUG_IRQ(fmt...) while (0) {}
#endif

static void
netx_hif_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
struct pt_regs *regs)
{
unsigned int irq = NETX_IRQ_HIF_CHAINED(0);
unsigned int stat;

stat = ((readl(NETX_DPMAS_INT_EN) &
readl(NETX_DPMAS_INT_STAT)) >> 24) & 0x1f;

desc = irq_desc + NETX_IRQ_HIF_CHAINED(0);

while (stat) {
if (stat & 1) {
DEBUG_IRQ("handling irq %d\n", irq);
desc_handle_irq(irq, desc, regs);
}
irq++;
desc++;
stat >>= 1;
}
}

static int
netx_hif_irq_type(unsigned int _irq, unsigned int type)
{
unsigned int val, irq;

val = readl(NETX_DPMAS_IF_CONF1);

irq = _irq - NETX_IRQ_HIF_CHAINED(0);

if (type & __IRQT_RISEDGE) {
DEBUG_IRQ("rising edges\n");
val |= (1 << 26) << irq;
}
if (type & __IRQT_FALEDGE) {
DEBUG_IRQ("falling edges\n");
val &= ~((1 << 26) << irq);
}
if (type & __IRQT_LOWLVL) {
DEBUG_IRQ("low level\n");
val &= ~((1 << 26) << irq);
}
if (type & __IRQT_HIGHLVL) {
DEBUG_IRQ("high level\n");
val |= (1 << 26) << irq;
}

writel(val, NETX_DPMAS_IF_CONF1);

return 0;
}

static void
netx_hif_ack_irq(unsigned int _irq)
{
unsigned int val, irq;

irq = _irq - NETX_IRQ_HIF_CHAINED(0);
writel((1 << 24) << irq, NETX_DPMAS_INT_STAT);

val = readl(NETX_DPMAS_INT_EN);
val &= ~((1 << 24) << irq);
writel(val, NETX_DPMAS_INT_EN);

DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, _irq);
}

static void
netx_hif_mask_irq(unsigned int _irq)
{
unsigned int val, irq;

irq = _irq - NETX_IRQ_HIF_CHAINED(0);
val = readl(NETX_DPMAS_INT_EN);
val &= ~((1 << 24) << irq);
writel(val, NETX_DPMAS_INT_EN);
DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, _irq);
}

static void
netx_hif_unmask_irq(unsigned int _irq)
{
unsigned int val, irq;

irq = _irq - NETX_IRQ_HIF_CHAINED(0);
val = readl(NETX_DPMAS_INT_EN);
val |= (1 << 24) << irq;
writel(val, NETX_DPMAS_INT_EN);
DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, _irq);
}

static struct irqchip netx_hif_chip = {
.ack = netx_hif_ack_irq,
.mask = netx_hif_mask_irq,
.unmask = netx_hif_unmask_irq,
.set_type = netx_hif_irq_type,
};

void __init netx_init_irq(void)
{
int irq;

vic_init(__io(io_p2v(NETX_PA_VIC)), 0, ~0);

for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) {
set_irq_chip(irq, &netx_hif_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID);
}

writel(NETX_DPMAS_INT_EN_GLB_EN, NETX_DPMAS_INT_EN);
set_irq_chained_handler(NETX_IRQ_HIF, netx_hif_demux_handler);
}

static int __init netx_init(void)
{
return platform_add_devices(devices, ARRAY_SIZE(devices));
}

subsys_initcall(netx_init);

24 changes: 24 additions & 0 deletions arch/arm/mach-netx/generic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* arch/arm/mach-netx/generic.h
*
* Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
* 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.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

extern void __init netx_map_io(void);
extern void __init netx_init_irq(void);

struct sys_timer;
extern struct sys_timer netx_timer;
88 changes: 88 additions & 0 deletions arch/arm/mach-netx/time.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* arch/arm/mach-netx/time.c
*
* Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
* 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.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <linux/init.h>
#include <linux/interrupt.h>

#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/mach/time.h>
#include <asm/arch/netx-regs.h>

/*
* Returns number of us since last clock interrupt. Note that interrupts
* will have been disabled by do_gettimeoffset()
*/
static unsigned long netx_gettimeoffset(void)
{
return readl(NETX_GPIO_COUNTER_CURRENT(0)) / 100;
}

/*
* IRQ handler for the timer
*/
static irqreturn_t
netx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
write_seqlock(&xtime_lock);

timer_tick(regs);
write_sequnlock(&xtime_lock);

/* acknowledge interrupt */
writel(COUNTER_BIT(0), NETX_GPIO_IRQ);

return IRQ_HANDLED;
}


static struct irqaction netx_timer_irq = {
.name = "NetX Timer Tick",
.flags = SA_INTERRUPT | SA_TIMER,
.handler = netx_timer_interrupt,
};

/*
* Set up timer interrupt
*/
static void __init netx_timer_init(void)
{
/* disable timer initially */
writel(0, NETX_GPIO_COUNTER_CTRL(0));

/* Reset the timer value to zero */
writel(0, NETX_GPIO_COUNTER_CURRENT(0));

writel(LATCH, NETX_GPIO_COUNTER_MAX(0));

/* acknowledge interrupt */
writel(COUNTER_BIT(0), NETX_GPIO_IRQ);

/* Enable the interrupt in the specific timer register and start timer */
writel(COUNTER_BIT(0), NETX_GPIO_IRQ_ENABLE);
writel(NETX_GPIO_COUNTER_CTRL_IRQ_EN | NETX_GPIO_COUNTER_CTRL_RUN,
NETX_GPIO_COUNTER_CTRL(0));

setup_irq(NETX_IRQ_TIMER0, &netx_timer_irq);
}

struct sys_timer netx_timer = {
.init = netx_timer_init,
.offset = netx_gettimeoffset,
};
4 changes: 2 additions & 2 deletions arch/arm/mm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ config CPU_ARM925T
# ARM926T
config CPU_ARM926T
bool "Support ARM926T processor"
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_CACHE_VIVT
Expand Down
Loading

0 comments on commit bb6d8c8

Please sign in to comment.