summaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap/at32ap7000.c
diff options
context:
space:
mode:
authorHaavard Skinnemoen2007-06-04 12:58:30 +0200
committerHaavard Skinnemoen2007-07-18 20:45:51 +0200
commit7a5b80590772c29bba1d54d3685622177d6fe39f (patch)
treed643198d28f6578febc2bcc0317a0681f951e62b /arch/avr32/mach-at32ap/at32ap7000.c
parent[AVR32] faster avr32 unaligned access (diff)
downloadkernel-qcow2-linux-7a5b80590772c29bba1d54d3685622177d6fe39f.tar.gz
kernel-qcow2-linux-7a5b80590772c29bba1d54d3685622177d6fe39f.tar.xz
kernel-qcow2-linux-7a5b80590772c29bba1d54d3685622177d6fe39f.zip
[AVR32] Split SM device into PM, RTC, WDT and EIC
Split the SM platform device into separate platform devices for PM, RTC, WDT and EIC. This is more correct according to the documentation and allows us to simplify the code a little. Also turn the EIC driver into a real platform driver. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com> Acked-by: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
Diffstat (limited to 'arch/avr32/mach-at32ap/at32ap7000.c')
-rw-r--r--arch/avr32/mach-at32ap/at32ap7000.c213
1 files changed, 124 insertions, 89 deletions
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
index 4dda42d3f6d5..5faa97e5ab16 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -17,14 +17,20 @@
#include <asm/arch/at32ap7000.h>
#include <asm/arch/board.h>
#include <asm/arch/portmux.h>
-#include <asm/arch/sm.h>
#include <video/atmel_lcdc.h>
#include "clock.h"
#include "hmatrix.h"
#include "pio.h"
-#include "sm.h"
+#include "pm.h"
+
+/*
+ * We can reduce the code size a bit by using a constant here. Since
+ * this file is completely chip-specific, it's safe to not use
+ * ioremap. Generic drivers should of course never do this.
+ */
+#define AT32_PM_BASE 0xfff00000
#define PBMEM(base) \
{ \
@@ -88,6 +94,8 @@ static struct clk devname##_##_name = { \
.index = _index, \
}
+static DEFINE_SPINLOCK(pm_lock);
+
unsigned long at32ap7000_osc_rates[3] = {
[0] = 32768,
/* FIXME: these are ATSTK1002-specific */
@@ -104,11 +112,11 @@ static unsigned long pll_get_rate(struct clk *clk, unsigned long control)
{
unsigned long div, mul, rate;
- if (!(control & SM_BIT(PLLEN)))
+ if (!(control & PM_BIT(PLLEN)))
return 0;
- div = SM_BFEXT(PLLDIV, control) + 1;
- mul = SM_BFEXT(PLLMUL, control) + 1;
+ div = PM_BFEXT(PLLDIV, control) + 1;
+ mul = PM_BFEXT(PLLMUL, control) + 1;
rate = clk->parent->get_rate(clk->parent);
rate = (rate + div / 2) / div;
@@ -121,7 +129,7 @@ static unsigned long pll0_get_rate(struct clk *clk)
{
u32 control;
- control = sm_readl(&system_manager, PM_PLL0);
+ control = pm_readl(PLL0);
return pll_get_rate(clk, control);
}
@@ -130,7 +138,7 @@ static unsigned long pll1_get_rate(struct clk *clk)
{
u32 control;
- control = sm_readl(&system_manager, PM_PLL1);
+ control = pm_readl(PLL1);
return pll_get_rate(clk, control);
}
@@ -187,108 +195,104 @@ static unsigned long bus_clk_get_rate(struct clk *clk, unsigned int shift)
static void cpu_clk_mode(struct clk *clk, int enabled)
{
- struct at32_sm *sm = &system_manager;
unsigned long flags;
u32 mask;
- spin_lock_irqsave(&sm->lock, flags);
- mask = sm_readl(sm, PM_CPU_MASK);
+ spin_lock_irqsave(&pm_lock, flags);
+ mask = pm_readl(CPU_MASK);
if (enabled)
mask |= 1 << clk->index;
else
mask &= ~(1 << clk->index);
- sm_writel(sm, PM_CPU_MASK, mask);
- spin_unlock_irqrestore(&sm->lock, flags);
+ pm_writel(CPU_MASK, mask);
+ spin_unlock_irqrestore(&pm_lock, flags);
}
static unsigned long cpu_clk_get_rate(struct clk *clk)
{
unsigned long cksel, shift = 0;
- cksel = sm_readl(&system_manager, PM_CKSEL);
- if (cksel & SM_BIT(CPUDIV))
- shift = SM_BFEXT(CPUSEL, cksel) + 1;
+ cksel = pm_readl(CKSEL);
+ if (cksel & PM_BIT(CPUDIV))
+ shift = PM_BFEXT(CPUSEL, cksel) + 1;
return bus_clk_get_rate(clk, shift);
}
static void hsb_clk_mode(struct clk *clk, int enabled)
{
- struct at32_sm *sm = &system_manager;
unsigned long flags;
u32 mask;
- spin_lock_irqsave(&sm->lock, flags);
- mask = sm_readl(sm, PM_HSB_MASK);
+ spin_lock_irqsave(&pm_lock, flags);
+ mask = pm_readl(HSB_MASK);
if (enabled)
mask |= 1 << clk->index;
else
mask &= ~(1 << clk->index);
- sm_writel(sm, PM_HSB_MASK, mask);
- spin_unlock_irqrestore(&sm->lock, flags);
+ pm_writel(HSB_MASK, mask);
+ spin_unlock_irqrestore(&pm_lock, flags);
}
static unsigned long hsb_clk_get_rate(struct clk *clk)
{
unsigned long cksel, shift = 0;
- cksel = sm_readl(&system_manager, PM_CKSEL);
- if (cksel & SM_BIT(HSBDIV))
- shift = SM_BFEXT(HSBSEL, cksel) + 1;
+ cksel = pm_readl(CKSEL);
+ if (cksel & PM_BIT(HSBDIV))
+ shift = PM_BFEXT(HSBSEL, cksel) + 1;
return bus_clk_get_rate(clk, shift);
}
static void pba_clk_mode(struct clk *clk, int enabled)
{
- struct at32_sm *sm = &system_manager;
unsigned long flags;
u32 mask;
- spin_lock_irqsave(&sm->lock, flags);
- mask = sm_readl(sm, PM_PBA_MASK);
+ spin_lock_irqsave(&pm_lock, flags);
+ mask = pm_readl(PBA_MASK);
if (enabled)
mask |= 1 << clk->index;
else
mask &= ~(1 << clk->index);
- sm_writel(sm, PM_PBA_MASK, mask);
- spin_unlock_irqrestore(&sm->lock, flags);
+ pm_writel(PBA_MASK, mask);
+ spin_unlock_irqrestore(&pm_lock, flags);
}
static unsigned long pba_clk_get_rate(struct clk *clk)
{
unsigned long cksel, shift = 0;
- cksel = sm_readl(&system_manager, PM_CKSEL);
- if (cksel & SM_BIT(PBADIV))
- shift = SM_BFEXT(PBASEL, cksel) + 1;
+ cksel = pm_readl(CKSEL);
+ if (cksel & PM_BIT(PBADIV))
+ shift = PM_BFEXT(PBASEL, cksel) + 1;
return bus_clk_get_rate(clk, shift);
}
static void pbb_clk_mode(struct clk *clk, int enabled)
{
- struct at32_sm *sm = &system_manager;
unsigned long flags;
u32 mask;
- spin_lock_irqsave(&sm->lock, flags);
- mask = sm_readl(sm, PM_PBB_MASK);
+ spin_lock_irqsave(&pm_lock, flags);
+ mask = pm_readl(PBB_MASK);
if (enabled)
mask |= 1 << clk->index;
else
mask &= ~(1 << clk->index);
- sm_writel(sm, PM_PBB_MASK, mask);
- spin_unlock_irqrestore(&sm->lock, flags);
+ pm_writel(PBB_MASK, mask);
+ spin_unlock_irqrestore(&pm_lock, flags);
}
static unsigned long pbb_clk_get_rate(struct clk *clk)
{
unsigned long cksel, shift = 0;
- cksel = sm_readl(&system_manager, PM_CKSEL);
- if (cksel & SM_BIT(PBBDIV))
- shift = SM_BFEXT(PBBSEL, cksel) + 1;
+ cksel = pm_readl(CKSEL);
+ if (cksel & PM_BIT(PBBDIV))
+ shift = PM_BFEXT(PBBSEL, cksel) + 1;
return bus_clk_get_rate(clk, shift);
}
@@ -327,12 +331,12 @@ static void genclk_mode(struct clk *clk, int enabled)
{
u32 control;
- control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
+ control = pm_readl(GCCTRL(clk->index));
if (enabled)
- control |= SM_BIT(CEN);
+ control |= PM_BIT(CEN);
else
- control &= ~SM_BIT(CEN);
- sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, control);
+ control &= ~PM_BIT(CEN);
+ pm_writel(GCCTRL(clk->index), control);
}
static unsigned long genclk_get_rate(struct clk *clk)
@@ -340,9 +344,9 @@ static unsigned long genclk_get_rate(struct clk *clk)
u32 control;
unsigned long div = 1;
- control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
- if (control & SM_BIT(DIVEN))
- div = 2 * (SM_BFEXT(DIV, control) + 1);
+ control = pm_readl(GCCTRL(clk->index));
+ if (control & PM_BIT(DIVEN))
+ div = 2 * (PM_BFEXT(DIV, control) + 1);
return clk->parent->get_rate(clk->parent) / div;
}
@@ -353,23 +357,22 @@ static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply)
unsigned long parent_rate, actual_rate, div;
parent_rate = clk->parent->get_rate(clk->parent);
- control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
+ control = pm_readl(GCCTRL(clk->index));
if (rate > 3 * parent_rate / 4) {
actual_rate = parent_rate;
- control &= ~SM_BIT(DIVEN);
+ control &= ~PM_BIT(DIVEN);
} else {
div = (parent_rate + rate) / (2 * rate) - 1;
- control = SM_BFINS(DIV, div, control) | SM_BIT(DIVEN);
+ control = PM_BFINS(DIV, div, control) | PM_BIT(DIVEN);
actual_rate = parent_rate / (2 * (div + 1));
}
- printk("clk %s: new rate %lu (actual rate %lu)\n",
- clk->name, rate, actual_rate);
+ dev_dbg(clk->dev, "clk %s: new rate %lu (actual rate %lu)\n",
+ clk->name, rate, actual_rate);
if (apply)
- sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index,
- control);
+ pm_writel(GCCTRL(clk->index), control);
return actual_rate;
}
@@ -378,24 +381,24 @@ int genclk_set_parent(struct clk *clk, struct clk *parent)
{
u32 control;
- printk("clk %s: new parent %s (was %s)\n",
- clk->name, parent->name, clk->parent->name);
+ dev_dbg(clk->dev, "clk %s: new parent %s (was %s)\n",
+ clk->name, parent->name, clk->parent->name);
- control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
+ control = pm_readl(GCCTRL(clk->index));
if (parent == &osc1 || parent == &pll1)
- control |= SM_BIT(OSCSEL);
+ control |= PM_BIT(OSCSEL);
else if (parent == &osc0 || parent == &pll0)
- control &= ~SM_BIT(OSCSEL);
+ control &= ~PM_BIT(OSCSEL);
else
return -EINVAL;
if (parent == &pll0 || parent == &pll1)
- control |= SM_BIT(PLLSEL);
+ control |= PM_BIT(PLLSEL);
else
- control &= ~SM_BIT(PLLSEL);
+ control &= ~PM_BIT(PLLSEL);
- sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, control);
+ pm_writel(GCCTRL(clk->index), control);
clk->parent = parent;
return 0;
@@ -408,11 +411,11 @@ static void __init genclk_init_parent(struct clk *clk)
BUG_ON(clk->index > 7);
- control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
- if (control & SM_BIT(OSCSEL))
- parent = (control & SM_BIT(PLLSEL)) ? &pll1 : &osc1;
+ control = pm_readl(GCCTRL(clk->index));
+ if (control & PM_BIT(OSCSEL))
+ parent = (control & PM_BIT(PLLSEL)) ? &pll1 : &osc1;
else
- parent = (control & SM_BIT(PLLSEL)) ? &pll0 : &osc0;
+ parent = (control & PM_BIT(PLLSEL)) ? &pll0 : &osc0;
clk->parent = parent;
}
@@ -420,21 +423,53 @@ static void __init genclk_init_parent(struct clk *clk)
/* --------------------------------------------------------------------
* System peripherals
* -------------------------------------------------------------------- */
-static struct resource sm_resource[] = {
- PBMEM(0xfff00000),
- NAMED_IRQ(19, "eim"),
- NAMED_IRQ(20, "pm"),
- NAMED_IRQ(21, "rtc"),
+static struct resource at32_pm0_resource[] = {
+ {
+ .start = 0xfff00000,
+ .end = 0xfff0007f,
+ .flags = IORESOURCE_MEM,
+ },
+ IRQ(20),
};
-struct platform_device at32_sm_device = {
- .name = "sm",
- .id = 0,
- .resource = sm_resource,
- .num_resources = ARRAY_SIZE(sm_resource),
+
+static struct resource at32ap700x_rtc0_resource[] = {
+ {
+ .start = 0xfff00080,
+ .end = 0xfff000af,
+ .flags = IORESOURCE_MEM,
+ },
+ IRQ(21),
};
-static struct clk at32_sm_pclk = {
+
+static struct resource at32_wdt0_resource[] = {
+ {
+ .start = 0xfff000b0,
+ .end = 0xfff000bf,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource at32_eic0_resource[] = {
+ {
+ .start = 0xfff00100,
+ .end = 0xfff0013f,
+ .flags = IORESOURCE_MEM,
+ },
+ IRQ(19),
+};
+
+DEFINE_DEV(at32_pm, 0);
+DEFINE_DEV(at32ap700x_rtc, 0);
+DEFINE_DEV(at32_wdt, 0);
+DEFINE_DEV(at32_eic, 0);
+
+/*
+ * Peripheral clock for PM, RTC, WDT and EIC. PM will ensure that this
+ * is always running.
+ */
+static struct clk at32_pm_pclk = {
.name = "pclk",
- .dev = &at32_sm_device.dev,
+ .dev = &at32_pm0_device.dev,
.parent = &pbb_clk,
.mode = pbb_clk_mode,
.get_rate = pbb_clk_get_rate,
@@ -583,10 +618,11 @@ DEV_CLK(mck, pio4, pba, 14);
void __init at32_add_system_devices(void)
{
- system_manager.eim_first_irq = EIM_IRQ_BASE;
-
- platform_device_register(&at32_sm_device);
+ platform_device_register(&at32_pm0_device);
platform_device_register(&at32_intc0_device);
+ platform_device_register(&at32ap700x_rtc0_device);
+ platform_device_register(&at32_wdt0_device);
+ platform_device_register(&at32_eic0_device);
platform_device_register(&smc0_device);
platform_device_register(&pdc_device);
@@ -1066,7 +1102,7 @@ struct clk *at32_clock_list[] = {
&hsb_clk,
&pba_clk,
&pbb_clk,
- &at32_sm_pclk,
+ &at32_pm_pclk,
&at32_intc0_pclk,
&hmatrix_clk,
&ebi_clk,
@@ -1113,18 +1149,17 @@ void __init at32_portmux_init(void)
void __init at32_clock_init(void)
{
- struct at32_sm *sm = &system_manager;
u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0;
int i;
- if (sm_readl(sm, PM_MCCTRL) & SM_BIT(PLLSEL))
+ if (pm_readl(MCCTRL) & PM_BIT(PLLSEL))
main_clock = &pll0;
else
main_clock = &osc0;
- if (sm_readl(sm, PM_PLL0) & SM_BIT(PLLOSC))
+ if (pm_readl(PLL0) & PM_BIT(PLLOSC))
pll0.parent = &osc1;
- if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC))
+ if (pm_readl(PLL1) & PM_BIT(PLLOSC))
pll1.parent = &osc1;
genclk_init_parent(&gclk0);
@@ -1157,8 +1192,8 @@ void __init at32_clock_init(void)
pbb_mask |= 1 << clk->index;
}
- sm_writel(sm, PM_CPU_MASK, cpu_mask);
- sm_writel(sm, PM_HSB_MASK, hsb_mask);
- sm_writel(sm, PM_PBA_MASK, pba_mask);
- sm_writel(sm, PM_PBB_MASK, pbb_mask);
+ pm_writel(CPU_MASK, cpu_mask);
+ pm_writel(HSB_MASK, hsb_mask);
+ pm_writel(PBA_MASK, pba_mask);
+ pm_writel(PBB_MASK, pbb_mask);
}