11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  linux/arch/arm/mach-ebsa110/core.c
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Copyright (C) 1998-2001 Russell King
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License version 2 as
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * published by the Free Software Foundation.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Extra MM routines for the EBSA-110 architecture
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/serial_8250.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
17fced80c735941fa518ac67c0b61bbe153fb8c050Russell King#include <linux/io.h>
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19a09e64fbc0094e3073dbb09c3b4bfe4ab669244bRussell King#include <mach/hardware.h>
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h>
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/setup.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mach-types.h>
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/pgtable.h>
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/page.h>
259f97da78bf018206fb623cd351d454af2f105fe0David Howells#include <asm/system_misc.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mach/arch.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mach/irq.h>
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mach/map.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mach/time.h>
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
33bcbbf908e3c6d60f8efb7e2e8f09285bbda9e11eRussell King#include "core.h"
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
35c365e506d18154bf430da10679e427abe982a84cLennert Buytenhekstatic void ebsa110_mask_irq(struct irq_data *d)
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
37c365e506d18154bf430da10679e427abe982a84cLennert Buytenhek	__raw_writeb(1 << d->irq, IRQ_MCLR);
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
40c365e506d18154bf430da10679e427abe982a84cLennert Buytenhekstatic void ebsa110_unmask_irq(struct irq_data *d)
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
42c365e506d18154bf430da10679e427abe982a84cLennert Buytenhek	__raw_writeb(1 << d->irq, IRQ_MSET);
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4510dd5ce28d78e2440e8fa1135d17e33399d75340Russell Kingstatic struct irq_chip ebsa110_irq_chip = {
46c365e506d18154bf430da10679e427abe982a84cLennert Buytenhek	.irq_ack	= ebsa110_mask_irq,
47c365e506d18154bf430da10679e427abe982a84cLennert Buytenhek	.irq_mask	= ebsa110_mask_irq,
48c365e506d18154bf430da10679e427abe982a84cLennert Buytenhek	.irq_unmask	= ebsa110_unmask_irq,
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __init ebsa110_init_irq(void)
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long flags;
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int irq;
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_save(flags);
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(0xff, IRQ_MCLR);
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(0x55, IRQ_MSET);
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(0x00, IRQ_MSET);
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (__raw_readb(IRQ_MASK) != 0x55)
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (1);
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(0xff, IRQ_MCLR);	/* clear all interrupt enables */
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_irq_restore(flags);
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (irq = 0; irq < NR_IRQS; irq++) {
66f38c02f3b338651e145aac2889ba976baf6b28b3Thomas Gleixner		irq_set_chip_and_handler(irq, &ebsa110_irq_chip,
67f38c02f3b338651e145aac2889ba976baf6b28b3Thomas Gleixner					 handle_level_irq);
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct map_desc ebsa110_io_desc[] __initdata = {
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * sparse external-decode ISAIO space
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
766cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena	{	/* IRQ_STAT/IRQ_MCLR */
77a21e5e282b7293ce1a192757ffe1baa71618961cArnd Bergmann		.virtual	= (unsigned long)IRQ_STAT,
786cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.pfn		= __phys_to_pfn(TRICK4_PHYS),
795eca8f3a8048235d7fa3faa9ee4fc292d25a7425Russell King		.length		= TRICK4_SIZE,
806cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.type		= MT_DEVICE
816cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena	}, {	/* IRQ_MASK/IRQ_MSET */
82a21e5e282b7293ce1a192757ffe1baa71618961cArnd Bergmann		.virtual	= (unsigned long)IRQ_MASK,
836cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.pfn		= __phys_to_pfn(TRICK3_PHYS),
845eca8f3a8048235d7fa3faa9ee4fc292d25a7425Russell King		.length		= TRICK3_SIZE,
856cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.type		= MT_DEVICE
866cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena	}, {	/* SOFT_BASE */
87a21e5e282b7293ce1a192757ffe1baa71618961cArnd Bergmann		.virtual	= (unsigned long)SOFT_BASE,
886cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.pfn		= __phys_to_pfn(TRICK1_PHYS),
895eca8f3a8048235d7fa3faa9ee4fc292d25a7425Russell King		.length		= TRICK1_SIZE,
906cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.type		= MT_DEVICE
916cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena	}, {	/* PIT_BASE */
92a21e5e282b7293ce1a192757ffe1baa71618961cArnd Bergmann		.virtual	= (unsigned long)PIT_BASE,
936cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.pfn		= __phys_to_pfn(TRICK0_PHYS),
945eca8f3a8048235d7fa3faa9ee4fc292d25a7425Russell King		.length		= TRICK0_SIZE,
956cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.type		= MT_DEVICE
966cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena	},
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * self-decode ISAIO space
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1016cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena	{
1026cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.virtual	= ISAIO_BASE,
1036cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.pfn		= __phys_to_pfn(ISAIO_PHYS),
1046cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.length		= ISAIO_SIZE,
1056cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.type		= MT_DEVICE
1066cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena	}, {
1076cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.virtual	= ISAMEM_BASE,
1086cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.pfn		= __phys_to_pfn(ISAMEM_PHYS),
1096cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.length		= ISAMEM_SIZE,
1106cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena		.type		= MT_DEVICE
1116cb1907c1a88563c84123c923b46424ea68b53ebDeepak Saxena	}
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __init ebsa110_map_io(void)
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc));
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1199b97173e785a54c5df0aa23d1e1f680f61e36e43Laura Abbottstatic void __iomem *ebsa110_ioremap_caller(phys_addr_t cookie, size_t size,
120ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring					    unsigned int flags, void *caller)
121ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring{
122ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring	return (void __iomem *)cookie;
123ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring}
124ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring
125ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herringstatic void ebsa110_iounmap(volatile void __iomem *io_addr)
126ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring{}
127ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring
128ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herringstatic void __init ebsa110_init_early(void)
129ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring{
130ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring	arch_ioremap_caller = ebsa110_ioremap_caller;
131ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring	arch_iounmap = ebsa110_iounmap;
132ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring}
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PIT_CTRL		(PIT_BASE + 0x0d)
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PIT_T2			(PIT_BASE + 0x09)
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PIT_T1			(PIT_BASE + 0x05)
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PIT_T0			(PIT_BASE + 0x01)
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is the rate at which your MCLK signal toggles (in Hz)
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This was measured on a 10 digit frequency counter sampling
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * over 1 second.
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MCLK	47894000
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is the rate at which the PIT timers get clocked
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CLKBY7	(MCLK / 7)
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is the counter value.  We tick at 200Hz on this platform.
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define COUNT	((CLKBY7 + (HZ / 2)) / HZ)
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Get the time offset from the system PIT.  Note that if we have missed an
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * interrupt, then the PIT counter will roll over (ie, be negative).
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This actually works out to be convenient.
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
16123c197b77f9553c30f9c8a5ab41279a35f135f37Stephen Warrenstatic u32 ebsa110_gettimeoffset(void)
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long offset, count;
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(0x40, PIT_CTRL);
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	count = __raw_readb(PIT_T1);
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	count |= __raw_readb(PIT_T1) << 8;
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If count > COUNT, make the number negative.
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (count > COUNT)
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		count |= 0xffff0000;
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	offset = COUNT;
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	offset -= count;
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * `offset' is in units of timer counts.  Convert
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * offset to units of microseconds.
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	offset = offset * (1000000 / HZ) / COUNT;
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18423c197b77f9553c30f9c8a5ab41279a35f135f37Stephen Warren	return offset * 1000;
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic irqreturn_t
1880cd61b68c340a4f901a06e8bb5e0dea4353161c0Linus Torvaldsebsa110_timer_interrupt(int irq, void *dev_id)
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32 count;
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* latch and read timer 1 */
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(0x40, PIT_CTRL);
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	count = __raw_readb(PIT_T1);
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	count |= __raw_readb(PIT_T1) << 8;
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	count += COUNT;
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(count & 0xff, PIT_T1);
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(count >> 8, PIT_T1);
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2020cd61b68c340a4f901a06e8bb5e0dea4353161c0Linus Torvalds	timer_tick();
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return IRQ_HANDLED;
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct irqaction ebsa110_timer_irq = {
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name		= "EBSA110 Timer Tick",
20978f6db99522bbdd2f2a90c963744bd51c8602990Michael Opdenacker	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
21009b8b5f843afc21daf710cc610e5ca890ee94696Russell King	.handler	= ebsa110_timer_interrupt,
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Set up timer interrupt.
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2166bb27d7349db51b50c40534710fe164ca0d58902Stephen Warrenvoid __init ebsa110_timer_init(void)
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
21823c197b77f9553c30f9c8a5ab41279a35f135f37Stephen Warren	arch_gettimeoffset = ebsa110_gettimeoffset;
21923c197b77f9553c30f9c8a5ab41279a35f135f37Stephen Warren
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Timer 1, mode 2, LSB/MSB
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(0x70, PIT_CTRL);
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(COUNT & 0xff, PIT_T1);
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__raw_writeb(COUNT >> 8, PIT_T1);
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	setup_irq(IRQ_EBSA110_TIMER0, &ebsa110_timer_irq);
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct plat_serial8250_port serial_platform_data[] = {
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.iobase		= 0x3f8,
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.irq		= 1,
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.uartclk	= 1843200,
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.regshift	= 0,
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.iotype		= UPIO_PORT,
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.iobase		= 0x2f8,
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.irq		= 2,
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.uartclk	= 1843200,
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.regshift	= 0,
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.iotype		= UPIO_PORT,
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ },
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct platform_device serial_device = {
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name			= "serial8250",
2526df29debb7fc04ac3f92038c57437f40bab4e72dRussell King	.id			= PLAT8250_DEV_PLATFORM,
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.dev			= {
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		.platform_data	= serial_platform_data,
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	},
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25837bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell Kingstatic struct resource am79c961_resources[] = {
25937bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King	{
26037bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King		.start		= 0x220,
26137bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King		.end		= 0x238,
26237bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King		.flags		= IORESOURCE_IO,
26337bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King	}, {
26437bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King		.start		= IRQ_EBSA110_ETHERNET,
26537bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King		.end		= IRQ_EBSA110_ETHERNET,
26637bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King		.flags		= IORESOURCE_IRQ,
26737bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King	},
26837bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King};
26937bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King
27037bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell Kingstatic struct platform_device am79c961_device = {
27137bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King	.name			= "am79c961",
27237bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King	.id			= -1,
27337bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King	.num_resources		= ARRAY_SIZE(am79c961_resources),
27437bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King	.resource		= am79c961_resources,
27537bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King};
27637bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King
27737bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell Kingstatic struct platform_device *ebsa110_devices[] = {
27837bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King	&serial_device,
27937bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King	&am79c961_device,
28037bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King};
28137bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King
2821b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre/*
2831b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre * EBSA110 idling methodology:
2841b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre *
2851b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre * We can not execute the "wait for interrupt" instruction since that
2861b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre * will stop our MCLK signal (which provides the clock for the glue
2871b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre * logic, and therefore the timer interrupt).
2881b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre *
2891b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre * Instead, we spin, polling the IRQ_STAT register for the occurrence
2901b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre * of any interrupt with core clock down to the memory clock.
2911b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre */
2921b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitrestatic void ebsa110_idle(void)
2931b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre{
2941b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre	const char *irq_stat = (char *)0xff000000;
2951b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre
2961b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre	/* disable clock switching */
2971b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre	asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc");
2981b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre
2991b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre	/* wait for an interrupt to occur */
3001b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre	while (!*irq_stat);
3011b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre
3021b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre	/* enable clock switching */
3031b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre	asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
3041b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre}
3051b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init ebsa110_init(void)
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3081b7f72fc395d3d2b498fee5ecfb9e46497f55cddNicolas Pitre	arm_pm_idle = ebsa110_idle;
30937bb30e86bc2e48d9affb25f6ce9eb3d8e65b2acRussell King	return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsarch_initcall(ebsa110_init);
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3147b6d864b48d95e6ea1df7df64475b9cb9616dcf9Robin Holtstatic void ebsa110_restart(enum reboot_mode mode, const char *cmd)
315da908260f21225d6f19ab29cfa401e550000eeaeRussell King{
316da908260f21225d6f19ab29cfa401e550000eeaeRussell King	soft_restart(0x80000000);
317da908260f21225d6f19ab29cfa401e550000eeaeRussell King}
318da908260f21225d6f19ab29cfa401e550000eeaeRussell King
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMACHINE_START(EBSA110, "EBSA110")
320e9dea0c65d2de6981356c055781fb99d7191b14eRussell King	/* Maintainer: Russell King */
3215eb980f3b8e51ac695bf06febd2bc0838fafc2daNicolas Pitre	.atag_offset	= 0x400,
322e9dea0c65d2de6981356c055781fb99d7191b14eRussell King	.reserve_lp0	= 1,
323e9dea0c65d2de6981356c055781fb99d7191b14eRussell King	.reserve_lp2	= 1,
324e9dea0c65d2de6981356c055781fb99d7191b14eRussell King	.map_io		= ebsa110_map_io,
325ed5bf6e884dc176acdd17cbc653154dc02718239Rob Herring	.init_early	= ebsa110_init_early,
326e9dea0c65d2de6981356c055781fb99d7191b14eRussell King	.init_irq	= ebsa110_init_irq,
3276bb27d7349db51b50c40534710fe164ca0d58902Stephen Warren	.init_time	= ebsa110_timer_init,
328da908260f21225d6f19ab29cfa401e550000eeaeRussell King	.restart	= ebsa110_restart,
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMACHINE_END
330