diff options
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r-- | arch/blackfin/mach-common/Makefile | 5 | ||||
-rw-r--r-- | arch/blackfin/mach-common/clock.h | 27 | ||||
-rw-r--r-- | arch/blackfin/mach-common/clocks-init.c | 153 | ||||
-rw-r--r-- | arch/blackfin/mach-common/cpufreq.c | 46 | ||||
-rw-r--r-- | arch/blackfin/mach-common/dpmc_modes.S | 606 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 7 | ||||
-rw-r--r-- | arch/blackfin/mach-common/head.S | 2 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 423 | ||||
-rw-r--r-- | arch/blackfin/mach-common/pm.c | 62 | ||||
-rw-r--r-- | arch/blackfin/mach-common/smp.c | 19 |
10 files changed, 688 insertions, 662 deletions
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile index ff299f24aba0..75f0ba29ebb9 100644 --- a/arch/blackfin/mach-common/Makefile +++ b/arch/blackfin/mach-common/Makefile | |||
@@ -6,7 +6,10 @@ obj-y := \ | |||
6 | cache.o cache-c.o entry.o head.o \ | 6 | cache.o cache-c.o entry.o head.o \ |
7 | interrupt.o arch_checks.o ints-priority.o | 7 | interrupt.o arch_checks.o ints-priority.o |
8 | 8 | ||
9 | obj-$(CONFIG_PM) += pm.o dpmc_modes.o | 9 | obj-$(CONFIG_PM) += pm.o |
10 | ifneq ($(CONFIG_BF60x),y) | ||
11 | obj-$(CONFIG_PM) += dpmc_modes.o | ||
12 | endif | ||
10 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | 13 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o |
11 | obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o | 14 | obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o |
12 | obj-$(CONFIG_SMP) += smp.o | 15 | obj-$(CONFIG_SMP) += smp.o |
diff --git a/arch/blackfin/mach-common/clock.h b/arch/blackfin/mach-common/clock.h new file mode 100644 index 000000000000..645ff460a1f2 --- /dev/null +++ b/arch/blackfin/mach-common/clock.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #ifndef __MACH_COMMON_CLKDEV_H | ||
2 | #define __MACH_COMMON_CLKDEV_H | ||
3 | |||
4 | #include <linux/clk.h> | ||
5 | |||
6 | struct clk_ops { | ||
7 | unsigned long (*get_rate)(struct clk *clk); | ||
8 | unsigned long (*round_rate)(struct clk *clk, unsigned long rate); | ||
9 | int (*set_rate)(struct clk *clk, unsigned long rate); | ||
10 | int (*enable)(struct clk *clk); | ||
11 | int (*disable)(struct clk *clk); | ||
12 | }; | ||
13 | |||
14 | struct clk { | ||
15 | const char *name; | ||
16 | unsigned long rate; | ||
17 | spinlock_t lock; | ||
18 | u32 flags; | ||
19 | const struct clk_ops *ops; | ||
20 | const struct params *params; | ||
21 | void __iomem *reg; | ||
22 | u32 mask; | ||
23 | u32 shift; | ||
24 | }; | ||
25 | |||
26 | #endif | ||
27 | |||
diff --git a/arch/blackfin/mach-common/clocks-init.c b/arch/blackfin/mach-common/clocks-init.c index d5cfe611b778..7ad2407d1571 100644 --- a/arch/blackfin/mach-common/clocks-init.c +++ b/arch/blackfin/mach-common/clocks-init.c | |||
@@ -15,10 +15,121 @@ | |||
15 | #include <asm/mem_init.h> | 15 | #include <asm/mem_init.h> |
16 | #include <asm/dpmc.h> | 16 | #include <asm/dpmc.h> |
17 | 17 | ||
18 | #ifdef CONFIG_BF60x | ||
19 | #define CSEL_P 0 | ||
20 | #define S0SEL_P 5 | ||
21 | #define SYSSEL_P 8 | ||
22 | #define S1SEL_P 13 | ||
23 | #define DSEL_P 16 | ||
24 | #define OSEL_P 22 | ||
25 | #define ALGN_P 29 | ||
26 | #define UPDT_P 30 | ||
27 | #define LOCK_P 31 | ||
28 | |||
29 | #define CGU_CTL_VAL ((CONFIG_VCO_MULT << 8) | CLKIN_HALF) | ||
30 | #define CGU_DIV_VAL \ | ||
31 | ((CONFIG_CCLK_DIV << CSEL_P) | \ | ||
32 | (CONFIG_SCLK_DIV << SYSSEL_P) | \ | ||
33 | (CONFIG_SCLK0_DIV << S0SEL_P) | \ | ||
34 | (CONFIG_SCLK1_DIV << S1SEL_P) | \ | ||
35 | (CONFIG_DCLK_DIV << DSEL_P)) | ||
36 | |||
37 | #define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000) | ||
38 | #if ((CONFIG_BFIN_DCLK != 125) && \ | ||
39 | (CONFIG_BFIN_DCLK != 133) && (CONFIG_BFIN_DCLK != 150) && \ | ||
40 | (CONFIG_BFIN_DCLK != 166) && (CONFIG_BFIN_DCLK != 200) && \ | ||
41 | (CONFIG_BFIN_DCLK != 225) && (CONFIG_BFIN_DCLK != 250)) | ||
42 | #error "DCLK must be in (125, 133, 150, 166, 200, 225, 250)MHz" | ||
43 | #endif | ||
44 | struct ddr_config { | ||
45 | u32 ddr_clk; | ||
46 | u32 dmc_ddrctl; | ||
47 | u32 dmc_ddrcfg; | ||
48 | u32 dmc_ddrtr0; | ||
49 | u32 dmc_ddrtr1; | ||
50 | u32 dmc_ddrtr2; | ||
51 | u32 dmc_ddrmr; | ||
52 | u32 dmc_ddrmr1; | ||
53 | }; | ||
54 | |||
55 | struct ddr_config ddr_config_table[] __attribute__((section(".data_l1"))) = { | ||
56 | [0] = { | ||
57 | .ddr_clk = 125, | ||
58 | .dmc_ddrctl = 0x00000904, | ||
59 | .dmc_ddrcfg = 0x00000422, | ||
60 | .dmc_ddrtr0 = 0x20705212, | ||
61 | .dmc_ddrtr1 = 0x201003CF, | ||
62 | .dmc_ddrtr2 = 0x00320107, | ||
63 | .dmc_ddrmr = 0x00000422, | ||
64 | .dmc_ddrmr1 = 0x4, | ||
65 | }, | ||
66 | [1] = { | ||
67 | .ddr_clk = 133, | ||
68 | .dmc_ddrctl = 0x00000904, | ||
69 | .dmc_ddrcfg = 0x00000422, | ||
70 | .dmc_ddrtr0 = 0x20806313, | ||
71 | .dmc_ddrtr1 = 0x2013040D, | ||
72 | .dmc_ddrtr2 = 0x00320108, | ||
73 | .dmc_ddrmr = 0x00000632, | ||
74 | .dmc_ddrmr1 = 0x4, | ||
75 | }, | ||
76 | [2] = { | ||
77 | .ddr_clk = 150, | ||
78 | .dmc_ddrctl = 0x00000904, | ||
79 | .dmc_ddrcfg = 0x00000422, | ||
80 | .dmc_ddrtr0 = 0x20A07323, | ||
81 | .dmc_ddrtr1 = 0x20160492, | ||
82 | .dmc_ddrtr2 = 0x00320209, | ||
83 | .dmc_ddrmr = 0x00000632, | ||
84 | .dmc_ddrmr1 = 0x4, | ||
85 | }, | ||
86 | [3] = { | ||
87 | .ddr_clk = 166, | ||
88 | .dmc_ddrctl = 0x00000904, | ||
89 | .dmc_ddrcfg = 0x00000422, | ||
90 | .dmc_ddrtr0 = 0x20A07323, | ||
91 | .dmc_ddrtr1 = 0x2016050E, | ||
92 | .dmc_ddrtr2 = 0x00320209, | ||
93 | .dmc_ddrmr = 0x00000632, | ||
94 | .dmc_ddrmr1 = 0x4, | ||
95 | }, | ||
96 | [4] = { | ||
97 | .ddr_clk = 200, | ||
98 | .dmc_ddrctl = 0x00000904, | ||
99 | .dmc_ddrcfg = 0x00000422, | ||
100 | .dmc_ddrtr0 = 0x20a07323, | ||
101 | .dmc_ddrtr1 = 0x2016050f, | ||
102 | .dmc_ddrtr2 = 0x00320509, | ||
103 | .dmc_ddrmr = 0x00000632, | ||
104 | .dmc_ddrmr1 = 0x4, | ||
105 | }, | ||
106 | [5] = { | ||
107 | .ddr_clk = 225, | ||
108 | .dmc_ddrctl = 0x00000904, | ||
109 | .dmc_ddrcfg = 0x00000422, | ||
110 | .dmc_ddrtr0 = 0x20E0A424, | ||
111 | .dmc_ddrtr1 = 0x302006DB, | ||
112 | .dmc_ddrtr2 = 0x0032020D, | ||
113 | .dmc_ddrmr = 0x00000842, | ||
114 | .dmc_ddrmr1 = 0x4, | ||
115 | }, | ||
116 | [6] = { | ||
117 | .ddr_clk = 250, | ||
118 | .dmc_ddrctl = 0x00000904, | ||
119 | .dmc_ddrcfg = 0x00000422, | ||
120 | .dmc_ddrtr0 = 0x20E0A424, | ||
121 | .dmc_ddrtr1 = 0x3020079E, | ||
122 | .dmc_ddrtr2 = 0x0032020D, | ||
123 | .dmc_ddrmr = 0x00000842, | ||
124 | .dmc_ddrmr1 = 0x4, | ||
125 | }, | ||
126 | }; | ||
127 | #else | ||
18 | #define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */ | 128 | #define SDGCTL_WIDTH (1 << 31) /* SDRAM external data path width */ |
19 | #define PLL_CTL_VAL \ | 129 | #define PLL_CTL_VAL \ |
20 | (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \ | 130 | (((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \ |
21 | (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000)) | 131 | (PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000)) |
132 | #endif | ||
22 | 133 | ||
23 | __attribute__((l1_text)) | 134 | __attribute__((l1_text)) |
24 | static void do_sync(void) | 135 | static void do_sync(void) |
@@ -33,6 +144,44 @@ void init_clocks(void) | |||
33 | * in the middle of reprogramming things, and that'll screw us up. | 144 | * in the middle of reprogramming things, and that'll screw us up. |
34 | * For example, any automatic DMAs left by U-Boot for splash screens. | 145 | * For example, any automatic DMAs left by U-Boot for splash screens. |
35 | */ | 146 | */ |
147 | |||
148 | #ifdef CONFIG_BF60x | ||
149 | int i, dlldatacycle, dll_ctl; | ||
150 | bfin_write32(CGU0_DIV, CGU_DIV_VAL); | ||
151 | bfin_write32(CGU0_CTL, CGU_CTL_VAL); | ||
152 | while ((bfin_read32(CGU0_STAT) & 0x8) || !(bfin_read32(CGU0_STAT) & 0x4)) | ||
153 | continue; | ||
154 | |||
155 | bfin_write32(CGU0_DIV, CGU_DIV_VAL | (1 << UPDT_P)); | ||
156 | while (bfin_read32(CGU0_STAT) & (1 << 3)) | ||
157 | continue; | ||
158 | |||
159 | for (i = 0; i < 7; i++) { | ||
160 | if (ddr_config_table[i].ddr_clk == CONFIG_BFIN_DCLK) { | ||
161 | bfin_write_DDR0_CFG(ddr_config_table[i].dmc_ddrcfg); | ||
162 | bfin_write_DDR0_TR0(ddr_config_table[i].dmc_ddrtr0); | ||
163 | bfin_write_DDR0_TR1(ddr_config_table[i].dmc_ddrtr1); | ||
164 | bfin_write_DDR0_TR2(ddr_config_table[i].dmc_ddrtr2); | ||
165 | bfin_write_DDR0_MR(ddr_config_table[i].dmc_ddrmr); | ||
166 | bfin_write_DDR0_EMR1(ddr_config_table[i].dmc_ddrmr1); | ||
167 | bfin_write_DDR0_CTL(ddr_config_table[i].dmc_ddrctl); | ||
168 | break; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | do_sync(); | ||
173 | while (!(bfin_read_DDR0_STAT() & 0x4)) | ||
174 | continue; | ||
175 | |||
176 | dlldatacycle = (bfin_read_DDR0_STAT() & 0x00f00000) >> 20; | ||
177 | dll_ctl = bfin_read_DDR0_DLLCTL(); | ||
178 | dll_ctl &= 0x0ff; | ||
179 | bfin_write_DDR0_DLLCTL(dll_ctl | (dlldatacycle << 8)); | ||
180 | |||
181 | do_sync(); | ||
182 | while (!(bfin_read_DDR0_STAT() & 0x2000)) | ||
183 | continue; | ||
184 | #else | ||
36 | size_t i; | 185 | size_t i; |
37 | for (i = 0; i < MAX_DMA_CHANNELS; ++i) { | 186 | for (i = 0; i < MAX_DMA_CHANNELS; ++i) { |
38 | struct dma_register *dma = dma_io_base_addr[i]; | 187 | struct dma_register *dma = dma_io_base_addr[i]; |
@@ -91,6 +240,8 @@ void init_clocks(void) | |||
91 | bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE); | 240 | bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE); |
92 | #endif | 241 | #endif |
93 | #endif | 242 | #endif |
243 | #endif | ||
94 | do_sync(); | 244 | do_sync(); |
95 | bfin_read16(0); | 245 | bfin_read16(0); |
246 | |||
96 | } | 247 | } |
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index 2e6eefd812f4..6e87dc13f6bf 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/clk.h> | ||
13 | #include <linux/cpufreq.h> | 14 | #include <linux/cpufreq.h> |
14 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
15 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
@@ -17,6 +18,7 @@ | |||
17 | #include <asm/time.h> | 18 | #include <asm/time.h> |
18 | #include <asm/dpmc.h> | 19 | #include <asm/dpmc.h> |
19 | 20 | ||
21 | |||
20 | /* this is the table of CCLK frequencies, in Hz */ | 22 | /* this is the table of CCLK frequencies, in Hz */ |
21 | /* .index is the entry in the auxiliary dpm_state_table[] */ | 23 | /* .index is the entry in the auxiliary dpm_state_table[] */ |
22 | static struct cpufreq_frequency_table bfin_freq_table[] = { | 24 | static struct cpufreq_frequency_table bfin_freq_table[] = { |
@@ -67,12 +69,22 @@ static void __init bfin_init_tables(unsigned long cclk, unsigned long sclk) | |||
67 | #else | 69 | #else |
68 | min_cclk = sclk; | 70 | min_cclk = sclk; |
69 | #endif | 71 | #endif |
72 | |||
73 | #ifndef CONFIG_BF60x | ||
70 | csel = ((bfin_read_PLL_DIV() & CSEL) >> 4); | 74 | csel = ((bfin_read_PLL_DIV() & CSEL) >> 4); |
75 | #else | ||
76 | csel = bfin_read32(CGU0_DIV) & 0x1F; | ||
77 | #endif | ||
71 | 78 | ||
72 | for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) { | 79 | for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) { |
73 | bfin_freq_table[index].frequency = cclk >> index; | 80 | bfin_freq_table[index].frequency = cclk >> index; |
81 | #ifndef CONFIG_BF60x | ||
74 | dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */ | 82 | dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */ |
75 | dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1; | 83 | dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1; |
84 | #else | ||
85 | dpm_state_table[index].csel = csel; | ||
86 | dpm_state_table[index].tscale = TIME_SCALE >> index; | ||
87 | #endif | ||
76 | 88 | ||
77 | pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n", | 89 | pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n", |
78 | bfin_freq_table[index].frequency, | 90 | bfin_freq_table[index].frequency, |
@@ -99,14 +111,34 @@ static unsigned int bfin_getfreq_khz(unsigned int cpu) | |||
99 | return get_cclk() / 1000; | 111 | return get_cclk() / 1000; |
100 | } | 112 | } |
101 | 113 | ||
114 | #ifdef CONFIG_BF60x | ||
115 | unsigned long cpu_set_cclk(int cpu, unsigned long new) | ||
116 | { | ||
117 | struct clk *clk; | ||
118 | int ret; | ||
119 | |||
120 | clk = clk_get(NULL, "CCLK"); | ||
121 | if (IS_ERR(clk)) | ||
122 | return -ENODEV; | ||
123 | |||
124 | ret = clk_set_rate(clk, new); | ||
125 | clk_put(clk); | ||
126 | return ret; | ||
127 | } | ||
128 | #endif | ||
129 | |||
102 | static int bfin_target(struct cpufreq_policy *poli, | 130 | static int bfin_target(struct cpufreq_policy *poli, |
103 | unsigned int target_freq, unsigned int relation) | 131 | unsigned int target_freq, unsigned int relation) |
104 | { | 132 | { |
105 | unsigned int index, plldiv, cpu; | 133 | #ifndef CONFIG_BF60x |
134 | unsigned int plldiv; | ||
135 | #endif | ||
136 | unsigned int index, cpu; | ||
106 | unsigned long flags, cclk_hz; | 137 | unsigned long flags, cclk_hz; |
107 | struct cpufreq_freqs freqs; | 138 | struct cpufreq_freqs freqs; |
108 | static unsigned long lpj_ref; | 139 | static unsigned long lpj_ref; |
109 | static unsigned int lpj_ref_freq; | 140 | static unsigned int lpj_ref_freq; |
141 | int ret = 0; | ||
110 | 142 | ||
111 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) | 143 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) |
112 | cycles_t cycles; | 144 | cycles_t cycles; |
@@ -134,9 +166,17 @@ static int bfin_target(struct cpufreq_policy *poli, | |||
134 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 166 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
135 | if (cpu == CPUFREQ_CPU) { | 167 | if (cpu == CPUFREQ_CPU) { |
136 | flags = hard_local_irq_save(); | 168 | flags = hard_local_irq_save(); |
169 | #ifndef CONFIG_BF60x | ||
137 | plldiv = (bfin_read_PLL_DIV() & SSEL) | | 170 | plldiv = (bfin_read_PLL_DIV() & SSEL) | |
138 | dpm_state_table[index].csel; | 171 | dpm_state_table[index].csel; |
139 | bfin_write_PLL_DIV(plldiv); | 172 | bfin_write_PLL_DIV(plldiv); |
173 | #else | ||
174 | ret = cpu_set_cclk(cpu, freqs.new * 1000); | ||
175 | if (ret != 0) { | ||
176 | pr_debug("cpufreq set freq failed %d\n", ret); | ||
177 | break; | ||
178 | } | ||
179 | #endif | ||
140 | on_each_cpu(bfin_adjust_core_timer, &index, 1); | 180 | on_each_cpu(bfin_adjust_core_timer, &index, 1); |
141 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) | 181 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) |
142 | cycles = get_cycles(); | 182 | cycles = get_cycles(); |
@@ -161,7 +201,7 @@ static int bfin_target(struct cpufreq_policy *poli, | |||
161 | } | 201 | } |
162 | 202 | ||
163 | pr_debug("cpufreq: done\n"); | 203 | pr_debug("cpufreq: done\n"); |
164 | return 0; | 204 | return ret; |
165 | } | 205 | } |
166 | 206 | ||
167 | static int bfin_verify_speed(struct cpufreq_policy *policy) | 207 | static int bfin_verify_speed(struct cpufreq_policy *policy) |
@@ -169,7 +209,7 @@ static int bfin_verify_speed(struct cpufreq_policy *policy) | |||
169 | return cpufreq_frequency_table_verify(policy, bfin_freq_table); | 209 | return cpufreq_frequency_table_verify(policy, bfin_freq_table); |
170 | } | 210 | } |
171 | 211 | ||
172 | static int __init __bfin_cpu_init(struct cpufreq_policy *policy) | 212 | static int __bfin_cpu_init(struct cpufreq_policy *policy) |
173 | { | 213 | { |
174 | 214 | ||
175 | unsigned long cclk, sclk; | 215 | unsigned long cclk, sclk; |
diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S index 1c534d298de4..de99f3aac2c5 100644 --- a/arch/blackfin/mach-common/dpmc_modes.S +++ b/arch/blackfin/mach-common/dpmc_modes.S | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <asm/dpmc.h> | 10 | #include <asm/dpmc.h> |
11 | 11 | ||
12 | .section .l1.text | 12 | .section .l1.text |
13 | |||
14 | ENTRY(_sleep_mode) | 13 | ENTRY(_sleep_mode) |
15 | [--SP] = (R7:4, P5:3); | 14 | [--SP] = (R7:4, P5:3); |
16 | [--SP] = RETS; | 15 | [--SP] = RETS; |
@@ -43,6 +42,9 @@ ENTRY(_sleep_mode) | |||
43 | BITCLR (R7, 5); | 42 | BITCLR (R7, 5); |
44 | w[p0] = R7.L; | 43 | w[p0] = R7.L; |
45 | IDLE; | 44 | IDLE; |
45 | |||
46 | bfin_init_pm_bench_cycles; | ||
47 | |||
46 | call _test_pll_locked; | 48 | call _test_pll_locked; |
47 | 49 | ||
48 | RETS = [SP++]; | 50 | RETS = [SP++]; |
@@ -58,12 +60,13 @@ ENDPROC(_sleep_mode) | |||
58 | * | 60 | * |
59 | * We accept just one argument -- the value to write to VR_CTL. | 61 | * We accept just one argument -- the value to write to VR_CTL. |
60 | */ | 62 | */ |
63 | |||
61 | ENTRY(_hibernate_mode) | 64 | ENTRY(_hibernate_mode) |
62 | /* Save/setup the regs we need early for minor pipeline optimization */ | 65 | /* Save/setup the regs we need early for minor pipeline optimization */ |
63 | R4 = R0; | 66 | R4 = R0; |
67 | |||
64 | P3.H = hi(VR_CTL); | 68 | P3.H = hi(VR_CTL); |
65 | P3.L = lo(VR_CTL); | 69 | P3.L = lo(VR_CTL); |
66 | |||
67 | /* Disable all wakeup sources */ | 70 | /* Disable all wakeup sources */ |
68 | R0 = IWR_DISABLE_ALL; | 71 | R0 = IWR_DISABLE_ALL; |
69 | R1 = IWR_DISABLE_ALL; | 72 | R1 = IWR_DISABLE_ALL; |
@@ -74,6 +77,9 @@ ENTRY(_hibernate_mode) | |||
74 | 77 | ||
75 | /* Finally, we climb into our cave to hibernate */ | 78 | /* Finally, we climb into our cave to hibernate */ |
76 | W[P3] = R4.L; | 79 | W[P3] = R4.L; |
80 | |||
81 | bfin_init_pm_bench_cycles; | ||
82 | |||
77 | CLI R2; | 83 | CLI R2; |
78 | IDLE; | 84 | IDLE; |
79 | .Lforever: | 85 | .Lforever: |
@@ -158,6 +164,8 @@ ENTRY(_sleep_deeper) | |||
158 | SSYNC; | 164 | SSYNC; |
159 | IDLE; | 165 | IDLE; |
160 | 166 | ||
167 | bfin_init_pm_bench_cycles; | ||
168 | |||
161 | call _test_pll_locked; | 169 | call _test_pll_locked; |
162 | 170 | ||
163 | P0.H = hi(PLL_DIV); | 171 | P0.H = hi(PLL_DIV); |
@@ -276,327 +284,10 @@ ENTRY(_test_pll_locked) | |||
276 | ENDPROC(_test_pll_locked) | 284 | ENDPROC(_test_pll_locked) |
277 | 285 | ||
278 | .section .text | 286 | .section .text |
279 | |||
280 | #define PM_REG0 R7 | ||
281 | #define PM_REG1 R6 | ||
282 | #define PM_REG2 R5 | ||
283 | #define PM_REG3 R4 | ||
284 | #define PM_REG4 R3 | ||
285 | #define PM_REG5 R2 | ||
286 | #define PM_REG6 R1 | ||
287 | #define PM_REG7 R0 | ||
288 | #define PM_REG8 P5 | ||
289 | #define PM_REG9 P4 | ||
290 | #define PM_REG10 P3 | ||
291 | #define PM_REG11 P2 | ||
292 | #define PM_REG12 P1 | ||
293 | #define PM_REG13 P0 | ||
294 | |||
295 | #define PM_REGSET0 R7:7 | ||
296 | #define PM_REGSET1 R7:6 | ||
297 | #define PM_REGSET2 R7:5 | ||
298 | #define PM_REGSET3 R7:4 | ||
299 | #define PM_REGSET4 R7:3 | ||
300 | #define PM_REGSET5 R7:2 | ||
301 | #define PM_REGSET6 R7:1 | ||
302 | #define PM_REGSET7 R7:0 | ||
303 | #define PM_REGSET8 R7:0, P5:5 | ||
304 | #define PM_REGSET9 R7:0, P5:4 | ||
305 | #define PM_REGSET10 R7:0, P5:3 | ||
306 | #define PM_REGSET11 R7:0, P5:2 | ||
307 | #define PM_REGSET12 R7:0, P5:1 | ||
308 | #define PM_REGSET13 R7:0, P5:0 | ||
309 | |||
310 | #define _PM_PUSH(n, x, w, base) PM_REG##n = w[FP + ((x) - (base))]; | ||
311 | #define _PM_POP(n, x, w, base) w[FP + ((x) - (base))] = PM_REG##n; | ||
312 | #define PM_PUSH_SYNC(n) [--sp] = (PM_REGSET##n); | ||
313 | #define PM_POP_SYNC(n) (PM_REGSET##n) = [sp++]; | ||
314 | #define PM_PUSH(n, x) PM_REG##n = [FP++]; | ||
315 | #define PM_POP(n, x) [FP--] = PM_REG##n; | ||
316 | #define PM_CORE_PUSH(n, x) _PM_PUSH(n, x, , COREMMR_BASE) | ||
317 | #define PM_CORE_POP(n, x) _PM_POP(n, x, , COREMMR_BASE) | ||
318 | #define PM_SYS_PUSH(n, x) _PM_PUSH(n, x, , SYSMMR_BASE) | ||
319 | #define PM_SYS_POP(n, x) _PM_POP(n, x, , SYSMMR_BASE) | ||
320 | #define PM_SYS_PUSH16(n, x) _PM_PUSH(n, x, w, SYSMMR_BASE) | ||
321 | #define PM_SYS_POP16(n, x) _PM_POP(n, x, w, SYSMMR_BASE) | ||
322 | |||
323 | ENTRY(_do_hibernate) | 287 | ENTRY(_do_hibernate) |
324 | /* | 288 | bfin_cpu_reg_save; |
325 | * Save the core regs early so we can blow them away when | 289 | bfin_sys_mmr_save; |
326 | * saving/restoring MMR states | 290 | bfin_core_mmr_save; |
327 | */ | ||
328 | [--sp] = (R7:0, P5:0); | ||
329 | [--sp] = fp; | ||
330 | [--sp] = usp; | ||
331 | |||
332 | [--sp] = i0; | ||
333 | [--sp] = i1; | ||
334 | [--sp] = i2; | ||
335 | [--sp] = i3; | ||
336 | |||
337 | [--sp] = m0; | ||
338 | [--sp] = m1; | ||
339 | [--sp] = m2; | ||
340 | [--sp] = m3; | ||
341 | |||
342 | [--sp] = l0; | ||
343 | [--sp] = l1; | ||
344 | [--sp] = l2; | ||
345 | [--sp] = l3; | ||
346 | |||
347 | [--sp] = b0; | ||
348 | [--sp] = b1; | ||
349 | [--sp] = b2; | ||
350 | [--sp] = b3; | ||
351 | [--sp] = a0.x; | ||
352 | [--sp] = a0.w; | ||
353 | [--sp] = a1.x; | ||
354 | [--sp] = a1.w; | ||
355 | |||
356 | [--sp] = LC0; | ||
357 | [--sp] = LC1; | ||
358 | [--sp] = LT0; | ||
359 | [--sp] = LT1; | ||
360 | [--sp] = LB0; | ||
361 | [--sp] = LB1; | ||
362 | |||
363 | /* We can't push RETI directly as that'll change IPEND[4] */ | ||
364 | r7 = RETI; | ||
365 | [--sp] = RETS; | ||
366 | [--sp] = ASTAT; | ||
367 | [--sp] = CYCLES; | ||
368 | [--sp] = CYCLES2; | ||
369 | [--sp] = SYSCFG; | ||
370 | [--sp] = RETX; | ||
371 | [--sp] = SEQSTAT; | ||
372 | [--sp] = r7; | ||
373 | |||
374 | /* Save first func arg in M3 */ | ||
375 | M3 = R0; | ||
376 | |||
377 | /* Save system MMRs */ | ||
378 | FP.H = hi(SYSMMR_BASE); | ||
379 | FP.L = lo(SYSMMR_BASE); | ||
380 | |||
381 | #ifdef SIC_IMASK0 | ||
382 | PM_SYS_PUSH(0, SIC_IMASK0) | ||
383 | PM_SYS_PUSH(1, SIC_IMASK1) | ||
384 | # ifdef SIC_IMASK2 | ||
385 | PM_SYS_PUSH(2, SIC_IMASK2) | ||
386 | # endif | ||
387 | #else | ||
388 | PM_SYS_PUSH(0, SIC_IMASK) | ||
389 | #endif | ||
390 | #ifdef SIC_IAR0 | ||
391 | PM_SYS_PUSH(3, SIC_IAR0) | ||
392 | PM_SYS_PUSH(4, SIC_IAR1) | ||
393 | PM_SYS_PUSH(5, SIC_IAR2) | ||
394 | #endif | ||
395 | #ifdef SIC_IAR3 | ||
396 | PM_SYS_PUSH(6, SIC_IAR3) | ||
397 | #endif | ||
398 | #ifdef SIC_IAR4 | ||
399 | PM_SYS_PUSH(7, SIC_IAR4) | ||
400 | PM_SYS_PUSH(8, SIC_IAR5) | ||
401 | PM_SYS_PUSH(9, SIC_IAR6) | ||
402 | #endif | ||
403 | #ifdef SIC_IAR7 | ||
404 | PM_SYS_PUSH(10, SIC_IAR7) | ||
405 | #endif | ||
406 | #ifdef SIC_IAR8 | ||
407 | PM_SYS_PUSH(11, SIC_IAR8) | ||
408 | PM_SYS_PUSH(12, SIC_IAR9) | ||
409 | PM_SYS_PUSH(13, SIC_IAR10) | ||
410 | #endif | ||
411 | PM_PUSH_SYNC(13) | ||
412 | #ifdef SIC_IAR11 | ||
413 | PM_SYS_PUSH(0, SIC_IAR11) | ||
414 | #endif | ||
415 | |||
416 | #ifdef SIC_IWR | ||
417 | PM_SYS_PUSH(1, SIC_IWR) | ||
418 | #endif | ||
419 | #ifdef SIC_IWR0 | ||
420 | PM_SYS_PUSH(1, SIC_IWR0) | ||
421 | #endif | ||
422 | #ifdef SIC_IWR1 | ||
423 | PM_SYS_PUSH(2, SIC_IWR1) | ||
424 | #endif | ||
425 | #ifdef SIC_IWR2 | ||
426 | PM_SYS_PUSH(3, SIC_IWR2) | ||
427 | #endif | ||
428 | |||
429 | #ifdef PINT0_ASSIGN | ||
430 | PM_SYS_PUSH(4, PINT0_MASK_SET) | ||
431 | PM_SYS_PUSH(5, PINT1_MASK_SET) | ||
432 | PM_SYS_PUSH(6, PINT2_MASK_SET) | ||
433 | PM_SYS_PUSH(7, PINT3_MASK_SET) | ||
434 | PM_SYS_PUSH(8, PINT0_ASSIGN) | ||
435 | PM_SYS_PUSH(9, PINT1_ASSIGN) | ||
436 | PM_SYS_PUSH(10, PINT2_ASSIGN) | ||
437 | PM_SYS_PUSH(11, PINT3_ASSIGN) | ||
438 | PM_SYS_PUSH(12, PINT0_INVERT_SET) | ||
439 | PM_SYS_PUSH(13, PINT1_INVERT_SET) | ||
440 | PM_PUSH_SYNC(13) | ||
441 | PM_SYS_PUSH(0, PINT2_INVERT_SET) | ||
442 | PM_SYS_PUSH(1, PINT3_INVERT_SET) | ||
443 | PM_SYS_PUSH(2, PINT0_EDGE_SET) | ||
444 | PM_SYS_PUSH(3, PINT1_EDGE_SET) | ||
445 | PM_SYS_PUSH(4, PINT2_EDGE_SET) | ||
446 | PM_SYS_PUSH(5, PINT3_EDGE_SET) | ||
447 | #endif | ||
448 | |||
449 | PM_SYS_PUSH16(6, SYSCR) | ||
450 | |||
451 | PM_SYS_PUSH16(7, EBIU_AMGCTL) | ||
452 | PM_SYS_PUSH(8, EBIU_AMBCTL0) | ||
453 | PM_SYS_PUSH(9, EBIU_AMBCTL1) | ||
454 | #ifdef EBIU_FCTL | ||
455 | PM_SYS_PUSH(10, EBIU_MBSCTL) | ||
456 | PM_SYS_PUSH(11, EBIU_MODE) | ||
457 | PM_SYS_PUSH(12, EBIU_FCTL) | ||
458 | PM_PUSH_SYNC(12) | ||
459 | #else | ||
460 | PM_PUSH_SYNC(9) | ||
461 | #endif | ||
462 | |||
463 | /* Save Core MMRs */ | ||
464 | I0.H = hi(COREMMR_BASE); | ||
465 | I0.L = lo(COREMMR_BASE); | ||
466 | I1 = I0; | ||
467 | I2 = I0; | ||
468 | I3 = I0; | ||
469 | B0 = I0; | ||
470 | B1 = I0; | ||
471 | B2 = I0; | ||
472 | B3 = I0; | ||
473 | I1.L = lo(DCPLB_ADDR0); | ||
474 | I2.L = lo(DCPLB_DATA0); | ||
475 | I3.L = lo(ICPLB_ADDR0); | ||
476 | B0.L = lo(ICPLB_DATA0); | ||
477 | B1.L = lo(EVT2); | ||
478 | B2.L = lo(IMASK); | ||
479 | B3.L = lo(TCNTL); | ||
480 | |||
481 | /* DCPLB Addr */ | ||
482 | FP = I1; | ||
483 | PM_PUSH(0, DCPLB_ADDR0) | ||
484 | PM_PUSH(1, DCPLB_ADDR1) | ||
485 | PM_PUSH(2, DCPLB_ADDR2) | ||
486 | PM_PUSH(3, DCPLB_ADDR3) | ||
487 | PM_PUSH(4, DCPLB_ADDR4) | ||
488 | PM_PUSH(5, DCPLB_ADDR5) | ||
489 | PM_PUSH(6, DCPLB_ADDR6) | ||
490 | PM_PUSH(7, DCPLB_ADDR7) | ||
491 | PM_PUSH(8, DCPLB_ADDR8) | ||
492 | PM_PUSH(9, DCPLB_ADDR9) | ||
493 | PM_PUSH(10, DCPLB_ADDR10) | ||
494 | PM_PUSH(11, DCPLB_ADDR11) | ||
495 | PM_PUSH(12, DCPLB_ADDR12) | ||
496 | PM_PUSH(13, DCPLB_ADDR13) | ||
497 | PM_PUSH_SYNC(13) | ||
498 | PM_PUSH(0, DCPLB_ADDR14) | ||
499 | PM_PUSH(1, DCPLB_ADDR15) | ||
500 | |||
501 | /* DCPLB Data */ | ||
502 | FP = I2; | ||
503 | PM_PUSH(2, DCPLB_DATA0) | ||
504 | PM_PUSH(3, DCPLB_DATA1) | ||
505 | PM_PUSH(4, DCPLB_DATA2) | ||
506 | PM_PUSH(5, DCPLB_DATA3) | ||
507 | PM_PUSH(6, DCPLB_DATA4) | ||
508 | PM_PUSH(7, DCPLB_DATA5) | ||
509 | PM_PUSH(8, DCPLB_DATA6) | ||
510 | PM_PUSH(9, DCPLB_DATA7) | ||
511 | PM_PUSH(10, DCPLB_DATA8) | ||
512 | PM_PUSH(11, DCPLB_DATA9) | ||
513 | PM_PUSH(12, DCPLB_DATA10) | ||
514 | PM_PUSH(13, DCPLB_DATA11) | ||
515 | PM_PUSH_SYNC(13) | ||
516 | PM_PUSH(0, DCPLB_DATA12) | ||
517 | PM_PUSH(1, DCPLB_DATA13) | ||
518 | PM_PUSH(2, DCPLB_DATA14) | ||
519 | PM_PUSH(3, DCPLB_DATA15) | ||
520 | |||
521 | /* ICPLB Addr */ | ||
522 | FP = I3; | ||
523 | PM_PUSH(4, ICPLB_ADDR0) | ||
524 | PM_PUSH(5, ICPLB_ADDR1) | ||
525 | PM_PUSH(6, ICPLB_ADDR2) | ||
526 | PM_PUSH(7, ICPLB_ADDR3) | ||
527 | PM_PUSH(8, ICPLB_ADDR4) | ||
528 | PM_PUSH(9, ICPLB_ADDR5) | ||
529 | PM_PUSH(10, ICPLB_ADDR6) | ||
530 | PM_PUSH(11, ICPLB_ADDR7) | ||
531 | PM_PUSH(12, ICPLB_ADDR8) | ||
532 | PM_PUSH(13, ICPLB_ADDR9) | ||
533 | PM_PUSH_SYNC(13) | ||
534 | PM_PUSH(0, ICPLB_ADDR10) | ||
535 | PM_PUSH(1, ICPLB_ADDR11) | ||
536 | PM_PUSH(2, ICPLB_ADDR12) | ||
537 | PM_PUSH(3, ICPLB_ADDR13) | ||
538 | PM_PUSH(4, ICPLB_ADDR14) | ||
539 | PM_PUSH(5, ICPLB_ADDR15) | ||
540 | |||
541 | /* ICPLB Data */ | ||
542 | FP = B0; | ||
543 | PM_PUSH(6, ICPLB_DATA0) | ||
544 | PM_PUSH(7, ICPLB_DATA1) | ||
545 | PM_PUSH(8, ICPLB_DATA2) | ||
546 | PM_PUSH(9, ICPLB_DATA3) | ||
547 | PM_PUSH(10, ICPLB_DATA4) | ||
548 | PM_PUSH(11, ICPLB_DATA5) | ||
549 | PM_PUSH(12, ICPLB_DATA6) | ||
550 | PM_PUSH(13, ICPLB_DATA7) | ||
551 | PM_PUSH_SYNC(13) | ||
552 | PM_PUSH(0, ICPLB_DATA8) | ||
553 | PM_PUSH(1, ICPLB_DATA9) | ||
554 | PM_PUSH(2, ICPLB_DATA10) | ||
555 | PM_PUSH(3, ICPLB_DATA11) | ||
556 | PM_PUSH(4, ICPLB_DATA12) | ||
557 | PM_PUSH(5, ICPLB_DATA13) | ||
558 | PM_PUSH(6, ICPLB_DATA14) | ||
559 | PM_PUSH(7, ICPLB_DATA15) | ||
560 | |||
561 | /* Event Vectors */ | ||
562 | FP = B1; | ||
563 | PM_PUSH(8, EVT2) | ||
564 | PM_PUSH(9, EVT3) | ||
565 | FP += 4; /* EVT4 */ | ||
566 | PM_PUSH(10, EVT5) | ||
567 | PM_PUSH(11, EVT6) | ||
568 | PM_PUSH(12, EVT7) | ||
569 | PM_PUSH(13, EVT8) | ||
570 | PM_PUSH_SYNC(13) | ||
571 | PM_PUSH(0, EVT9) | ||
572 | PM_PUSH(1, EVT10) | ||
573 | PM_PUSH(2, EVT11) | ||
574 | PM_PUSH(3, EVT12) | ||
575 | PM_PUSH(4, EVT13) | ||
576 | PM_PUSH(5, EVT14) | ||
577 | PM_PUSH(6, EVT15) | ||
578 | |||
579 | /* CEC */ | ||
580 | FP = B2; | ||
581 | PM_PUSH(7, IMASK) | ||
582 | FP += 4; /* IPEND */ | ||
583 | PM_PUSH(8, ILAT) | ||
584 | PM_PUSH(9, IPRIO) | ||
585 | |||
586 | /* Core Timer */ | ||
587 | FP = B3; | ||
588 | PM_PUSH(10, TCNTL) | ||
589 | PM_PUSH(11, TPERIOD) | ||
590 | PM_PUSH(12, TSCALE) | ||
591 | PM_PUSH(13, TCOUNT) | ||
592 | PM_PUSH_SYNC(13) | ||
593 | |||
594 | /* Misc non-contiguous registers */ | ||
595 | FP = I0; | ||
596 | PM_CORE_PUSH(0, DMEM_CONTROL); | ||
597 | PM_CORE_PUSH(1, IMEM_CONTROL); | ||
598 | PM_CORE_PUSH(2, TBUFCTL); | ||
599 | PM_PUSH_SYNC(2) | ||
600 | 291 | ||
601 | /* Setup args to hibernate mode early for pipeline optimization */ | 292 | /* Setup args to hibernate mode early for pipeline optimization */ |
602 | R0 = M3; | 293 | R0 = M3; |
@@ -618,274 +309,9 @@ ENTRY(_do_hibernate) | |||
618 | 309 | ||
619 | .Lpm_resume_here: | 310 | .Lpm_resume_here: |
620 | 311 | ||
621 | /* Restore Core MMRs */ | 312 | bfin_core_mmr_restore; |
622 | I0.H = hi(COREMMR_BASE); | 313 | bfin_sys_mmr_restore; |
623 | I0.L = lo(COREMMR_BASE); | 314 | bfin_cpu_reg_restore; |
624 | I1 = I0; | ||
625 | I2 = I0; | ||
626 | I3 = I0; | ||
627 | B0 = I0; | ||
628 | B1 = I0; | ||
629 | B2 = I0; | ||
630 | B3 = I0; | ||
631 | I1.L = lo(DCPLB_ADDR15); | ||
632 | I2.L = lo(DCPLB_DATA15); | ||
633 | I3.L = lo(ICPLB_ADDR15); | ||
634 | B0.L = lo(ICPLB_DATA15); | ||
635 | B1.L = lo(EVT15); | ||
636 | B2.L = lo(IPRIO); | ||
637 | B3.L = lo(TCOUNT); | ||
638 | |||
639 | /* Misc non-contiguous registers */ | ||
640 | FP = I0; | ||
641 | PM_POP_SYNC(2) | ||
642 | PM_CORE_POP(2, TBUFCTL) | ||
643 | PM_CORE_POP(1, IMEM_CONTROL) | ||
644 | PM_CORE_POP(0, DMEM_CONTROL) | ||
645 | |||
646 | /* Core Timer */ | ||
647 | PM_POP_SYNC(13) | ||
648 | FP = B3; | ||
649 | PM_POP(13, TCOUNT) | ||
650 | PM_POP(12, TSCALE) | ||
651 | PM_POP(11, TPERIOD) | ||
652 | PM_POP(10, TCNTL) | ||
653 | |||
654 | /* CEC */ | ||
655 | FP = B2; | ||
656 | PM_POP(9, IPRIO) | ||
657 | PM_POP(8, ILAT) | ||
658 | FP += -4; /* IPEND */ | ||
659 | PM_POP(7, IMASK) | ||
660 | |||
661 | /* Event Vectors */ | ||
662 | FP = B1; | ||
663 | PM_POP(6, EVT15) | ||
664 | PM_POP(5, EVT14) | ||
665 | PM_POP(4, EVT13) | ||
666 | PM_POP(3, EVT12) | ||
667 | PM_POP(2, EVT11) | ||
668 | PM_POP(1, EVT10) | ||
669 | PM_POP(0, EVT9) | ||
670 | PM_POP_SYNC(13) | ||
671 | PM_POP(13, EVT8) | ||
672 | PM_POP(12, EVT7) | ||
673 | PM_POP(11, EVT6) | ||
674 | PM_POP(10, EVT5) | ||
675 | FP += -4; /* EVT4 */ | ||
676 | PM_POP(9, EVT3) | ||
677 | PM_POP(8, EVT2) | ||
678 | |||
679 | /* ICPLB Data */ | ||
680 | FP = B0; | ||
681 | PM_POP(7, ICPLB_DATA15) | ||
682 | PM_POP(6, ICPLB_DATA14) | ||
683 | PM_POP(5, ICPLB_DATA13) | ||
684 | PM_POP(4, ICPLB_DATA12) | ||
685 | PM_POP(3, ICPLB_DATA11) | ||
686 | PM_POP(2, ICPLB_DATA10) | ||
687 | PM_POP(1, ICPLB_DATA9) | ||
688 | PM_POP(0, ICPLB_DATA8) | ||
689 | PM_POP_SYNC(13) | ||
690 | PM_POP(13, ICPLB_DATA7) | ||
691 | PM_POP(12, ICPLB_DATA6) | ||
692 | PM_POP(11, ICPLB_DATA5) | ||
693 | PM_POP(10, ICPLB_DATA4) | ||
694 | PM_POP(9, ICPLB_DATA3) | ||
695 | PM_POP(8, ICPLB_DATA2) | ||
696 | PM_POP(7, ICPLB_DATA1) | ||
697 | PM_POP(6, ICPLB_DATA0) | ||
698 | |||
699 | /* ICPLB Addr */ | ||
700 | FP = I3; | ||
701 | PM_POP(5, ICPLB_ADDR15) | ||
702 | PM_POP(4, ICPLB_ADDR14) | ||
703 | PM_POP(3, ICPLB_ADDR13) | ||
704 | PM_POP(2, ICPLB_ADDR12) | ||
705 | PM_POP(1, ICPLB_ADDR11) | ||
706 | PM_POP(0, ICPLB_ADDR10) | ||
707 | PM_POP_SYNC(13) | ||
708 | PM_POP(13, ICPLB_ADDR9) | ||
709 | PM_POP(12, ICPLB_ADDR8) | ||
710 | PM_POP(11, ICPLB_ADDR7) | ||
711 | PM_POP(10, ICPLB_ADDR6) | ||
712 | PM_POP(9, ICPLB_ADDR5) | ||
713 | PM_POP(8, ICPLB_ADDR4) | ||
714 | PM_POP(7, ICPLB_ADDR3) | ||
715 | PM_POP(6, ICPLB_ADDR2) | ||
716 | PM_POP(5, ICPLB_ADDR1) | ||
717 | PM_POP(4, ICPLB_ADDR0) | ||
718 | |||
719 | /* DCPLB Data */ | ||
720 | FP = I2; | ||
721 | PM_POP(3, DCPLB_DATA15) | ||
722 | PM_POP(2, DCPLB_DATA14) | ||
723 | PM_POP(1, DCPLB_DATA13) | ||
724 | PM_POP(0, DCPLB_DATA12) | ||
725 | PM_POP_SYNC(13) | ||
726 | PM_POP(13, DCPLB_DATA11) | ||
727 | PM_POP(12, DCPLB_DATA10) | ||
728 | PM_POP(11, DCPLB_DATA9) | ||
729 | PM_POP(10, DCPLB_DATA8) | ||
730 | PM_POP(9, DCPLB_DATA7) | ||
731 | PM_POP(8, DCPLB_DATA6) | ||
732 | PM_POP(7, DCPLB_DATA5) | ||
733 | PM_POP(6, DCPLB_DATA4) | ||
734 | PM_POP(5, DCPLB_DATA3) | ||
735 | PM_POP(4, DCPLB_DATA2) | ||
736 | PM_POP(3, DCPLB_DATA1) | ||
737 | PM_POP(2, DCPLB_DATA0) | ||
738 | |||
739 | /* DCPLB Addr */ | ||
740 | FP = I1; | ||
741 | PM_POP(1, DCPLB_ADDR15) | ||
742 | PM_POP(0, DCPLB_ADDR14) | ||
743 | PM_POP_SYNC(13) | ||
744 | PM_POP(13, DCPLB_ADDR13) | ||
745 | PM_POP(12, DCPLB_ADDR12) | ||
746 | PM_POP(11, DCPLB_ADDR11) | ||
747 | PM_POP(10, DCPLB_ADDR10) | ||
748 | PM_POP(9, DCPLB_ADDR9) | ||
749 | PM_POP(8, DCPLB_ADDR8) | ||
750 | PM_POP(7, DCPLB_ADDR7) | ||
751 | PM_POP(6, DCPLB_ADDR6) | ||
752 | PM_POP(5, DCPLB_ADDR5) | ||
753 | PM_POP(4, DCPLB_ADDR4) | ||
754 | PM_POP(3, DCPLB_ADDR3) | ||
755 | PM_POP(2, DCPLB_ADDR2) | ||
756 | PM_POP(1, DCPLB_ADDR1) | ||
757 | PM_POP(0, DCPLB_ADDR0) | ||
758 | |||
759 | /* Restore System MMRs */ | ||
760 | FP.H = hi(SYSMMR_BASE); | ||
761 | FP.L = lo(SYSMMR_BASE); | ||
762 | |||
763 | #ifdef EBIU_FCTL | ||
764 | PM_POP_SYNC(12) | ||
765 | PM_SYS_POP(12, EBIU_FCTL) | ||
766 | PM_SYS_POP(11, EBIU_MODE) | ||
767 | PM_SYS_POP(10, EBIU_MBSCTL) | ||
768 | #else | ||
769 | PM_POP_SYNC(9) | ||
770 | #endif | ||
771 | PM_SYS_POP(9, EBIU_AMBCTL1) | ||
772 | PM_SYS_POP(8, EBIU_AMBCTL0) | ||
773 | PM_SYS_POP16(7, EBIU_AMGCTL) | ||
774 | |||
775 | PM_SYS_POP16(6, SYSCR) | ||
776 | |||
777 | #ifdef PINT0_ASSIGN | ||
778 | PM_SYS_POP(5, PINT3_EDGE_SET) | ||
779 | PM_SYS_POP(4, PINT2_EDGE_SET) | ||
780 | PM_SYS_POP(3, PINT1_EDGE_SET) | ||
781 | PM_SYS_POP(2, PINT0_EDGE_SET) | ||
782 | PM_SYS_POP(1, PINT3_INVERT_SET) | ||
783 | PM_SYS_POP(0, PINT2_INVERT_SET) | ||
784 | PM_POP_SYNC(13) | ||
785 | PM_SYS_POP(13, PINT1_INVERT_SET) | ||
786 | PM_SYS_POP(12, PINT0_INVERT_SET) | ||
787 | PM_SYS_POP(11, PINT3_ASSIGN) | ||
788 | PM_SYS_POP(10, PINT2_ASSIGN) | ||
789 | PM_SYS_POP(9, PINT1_ASSIGN) | ||
790 | PM_SYS_POP(8, PINT0_ASSIGN) | ||
791 | PM_SYS_POP(7, PINT3_MASK_SET) | ||
792 | PM_SYS_POP(6, PINT2_MASK_SET) | ||
793 | PM_SYS_POP(5, PINT1_MASK_SET) | ||
794 | PM_SYS_POP(4, PINT0_MASK_SET) | ||
795 | #endif | ||
796 | |||
797 | #ifdef SIC_IWR2 | ||
798 | PM_SYS_POP(3, SIC_IWR2) | ||
799 | #endif | ||
800 | #ifdef SIC_IWR1 | ||
801 | PM_SYS_POP(2, SIC_IWR1) | ||
802 | #endif | ||
803 | #ifdef SIC_IWR0 | ||
804 | PM_SYS_POP(1, SIC_IWR0) | ||
805 | #endif | ||
806 | #ifdef SIC_IWR | ||
807 | PM_SYS_POP(1, SIC_IWR) | ||
808 | #endif | ||
809 | |||
810 | #ifdef SIC_IAR11 | ||
811 | PM_SYS_POP(0, SIC_IAR11) | ||
812 | #endif | ||
813 | PM_POP_SYNC(13) | ||
814 | #ifdef SIC_IAR8 | ||
815 | PM_SYS_POP(13, SIC_IAR10) | ||
816 | PM_SYS_POP(12, SIC_IAR9) | ||
817 | PM_SYS_POP(11, SIC_IAR8) | ||
818 | #endif | ||
819 | #ifdef SIC_IAR7 | ||
820 | PM_SYS_POP(10, SIC_IAR7) | ||
821 | #endif | ||
822 | #ifdef SIC_IAR6 | ||
823 | PM_SYS_POP(9, SIC_IAR6) | ||
824 | PM_SYS_POP(8, SIC_IAR5) | ||
825 | PM_SYS_POP(7, SIC_IAR4) | ||
826 | #endif | ||
827 | #ifdef SIC_IAR3 | ||
828 | PM_SYS_POP(6, SIC_IAR3) | ||
829 | #endif | ||
830 | #ifdef SIC_IAR0 | ||
831 | PM_SYS_POP(5, SIC_IAR2) | ||
832 | PM_SYS_POP(4, SIC_IAR1) | ||
833 | PM_SYS_POP(3, SIC_IAR0) | ||
834 | #endif | ||
835 | #ifdef SIC_IMASK0 | ||
836 | # ifdef SIC_IMASK2 | ||
837 | PM_SYS_POP(2, SIC_IMASK2) | ||
838 | # endif | ||
839 | PM_SYS_POP(1, SIC_IMASK1) | ||
840 | PM_SYS_POP(0, SIC_IMASK0) | ||
841 | #else | ||
842 | PM_SYS_POP(0, SIC_IMASK) | ||
843 | #endif | ||
844 | |||
845 | /* Restore Core Registers */ | ||
846 | RETI = [sp++]; | ||
847 | SEQSTAT = [sp++]; | ||
848 | RETX = [sp++]; | ||
849 | SYSCFG = [sp++]; | ||
850 | CYCLES2 = [sp++]; | ||
851 | CYCLES = [sp++]; | ||
852 | ASTAT = [sp++]; | ||
853 | RETS = [sp++]; | ||
854 | |||
855 | LB1 = [sp++]; | ||
856 | LB0 = [sp++]; | ||
857 | LT1 = [sp++]; | ||
858 | LT0 = [sp++]; | ||
859 | LC1 = [sp++]; | ||
860 | LC0 = [sp++]; | ||
861 | |||
862 | a1.w = [sp++]; | ||
863 | a1.x = [sp++]; | ||
864 | a0.w = [sp++]; | ||
865 | a0.x = [sp++]; | ||
866 | b3 = [sp++]; | ||
867 | b2 = [sp++]; | ||
868 | b1 = [sp++]; | ||
869 | b0 = [sp++]; | ||
870 | |||
871 | l3 = [sp++]; | ||
872 | l2 = [sp++]; | ||
873 | l1 = [sp++]; | ||
874 | l0 = [sp++]; | ||
875 | |||
876 | m3 = [sp++]; | ||
877 | m2 = [sp++]; | ||
878 | m1 = [sp++]; | ||
879 | m0 = [sp++]; | ||
880 | |||
881 | i3 = [sp++]; | ||
882 | i2 = [sp++]; | ||
883 | i1 = [sp++]; | ||
884 | i0 = [sp++]; | ||
885 | |||
886 | usp = [sp++]; | ||
887 | fp = [sp++]; | ||
888 | (R7:0, P5:0) = [sp++]; | ||
889 | 315 | ||
890 | [--sp] = RETI; /* Clear Global Interrupt Disable */ | 316 | [--sp] = RETI; /* Clear Global Interrupt Disable */ |
891 | SP += 4; | 317 | SP += 4; |
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 4698a9800522..04c2fbe41a7f 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -711,8 +711,6 @@ ENTRY(_system_call) | |||
711 | jump .Lresume_userspace_1; | 711 | jump .Lresume_userspace_1; |
712 | 712 | ||
713 | .Lsyscall_sigpending: | 713 | .Lsyscall_sigpending: |
714 | cc = BITTST(r7, TIF_RESTORE_SIGMASK); | ||
715 | if cc jump .Lsyscall_do_signals; | ||
716 | cc = BITTST(r7, TIF_SIGPENDING); | 714 | cc = BITTST(r7, TIF_SIGPENDING); |
717 | if cc jump .Lsyscall_do_signals; | 715 | if cc jump .Lsyscall_do_signals; |
718 | cc = BITTST(r7, TIF_NOTIFY_RESUME); | 716 | cc = BITTST(r7, TIF_NOTIFY_RESUME); |
@@ -1141,7 +1139,8 @@ ENTRY(_schedule_and_signal_from_int) | |||
1141 | sti r0; | 1139 | sti r0; |
1142 | 1140 | ||
1143 | /* finish the userspace "atomic" functions for it */ | 1141 | /* finish the userspace "atomic" functions for it */ |
1144 | r1 = FIXED_CODE_END; | 1142 | r1.l = lo(FIXED_CODE_END); |
1143 | r1.h = hi(FIXED_CODE_END); | ||
1145 | r2 = [sp + PT_PC]; | 1144 | r2 = [sp + PT_PC]; |
1146 | cc = r1 <= r2; | 1145 | cc = r1 <= r2; |
1147 | if cc jump .Lresume_userspace (bp); | 1146 | if cc jump .Lresume_userspace (bp); |
@@ -1376,7 +1375,7 @@ END(_ex_table) | |||
1376 | ENTRY(_sys_call_table) | 1375 | ENTRY(_sys_call_table) |
1377 | .long _sys_restart_syscall /* 0 */ | 1376 | .long _sys_restart_syscall /* 0 */ |
1378 | .long _sys_exit | 1377 | .long _sys_exit |
1379 | .long _sys_fork | 1378 | .long _sys_ni_syscall /* fork */ |
1380 | .long _sys_read | 1379 | .long _sys_read |
1381 | .long _sys_write | 1380 | .long _sys_write |
1382 | .long _sys_open /* 5 */ | 1381 | .long _sys_open /* 5 */ |
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S index 8b4d98854403..31515f0146f9 100644 --- a/arch/blackfin/mach-common/head.S +++ b/arch/blackfin/mach-common/head.S | |||
@@ -210,14 +210,12 @@ ENDPROC(__start) | |||
210 | ENTRY(_real_start) | 210 | ENTRY(_real_start) |
211 | /* Enable nested interrupts */ | 211 | /* Enable nested interrupts */ |
212 | [--sp] = reti; | 212 | [--sp] = reti; |
213 | |||
214 | /* watchdog off for now */ | 213 | /* watchdog off for now */ |
215 | p0.l = lo(WDOG_CTL); | 214 | p0.l = lo(WDOG_CTL); |
216 | p0.h = hi(WDOG_CTL); | 215 | p0.h = hi(WDOG_CTL); |
217 | r0 = 0xAD6(z); | 216 | r0 = 0xAD6(z); |
218 | w[p0] = r0; | 217 | w[p0] = r0; |
219 | ssync; | 218 | ssync; |
220 | |||
221 | /* Pass the u-boot arguments to the global value command line */ | 219 | /* Pass the u-boot arguments to the global value command line */ |
222 | R0 = R7; | 220 | R0 = R7; |
223 | call _cmdline_init; | 221 | call _cmdline_init; |
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 332dace6af34..2729cba715b0 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/seq_file.h> | 16 | #include <linux/seq_file.h> |
17 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/syscore_ops.h> | ||
20 | #include <asm/delay.h> | ||
19 | #ifdef CONFIG_IPIPE | 21 | #ifdef CONFIG_IPIPE |
20 | #include <linux/ipipe.h> | 22 | #include <linux/ipipe.h> |
21 | #endif | 23 | #endif |
@@ -25,7 +27,11 @@ | |||
25 | #include <asm/irq_handler.h> | 27 | #include <asm/irq_handler.h> |
26 | #include <asm/dpmc.h> | 28 | #include <asm/dpmc.h> |
27 | 29 | ||
28 | #define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) | 30 | #ifndef CONFIG_BF60x |
31 | # define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) | ||
32 | #else | ||
33 | # define SIC_SYSIRQ(irq) ((irq) - IVG15) | ||
34 | #endif | ||
29 | 35 | ||
30 | /* | 36 | /* |
31 | * NOTES: | 37 | * NOTES: |
@@ -50,6 +56,7 @@ unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */ | |||
50 | unsigned vr_wakeup; | 56 | unsigned vr_wakeup; |
51 | #endif | 57 | #endif |
52 | 58 | ||
59 | #ifndef CONFIG_BF60x | ||
53 | static struct ivgx { | 60 | static struct ivgx { |
54 | /* irq number for request_irq, available in mach-bf5xx/irq.h */ | 61 | /* irq number for request_irq, available in mach-bf5xx/irq.h */ |
55 | unsigned int irqno; | 62 | unsigned int irqno; |
@@ -78,7 +85,8 @@ static void __init search_IAR(void) | |||
78 | 85 | ||
79 | for (irqN = 0; irqN < NR_PERI_INTS; irqN += 4) { | 86 | for (irqN = 0; irqN < NR_PERI_INTS; irqN += 4) { |
80 | int irqn; | 87 | int irqn; |
81 | u32 iar = bfin_read32((unsigned long *)SIC_IAR0 + | 88 | u32 iar = |
89 | bfin_read32((unsigned long *)SIC_IAR0 + | ||
82 | #if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || \ | 90 | #if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || \ |
83 | defined(CONFIG_BF538) || defined(CONFIG_BF539) | 91 | defined(CONFIG_BF538) || defined(CONFIG_BF539) |
84 | ((irqN % 32) >> 3) + ((irqN / 32) * ((SIC_IAR4 - SIC_IAR0) / 4)) | 92 | ((irqN % 32) >> 3) + ((irqN / 32) * ((SIC_IAR4 - SIC_IAR0) / 4)) |
@@ -86,7 +94,6 @@ static void __init search_IAR(void) | |||
86 | (irqN >> 3) | 94 | (irqN >> 3) |
87 | #endif | 95 | #endif |
88 | ); | 96 | ); |
89 | |||
90 | for (irqn = irqN; irqn < irqN + 4; ++irqn) { | 97 | for (irqn = irqN; irqn < irqN + 4; ++irqn) { |
91 | int iar_shift = (irqn & 7) * 4; | 98 | int iar_shift = (irqn & 7) * 4; |
92 | if (ivg == (0xf & (iar >> iar_shift))) { | 99 | if (ivg == (0xf & (iar >> iar_shift))) { |
@@ -99,11 +106,11 @@ static void __init search_IAR(void) | |||
99 | } | 106 | } |
100 | } | 107 | } |
101 | } | 108 | } |
109 | #endif | ||
102 | 110 | ||
103 | /* | 111 | /* |
104 | * This is for core internal IRQs | 112 | * This is for core internal IRQs |
105 | */ | 113 | */ |
106 | |||
107 | void bfin_ack_noop(struct irq_data *d) | 114 | void bfin_ack_noop(struct irq_data *d) |
108 | { | 115 | { |
109 | /* Dummy function. */ | 116 | /* Dummy function. */ |
@@ -136,21 +143,21 @@ static void bfin_core_unmask_irq(struct irq_data *d) | |||
136 | void bfin_internal_mask_irq(unsigned int irq) | 143 | void bfin_internal_mask_irq(unsigned int irq) |
137 | { | 144 | { |
138 | unsigned long flags = hard_local_irq_save(); | 145 | unsigned long flags = hard_local_irq_save(); |
139 | 146 | #ifndef CONFIG_BF60x | |
140 | #ifdef SIC_IMASK0 | 147 | #ifdef SIC_IMASK0 |
141 | unsigned mask_bank = SIC_SYSIRQ(irq) / 32; | 148 | unsigned mask_bank = SIC_SYSIRQ(irq) / 32; |
142 | unsigned mask_bit = SIC_SYSIRQ(irq) % 32; | 149 | unsigned mask_bit = SIC_SYSIRQ(irq) % 32; |
143 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & | 150 | bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & |
144 | ~(1 << mask_bit)); | 151 | ~(1 << mask_bit)); |
145 | # ifdef CONFIG_SMP | 152 | # if defined(CONFIG_SMP) || defined(CONFIG_ICC) |
146 | bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) & | 153 | bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) & |
147 | ~(1 << mask_bit)); | 154 | ~(1 << mask_bit)); |
148 | # endif | 155 | # endif |
149 | #else | 156 | #else |
150 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & | 157 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & |
151 | ~(1 << SIC_SYSIRQ(irq))); | 158 | ~(1 << SIC_SYSIRQ(irq))); |
159 | #endif /* end of SIC_IMASK0 */ | ||
152 | #endif | 160 | #endif |
153 | |||
154 | hard_local_irq_restore(flags); | 161 | hard_local_irq_restore(flags); |
155 | } | 162 | } |
156 | 163 | ||
@@ -160,7 +167,7 @@ static void bfin_internal_mask_irq_chip(struct irq_data *d) | |||
160 | } | 167 | } |
161 | 168 | ||
162 | #ifdef CONFIG_SMP | 169 | #ifdef CONFIG_SMP |
163 | static void bfin_internal_unmask_irq_affinity(unsigned int irq, | 170 | void bfin_internal_unmask_irq_affinity(unsigned int irq, |
164 | const struct cpumask *affinity) | 171 | const struct cpumask *affinity) |
165 | #else | 172 | #else |
166 | void bfin_internal_unmask_irq(unsigned int irq) | 173 | void bfin_internal_unmask_irq(unsigned int irq) |
@@ -168,6 +175,7 @@ void bfin_internal_unmask_irq(unsigned int irq) | |||
168 | { | 175 | { |
169 | unsigned long flags = hard_local_irq_save(); | 176 | unsigned long flags = hard_local_irq_save(); |
170 | 177 | ||
178 | #ifndef CONFIG_BF60x | ||
171 | #ifdef SIC_IMASK0 | 179 | #ifdef SIC_IMASK0 |
172 | unsigned mask_bank = SIC_SYSIRQ(irq) / 32; | 180 | unsigned mask_bank = SIC_SYSIRQ(irq) / 32; |
173 | unsigned mask_bit = SIC_SYSIRQ(irq) % 32; | 181 | unsigned mask_bit = SIC_SYSIRQ(irq) % 32; |
@@ -175,22 +183,239 @@ void bfin_internal_unmask_irq(unsigned int irq) | |||
175 | if (cpumask_test_cpu(0, affinity)) | 183 | if (cpumask_test_cpu(0, affinity)) |
176 | # endif | 184 | # endif |
177 | bfin_write_SIC_IMASK(mask_bank, | 185 | bfin_write_SIC_IMASK(mask_bank, |
178 | bfin_read_SIC_IMASK(mask_bank) | | 186 | bfin_read_SIC_IMASK(mask_bank) | |
179 | (1 << mask_bit)); | 187 | (1 << mask_bit)); |
180 | # ifdef CONFIG_SMP | 188 | # ifdef CONFIG_SMP |
181 | if (cpumask_test_cpu(1, affinity)) | 189 | if (cpumask_test_cpu(1, affinity)) |
182 | bfin_write_SICB_IMASK(mask_bank, | 190 | bfin_write_SICB_IMASK(mask_bank, |
183 | bfin_read_SICB_IMASK(mask_bank) | | 191 | bfin_read_SICB_IMASK(mask_bank) | |
184 | (1 << mask_bit)); | 192 | (1 << mask_bit)); |
185 | # endif | 193 | # endif |
186 | #else | 194 | #else |
187 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | | 195 | bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | |
188 | (1 << SIC_SYSIRQ(irq))); | 196 | (1 << SIC_SYSIRQ(irq))); |
197 | #endif | ||
189 | #endif | 198 | #endif |
199 | hard_local_irq_restore(flags); | ||
200 | } | ||
201 | |||
202 | #ifdef CONFIG_BF60x | ||
203 | static void bfin_sec_preflow_handler(struct irq_data *d) | ||
204 | { | ||
205 | unsigned long flags = hard_local_irq_save(); | ||
206 | unsigned int sid = SIC_SYSIRQ(d->irq); | ||
207 | |||
208 | bfin_write_SEC_SCI(0, SEC_CSID, sid); | ||
209 | |||
210 | hard_local_irq_restore(flags); | ||
211 | } | ||
212 | |||
213 | static void bfin_sec_mask_ack_irq(struct irq_data *d) | ||
214 | { | ||
215 | unsigned long flags = hard_local_irq_save(); | ||
216 | unsigned int sid = SIC_SYSIRQ(d->irq); | ||
217 | |||
218 | bfin_write_SEC_SCI(0, SEC_CSID, sid); | ||
190 | 219 | ||
191 | hard_local_irq_restore(flags); | 220 | hard_local_irq_restore(flags); |
192 | } | 221 | } |
193 | 222 | ||
223 | static void bfin_sec_unmask_irq(struct irq_data *d) | ||
224 | { | ||
225 | unsigned long flags = hard_local_irq_save(); | ||
226 | unsigned int sid = SIC_SYSIRQ(d->irq); | ||
227 | |||
228 | bfin_write32(SEC_END, sid); | ||
229 | |||
230 | hard_local_irq_restore(flags); | ||
231 | } | ||
232 | |||
233 | static void bfin_sec_enable_ssi(unsigned int sid) | ||
234 | { | ||
235 | unsigned long flags = hard_local_irq_save(); | ||
236 | uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); | ||
237 | |||
238 | reg_sctl |= SEC_SCTL_SRC_EN; | ||
239 | bfin_write_SEC_SCTL(sid, reg_sctl); | ||
240 | |||
241 | hard_local_irq_restore(flags); | ||
242 | } | ||
243 | |||
244 | static void bfin_sec_disable_ssi(unsigned int sid) | ||
245 | { | ||
246 | unsigned long flags = hard_local_irq_save(); | ||
247 | uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); | ||
248 | |||
249 | reg_sctl &= ((uint32_t)~SEC_SCTL_SRC_EN); | ||
250 | bfin_write_SEC_SCTL(sid, reg_sctl); | ||
251 | |||
252 | hard_local_irq_restore(flags); | ||
253 | } | ||
254 | |||
255 | static void bfin_sec_set_ssi_coreid(unsigned int sid, unsigned int coreid) | ||
256 | { | ||
257 | unsigned long flags = hard_local_irq_save(); | ||
258 | uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); | ||
259 | |||
260 | reg_sctl &= ((uint32_t)~SEC_SCTL_CTG); | ||
261 | bfin_write_SEC_SCTL(sid, reg_sctl | ((coreid << 20) & SEC_SCTL_CTG)); | ||
262 | |||
263 | hard_local_irq_restore(flags); | ||
264 | } | ||
265 | |||
266 | static void bfin_sec_enable_sci(unsigned int sid) | ||
267 | { | ||
268 | unsigned long flags = hard_local_irq_save(); | ||
269 | uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); | ||
270 | |||
271 | if (sid == SIC_SYSIRQ(IRQ_WATCH0)) | ||
272 | reg_sctl |= SEC_SCTL_FAULT_EN; | ||
273 | else | ||
274 | reg_sctl |= SEC_SCTL_INT_EN; | ||
275 | bfin_write_SEC_SCTL(sid, reg_sctl); | ||
276 | |||
277 | hard_local_irq_restore(flags); | ||
278 | } | ||
279 | |||
280 | static void bfin_sec_disable_sci(unsigned int sid) | ||
281 | { | ||
282 | unsigned long flags = hard_local_irq_save(); | ||
283 | uint32_t reg_sctl = bfin_read_SEC_SCTL(sid); | ||
284 | |||
285 | reg_sctl &= ((uint32_t)~SEC_SCTL_INT_EN); | ||
286 | bfin_write_SEC_SCTL(sid, reg_sctl); | ||
287 | |||
288 | hard_local_irq_restore(flags); | ||
289 | } | ||
290 | |||
291 | static void bfin_sec_enable(struct irq_data *d) | ||
292 | { | ||
293 | unsigned long flags = hard_local_irq_save(); | ||
294 | unsigned int sid = SIC_SYSIRQ(d->irq); | ||
295 | |||
296 | bfin_sec_enable_sci(sid); | ||
297 | bfin_sec_enable_ssi(sid); | ||
298 | |||
299 | hard_local_irq_restore(flags); | ||
300 | } | ||
301 | |||
302 | static void bfin_sec_disable(struct irq_data *d) | ||
303 | { | ||
304 | unsigned long flags = hard_local_irq_save(); | ||
305 | unsigned int sid = SIC_SYSIRQ(d->irq); | ||
306 | |||
307 | bfin_sec_disable_sci(sid); | ||
308 | bfin_sec_disable_ssi(sid); | ||
309 | |||
310 | hard_local_irq_restore(flags); | ||
311 | } | ||
312 | |||
313 | static void bfin_sec_raise_irq(unsigned int sid) | ||
314 | { | ||
315 | unsigned long flags = hard_local_irq_save(); | ||
316 | |||
317 | bfin_write32(SEC_RAISE, sid); | ||
318 | |||
319 | hard_local_irq_restore(flags); | ||
320 | } | ||
321 | |||
322 | static void init_software_driven_irq(void) | ||
323 | { | ||
324 | bfin_sec_set_ssi_coreid(34, 0); | ||
325 | bfin_sec_set_ssi_coreid(35, 1); | ||
326 | bfin_sec_set_ssi_coreid(36, 0); | ||
327 | bfin_sec_set_ssi_coreid(37, 1); | ||
328 | } | ||
329 | |||
330 | void bfin_sec_resume(void) | ||
331 | { | ||
332 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); | ||
333 | udelay(100); | ||
334 | bfin_write_SEC_GCTL(SEC_GCTL_EN); | ||
335 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); | ||
336 | } | ||
337 | |||
338 | void handle_sec_sfi_fault(uint32_t gstat) | ||
339 | { | ||
340 | |||
341 | } | ||
342 | |||
343 | void handle_sec_sci_fault(uint32_t gstat) | ||
344 | { | ||
345 | uint32_t core_id; | ||
346 | uint32_t cstat; | ||
347 | |||
348 | core_id = gstat & SEC_GSTAT_SCI; | ||
349 | cstat = bfin_read_SEC_SCI(core_id, SEC_CSTAT); | ||
350 | if (cstat & SEC_CSTAT_ERR) { | ||
351 | switch (cstat & SEC_CSTAT_ERRC) { | ||
352 | case SEC_CSTAT_ACKERR: | ||
353 | printk(KERN_DEBUG "sec ack err\n"); | ||
354 | break; | ||
355 | default: | ||
356 | printk(KERN_DEBUG "sec sci unknow err\n"); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | } | ||
361 | |||
362 | void handle_sec_ssi_fault(uint32_t gstat) | ||
363 | { | ||
364 | uint32_t sid; | ||
365 | uint32_t sstat; | ||
366 | |||
367 | sid = gstat & SEC_GSTAT_SID; | ||
368 | sstat = bfin_read_SEC_SSTAT(sid); | ||
369 | |||
370 | } | ||
371 | |||
372 | void handle_sec_fault(unsigned int irq, struct irq_desc *desc) | ||
373 | { | ||
374 | uint32_t sec_gstat; | ||
375 | |||
376 | raw_spin_lock(&desc->lock); | ||
377 | |||
378 | sec_gstat = bfin_read32(SEC_GSTAT); | ||
379 | if (sec_gstat & SEC_GSTAT_ERR) { | ||
380 | |||
381 | switch (sec_gstat & SEC_GSTAT_ERRC) { | ||
382 | case 0: | ||
383 | handle_sec_sfi_fault(sec_gstat); | ||
384 | break; | ||
385 | case SEC_GSTAT_SCIERR: | ||
386 | handle_sec_sci_fault(sec_gstat); | ||
387 | break; | ||
388 | case SEC_GSTAT_SSIERR: | ||
389 | handle_sec_ssi_fault(sec_gstat); | ||
390 | break; | ||
391 | } | ||
392 | |||
393 | |||
394 | } | ||
395 | |||
396 | raw_spin_unlock(&desc->lock); | ||
397 | } | ||
398 | |||
399 | static int sec_suspend(void) | ||
400 | { | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | static void sec_resume(void) | ||
405 | { | ||
406 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); | ||
407 | udelay(100); | ||
408 | bfin_write_SEC_GCTL(SEC_GCTL_EN); | ||
409 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); | ||
410 | } | ||
411 | |||
412 | static struct syscore_ops sec_pm_syscore_ops = { | ||
413 | .suspend = sec_suspend, | ||
414 | .resume = sec_resume, | ||
415 | }; | ||
416 | |||
417 | #endif | ||
418 | |||
194 | #ifdef CONFIG_SMP | 419 | #ifdef CONFIG_SMP |
195 | static void bfin_internal_unmask_irq_chip(struct irq_data *d) | 420 | static void bfin_internal_unmask_irq_chip(struct irq_data *d) |
196 | { | 421 | { |
@@ -212,7 +437,7 @@ static void bfin_internal_unmask_irq_chip(struct irq_data *d) | |||
212 | } | 437 | } |
213 | #endif | 438 | #endif |
214 | 439 | ||
215 | #ifdef CONFIG_PM | 440 | #if defined(CONFIG_PM) && !defined(CONFIG_BF60x) |
216 | int bfin_internal_set_wake(unsigned int irq, unsigned int state) | 441 | int bfin_internal_set_wake(unsigned int irq, unsigned int state) |
217 | { | 442 | { |
218 | u32 bank, bit, wakeup = 0; | 443 | u32 bank, bit, wakeup = 0; |
@@ -271,22 +496,20 @@ static int bfin_internal_set_wake_chip(struct irq_data *d, unsigned int state) | |||
271 | return bfin_internal_set_wake(d->irq, state); | 496 | return bfin_internal_set_wake(d->irq, state); |
272 | } | 497 | } |
273 | #else | 498 | #else |
499 | # define bfin_internal_set_wake(irq, state) | ||
274 | # define bfin_internal_set_wake_chip NULL | 500 | # define bfin_internal_set_wake_chip NULL |
275 | #endif | 501 | #endif |
276 | 502 | ||
277 | static struct irq_chip bfin_core_irqchip = { | 503 | static struct irq_chip bfin_core_irqchip = { |
278 | .name = "CORE", | 504 | .name = "CORE", |
279 | .irq_ack = bfin_ack_noop, | ||
280 | .irq_mask = bfin_core_mask_irq, | 505 | .irq_mask = bfin_core_mask_irq, |
281 | .irq_unmask = bfin_core_unmask_irq, | 506 | .irq_unmask = bfin_core_unmask_irq, |
282 | }; | 507 | }; |
283 | 508 | ||
284 | static struct irq_chip bfin_internal_irqchip = { | 509 | static struct irq_chip bfin_internal_irqchip = { |
285 | .name = "INTN", | 510 | .name = "INTN", |
286 | .irq_ack = bfin_ack_noop, | ||
287 | .irq_mask = bfin_internal_mask_irq_chip, | 511 | .irq_mask = bfin_internal_mask_irq_chip, |
288 | .irq_unmask = bfin_internal_unmask_irq_chip, | 512 | .irq_unmask = bfin_internal_unmask_irq_chip, |
289 | .irq_mask_ack = bfin_internal_mask_irq_chip, | ||
290 | .irq_disable = bfin_internal_mask_irq_chip, | 513 | .irq_disable = bfin_internal_mask_irq_chip, |
291 | .irq_enable = bfin_internal_unmask_irq_chip, | 514 | .irq_enable = bfin_internal_unmask_irq_chip, |
292 | #ifdef CONFIG_SMP | 515 | #ifdef CONFIG_SMP |
@@ -295,6 +518,18 @@ static struct irq_chip bfin_internal_irqchip = { | |||
295 | .irq_set_wake = bfin_internal_set_wake_chip, | 518 | .irq_set_wake = bfin_internal_set_wake_chip, |
296 | }; | 519 | }; |
297 | 520 | ||
521 | #ifdef CONFIG_BF60x | ||
522 | static struct irq_chip bfin_sec_irqchip = { | ||
523 | .name = "SEC", | ||
524 | .irq_mask_ack = bfin_sec_mask_ack_irq, | ||
525 | .irq_mask = bfin_sec_mask_ack_irq, | ||
526 | .irq_unmask = bfin_sec_unmask_irq, | ||
527 | .irq_eoi = bfin_sec_unmask_irq, | ||
528 | .irq_disable = bfin_sec_disable, | ||
529 | .irq_enable = bfin_sec_enable, | ||
530 | }; | ||
531 | #endif | ||
532 | |||
298 | void bfin_handle_irq(unsigned irq) | 533 | void bfin_handle_irq(unsigned irq) |
299 | { | 534 | { |
300 | #ifdef CONFIG_IPIPE | 535 | #ifdef CONFIG_IPIPE |
@@ -396,8 +631,6 @@ int bfin_mac_status_set_wake(struct irq_data *d, unsigned int state) | |||
396 | 631 | ||
397 | static struct irq_chip bfin_mac_status_irqchip = { | 632 | static struct irq_chip bfin_mac_status_irqchip = { |
398 | .name = "MACST", | 633 | .name = "MACST", |
399 | .irq_ack = bfin_ack_noop, | ||
400 | .irq_mask_ack = bfin_mac_status_mask_irq, | ||
401 | .irq_mask = bfin_mac_status_mask_irq, | 634 | .irq_mask = bfin_mac_status_mask_irq, |
402 | .irq_unmask = bfin_mac_status_unmask_irq, | 635 | .irq_unmask = bfin_mac_status_unmask_irq, |
403 | .irq_set_wake = bfin_mac_status_set_wake, | 636 | .irq_set_wake = bfin_mac_status_set_wake, |
@@ -421,15 +654,15 @@ void bfin_demux_mac_status_irq(unsigned int int_err_irq, | |||
421 | } else { | 654 | } else { |
422 | bfin_mac_status_ack_irq(irq); | 655 | bfin_mac_status_ack_irq(irq); |
423 | pr_debug("IRQ %d:" | 656 | pr_debug("IRQ %d:" |
424 | " MASKED MAC ERROR INTERRUPT ASSERTED\n", | 657 | " MASKED MAC ERROR INTERRUPT ASSERTED\n", |
425 | irq); | 658 | irq); |
426 | } | 659 | } |
427 | } else | 660 | } else |
428 | printk(KERN_ERR | 661 | printk(KERN_ERR |
429 | "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" | 662 | "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" |
430 | " INTERRUPT ASSERTED BUT NO SOURCE FOUND" | 663 | " INTERRUPT ASSERTED BUT NO SOURCE FOUND" |
431 | "(EMAC_SYSTAT=0x%X)\n", | 664 | "(EMAC_SYSTAT=0x%X)\n", |
432 | __func__, __FILE__, __LINE__, status); | 665 | __func__, __FILE__, __LINE__, status); |
433 | } | 666 | } |
434 | #endif | 667 | #endif |
435 | 668 | ||
@@ -583,7 +816,7 @@ static void bfin_demux_gpio_block(unsigned int irq) | |||
583 | } | 816 | } |
584 | 817 | ||
585 | void bfin_demux_gpio_irq(unsigned int inta_irq, | 818 | void bfin_demux_gpio_irq(unsigned int inta_irq, |
586 | struct irq_desc *desc) | 819 | struct irq_desc *desc) |
587 | { | 820 | { |
588 | unsigned int irq; | 821 | unsigned int irq; |
589 | 822 | ||
@@ -635,9 +868,15 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
635 | 868 | ||
636 | #else | 869 | #else |
637 | 870 | ||
871 | # ifndef CONFIG_BF60x | ||
638 | #define NR_PINT_SYS_IRQS 4 | 872 | #define NR_PINT_SYS_IRQS 4 |
639 | #define NR_PINT_BITS 32 | ||
640 | #define NR_PINTS 160 | 873 | #define NR_PINTS 160 |
874 | # else | ||
875 | #define NR_PINT_SYS_IRQS 6 | ||
876 | #define NR_PINTS 112 | ||
877 | #endif | ||
878 | |||
879 | #define NR_PINT_BITS 32 | ||
641 | #define IRQ_NOT_AVAIL 0xFF | 880 | #define IRQ_NOT_AVAIL 0xFF |
642 | 881 | ||
643 | #define PINT_2_BANK(x) ((x) >> 5) | 882 | #define PINT_2_BANK(x) ((x) >> 5) |
@@ -652,8 +891,13 @@ static struct bfin_pint_regs * const pint[NR_PINT_SYS_IRQS] = { | |||
652 | (struct bfin_pint_regs *)PINT1_MASK_SET, | 891 | (struct bfin_pint_regs *)PINT1_MASK_SET, |
653 | (struct bfin_pint_regs *)PINT2_MASK_SET, | 892 | (struct bfin_pint_regs *)PINT2_MASK_SET, |
654 | (struct bfin_pint_regs *)PINT3_MASK_SET, | 893 | (struct bfin_pint_regs *)PINT3_MASK_SET, |
894 | #ifdef CONFIG_BF60x | ||
895 | (struct bfin_pint_regs *)PINT4_MASK_SET, | ||
896 | (struct bfin_pint_regs *)PINT5_MASK_SET, | ||
897 | #endif | ||
655 | }; | 898 | }; |
656 | 899 | ||
900 | #ifndef CONFIG_BF60x | ||
657 | inline unsigned int get_irq_base(u32 bank, u8 bmap) | 901 | inline unsigned int get_irq_base(u32 bank, u8 bmap) |
658 | { | 902 | { |
659 | unsigned int irq_base; | 903 | unsigned int irq_base; |
@@ -666,6 +910,16 @@ inline unsigned int get_irq_base(u32 bank, u8 bmap) | |||
666 | 910 | ||
667 | return irq_base; | 911 | return irq_base; |
668 | } | 912 | } |
913 | #else | ||
914 | inline unsigned int get_irq_base(u32 bank, u8 bmap) | ||
915 | { | ||
916 | unsigned int irq_base; | ||
917 | |||
918 | irq_base = IRQ_PA0 + bank * 16 + bmap * 16; | ||
919 | |||
920 | return irq_base; | ||
921 | } | ||
922 | #endif | ||
669 | 923 | ||
670 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ | 924 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ |
671 | void init_pint_lut(void) | 925 | void init_pint_lut(void) |
@@ -854,6 +1108,14 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) | |||
854 | case 1: | 1108 | case 1: |
855 | pint_irq = IRQ_PINT1; | 1109 | pint_irq = IRQ_PINT1; |
856 | break; | 1110 | break; |
1111 | #ifdef CONFIG_BF60x | ||
1112 | case 4: | ||
1113 | pint_irq = IRQ_PINT4; | ||
1114 | break; | ||
1115 | case 5: | ||
1116 | pint_irq = IRQ_PINT5; | ||
1117 | break; | ||
1118 | #endif | ||
857 | default: | 1119 | default: |
858 | return -EINVAL; | 1120 | return -EINVAL; |
859 | } | 1121 | } |
@@ -867,10 +1129,21 @@ static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state) | |||
867 | #endif | 1129 | #endif |
868 | 1130 | ||
869 | void bfin_demux_gpio_irq(unsigned int inta_irq, | 1131 | void bfin_demux_gpio_irq(unsigned int inta_irq, |
870 | struct irq_desc *desc) | 1132 | struct irq_desc *desc) |
871 | { | 1133 | { |
872 | u32 bank, pint_val; | 1134 | u32 bank, pint_val; |
873 | u32 request, irq; | 1135 | u32 request, irq; |
1136 | u32 level_mask; | ||
1137 | int umask = 0; | ||
1138 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
1139 | |||
1140 | if (chip->irq_mask_ack) { | ||
1141 | chip->irq_mask_ack(&desc->irq_data); | ||
1142 | } else { | ||
1143 | chip->irq_mask(&desc->irq_data); | ||
1144 | if (chip->irq_ack) | ||
1145 | chip->irq_ack(&desc->irq_data); | ||
1146 | } | ||
874 | 1147 | ||
875 | switch (inta_irq) { | 1148 | switch (inta_irq) { |
876 | case IRQ_PINT0: | 1149 | case IRQ_PINT0: |
@@ -885,6 +1158,14 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
885 | case IRQ_PINT1: | 1158 | case IRQ_PINT1: |
886 | bank = 1; | 1159 | bank = 1; |
887 | break; | 1160 | break; |
1161 | #ifdef CONFIG_BF60x | ||
1162 | case IRQ_PINT4: | ||
1163 | bank = 4; | ||
1164 | break; | ||
1165 | case IRQ_PINT5: | ||
1166 | bank = 5; | ||
1167 | break; | ||
1168 | #endif | ||
888 | default: | 1169 | default: |
889 | return; | 1170 | return; |
890 | } | 1171 | } |
@@ -893,15 +1174,23 @@ void bfin_demux_gpio_irq(unsigned int inta_irq, | |||
893 | 1174 | ||
894 | request = pint[bank]->request; | 1175 | request = pint[bank]->request; |
895 | 1176 | ||
1177 | level_mask = pint[bank]->edge_set & request; | ||
1178 | |||
896 | while (request) { | 1179 | while (request) { |
897 | if (request & 1) { | 1180 | if (request & 1) { |
898 | irq = pint2irq_lut[pint_val] + SYS_IRQS; | 1181 | irq = pint2irq_lut[pint_val] + SYS_IRQS; |
1182 | if (level_mask & PINT_BIT(pint_val)) { | ||
1183 | umask = 1; | ||
1184 | chip->irq_unmask(&desc->irq_data); | ||
1185 | } | ||
899 | bfin_handle_irq(irq); | 1186 | bfin_handle_irq(irq); |
900 | } | 1187 | } |
901 | pint_val++; | 1188 | pint_val++; |
902 | request >>= 1; | 1189 | request >>= 1; |
903 | } | 1190 | } |
904 | 1191 | ||
1192 | if (!umask) | ||
1193 | chip->irq_unmask(&desc->irq_data); | ||
905 | } | 1194 | } |
906 | #endif | 1195 | #endif |
907 | 1196 | ||
@@ -951,6 +1240,7 @@ int __init init_arch_irq(void) | |||
951 | int irq; | 1240 | int irq; |
952 | unsigned long ilat = 0; | 1241 | unsigned long ilat = 0; |
953 | 1242 | ||
1243 | #ifndef CONFIG_BF60x | ||
954 | /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ | 1244 | /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ |
955 | #ifdef SIC_IMASK0 | 1245 | #ifdef SIC_IMASK0 |
956 | bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); | 1246 | bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); |
@@ -958,13 +1248,16 @@ int __init init_arch_irq(void) | |||
958 | # ifdef SIC_IMASK2 | 1248 | # ifdef SIC_IMASK2 |
959 | bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); | 1249 | bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); |
960 | # endif | 1250 | # endif |
961 | # ifdef CONFIG_SMP | 1251 | # if defined(CONFIG_SMP) || defined(CONFIG_ICC) |
962 | bfin_write_SICB_IMASK0(SIC_UNMASK_ALL); | 1252 | bfin_write_SICB_IMASK0(SIC_UNMASK_ALL); |
963 | bfin_write_SICB_IMASK1(SIC_UNMASK_ALL); | 1253 | bfin_write_SICB_IMASK1(SIC_UNMASK_ALL); |
964 | # endif | 1254 | # endif |
965 | #else | 1255 | #else |
966 | bfin_write_SIC_IMASK(SIC_UNMASK_ALL); | 1256 | bfin_write_SIC_IMASK(SIC_UNMASK_ALL); |
967 | #endif | 1257 | #endif |
1258 | #else /* CONFIG_BF60x */ | ||
1259 | bfin_write_SEC_GCTL(SEC_GCTL_RESET); | ||
1260 | #endif | ||
968 | 1261 | ||
969 | local_irq_disable(); | 1262 | local_irq_disable(); |
970 | 1263 | ||
@@ -974,6 +1267,10 @@ int __init init_arch_irq(void) | |||
974 | pint[1]->assign = CONFIG_PINT1_ASSIGN; | 1267 | pint[1]->assign = CONFIG_PINT1_ASSIGN; |
975 | pint[2]->assign = CONFIG_PINT2_ASSIGN; | 1268 | pint[2]->assign = CONFIG_PINT2_ASSIGN; |
976 | pint[3]->assign = CONFIG_PINT3_ASSIGN; | 1269 | pint[3]->assign = CONFIG_PINT3_ASSIGN; |
1270 | # ifdef CONFIG_BF60x | ||
1271 | pint[4]->assign = CONFIG_PINT4_ASSIGN; | ||
1272 | pint[5]->assign = CONFIG_PINT5_ASSIGN; | ||
1273 | # endif | ||
977 | # endif | 1274 | # endif |
978 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ | 1275 | /* Whenever PINTx_ASSIGN is altered init_pint_lut() must be executed! */ |
979 | init_pint_lut(); | 1276 | init_pint_lut(); |
@@ -986,6 +1283,7 @@ int __init init_arch_irq(void) | |||
986 | irq_set_chip(irq, &bfin_internal_irqchip); | 1283 | irq_set_chip(irq, &bfin_internal_irqchip); |
987 | 1284 | ||
988 | switch (irq) { | 1285 | switch (irq) { |
1286 | #ifndef CONFIG_BF60x | ||
989 | #if BFIN_GPIO_PINT | 1287 | #if BFIN_GPIO_PINT |
990 | case IRQ_PINT0: | 1288 | case IRQ_PINT0: |
991 | case IRQ_PINT1: | 1289 | case IRQ_PINT1: |
@@ -1015,12 +1313,13 @@ int __init init_arch_irq(void) | |||
1015 | bfin_demux_mac_status_irq); | 1313 | bfin_demux_mac_status_irq); |
1016 | break; | 1314 | break; |
1017 | #endif | 1315 | #endif |
1018 | #ifdef CONFIG_SMP | 1316 | #if defined(CONFIG_SMP) || defined(CONFIG_ICC) |
1019 | case IRQ_SUPPLE_0: | 1317 | case IRQ_SUPPLE_0: |
1020 | case IRQ_SUPPLE_1: | 1318 | case IRQ_SUPPLE_1: |
1021 | irq_set_handler(irq, handle_percpu_irq); | 1319 | irq_set_handler(irq, handle_percpu_irq); |
1022 | break; | 1320 | break; |
1023 | #endif | 1321 | #endif |
1322 | #endif | ||
1024 | 1323 | ||
1025 | #ifdef CONFIG_TICKSOURCE_CORETMR | 1324 | #ifdef CONFIG_TICKSOURCE_CORETMR |
1026 | case IRQ_CORETMR: | 1325 | case IRQ_CORETMR: |
@@ -1050,7 +1349,8 @@ int __init init_arch_irq(void) | |||
1050 | 1349 | ||
1051 | init_mach_irq(); | 1350 | init_mach_irq(); |
1052 | 1351 | ||
1053 | #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) | 1352 | #ifndef CONFIG_BF60x |
1353 | #if (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) && !defined(CONFIG_BF60x) | ||
1054 | for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) | 1354 | for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) |
1055 | irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip, | 1355 | irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip, |
1056 | handle_level_irq); | 1356 | handle_level_irq); |
@@ -1060,7 +1360,28 @@ int __init init_arch_irq(void) | |||
1060 | irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) | 1360 | irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) |
1061 | irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, | 1361 | irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, |
1062 | handle_level_irq); | 1362 | handle_level_irq); |
1063 | 1363 | #else | |
1364 | for (irq = BFIN_IRQ(0); irq <= SYS_IRQS; irq++) { | ||
1365 | if (irq < CORE_IRQS) { | ||
1366 | irq_set_chip(irq, &bfin_sec_irqchip); | ||
1367 | __irq_set_handler(irq, handle_sec_fault, 0, NULL); | ||
1368 | } else if (irq >= BFIN_IRQ(21) && irq <= BFIN_IRQ(26)) { | ||
1369 | irq_set_chip(irq, &bfin_sec_irqchip); | ||
1370 | irq_set_chained_handler(irq, bfin_demux_gpio_irq); | ||
1371 | } else if (irq >= BFIN_IRQ(34) && irq <= BFIN_IRQ(37)) { | ||
1372 | irq_set_chip(irq, &bfin_sec_irqchip); | ||
1373 | irq_set_handler(irq, handle_percpu_irq); | ||
1374 | } else { | ||
1375 | irq_set_chip_and_handler(irq, &bfin_sec_irqchip, | ||
1376 | handle_fasteoi_irq); | ||
1377 | __irq_set_preflow_handler(irq, bfin_sec_preflow_handler); | ||
1378 | } | ||
1379 | } | ||
1380 | for (irq = GPIO_IRQ_BASE; | ||
1381 | irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) | ||
1382 | irq_set_chip_and_handler(irq, &bfin_gpio_irqchip, | ||
1383 | handle_level_irq); | ||
1384 | #endif | ||
1064 | bfin_write_IMASK(0); | 1385 | bfin_write_IMASK(0); |
1065 | CSYNC(); | 1386 | CSYNC(); |
1066 | ilat = bfin_read_ILAT(); | 1387 | ilat = bfin_read_ILAT(); |
@@ -1072,14 +1393,17 @@ int __init init_arch_irq(void) | |||
1072 | /* IMASK=xxx is equivalent to STI xx or bfin_irq_flags=xx, | 1393 | /* IMASK=xxx is equivalent to STI xx or bfin_irq_flags=xx, |
1073 | * local_irq_enable() | 1394 | * local_irq_enable() |
1074 | */ | 1395 | */ |
1396 | #ifndef CONFIG_BF60x | ||
1075 | program_IAR(); | 1397 | program_IAR(); |
1076 | /* Therefore it's better to setup IARs before interrupts enabled */ | 1398 | /* Therefore it's better to setup IARs before interrupts enabled */ |
1077 | search_IAR(); | 1399 | search_IAR(); |
1078 | 1400 | ||
1079 | /* Enable interrupts IVG7-15 */ | 1401 | /* Enable interrupts IVG7-15 */ |
1080 | bfin_irq_flags |= IMASK_IVG15 | | 1402 | bfin_irq_flags |= IMASK_IVG15 | |
1081 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | | 1403 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | |
1082 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; | 1404 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; |
1405 | |||
1406 | bfin_sti(bfin_irq_flags); | ||
1083 | 1407 | ||
1084 | /* This implicitly covers ANOMALY_05000171 | 1408 | /* This implicitly covers ANOMALY_05000171 |
1085 | * Boot-ROM code modifies SICA_IWRx wakeup registers | 1409 | * Boot-ROM code modifies SICA_IWRx wakeup registers |
@@ -1103,7 +1427,23 @@ int __init init_arch_irq(void) | |||
1103 | #else | 1427 | #else |
1104 | bfin_write_SIC_IWR(IWR_DISABLE_ALL); | 1428 | bfin_write_SIC_IWR(IWR_DISABLE_ALL); |
1105 | #endif | 1429 | #endif |
1430 | #else /* CONFIG_BF60x */ | ||
1431 | /* Enable interrupts IVG7-15 */ | ||
1432 | bfin_irq_flags |= IMASK_IVG15 | | ||
1433 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | | ||
1434 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; | ||
1106 | 1435 | ||
1436 | |||
1437 | bfin_write_SEC_FCTL(SEC_FCTL_EN | SEC_FCTL_SYSRST_EN | SEC_FCTL_FLTIN_EN); | ||
1438 | bfin_sec_enable_sci(SIC_SYSIRQ(IRQ_WATCH0)); | ||
1439 | bfin_sec_enable_ssi(SIC_SYSIRQ(IRQ_WATCH0)); | ||
1440 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_RESET); | ||
1441 | udelay(100); | ||
1442 | bfin_write_SEC_GCTL(SEC_GCTL_EN); | ||
1443 | bfin_write_SEC_SCI(0, SEC_CCTL, SEC_CCTL_EN | SEC_CCTL_NMI_EN); | ||
1444 | init_software_driven_irq(); | ||
1445 | register_syscore_ops(&sec_pm_syscore_ops); | ||
1446 | #endif | ||
1107 | return 0; | 1447 | return 0; |
1108 | } | 1448 | } |
1109 | 1449 | ||
@@ -1112,13 +1452,14 @@ __attribute__((l1_text)) | |||
1112 | #endif | 1452 | #endif |
1113 | static int vec_to_irq(int vec) | 1453 | static int vec_to_irq(int vec) |
1114 | { | 1454 | { |
1455 | #ifndef CONFIG_BF60x | ||
1115 | struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; | 1456 | struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; |
1116 | struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; | 1457 | struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; |
1117 | unsigned long sic_status[3]; | 1458 | unsigned long sic_status[3]; |
1118 | 1459 | #endif | |
1119 | if (likely(vec == EVT_IVTMR_P)) | 1460 | if (likely(vec == EVT_IVTMR_P)) |
1120 | return IRQ_CORETMR; | 1461 | return IRQ_CORETMR; |
1121 | 1462 | #ifndef CONFIG_BF60x | |
1122 | #ifdef SIC_ISR | 1463 | #ifdef SIC_ISR |
1123 | sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); | 1464 | sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); |
1124 | #else | 1465 | #else |
@@ -1147,6 +1488,10 @@ static int vec_to_irq(int vec) | |||
1147 | #endif | 1488 | #endif |
1148 | return ivg->irqno; | 1489 | return ivg->irqno; |
1149 | } | 1490 | } |
1491 | #else | ||
1492 | /* for bf60x read */ | ||
1493 | return BFIN_IRQ(bfin_read_SEC_SCI(0, SEC_CSID)); | ||
1494 | #endif /* end of CONFIG_BF60x */ | ||
1150 | } | 1495 | } |
1151 | 1496 | ||
1152 | #ifdef CONFIG_DO_IRQ_L1 | 1497 | #ifdef CONFIG_DO_IRQ_L1 |
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 3c648a077e75..ca6655e0d653 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c | |||
@@ -19,20 +19,33 @@ | |||
19 | #include <asm/gpio.h> | 19 | #include <asm/gpio.h> |
20 | #include <asm/dma.h> | 20 | #include <asm/dma.h> |
21 | #include <asm/dpmc.h> | 21 | #include <asm/dpmc.h> |
22 | #include <asm/pm.h> | ||
22 | 23 | ||
24 | #ifdef CONFIG_BF60x | ||
25 | struct bfin_cpu_pm_fns *bfin_cpu_pm; | ||
26 | #endif | ||
23 | 27 | ||
24 | void bfin_pm_suspend_standby_enter(void) | 28 | void bfin_pm_suspend_standby_enter(void) |
25 | { | 29 | { |
30 | #ifndef CONFIG_BF60x | ||
26 | bfin_pm_standby_setup(); | 31 | bfin_pm_standby_setup(); |
32 | #endif | ||
27 | 33 | ||
28 | #ifdef CONFIG_PM_BFIN_SLEEP_DEEPER | 34 | #ifdef CONFIG_BF60x |
29 | sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); | 35 | bfin_cpu_pm->enter(PM_SUSPEND_STANDBY); |
30 | #else | 36 | #else |
37 | # ifdef CONFIG_PM_BFIN_SLEEP_DEEPER | ||
38 | sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); | ||
39 | # else | ||
31 | sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); | 40 | sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); |
41 | # endif | ||
32 | #endif | 42 | #endif |
33 | 43 | ||
44 | #ifndef CONFIG_BF60x | ||
34 | bfin_pm_standby_restore(); | 45 | bfin_pm_standby_restore(); |
46 | #endif | ||
35 | 47 | ||
48 | #ifndef CONFIG_BF60x | ||
36 | #ifdef SIC_IWR0 | 49 | #ifdef SIC_IWR0 |
37 | bfin_write_SIC_IWR0(IWR_DISABLE_ALL); | 50 | bfin_write_SIC_IWR0(IWR_DISABLE_ALL); |
38 | # ifdef SIC_IWR1 | 51 | # ifdef SIC_IWR1 |
@@ -52,6 +65,8 @@ void bfin_pm_suspend_standby_enter(void) | |||
52 | #else | 65 | #else |
53 | bfin_write_SIC_IWR(IWR_DISABLE_ALL); | 66 | bfin_write_SIC_IWR(IWR_DISABLE_ALL); |
54 | #endif | 67 | #endif |
68 | |||
69 | #endif | ||
55 | } | 70 | } |
56 | 71 | ||
57 | int bf53x_suspend_l1_mem(unsigned char *memptr) | 72 | int bf53x_suspend_l1_mem(unsigned char *memptr) |
@@ -83,10 +98,13 @@ int bf53x_resume_l1_mem(unsigned char *memptr) | |||
83 | } | 98 | } |
84 | 99 | ||
85 | #if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) | 100 | #if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) |
101 | # ifdef CONFIG_BF60x | ||
102 | __attribute__((l1_text)) | ||
103 | # endif | ||
86 | static void flushinv_all_dcache(void) | 104 | static void flushinv_all_dcache(void) |
87 | { | 105 | { |
88 | u32 way, bank, subbank, set; | 106 | register u32 way, bank, subbank, set; |
89 | u32 status, addr; | 107 | register u32 status, addr; |
90 | u32 dmem_ctl = bfin_read_DMEM_CONTROL(); | 108 | u32 dmem_ctl = bfin_read_DMEM_CONTROL(); |
91 | 109 | ||
92 | for (bank = 0; bank < 2; ++bank) { | 110 | for (bank = 0; bank < 2; ++bank) { |
@@ -133,6 +151,7 @@ int bfin_pm_suspend_mem_enter(void) | |||
133 | return -ENOMEM; | 151 | return -ENOMEM; |
134 | } | 152 | } |
135 | 153 | ||
154 | #ifndef CONFIG_BF60x | ||
136 | wakeup = bfin_read_VR_CTL() & ~FREQ; | 155 | wakeup = bfin_read_VR_CTL() & ~FREQ; |
137 | wakeup |= SCKELOW; | 156 | wakeup |= SCKELOW; |
138 | 157 | ||
@@ -142,6 +161,7 @@ int bfin_pm_suspend_mem_enter(void) | |||
142 | #ifdef CONFIG_PM_BFIN_WAKE_GP | 161 | #ifdef CONFIG_PM_BFIN_WAKE_GP |
143 | wakeup |= GPWE; | 162 | wakeup |= GPWE; |
144 | #endif | 163 | #endif |
164 | #endif | ||
145 | 165 | ||
146 | ret = blackfin_dma_suspend(); | 166 | ret = blackfin_dma_suspend(); |
147 | 167 | ||
@@ -159,7 +179,11 @@ int bfin_pm_suspend_mem_enter(void) | |||
159 | _disable_icplb(); | 179 | _disable_icplb(); |
160 | bf53x_suspend_l1_mem(memptr); | 180 | bf53x_suspend_l1_mem(memptr); |
161 | 181 | ||
182 | #ifndef CONFIG_BF60x | ||
162 | do_hibernate(wakeup | vr_wakeup); /* See you later! */ | 183 | do_hibernate(wakeup | vr_wakeup); /* See you later! */ |
184 | #else | ||
185 | bfin_cpu_pm->enter(PM_SUSPEND_MEM); | ||
186 | #endif | ||
163 | 187 | ||
164 | bf53x_resume_l1_mem(memptr); | 188 | bf53x_resume_l1_mem(memptr); |
165 | 189 | ||
@@ -223,9 +247,39 @@ static int bfin_pm_enter(suspend_state_t state) | |||
223 | return 0; | 247 | return 0; |
224 | } | 248 | } |
225 | 249 | ||
250 | #ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH | ||
251 | void bfin_pm_end(void) | ||
252 | { | ||
253 | u32 cycle, cycle2; | ||
254 | u64 usec64; | ||
255 | u32 usec; | ||
256 | |||
257 | __asm__ __volatile__ ( | ||
258 | "1: %0 = CYCLES2\n" | ||
259 | "%1 = CYCLES\n" | ||
260 | "%2 = CYCLES2\n" | ||
261 | "CC = %2 == %0\n" | ||
262 | "if ! CC jump 1b\n" | ||
263 | : "=d,a" (cycle2), "=d,a" (cycle), "=d,a" (usec) : : "CC" | ||
264 | ); | ||
265 | |||
266 | usec64 = ((u64)cycle2 << 32) + cycle; | ||
267 | do_div(usec64, get_cclk() / USEC_PER_SEC); | ||
268 | usec = usec64; | ||
269 | if (usec == 0) | ||
270 | usec = 1; | ||
271 | |||
272 | pr_info("PM: resume of kernel completes after %ld msec %03ld usec\n", | ||
273 | usec / USEC_PER_MSEC, usec % USEC_PER_MSEC); | ||
274 | } | ||
275 | #endif | ||
276 | |||
226 | static const struct platform_suspend_ops bfin_pm_ops = { | 277 | static const struct platform_suspend_ops bfin_pm_ops = { |
227 | .enter = bfin_pm_enter, | 278 | .enter = bfin_pm_enter, |
228 | .valid = bfin_pm_valid, | 279 | .valid = bfin_pm_valid, |
280 | #ifdef CONFIG_BFIN_PM_WAKEUP_TIME_BENCH | ||
281 | .end = bfin_pm_end, | ||
282 | #endif | ||
229 | }; | 283 | }; |
230 | 284 | ||
231 | static int __init bfin_pm_init(void) | 285 | static int __init bfin_pm_init(void) |
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index ac8f8a43158c..00bbe672b3b3 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c | |||
@@ -340,27 +340,10 @@ void smp_send_stop(void) | |||
340 | return; | 340 | return; |
341 | } | 341 | } |
342 | 342 | ||
343 | int __cpuinit __cpu_up(unsigned int cpu) | 343 | int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) |
344 | { | 344 | { |
345 | int ret; | 345 | int ret; |
346 | struct blackfin_cpudata *ci = &per_cpu(cpu_data, cpu); | ||
347 | struct task_struct *idle = ci->idle; | ||
348 | 346 | ||
349 | if (idle) { | ||
350 | free_task(idle); | ||
351 | idle = NULL; | ||
352 | } | ||
353 | |||
354 | if (!idle) { | ||
355 | idle = fork_idle(cpu); | ||
356 | if (IS_ERR(idle)) { | ||
357 | printk(KERN_ERR "CPU%u: fork() failed\n", cpu); | ||
358 | return PTR_ERR(idle); | ||
359 | } | ||
360 | ci->idle = idle; | ||
361 | } else { | ||
362 | init_idle(idle, cpu); | ||
363 | } | ||
364 | secondary_stack = task_stack_page(idle) + THREAD_SIZE; | 347 | secondary_stack = task_stack_page(idle) + THREAD_SIZE; |
365 | 348 | ||
366 | ret = platform_boot_secondary(cpu, idle); | 349 | ret = platform_boot_secondary(cpu, idle); |