Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

blackfin: bf60x: enable gptimer clock source

Signed-off-by: Steven Miao <realmz6@gmail.com>
Signed-off-by: Bob Liu <lliubbo@gmail.com>

authored by

Steven Miao and committed by
Bob Liu
2879bb30 e578bbde

+211 -3
+104
arch/blackfin/include/asm/gptimers.h
··· 44 44 # define TIMER_GROUP2 1 45 45 #endif 46 46 /* 47 + * BF609: 8 timers: 48 + */ 49 + #if defined(CONFIG_BF60x) 50 + # define MAX_BLACKFIN_GPTIMERS 8 51 + # define TIMER0_GROUP_REG TIMER_RUN 52 + #endif 53 + /* 47 54 * All others: 3 timers: 48 55 */ 49 56 #define TIMER_GROUP1 0 ··· 110 103 # define FS1_TIMER_BIT TIMER0bit 111 104 # define FS2_TIMER_BIT TIMER1bit 112 105 #endif 106 + 107 + #ifdef CONFIG_BF60x 108 + /* 109 + * Timer Configuration Register Bits 110 + */ 111 + #define TIMER_EMU_RUN 0x8000 112 + #define TIMER_BPER_EN 0x4000 113 + #define TIMER_BWID_EN 0x2000 114 + #define TIMER_BDLY_EN 0x1000 115 + #define TIMER_OUT_DIS 0x0800 116 + #define TIMER_TIN_SEL 0x0400 117 + #define TIMER_CLK_SEL 0x0300 118 + #define TIMER_CLK_SCLK 0x0000 119 + #define TIMER_CLK_ALT_CLK0 0x0100 120 + #define TIMER_CLK_ALT_CLK1 0x0300 121 + #define TIMER_PULSE_HI 0x0080 122 + #define TIMER_SLAVE_TRIG 0x0040 123 + #define TIMER_IRQ_MODE 0x0030 124 + #define TIMER_IRQ_ACT_EDGE 0x0000 125 + #define TIMER_IRQ_DLY 0x0010 126 + #define TIMER_IRQ_WID_DLY 0x0020 127 + #define TIMER_IRQ_PER 0x0030 128 + #define TIMER_MODE 0x000f 129 + #define TIMER_MODE_WDOG_P 0x0008 130 + #define TIMER_MODE_WDOG_W 0x0009 131 + #define TIMER_MODE_PWM_CONT 0x000c 132 + #define TIMER_MODE_PWM 0x000d 133 + #define TIMER_MODE_WDTH 0x000a 134 + #define TIMER_MODE_WDTH_D 0x000b 135 + #define TIMER_MODE_EXT_CLK 0x000e 136 + #define TIMER_MODE_PININT 0x000f 137 + 138 + /* 139 + * Timer Status Register Bits 140 + */ 141 + #define TIMER_STATUS_TIMIL0 0x0001 142 + #define TIMER_STATUS_TIMIL1 0x0002 143 + #define TIMER_STATUS_TIMIL2 0x0004 144 + #define TIMER_STATUS_TIMIL3 0x0008 145 + #define TIMER_STATUS_TIMIL4 0x0010 146 + #define TIMER_STATUS_TIMIL5 0x0020 147 + #define TIMER_STATUS_TIMIL6 0x0040 148 + #define TIMER_STATUS_TIMIL7 0x0080 149 + 150 + #define TIMER_STATUS_TOVF0 0x0001 /* timer 0 overflow error */ 151 + #define TIMER_STATUS_TOVF1 0x0002 152 + #define TIMER_STATUS_TOVF2 0x0004 153 + #define TIMER_STATUS_TOVF3 0x0008 154 + #define TIMER_STATUS_TOVF4 0x0010 155 + #define TIMER_STATUS_TOVF5 0x0020 156 + #define TIMER_STATUS_TOVF6 0x0040 157 + #define TIMER_STATUS_TOVF7 0x0080 158 + 159 + /* 160 + * Timer Slave Enable Status : write 1 to clear 161 + */ 162 + #define TIMER_STATUS_TRUN0 0x0001 163 + #define TIMER_STATUS_TRUN1 0x0002 164 + #define TIMER_STATUS_TRUN2 0x0004 165 + #define TIMER_STATUS_TRUN3 0x0008 166 + #define TIMER_STATUS_TRUN4 0x0010 167 + #define TIMER_STATUS_TRUN5 0x0020 168 + #define TIMER_STATUS_TRUN6 0x0040 169 + #define TIMER_STATUS_TRUN7 0x0080 170 + 171 + #else 113 172 114 173 /* 115 174 * Timer Configuration Register Bits ··· 243 170 #define TIMER_STATUS_TRUN10 0x4000 244 171 #define TIMER_STATUS_TRUN11 0x8000 245 172 173 + #endif 174 + 246 175 /* The actual gptimer API */ 247 176 248 177 void set_gptimer_pwidth(unsigned int timer_id, uint32_t width); 249 178 uint32_t get_gptimer_pwidth(unsigned int timer_id); 250 179 void set_gptimer_period(unsigned int timer_id, uint32_t period); 251 180 uint32_t get_gptimer_period(unsigned int timer_id); 181 + #ifdef CONFIG_BF60x 182 + void set_gptimer_delay(unsigned int timer_id, uint32_t delay); 183 + uint32_t get_gptimer_delay(unsigned int timer_id); 184 + #endif 252 185 uint32_t get_gptimer_count(unsigned int timer_id); 253 186 int get_gptimer_intr(unsigned int timer_id); 254 187 void clear_gptimer_intr(unsigned int timer_id); ··· 296 217 u32 counter; 297 218 u32 period; 298 219 u32 width; 220 + #ifdef CONFIG_BF60x 221 + u32 delay; 222 + #endif 299 223 }; 300 224 301 225 /* 302 226 * bfin group timer registers layout 303 227 */ 228 + #ifndef CONFIG_BF60x 304 229 struct bfin_gptimer_group_regs { 305 230 __BFP(enable); 306 231 __BFP(disable); 307 232 u32 status; 308 233 }; 234 + #else 235 + struct bfin_gptimer_group_regs { 236 + __BFP(run); 237 + __BFP(enable); 238 + __BFP(disable); 239 + __BFP(stop_cfg); 240 + __BFP(stop_cfg_set); 241 + __BFP(stop_cfg_clr); 242 + __BFP(data_imsk); 243 + __BFP(stat_imsk); 244 + __BFP(tr_msk); 245 + __BFP(tr_ie); 246 + __BFP(data_ilat); 247 + __BFP(stat_ilat); 248 + __BFP(err_status); 249 + __BFP(bcast_per); 250 + __BFP(bcast_wid); 251 + __BFP(bcast_dly); 252 + 253 + }; 254 + #endif 309 255 310 256 #undef __BFP 311 257
+82 -1
arch/blackfin/kernel/gptimers.c
··· 23 23 printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", __FILE__, __func__, __LINE__); 24 24 #endif 25 25 26 - #define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1) 26 + #ifndef CONFIG_BF60x 27 + # define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1) 28 + #else 29 + # define BFIN_TIMER_NUM_GROUP 1 30 + #endif 27 31 28 32 static struct bfin_gptimer_regs * const timer_regs[MAX_BLACKFIN_GPTIMERS] = 29 33 { ··· 162 158 } 163 159 EXPORT_SYMBOL(get_gptimer_count); 164 160 161 + #ifdef CONFIG_BF60x 162 + void set_gptimer_delay(unsigned int timer_id, uint32_t delay) 163 + { 164 + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); 165 + bfin_write(&timer_regs[timer_id]->delay, delay); 166 + SSYNC(); 167 + } 168 + EXPORT_SYMBOL(set_gptimer_delay); 169 + 170 + uint32_t get_gptimer_delay(unsigned int timer_id) 171 + { 172 + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); 173 + return bfin_read(&timer_regs[timer_id]->delay); 174 + } 175 + EXPORT_SYMBOL(get_gptimer_delay); 176 + #endif 177 + 178 + #ifdef CONFIG_BF60x 179 + int get_gptimer_intr(unsigned int timer_id) 180 + { 181 + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); 182 + return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat) & timil_mask[timer_id]); 183 + } 184 + EXPORT_SYMBOL(get_gptimer_intr); 185 + 186 + void clear_gptimer_intr(unsigned int timer_id) 187 + { 188 + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); 189 + bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat, timil_mask[timer_id]); 190 + } 191 + EXPORT_SYMBOL(clear_gptimer_intr); 192 + 193 + int get_gptimer_over(unsigned int timer_id) 194 + { 195 + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); 196 + return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat) & tovf_mask[timer_id]); 197 + } 198 + EXPORT_SYMBOL(get_gptimer_over); 199 + 200 + void clear_gptimer_over(unsigned int timer_id) 201 + { 202 + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); 203 + bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat, tovf_mask[timer_id]); 204 + } 205 + EXPORT_SYMBOL(clear_gptimer_over); 206 + 207 + int get_gptimer_run(unsigned int timer_id) 208 + { 209 + tassert(timer_id < MAX_BLACKFIN_GPTIMERS); 210 + return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->run) & trun_mask[timer_id]); 211 + } 212 + EXPORT_SYMBOL(get_gptimer_run); 213 + 214 + uint32_t get_gptimer_status(unsigned int group) 215 + { 216 + tassert(group < BFIN_TIMER_NUM_GROUP); 217 + return bfin_read(&group_regs[group]->data_ilat); 218 + } 219 + EXPORT_SYMBOL(get_gptimer_status); 220 + 221 + void set_gptimer_status(unsigned int group, uint32_t value) 222 + { 223 + tassert(group < BFIN_TIMER_NUM_GROUP); 224 + bfin_write(&group_regs[group]->data_ilat, value); 225 + SSYNC(); 226 + } 227 + EXPORT_SYMBOL(set_gptimer_status); 228 + #else 165 229 uint32_t get_gptimer_status(unsigned int group) 166 230 { 167 231 tassert(group < BFIN_TIMER_NUM_GROUP); ··· 284 212 return !!(read_gptimer_status(timer_id) & trun_mask[timer_id]); 285 213 } 286 214 EXPORT_SYMBOL(get_gptimer_run); 215 + #endif 287 216 288 217 void set_gptimer_config(unsigned int timer_id, uint16_t config) 289 218 { ··· 304 231 void enable_gptimers(uint16_t mask) 305 232 { 306 233 int i; 234 + #ifdef CONFIG_BF60x 235 + uint16_t imask; 236 + imask = bfin_read16(TIMER_DATA_IMSK); 237 + imask &= ~mask; 238 + bfin_write16(TIMER_DATA_IMSK, imask); 239 + #endif 307 240 tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0); 308 241 for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) { 309 242 bfin_write(&group_regs[i]->enable, mask & 0xFF); ··· 334 255 { 335 256 int i; 336 257 _disable_gptimers(mask); 258 + #ifndef CONFIG_BF60x 337 259 for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i) 338 260 if (mask & (1 << i)) 339 261 bfin_write(&group_regs[BFIN_TIMER_OCTET(i)]->status, trun_mask[i]); 340 262 SSYNC(); 263 + #endif 341 264 } 342 265 EXPORT_SYMBOL(disable_gptimers); 343 266
+25 -2
arch/blackfin/kernel/time-ts.c
··· 66 66 { 67 67 disable_gptimers(TIMER0bit); 68 68 69 + #ifdef CONFIG_BF60x 70 + bfin_write16(TIMER_DATA_IMSK, 0); 71 + set_gptimer_config(TIMER0_id, TIMER_OUT_DIS 72 + | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); 73 + #else 69 74 set_gptimer_config(TIMER0_id, \ 70 75 TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM); 76 + #endif 71 77 set_gptimer_period(TIMER0_id, -1); 72 78 set_gptimer_pwidth(TIMER0_id, -2); 73 79 SSYNC(); ··· 141 135 { 142 136 switch (mode) { 143 137 case CLOCK_EVT_MODE_PERIODIC: { 138 + #ifndef CONFIG_BF60x 144 139 set_gptimer_config(TIMER0_id, \ 145 140 TIMER_OUT_DIS | TIMER_IRQ_ENA | \ 146 141 TIMER_PERIOD_CNT | TIMER_MODE_PWM); 142 + #else 143 + set_gptimer_config(TIMER0_id, TIMER_OUT_DIS 144 + | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER); 145 + #endif 146 + 147 147 set_gptimer_period(TIMER0_id, get_sclk() / HZ); 148 148 set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1); 149 149 enable_gptimers(TIMER0bit); ··· 157 145 } 158 146 case CLOCK_EVT_MODE_ONESHOT: 159 147 disable_gptimers(TIMER0bit); 148 + #ifndef CONFIG_BF60x 160 149 set_gptimer_config(TIMER0_id, \ 161 150 TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); 151 + #else 152 + set_gptimer_config(TIMER0_id, TIMER_OUT_DIS | TIMER_MODE_PWM 153 + | TIMER_PULSE_HI | TIMER_IRQ_WID_DLY); 154 + #endif 155 + 162 156 set_gptimer_period(TIMER0_id, 0); 163 157 break; 164 158 case CLOCK_EVT_MODE_UNUSED: ··· 178 160 179 161 static void bfin_gptmr0_ack(void) 180 162 { 181 - set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0); 163 + clear_gptimer_intr(TIMER0_id); 182 164 } 183 165 184 166 static void __init bfin_gptmr0_init(void) ··· 215 197 .rating = 300, 216 198 .irq = IRQ_TIMER0, 217 199 .shift = 32, 218 - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 200 + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 219 201 .set_next_event = bfin_gptmr0_set_next_event, 220 202 .set_mode = bfin_gptmr0_set_mode, 221 203 }; ··· 324 306 unsigned long clock_tick; 325 307 unsigned int cpu = smp_processor_id(); 326 308 struct clock_event_device *evt = &per_cpu(coretmr_events, cpu); 309 + 310 + #ifdef CONFIG_SMP 311 + evt->broadcast = smp_timer_broadcast; 312 + #endif 313 + 327 314 328 315 #ifdef CONFIG_SMP 329 316 evt->broadcast = smp_timer_broadcast;