aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ep93xx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-ep93xx')
-rw-r--r--arch/arm/mach-ep93xx/clock.c24
-rw-r--r--arch/arm/mach-ep93xx/core.c52
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h36
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h16
-rw-r--r--arch/arm/mach-ep93xx/include/mach/system.h12
5 files changed, 109 insertions, 31 deletions
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 6c4c1633ed12..c7642acfd022 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -50,20 +50,20 @@ static unsigned long get_uart_rate(struct clk *clk);
static struct clk clk_uart1 = {
.sw_locked = 1,
- .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG,
- .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U1EN,
+ .enable_reg = EP93XX_SYSCON_DEVCFG,
+ .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN,
.get_rate = get_uart_rate,
};
static struct clk clk_uart2 = {
.sw_locked = 1,
- .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG,
- .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U2EN,
+ .enable_reg = EP93XX_SYSCON_DEVCFG,
+ .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN,
.get_rate = get_uart_rate,
};
static struct clk clk_uart3 = {
.sw_locked = 1,
- .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG,
- .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U3EN,
+ .enable_reg = EP93XX_SYSCON_DEVCFG,
+ .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN,
.get_rate = get_uart_rate,
};
static struct clk clk_pll1;
@@ -160,9 +160,11 @@ int clk_enable(struct clk *clk)
u32 value;
value = __raw_readl(clk->enable_reg);
+ value |= clk->enable_mask;
if (clk->sw_locked)
- __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
- __raw_writel(value | clk->enable_mask, clk->enable_reg);
+ ep93xx_syscon_swlocked_write(value, clk->enable_reg);
+ else
+ __raw_writel(value, clk->enable_reg);
}
return 0;
@@ -175,9 +177,11 @@ void clk_disable(struct clk *clk)
u32 value;
value = __raw_readl(clk->enable_reg);
+ value &= ~clk->enable_mask;
if (clk->sw_locked)
- __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
- __raw_writel(value & ~clk->enable_mask, clk->enable_reg);
+ ep93xx_syscon_swlocked_write(value, clk->enable_reg);
+ else
+ __raw_writel(value, clk->enable_reg);
}
}
EXPORT_SYMBOL(clk_disable);
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 204dc5cbd0b8..9399d3af9906 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -385,6 +385,47 @@ void __init ep93xx_init_irq(void)
/*************************************************************************
+ * EP93xx System Controller Software Locked register handling
+ *************************************************************************/
+
+/*
+ * syscon_swlock prevents anything else from writing to the syscon
+ * block while a software locked register is being written.
+ */
+static DEFINE_SPINLOCK(syscon_swlock);
+
+void ep93xx_syscon_swlocked_write(unsigned int val, unsigned int reg)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&syscon_swlock, flags);
+
+ __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+ __raw_writel(val, reg);
+
+ spin_unlock_irqrestore(&syscon_swlock, flags);
+}
+EXPORT_SYMBOL(ep93xx_syscon_swlocked_write);
+
+void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
+{
+ unsigned long flags;
+ unsigned int val;
+
+ spin_lock_irqsave(&syscon_swlock, flags);
+
+ val = __raw_readl(EP93XX_SYSCON_DEVCFG);
+ val |= set_bits;
+ val &= ~clear_bits;
+ __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+ __raw_writel(val, EP93XX_SYSCON_DEVCFG);
+
+ spin_unlock_irqrestore(&syscon_swlock, flags);
+}
+EXPORT_SYMBOL(ep93xx_devcfg_set_clear);
+
+
+/*************************************************************************
* EP93xx peripheral handling
*************************************************************************/
#define EP93XX_UART_MCR_OFFSET (0x0100)
@@ -550,15 +591,8 @@ extern void ep93xx_gpio_init(void);
void __init ep93xx_init_devices(void)
{
- unsigned int v;
-
- /*
- * Disallow access to MaverickCrunch initially.
- */
- v = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
- v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
- __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
- __raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG);
+ /* Disallow access to MaverickCrunch initially */
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
ep93xx_gpio_init();
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index 49b256b3ddfc..087d22b8f351 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -175,11 +175,37 @@
#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c)
#define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20)
#define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24)
-#define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80)
-#define EP93XX_SYSCON_DEVICE_CONFIG_U3EN (1<<24)
-#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE (1<<23)
-#define EP93XX_SYSCON_DEVICE_CONFIG_U2EN (1<<20)
-#define EP93XX_SYSCON_DEVICE_CONFIG_U1EN (1<<18)
+#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80)
+#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31)
+#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30)
+#define EP93XX_SYSCON_DEVCFG_D0ONG (1<<29)
+#define EP93XX_SYSCON_DEVCFG_IONU2 (1<<28)
+#define EP93XX_SYSCON_DEVCFG_GONK (1<<27)
+#define EP93XX_SYSCON_DEVCFG_TONG (1<<26)
+#define EP93XX_SYSCON_DEVCFG_MONG (1<<25)
+#define EP93XX_SYSCON_DEVCFG_U3EN (1<<24)
+#define EP93XX_SYSCON_DEVCFG_CPENA (1<<23)
+#define EP93XX_SYSCON_DEVCFG_A2ONG (1<<22)
+#define EP93XX_SYSCON_DEVCFG_A1ONG (1<<21)
+#define EP93XX_SYSCON_DEVCFG_U2EN (1<<20)
+#define EP93XX_SYSCON_DEVCFG_EXVC (1<<19)
+#define EP93XX_SYSCON_DEVCFG_U1EN (1<<18)
+#define EP93XX_SYSCON_DEVCFG_TIN (1<<17)
+#define EP93XX_SYSCON_DEVCFG_HC3IN (1<<15)
+#define EP93XX_SYSCON_DEVCFG_HC3EN (1<<14)
+#define EP93XX_SYSCON_DEVCFG_HC1IN (1<<13)
+#define EP93XX_SYSCON_DEVCFG_HC1EN (1<<12)
+#define EP93XX_SYSCON_DEVCFG_HONIDE (1<<11)
+#define EP93XX_SYSCON_DEVCFG_GONIDE (1<<10)
+#define EP93XX_SYSCON_DEVCFG_PONG (1<<9)
+#define EP93XX_SYSCON_DEVCFG_EONIDE (1<<8)
+#define EP93XX_SYSCON_DEVCFG_I2SONSSP (1<<7)
+#define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6)
+#define EP93XX_SYSCON_DEVCFG_RASONP3 (1<<4)
+#define EP93XX_SYSCON_DEVCFG_RAS (1<<3)
+#define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2)
+#define EP93XX_SYSCON_DEVCFG_KEYS (1<<1)
+#define EP93XX_SYSCON_DEVCFG_SHENA (1<<0)
#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000)
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 05f0f4f2f3ce..fb5e59a3ea04 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -15,8 +15,24 @@ struct ep93xx_eth_data
void ep93xx_map_io(void);
void ep93xx_init_irq(void);
void ep93xx_init_time(unsigned long);
+
+/* EP93xx System Controller software locked register write */
+void ep93xx_syscon_swlocked_write(unsigned int val, unsigned int reg);
+void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits);
+
+static inline void ep93xx_devcfg_set_bits(unsigned int bits)
+{
+ ep93xx_devcfg_set_clear(bits, 0x00);
+}
+
+static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
+{
+ ep93xx_devcfg_set_clear(0x00, bits);
+}
+
void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
+
void ep93xx_init_devices(void);
extern struct sys_timer ep93xx_timer;
diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h
index ed8f35e4f068..6d661fe9d66c 100644
--- a/arch/arm/mach-ep93xx/include/mach/system.h
+++ b/arch/arm/mach-ep93xx/include/mach/system.h
@@ -11,15 +11,13 @@ static inline void arch_idle(void)
static inline void arch_reset(char mode, const char *cmd)
{
- u32 devicecfg;
-
local_irq_disable();
- devicecfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
- __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
- __raw_writel(devicecfg | 0x80000000, EP93XX_SYSCON_DEVICE_CONFIG);
- __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
- __raw_writel(devicecfg & ~0x80000000, EP93XX_SYSCON_DEVICE_CONFIG);
+ /*
+ * Set then clear the SWRST bit to initiate a software reset
+ */
+ ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST);
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST);
while (1)
;