aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/crunch.c13
-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
6 files changed, 118 insertions, 35 deletions
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c
index 99995c2b2312..769abe15cf91 100644
--- a/arch/arm/kernel/crunch.c
+++ b/arch/arm/kernel/crunch.c
@@ -31,7 +31,7 @@ void crunch_task_release(struct thread_info *thread)
31 31
32static int crunch_enabled(u32 devcfg) 32static int crunch_enabled(u32 devcfg)
33{ 33{
34 return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); 34 return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA);
35} 35}
36 36
37static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) 37static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
@@ -56,11 +56,16 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
56 break; 56 break;
57 57
58 case THREAD_NOTIFY_SWITCH: 58 case THREAD_NOTIFY_SWITCH:
59 devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); 59 devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
60 if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { 60 if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
61 devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; 61 /*
62 * We don't use ep93xx_syscon_swlocked_write() here
63 * because we are on the context switch path and
64 * preemption is already disabled.
65 */
66 devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA;
62 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 67 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
63 __raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG); 68 __raw_writel(devcfg, EP93XX_SYSCON_DEVCFG);
64 } 69 }
65 break; 70 break;
66 } 71 }
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);
50 50
51static struct clk clk_uart1 = { 51static struct clk clk_uart1 = {
52 .sw_locked = 1, 52 .sw_locked = 1,
53 .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, 53 .enable_reg = EP93XX_SYSCON_DEVCFG,
54 .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U1EN, 54 .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN,
55 .get_rate = get_uart_rate, 55 .get_rate = get_uart_rate,
56}; 56};
57static struct clk clk_uart2 = { 57static struct clk clk_uart2 = {
58 .sw_locked = 1, 58 .sw_locked = 1,
59 .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, 59 .enable_reg = EP93XX_SYSCON_DEVCFG,
60 .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U2EN, 60 .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN,
61 .get_rate = get_uart_rate, 61 .get_rate = get_uart_rate,
62}; 62};
63static struct clk clk_uart3 = { 63static struct clk clk_uart3 = {
64 .sw_locked = 1, 64 .sw_locked = 1,
65 .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, 65 .enable_reg = EP93XX_SYSCON_DEVCFG,
66 .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U3EN, 66 .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN,
67 .get_rate = get_uart_rate, 67 .get_rate = get_uart_rate,
68}; 68};
69static struct clk clk_pll1; 69static struct clk clk_pll1;
@@ -160,9 +160,11 @@ int clk_enable(struct clk *clk)
160 u32 value; 160 u32 value;
161 161
162 value = __raw_readl(clk->enable_reg); 162 value = __raw_readl(clk->enable_reg);
163 value |= clk->enable_mask;
163 if (clk->sw_locked) 164 if (clk->sw_locked)
164 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 165 ep93xx_syscon_swlocked_write(value, clk->enable_reg);
165 __raw_writel(value | clk->enable_mask, clk->enable_reg); 166 else
167 __raw_writel(value, clk->enable_reg);
166 } 168 }
167 169
168 return 0; 170 return 0;
@@ -175,9 +177,11 @@ void clk_disable(struct clk *clk)
175 u32 value; 177 u32 value;
176 178
177 value = __raw_readl(clk->enable_reg); 179 value = __raw_readl(clk->enable_reg);
180 value &= ~clk->enable_mask;
178 if (clk->sw_locked) 181 if (clk->sw_locked)
179 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 182 ep93xx_syscon_swlocked_write(value, clk->enable_reg);
180 __raw_writel(value & ~clk->enable_mask, clk->enable_reg); 183 else
184 __raw_writel(value, clk->enable_reg);
181 } 185 }
182} 186}
183EXPORT_SYMBOL(clk_disable); 187EXPORT_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)
385 385
386 386
387/************************************************************************* 387/*************************************************************************
388 * EP93xx System Controller Software Locked register handling
389 *************************************************************************/
390
391/*
392 * syscon_swlock prevents anything else from writing to the syscon
393 * block while a software locked register is being written.
394 */
395static DEFINE_SPINLOCK(syscon_swlock);
396
397void ep93xx_syscon_swlocked_write(unsigned int val, unsigned int reg)
398{
399 unsigned long flags;
400
401 spin_lock_irqsave(&syscon_swlock, flags);
402
403 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
404 __raw_writel(val, reg);
405
406 spin_unlock_irqrestore(&syscon_swlock, flags);
407}
408EXPORT_SYMBOL(ep93xx_syscon_swlocked_write);
409
410void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
411{
412 unsigned long flags;
413 unsigned int val;
414
415 spin_lock_irqsave(&syscon_swlock, flags);
416
417 val = __raw_readl(EP93XX_SYSCON_DEVCFG);
418 val |= set_bits;
419 val &= ~clear_bits;
420 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
421 __raw_writel(val, EP93XX_SYSCON_DEVCFG);
422
423 spin_unlock_irqrestore(&syscon_swlock, flags);
424}
425EXPORT_SYMBOL(ep93xx_devcfg_set_clear);
426
427
428/*************************************************************************
388 * EP93xx peripheral handling 429 * EP93xx peripheral handling
389 *************************************************************************/ 430 *************************************************************************/
390#define EP93XX_UART_MCR_OFFSET (0x0100) 431#define EP93XX_UART_MCR_OFFSET (0x0100)
@@ -550,15 +591,8 @@ extern void ep93xx_gpio_init(void);
550 591
551void __init ep93xx_init_devices(void) 592void __init ep93xx_init_devices(void)
552{ 593{
553 unsigned int v; 594 /* Disallow access to MaverickCrunch initially */
554 595 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
555 /*
556 * Disallow access to MaverickCrunch initially.
557 */
558 v = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
559 v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
560 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
561 __raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG);
562 596
563 ep93xx_gpio_init(); 597 ep93xx_gpio_init();
564 598
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 @@
175#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) 175#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c)
176#define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) 176#define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20)
177#define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) 177#define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24)
178#define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80) 178#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80)
179#define EP93XX_SYSCON_DEVICE_CONFIG_U3EN (1<<24) 179#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31)
180#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE (1<<23) 180#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30)
181#define EP93XX_SYSCON_DEVICE_CONFIG_U2EN (1<<20) 181#define EP93XX_SYSCON_DEVCFG_D0ONG (1<<29)
182#define EP93XX_SYSCON_DEVICE_CONFIG_U1EN (1<<18) 182#define EP93XX_SYSCON_DEVCFG_IONU2 (1<<28)
183#define EP93XX_SYSCON_DEVCFG_GONK (1<<27)
184#define EP93XX_SYSCON_DEVCFG_TONG (1<<26)
185#define EP93XX_SYSCON_DEVCFG_MONG (1<<25)
186#define EP93XX_SYSCON_DEVCFG_U3EN (1<<24)
187#define EP93XX_SYSCON_DEVCFG_CPENA (1<<23)
188#define EP93XX_SYSCON_DEVCFG_A2ONG (1<<22)
189#define EP93XX_SYSCON_DEVCFG_A1ONG (1<<21)
190#define EP93XX_SYSCON_DEVCFG_U2EN (1<<20)
191#define EP93XX_SYSCON_DEVCFG_EXVC (1<<19)
192#define EP93XX_SYSCON_DEVCFG_U1EN (1<<18)
193#define EP93XX_SYSCON_DEVCFG_TIN (1<<17)
194#define EP93XX_SYSCON_DEVCFG_HC3IN (1<<15)
195#define EP93XX_SYSCON_DEVCFG_HC3EN (1<<14)
196#define EP93XX_SYSCON_DEVCFG_HC1IN (1<<13)
197#define EP93XX_SYSCON_DEVCFG_HC1EN (1<<12)
198#define EP93XX_SYSCON_DEVCFG_HONIDE (1<<11)
199#define EP93XX_SYSCON_DEVCFG_GONIDE (1<<10)
200#define EP93XX_SYSCON_DEVCFG_PONG (1<<9)
201#define EP93XX_SYSCON_DEVCFG_EONIDE (1<<8)
202#define EP93XX_SYSCON_DEVCFG_I2SONSSP (1<<7)
203#define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6)
204#define EP93XX_SYSCON_DEVCFG_RASONP3 (1<<4)
205#define EP93XX_SYSCON_DEVCFG_RAS (1<<3)
206#define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2)
207#define EP93XX_SYSCON_DEVCFG_KEYS (1<<1)
208#define EP93XX_SYSCON_DEVCFG_SHENA (1<<0)
183#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) 209#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
184 210
185#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000) 211#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
15void ep93xx_map_io(void); 15void ep93xx_map_io(void);
16void ep93xx_init_irq(void); 16void ep93xx_init_irq(void);
17void ep93xx_init_time(unsigned long); 17void ep93xx_init_time(unsigned long);
18
19/* EP93xx System Controller software locked register write */
20void ep93xx_syscon_swlocked_write(unsigned int val, unsigned int reg);
21void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits);
22
23static inline void ep93xx_devcfg_set_bits(unsigned int bits)
24{
25 ep93xx_devcfg_set_clear(bits, 0x00);
26}
27
28static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
29{
30 ep93xx_devcfg_set_clear(0x00, bits);
31}
32
18void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); 33void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
19void ep93xx_register_i2c(struct i2c_board_info *devices, int num); 34void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
35
20void ep93xx_init_devices(void); 36void ep93xx_init_devices(void);
21extern struct sys_timer ep93xx_timer; 37extern struct sys_timer ep93xx_timer;
22 38
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)
11 11
12static inline void arch_reset(char mode, const char *cmd) 12static inline void arch_reset(char mode, const char *cmd)
13{ 13{
14 u32 devicecfg;
15
16 local_irq_disable(); 14 local_irq_disable();
17 15
18 devicecfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); 16 /*
19 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 17 * Set then clear the SWRST bit to initiate a software reset
20 __raw_writel(devicecfg | 0x80000000, EP93XX_SYSCON_DEVICE_CONFIG); 18 */
21 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 19 ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST);
22 __raw_writel(devicecfg & ~0x80000000, EP93XX_SYSCON_DEVICE_CONFIG); 20 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST);
23 21
24 while (1) 22 while (1)
25 ; 23 ;