File indexing completed on 2025-05-11 08:24:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 #include <drvmgr/drvmgr.h>
0054 #include <grlib/ambapp_bus.h>
0055 #include <grlib/gptimer.h>
0056 #include <grlib/gptimer-regs.h>
0057 #include <grlib/io.h>
0058 #include <grlib/tlib.h>
0059
0060 #if defined(LEON3)
0061 #include <bsp/leon3.h>
0062 #endif
0063
0064 #ifdef GPTIMER_INFO_AVAIL
0065 #include <stdio.h>
0066 #endif
0067
0068 #ifdef RTEMS_SMP
0069 #include <rtems/score/processormask.h>
0070 #include <rtems/score/smpimpl.h>
0071 #endif
0072
0073 #include <grlib/grlib_impl.h>
0074
0075 #define DBG(x...)
0076
0077
0078 struct gptimer_timer_priv {
0079 struct tlib_dev tdev;
0080 gptimer_timer *tregs;
0081 char index;
0082 char tindex;
0083 uint32_t irq_ack_mask;
0084 };
0085
0086
0087 struct gptimer_priv {
0088 struct drvmgr_dev *dev;
0089 gptimer *regs;
0090 unsigned int base_clk;
0091 unsigned int base_freq;
0092 unsigned int widthmask;
0093 char separate_interrupt;
0094 char isr_installed;
0095
0096
0097 int timer_cnt;
0098 struct gptimer_timer_priv timers[0];
0099 };
0100
0101 void gptimer_isr(void *data);
0102
0103 #if 0
0104 void gptimer_tlib_irq_register(struct tlib_drv *tdrv, tlib_isr_t func, void *data)
0105 {
0106 struct gptimer_priv *priv = (struct gptimer_priv *)tdrv;
0107
0108 if ( SHARED ...)
0109
0110
0111 drvmgr_interrupt_register();
0112 }
0113 #endif
0114
0115
0116
0117
0118 static struct tlib_drv gptimer_tlib_drv;
0119 int gptimer_device_init(struct gptimer_priv *priv);
0120
0121 int gptimer_init1(struct drvmgr_dev *dev);
0122 #ifdef GPTIMER_INFO_AVAIL
0123 static int gptimer_info(
0124 struct drvmgr_dev *dev,
0125 void (*print_line)(void *p, char *str),
0126 void *p, int, char *argv[]);
0127 #define GTIMER_INFO_FUNC gptimer_info
0128 #else
0129 #define GTIMER_INFO_FUNC NULL
0130 #endif
0131
0132 struct drvmgr_drv_ops gptimer_ops =
0133 {
0134 .init = {gptimer_init1, NULL, NULL, NULL},
0135 .remove = NULL,
0136 .info = GTIMER_INFO_FUNC,
0137 };
0138
0139 struct amba_dev_id gptimer_ids[] =
0140 {
0141 {VENDOR_GAISLER, GAISLER_GPTIMER},
0142 {VENDOR_GAISLER, GAISLER_GRTIMER},
0143 {0, 0}
0144 };
0145
0146 struct amba_drv_info gptimer_drv_info =
0147 {
0148 {
0149 DRVMGR_OBJ_DRV,
0150 NULL,
0151 NULL,
0152 DRIVER_AMBAPP_GAISLER_GPTIMER_ID,
0153 "GPTIMER_DRV",
0154 DRVMGR_BUS_TYPE_AMBAPP,
0155 &gptimer_ops,
0156 NULL,
0157 0,
0158 0,
0159 },
0160 &gptimer_ids[0]
0161 };
0162
0163 void gptimer_register_drv (void)
0164 {
0165 DBG("Registering GPTIMER driver\n");
0166 drvmgr_drv_register(&gptimer_drv_info.general);
0167 }
0168
0169 int gptimer_init1(struct drvmgr_dev *dev)
0170 {
0171 struct gptimer_priv *priv;
0172 gptimer *regs;
0173 struct amba_dev_info *ambadev;
0174 struct ambapp_core *pnpinfo;
0175 int timer_hw_cnt, timer_cnt, timer_start;
0176 int i, size;
0177 struct gptimer_timer_priv *timer;
0178 union drvmgr_key_value *value;
0179 uint32_t irq_ack_mask;
0180
0181
0182 ambadev = (struct amba_dev_info *)dev->businfo;
0183 if ( ambadev == NULL ) {
0184 return -1;
0185 }
0186 pnpinfo = &ambadev->info;
0187 regs = (gptimer *)pnpinfo->apb_slv->start;
0188
0189 DBG("GPTIMER[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0190
0191
0192 timer_hw_cnt = GPTIMER_CONFIG_TIMERS_GET(grlib_load_32(®s->config));
0193
0194
0195
0196
0197
0198
0199
0200
0201 timer_cnt = timer_hw_cnt;
0202 timer_start = 0;
0203 #if defined(RTEMS_MULTIPROCESSING) && defined(LEON3)
0204 if ((dev->minor_drv == 0) && drvmgr_on_rootbus(dev)) {
0205 timer_cnt = 1;
0206 timer_start = LEON3_Cpu_Index;
0207 }
0208 #endif
0209 value = drvmgr_dev_key_get(dev, "timerStart", DRVMGR_KT_INT);
0210 if ( value) {
0211 timer_start = value->i;
0212 timer_cnt = timer_hw_cnt - timer_start;
0213 }
0214 value = drvmgr_dev_key_get(dev, "timerCnt", DRVMGR_KT_INT);
0215 if ( value && (value->i < timer_cnt) ) {
0216 timer_cnt = value->i;
0217 }
0218
0219
0220
0221
0222 size = sizeof(struct gptimer_priv) +
0223 timer_cnt*sizeof(struct gptimer_timer_priv);
0224 priv = dev->priv = grlib_calloc(1, size);
0225 if ( !priv )
0226 return DRVMGR_NOMEM;
0227 priv->dev = dev;
0228 priv->regs = regs;
0229
0230
0231
0232
0233 drvmgr_freq_get(dev, DEV_APB_SLV, &priv->base_clk);
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 value = drvmgr_dev_key_get(priv->dev, "prescaler", DRVMGR_KT_INT);
0248 if ( value )
0249 grlib_store_32(®s->sreload, value->i);
0250
0251
0252 priv->base_freq = priv->base_clk / (grlib_load_32(®s->sreload) + 1);
0253
0254
0255
0256
0257
0258 grlib_store_32(®s->timer[timer_start].tctrl, GPTIMER_TCTRL_IP);
0259 if ((grlib_load_32(®s->timer[timer_start].tctrl) & GPTIMER_TCTRL_IP) != 0)
0260 irq_ack_mask = ~GPTIMER_TCTRL_IP;
0261 else
0262 irq_ack_mask = ~0U;
0263
0264
0265 grlib_store_32(®s->timer[timer_start].tcntval, 0xffffffff);
0266 priv->widthmask = grlib_load_32(®s->timer[timer_start].tcntval);
0267
0268 priv->timer_cnt = timer_cnt;
0269 for (i=0; i<timer_cnt; i++) {
0270 timer = &priv->timers[i];
0271 timer->index = i;
0272 timer->tindex = i + timer_start;
0273 timer->tregs = ®s->timer[(int)timer->tindex];
0274 timer->tdev.drv = &gptimer_tlib_drv;
0275 timer->irq_ack_mask = irq_ack_mask;
0276
0277
0278 tlib_dev_reg(&timer->tdev);
0279 }
0280
0281
0282
0283
0284
0285
0286 priv->separate_interrupt = (grlib_load_32(®s->config) & GPTIMER_CONFIG_SI) != 0;
0287
0288 return DRVMGR_OK;
0289 }
0290
0291 #ifdef GPTIMER_INFO_AVAIL
0292 static int gptimer_info(
0293 struct drvmgr_dev *dev,
0294 void (*print_line)(void *p, char *str),
0295 void *p, int argc, char *argv[])
0296 {
0297 struct gptimer_priv *priv = dev->priv;
0298 struct gptimer_timer_priv *timer;
0299 char buf[64];
0300 int i;
0301
0302 if (priv == NULL || argc != 0)
0303 return -DRVMGR_EINVAL;
0304
0305 sprintf(buf, "Timer Count: %d", priv->timer_cnt);
0306 print_line(p, buf);
0307 sprintf(buf, "REGS: 0x%08x", (unsigned int)priv->regs);
0308 print_line(p, buf);
0309 sprintf(buf, "BASE SCALER: %d", grlib_load_32(&priv->regs->sreload));
0310 print_line(p, buf);
0311 sprintf(buf, "BASE FREQ: %dkHz", priv->base_freq / 1000);
0312 print_line(p, buf);
0313 sprintf(buf, "SeparateIRQ: %s", priv->separate_interrupt ? "YES":"NO");
0314 print_line(p, buf);
0315
0316 for (i=0; i<priv->timer_cnt; i++) {
0317 timer = &priv->timers[i];
0318 sprintf(buf, " - TIMER HW Index %d -", timer->tindex);
0319 print_line(p, buf);
0320 sprintf(buf, " TLIB Index: %d", timer->index);
0321 print_line(p, buf);
0322 sprintf(buf, " RELOAD REG: %d", grlib_load_32(&timer->tregs->trldval));
0323 print_line(p, buf);
0324 sprintf(buf, " CTRL REG: %d", grlib_load_32(&timer->tregs->tctrl));
0325 print_line(p, buf);
0326 }
0327
0328 return DRVMGR_OK;
0329 }
0330 #endif
0331
0332 static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer_priv *t)
0333 {
0334 return (struct gptimer_priv *)
0335 ((unsigned int)t -
0336 sizeof(struct gptimer_priv) -
0337 t->index * sizeof(struct gptimer_timer_priv));
0338 }
0339
0340 static int gptimer_tlib_int_pend(struct tlib_dev *hand, int ack)
0341 {
0342 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0343 uint32_t tctrl;
0344
0345 tctrl = grlib_load_32(&timer->tregs->tctrl);
0346
0347 if ((tctrl & (GPTIMER_TCTRL_IP | GPTIMER_TCTRL_IE)) ==
0348 (GPTIMER_TCTRL_IP | GPTIMER_TCTRL_IE)) {
0349
0350 if (ack) {
0351 tctrl &= timer->irq_ack_mask;
0352 grlib_store_32(&timer->tregs->tctrl, tctrl);
0353 }
0354 return 1;
0355 } else
0356 return 0;
0357 }
0358
0359 void gptimer_isr(void *data)
0360 {
0361 struct gptimer_priv *priv = data;
0362 int i;
0363
0364
0365 for (i=0;i<priv->timer_cnt; i++) {
0366 if (gptimer_tlib_int_pend((void *)&priv->timers[i], 0)) {
0367
0368
0369
0370
0371 if (priv->timers[i].tdev.isr_func) {
0372 priv->timers[i].tdev.isr_func(
0373 priv->timers[i].tdev.isr_data);
0374 }
0375 gptimer_tlib_int_pend((void *)&priv->timers[i], 1);
0376 }
0377 }
0378 }
0379
0380 static void gptimer_tlib_reset(struct tlib_dev *hand)
0381 {
0382 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0383 uint32_t tctrl;
0384
0385 tctrl = grlib_load_32(&timer->tregs->tctrl);
0386 tctrl &= timer->irq_ack_mask;
0387 tctrl &= GPTIMER_TCTRL_IP;
0388 grlib_store_32(&timer->tregs->tctrl, tctrl);
0389 grlib_store_32(&timer->tregs->trldval, 0xffffffff);
0390 grlib_store_32(&timer->tregs->tctrl, GPTIMER_TCTRL_LD);
0391 }
0392
0393 static void gptimer_tlib_get_freq(
0394 struct tlib_dev *hand,
0395 unsigned int *basefreq,
0396 unsigned int *tickrate)
0397 {
0398 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0399 struct gptimer_priv *priv = priv_from_timer(timer);
0400
0401
0402 if ( basefreq )
0403 *basefreq = priv->base_freq;
0404 if ( tickrate )
0405 *tickrate = grlib_load_32(&timer->tregs->trldval) + 1;
0406 }
0407
0408 static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate)
0409 {
0410 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0411
0412 grlib_store_32(&timer->tregs->trldval, tickrate - 1);
0413
0414
0415 if (grlib_load_32(&timer->tregs->trldval) != (tickrate - 1))
0416 return -1;
0417 else
0418 return 0;
0419 }
0420
0421 static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *data, int flags)
0422 {
0423 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0424 struct gptimer_priv *priv = priv_from_timer(timer);
0425 uint32_t tctrl;
0426
0427 if ( priv->separate_interrupt ) {
0428 drvmgr_interrupt_register(priv->dev, timer->tindex,
0429 "gptimer", func, data);
0430 } else {
0431 if (priv->isr_installed == 0) {
0432
0433 drvmgr_interrupt_register(
0434 priv->dev,
0435 0,
0436 "gptimer_shared",
0437 gptimer_isr,
0438 priv);
0439 }
0440 priv->isr_installed++;
0441 }
0442
0443 #if RTEMS_SMP
0444 if (flags & TLIB_FLAGS_BROADCAST) {
0445 int tindex = 0;
0446
0447 if (priv->separate_interrupt) {
0448
0449 tindex = timer->tindex;
0450 }
0451 drvmgr_interrupt_set_affinity(priv->dev, tindex,
0452 _SMP_Get_online_processors());
0453 }
0454 #endif
0455
0456 tctrl = grlib_load_32(&timer->tregs->tctrl);
0457 tctrl |= GPTIMER_TCTRL_IE;
0458 grlib_store_32(&timer->tregs->tctrl, tctrl);
0459 }
0460
0461 static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void *data)
0462 {
0463 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0464 struct gptimer_priv *priv = priv_from_timer(timer);
0465 uint32_t tctrl;
0466
0467
0468 tctrl = grlib_load_32(&timer->tregs->tctrl);
0469 tctrl &= ~GPTIMER_TCTRL_IE;
0470 grlib_store_32(&timer->tregs->tctrl, tctrl);
0471
0472 if ( priv->separate_interrupt ) {
0473 drvmgr_interrupt_unregister(priv->dev, timer->tindex,
0474 func, data);
0475 } else {
0476 timer->tdev.isr_func = NULL;
0477 priv->isr_installed--;
0478 if (priv->isr_installed == 0) {
0479 drvmgr_interrupt_unregister(priv->dev, 0,
0480 gptimer_isr, priv);
0481 }
0482 }
0483 }
0484
0485 static void gptimer_tlib_start(struct tlib_dev *hand, int once)
0486 {
0487 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0488 uint32_t tctrl;
0489
0490
0491 tctrl = grlib_load_32(&timer->tregs->tctrl);
0492 tctrl &= timer->irq_ack_mask;
0493 tctrl &= ~GPTIMER_TCTRL_RS;
0494 tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN;
0495 if ( once == 0 )
0496 tctrl |= GPTIMER_TCTRL_RS;
0497 grlib_store_32(&timer->tregs->tctrl, tctrl);
0498 }
0499
0500 static void gptimer_tlib_stop(struct tlib_dev *hand)
0501 {
0502 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0503 uint32_t tctrl;
0504
0505
0506 tctrl = grlib_load_32(&timer->tregs->tctrl);
0507 tctrl &= ~(GPTIMER_TCTRL_EN|GPTIMER_TCTRL_IP);
0508 grlib_store_32(&timer->tregs->tctrl, tctrl);
0509 }
0510
0511 static void gptimer_tlib_restart(struct tlib_dev *hand)
0512 {
0513 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0514 uint32_t tctrl;
0515
0516 tctrl = grlib_load_32(&timer->tregs->tctrl);
0517 tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN;
0518 grlib_store_32(&timer->tregs->tctrl, tctrl);
0519 }
0520
0521 static void gptimer_tlib_get_counter(
0522 struct tlib_dev *hand,
0523 unsigned int *counter)
0524 {
0525 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0526
0527 *counter = grlib_load_32(&timer->tregs->tcntval);
0528 }
0529
0530 static void gptimer_tlib_get_widthmask(
0531 struct tlib_dev *hand,
0532 unsigned int *widthmask)
0533 {
0534 struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand;
0535 struct gptimer_priv *priv = priv_from_timer(timer);
0536
0537 *widthmask = priv->widthmask;
0538 }
0539
0540 static struct tlib_drv gptimer_tlib_drv =
0541 {
0542 .reset = gptimer_tlib_reset,
0543 .get_freq = gptimer_tlib_get_freq,
0544 .set_freq = gptimer_tlib_set_freq,
0545 .irq_reg = gptimer_tlib_irq_reg,
0546 .irq_unreg = gptimer_tlib_irq_unreg,
0547 .start = gptimer_tlib_start,
0548 .stop = gptimer_tlib_stop,
0549 .restart = gptimer_tlib_restart,
0550 .get_counter = gptimer_tlib_get_counter,
0551 .custom = NULL,
0552 .int_pend = gptimer_tlib_int_pend,
0553 .get_widthmask = gptimer_tlib_get_widthmask,
0554 };