Commit 84d00883 authored by Russell King's avatar Russell King

Clean up sa1111 initialisation. Provide sa1111 base 'device' in the

device tree.  Move towards using ioremap to map the sa1111 device.
parent 11c7f84a
......@@ -52,26 +52,10 @@ static int __init adsbitsy_init(void)
/*
* Probe for SA1111.
*/
ret = sa1111_probe(0x18000000);
ret = sa1111_init(NULL, 0x18000000, IRQ_GPIO0);
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* Enable PWM control for LCD
*/
......@@ -81,20 +65,6 @@ static int __init adsbitsy_init(void)
SKPWM1 = 0x01; // Backlight
SKPEN1 = 1;
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
sa1111_init_irq(IRQ_GPIO0);
return 0;
}
......
......@@ -34,8 +34,6 @@
static int __init badge4_sa1111_init(void)
{
int ret;
/*
* Ensure that the memory bus request/grant signals are setup,
* and the grant is held in its inactive state
......@@ -45,40 +43,7 @@ static int __init badge4_sa1111_init(void)
/*
* Probe for SA1111.
*/
ret = sa1111_probe(BADGE4_SA1111_BASE);
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
sa1111_init_irq(BADGE4_IRQ_GPIO_SA1111);
return 0;
return sa1111_init(NULL, BADGE4_SA1111_BASE, BADGE4_IRQ_GPIO_SA1111);
}
static int __init badge4_init(void)
......
......@@ -42,26 +42,10 @@ static int __init graphicsmaster_init(void)
/*
* Probe for SA1111.
*/
ret = sa1111_probe(0x18000000);
ret = sa1111_init(NULL, 0x18000000, ADS_EXT_IRQ(0));
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* Enable PWM control for LCD
*/
......@@ -71,19 +55,6 @@ static int __init graphicsmaster_init(void)
SKPWM1 = 0x01; // Backlight
SKPEN1 = 1;
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
sa1111_init_irq(ADS_EXT_IRQ(0));
return 0;
}
......
......@@ -10,6 +10,7 @@
#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/serial_core.h>
#include <linux/device.h>
#include <asm/hardware.h>
#include <asm/irq.h>
......@@ -21,6 +22,10 @@
#include "sa1111.h"
static struct device neponset_device = {
name: "Neponset",
bus_id: "nep_bus",
};
/*
* Install handler for Neponset IRQ. Note that we have to loop here
......@@ -125,6 +130,10 @@ static int __init neponset_init(void)
return -ENODEV;
}
ret = device_register(&neponset_device);
if (ret)
return ret;
neponset_init_irq();
/*
......@@ -139,45 +148,9 @@ static int __init neponset_init(void)
/* FIXME: setup MSC2 */
/*
* Probe for a SA1111.
*/
ret = sa1111_probe(0x40000000);
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
* Probe and initialise the SA1111.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
/*
* Initialise SA1111 IRQs
*/
sa1111_init_irq(IRQ_NEPONSET_SA1111);
return 0;
return sa1111_init(&neponset_device, 0x40000000, IRQ_NEPONSET_SA1111);
}
__initcall(neponset_init);
......
......@@ -35,40 +35,7 @@ static int __init pfs168_init(void)
/*
* Probe for SA1111.
*/
ret = sa1111_probe(0x40000000);
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
sa1111_init_irq(IRQ_GPIO25); /* SA1111 IRQ on GPIO 25 */
return 0;
return sa1111_init(NULL, 0x40000000, IRQ_GPIO25);
}
__initcall(pfs168_init);
......
......@@ -23,8 +23,11 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
......@@ -32,11 +35,9 @@
#include "sa1111.h"
struct resource sa1111_resource = {
name: "SA1111",
};
struct sa1111_device *sa1111;
EXPORT_SYMBOL(sa1111_resource);
EXPORT_SYMBOL(sa1111);
/*
* SA1111 interrupt support. Since clearing an IRQ while there are
......@@ -65,6 +66,9 @@ sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
if (stat1 & 1)
do_edge_IRQ(i, irq_desc + i, regs);
/* For level-based interrupts */
desc->chip->unmask(irq);
}
#define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START))
......@@ -198,7 +202,7 @@ static struct irqchip sa1111_high_chip = {
type: sa1111_type_highirq,
};
void __init sa1111_init_irq(int irq_nr)
static void __init sa1111_init_irq(int irq_nr)
{
unsigned int irq;
......@@ -239,6 +243,21 @@ void __init sa1111_init_irq(int irq_nr)
set_irq_chained_handler(irq_nr, sa1111_irq_handler);
}
static int sa1111_suspend(struct device *dev, u32 state, u32 level)
{
return 0;
}
static int sa1111_resume(struct device *dev, u32 level)
{
return 0;
}
static struct device_driver sa1111_device_driver = {
suspend: sa1111_suspend,
resume: sa1111_resume,
};
/**
* sa1111_probe - probe for a single SA1111 chip.
* @phys_addr: physical address of device.
......@@ -251,38 +270,71 @@ void __init sa1111_init_irq(int irq_nr)
* %-EBUSY physical address already marked in-use.
* %0 successful.
*/
int __init sa1111_probe(unsigned long phys_addr)
static int __init
sa1111_probe(struct device *parent, unsigned long phys_addr)
{
struct sa1111_device *sa;
unsigned long id;
int ret = -ENODEV;
sa1111_resource.start = phys_addr;
sa1111_resource.end = phys_addr + 0x2000;
sa = kmalloc(sizeof(struct sa1111_device), GFP_KERNEL);
if (!sa)
return -ENOMEM;
memset(sa, 0, sizeof(struct sa1111_device));
sa->resource.name = "SA1111";
sa->resource.start = phys_addr;
sa->resource.end = phys_addr + 0x2000;
if (request_resource(&iomem_resource, &sa1111_resource)) {
if (request_resource(&iomem_resource, &sa->resource)) {
ret = -EBUSY;
goto out;
}
/* eventually ioremap... */
sa->base = (void *)0xf4000000;
if (!sa->base) {
ret = -ENOMEM;
goto release;
}
/*
* Probe for the chip. Only touch the SBI registers.
*/
id = SBI_SKID;
id = readl(sa->base + SA1111_SKID);
if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id);
ret = -ENODEV;
goto release;
goto unmap;
}
/*
* We found the chip.
*/
strcpy(sa->dev.name, "SA1111");
sprintf(sa->dev.bus_id, "%8.8lx", phys_addr);
sa->dev.parent = parent;
sa->dev.driver = &sa1111_device_driver;
ret = device_register(&sa->dev);
if (ret)
printk("sa1111 device_register failed: %d\n", ret);
printk(KERN_INFO "SA1111 Microprocessor Companion Chip: "
"silicon revision %lx, metal revision %lx\n",
(id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
sa1111 = sa;
return 0;
unmap:
// iounmap(sa->base);
release:
release_resource(&sa1111_resource);
release_resource(&sa->resource);
out:
kfree(sa);
return ret;
}
......@@ -302,7 +354,8 @@ int __init sa1111_probe(unsigned long phys_addr)
*/
void sa1111_wake(void)
{
unsigned long flags;
struct sa1111_device *sa = sa1111;
unsigned long flags, r;
local_irq_save(flags);
......@@ -317,8 +370,11 @@ void sa1111_wake(void)
/*
* Turn VCO on, and disable PLL Bypass.
*/
SBI_SKCR &= ~SKCR_VCO_OFF;
SBI_SKCR |= SKCR_PLL_BYPASS | SKCR_OE_EN;
r = readl(sa->base + SA1111_SKCR);
r &= ~SKCR_VCO_OFF;
writel(r, sa->base + SA1111_SKCR);
r |= SKCR_PLL_BYPASS | SKCR_OE_EN;
writel(r, sa->base + SA1111_SKCR);
/*
* Wait lock time. SA1111 manual _doesn't_
......@@ -329,7 +385,8 @@ void sa1111_wake(void)
/*
* Enable RCLK. We also ensure that RDYEN is set.
*/
SBI_SKCR |= SKCR_RCLKEN | SKCR_RDYEN;
r |= SKCR_RCLKEN | SKCR_RDYEN;
writel(r, sa->base + SA1111_SKCR);
/*
* Wait 14 RCLK cycles for the chip to finish coming out
......@@ -340,18 +397,26 @@ void sa1111_wake(void)
/*
* Ensure all clocks are initially off.
*/
SKPCR = 0;
writel(0, sa->base + SA1111_SKPCR);
local_irq_restore(flags);
}
void sa1111_doze(void)
{
if (SKPCR & SKPCR_UCLKEN) {
struct sa1111_device *sa = sa1111;
unsigned long flags;
local_irq_save(flags);
if (readl(sa->base + SA1111_SKPCR) & SKPCR_UCLKEN) {
local_irq_restore(flags);
printk("SA1111 doze mode refused\n");
return;
}
SBI_SKCR &= ~SKCR_RCLKEN;
writel(readl(sa->base + SA1111_SKCR) & ~SKCR_RCLKEN, sa->base + SA1111_SKCR);
local_irq_restore(flags);
}
/*
......@@ -359,12 +424,13 @@ void sa1111_doze(void)
*/
void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency)
{
struct sa1111_device *sa = sa1111;
unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC);
if (cas_latency == 3)
smcr |= SMCR_CLAT;
SBI_SMCR = smcr;
writel(smcr, sa->base + SA1111_SMCR);
}
/* According to the "Intel StrongARM SA-1111 Microprocessor Companion
......@@ -432,3 +498,46 @@ int sa1111_check_dma_bug(dma_addr_t addr)
}
EXPORT_SYMBOL(sa1111_check_dma_bug);
int sa1111_init(struct device *parent, unsigned long phys, unsigned int irq)
{
int ret;
ret = sa1111_probe(parent, phys);
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
/*
* Initialise SA1111 IRQs
*/
sa1111_init_irq(irq);
return 0;
}
/*
* linux/arch/arm/mach-sa1100/sa1111.h
*/
struct device;
/*
* Probe for a SA1111 chip.
*/
extern int sa1111_probe(unsigned long phys);
extern int
sa1111_init(struct device *parent, unsigned long phys, unsigned int irq);
/*
* Wake up a SA1111 chip.
......@@ -16,9 +18,3 @@ extern void sa1111_wake(void);
* Doze the SA1111 chip.
*/
extern void sa1111_doze(void);
/*
* Configure the SA1111 shared memory controller.
*/
extern void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency);
extern void sa1111_init_irq(int irq_nr);
......@@ -426,45 +426,12 @@ static int __init system3_init(void)
/*
* Probe for a SA1111.
*/
ret = sa1111_probe(PT_SA1111_BASE);
ret = sa1111_init(NULL, PT_SA1111_BASE, IRQ_SYSTEM3_SA1111);
if (ret < 0) {
printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" );
goto DONE;
}
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
/*
* Initialise SA1111 IRQs
*/
sa1111_init_irq(IRQ_SYSTEM3_SA1111);
#if defined( CONFIG_CPU_FREQ )
ret = cpufreq_register_notifier(&system3_clkchg_block);
if ( ret != 0 ) {
......
......@@ -26,9 +26,7 @@
#define SA1111_v2p( x ) ((x) - SA1111_VBASE + SA1111_BASE)
#ifndef __ASSEMBLY__
extern struct resource sa1111_resource;
#define _SA1111(x) ((x) + sa1111_resource.start)
#define _SA1111(x) ((x) + sa1111->resource.start)
#endif
/*
......@@ -51,7 +49,8 @@ extern struct resource sa1111_resource;
*/
#define __CCREG(x) __REGP(SA1111_VBASE + (x))
/* System Bus Interface (SBI)
/*
* System Bus Interface (SBI)
*
* Registers
* SKCR Control Register
......@@ -127,28 +126,37 @@ extern struct resource sa1111_resource;
* SKPEN1 PWM1 Enable Register
* SKPWM1 PWM1 Clock Register
*/
#define _SKPCR _SA1111(0x0200)
#define _SKCDR _SA1111(0x0204)
#define _SKAUD _SA1111(0x0208)
#define _SKPMC _SA1111(0x020c)
#define _SKPTC _SA1111(0x0210)
#define _SKPEN0 _SA1111(0x0214)
#define _SKPWM0 _SA1111(0x0218)
#define _SKPEN1 _SA1111(0x021c)
#define _SKPWM1 _SA1111(0x0220)
#define SA1111_SKPCR 0x0200
#define SA1111_SKCDR 0x0204
#define SA1111_SKAUD 0x0208
#define SA1111_SKPMC 0x020c
#define SA1111_SKPTC 0x0210
#define SA1111_SKPEN0 0x0214
#define SA1111_SKPWN0 0x0218
#define SA1111_SKPEN1 0x021c
#define SA1111_SKPWM1 0x0220
#define _SKPCR _SA1111(SA1111_SKPCR)
#define _SKCDR _SA1111(SA1111_SKCDR)
#define _SKAUD _SA1111(SA1111_SKAUD)
#define _SKPMC _SA1111(SA1111_SKPMC)
#define _SKPTC _SA1111(SA1111_SKPTC)
#define _SKPEN0 _SA1111(SA1111_SKPEN0)
#define _SKPWM0 _SA1111(SA1111_SKPWM0)
#define _SKPEN1 _SA1111(SA1111_SKPEN1)
#define _SKPWM1 _SA1111(SA1111_SKPWM1)
#if LANGUAGE == C
#define SKPCR __CCREG(0x0200)
#define SKCDR __CCREG(0x0204)
#define SKAUD __CCREG(0x0208)
#define SKPMC __CCREG(0x020c)
#define SKPTC __CCREG(0x0210)
#define SKPEN0 __CCREG(0x0214)
#define SKPWM0 __CCREG(0x0218)
#define SKPEN1 __CCREG(0x021c)
#define SKPWM1 __CCREG(0x0220)
#define SKPCR __CCREG(SA1111_SKPCR)
#define SKCDR __CCREG(SA1111_SKCDR)
#define SKAUD __CCREG(SA1111_SKAUD)
#define SKPMC __CCREG(SA1111_SKPMC)
#define SKPTC __CCREG(SA1111_SKPTC)
#define SKPEN0 __CCREG(SA1111_SKPEN0)
#define SKPWM0 __CCREG(SA1111_SKPWM0)
#define SKPEN1 __CCREG(SA1111_SKPEN1)
#define SKPWM1 __CCREG(SA1111_SKPWM1)
#endif /* LANGUAGE == C */
......@@ -675,4 +683,12 @@ extern struct resource sa1111_resource;
#define PCSSR_S0_SLEEP (1<<0)
#define PCSSR_S1_SLEEP (1<<1)
struct sa1111_device {
struct device dev;
struct resource resource;
void *base;
};
extern struct sa1111_device *sa1111;
#endif /* _ASM_ARCH_SA1111 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment