File indexing completed on 2025-05-11 08:24:07
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 #include <drvmgr/drvmgr.h>
0031 #include <grlib/ambapp_bus.h>
0032 #include <stdlib.h>
0033 #include <string.h>
0034
0035 #include <grlib/grctm.h>
0036
0037 #include <grlib/grlib_impl.h>
0038
0039
0040 struct grctm_priv {
0041 struct drvmgr_dev *dev;
0042 struct grctm_regs *regs;
0043 int open;
0044
0045 grctm_isr_t user_isr;
0046 void *user_isr_arg;
0047
0048 struct grctm_stats stats;
0049 };
0050
0051 void grctm_isr(void *data);
0052
0053 struct amba_drv_info grctm_drv_info;
0054
0055 void *grctm_open(int minor)
0056 {
0057 struct grctm_priv *priv;
0058 struct drvmgr_dev *dev;
0059
0060
0061 if ( drvmgr_get_dev(&grctm_drv_info.general, minor, &dev) ) {
0062 return NULL;
0063 }
0064
0065 priv = dev->priv;
0066 if ( (priv == NULL) || priv->open )
0067 return NULL;
0068
0069
0070 priv->open = 1;
0071
0072
0073 grctm_clr_stats(priv);
0074 priv->user_isr = NULL;
0075 priv->user_isr_arg = NULL;
0076
0077 return priv;
0078 }
0079
0080 void grctm_close(void *grctm)
0081 {
0082 struct grctm_priv *priv = (struct grctm_priv *)grctm;
0083
0084 if ( priv->open == 0 )
0085 return;
0086
0087
0088 grctm_reset(priv);
0089
0090 priv->open = 0;
0091 }
0092
0093
0094 int grctm_reset(void *grctm)
0095 {
0096 struct grctm_priv *priv = grctm;
0097 struct grctm_regs *r = priv->regs;
0098
0099 r->grr = 0x55000001;
0100
0101 int i = 1000;
0102 while ((r->grr & 1) && i > 0) {
0103 i--;
0104 }
0105
0106 return i ? 0 : -1;
0107 }
0108
0109 void grctm_int_enable(void *grctm)
0110 {
0111 struct grctm_priv *priv = (struct grctm_priv *)grctm;
0112
0113
0114 drvmgr_interrupt_register(priv->dev, 0, "grctm", grctm_isr, priv);
0115 }
0116
0117 void grctm_int_disable(void *grctm)
0118 {
0119 struct grctm_priv *priv = (struct grctm_priv *)grctm;
0120
0121
0122 drvmgr_interrupt_unregister(priv->dev, 0, grctm_isr, priv);
0123 }
0124
0125 void grctm_clr_stats(void *grctm)
0126 {
0127 struct grctm_priv *priv = (struct grctm_priv *)grctm;
0128
0129 memset(&priv->stats, 0, sizeof(priv->stats));
0130 }
0131
0132 void grctm_get_stats(void *grctm, struct grctm_stats *stats)
0133 {
0134 struct grctm_priv *priv = (struct grctm_priv *)grctm;
0135
0136 memcpy(stats, &priv->stats, sizeof(priv->stats));
0137 }
0138
0139
0140 void grctm_enable_ext_sync(void *grctm)
0141 {
0142 struct grctm_priv *priv = grctm;
0143
0144 priv->regs->gcr |= 0x55<<24 | 1<<9;
0145 }
0146
0147
0148 void grctm_disable_ext_sync(void *grctm)
0149 {
0150 struct grctm_priv *priv = grctm;
0151
0152 priv->regs->gcr &= ~((0xAA<<24) | 1<<9);
0153 }
0154
0155
0156 void grctm_enable_tw_sync(void *grctm)
0157 {
0158 struct grctm_priv *priv = grctm;
0159
0160 priv->regs->gcr |= 0x55<<24 | 1<<8;
0161 }
0162
0163
0164 void grctm_disable_tw_sync(void *grctm)
0165 {
0166 struct grctm_priv *priv = grctm;
0167
0168 priv->regs->gcr &= ~((0xAA<<24) | 1<<8);
0169 }
0170
0171
0172 void grctm_disable_fs(void *grctm)
0173 {
0174 struct grctm_priv *priv = grctm;
0175
0176 priv->regs->gcr |= 0x55<<24 | 1<<7;
0177 }
0178
0179
0180 void grctm_enable_fs(void *grctm)
0181 {
0182 struct grctm_priv *priv = grctm;
0183
0184 priv->regs->gcr &= ~((0xAA<<24) | 1<<7);
0185 }
0186
0187
0188 unsigned int grctm_get_et_coarse(void *grctm)
0189 {
0190 struct grctm_priv *priv = grctm;
0191
0192 return priv->regs->etcr;
0193 }
0194
0195
0196 unsigned int grctm_get_et_fine(void *grctm)
0197 {
0198 struct grctm_priv *priv = grctm;
0199
0200 return (priv->regs->etfr & 0xffffff00) >> 8;
0201 }
0202
0203
0204 unsigned long long grctm_get_et(void *grctm)
0205 {
0206 return (((unsigned long)grctm_get_et_coarse(grctm)) << 24) | grctm_get_et_fine(grctm);
0207 }
0208
0209
0210
0211 int grctm_is_dat_latched(void *grctm, int dat)
0212 {
0213 struct grctm_priv *priv = grctm;
0214
0215 return (priv->regs->gsr >> dat) & 1;
0216 }
0217
0218
0219 void grctm_set_dat_edge(void *grctm, int dat, int edge)
0220 {
0221 struct grctm_priv *priv = grctm;
0222
0223 priv->regs->gcr &= ~((0xAA<<24) | 1 << (10+dat));
0224 priv->regs->gcr |= 0x55<<24 | (edge&1) << (10+dat);
0225 }
0226
0227
0228 unsigned int grctm_get_dat_coarse(void *grctm, int dat)
0229 {
0230 struct grctm_priv *priv = grctm;
0231
0232 switch (dat) {
0233 case 0 : return priv->regs->dcr0;
0234 case 1 : return priv->regs->dcr1;
0235 case 2 : return priv->regs->dcr2;
0236 default: return -1;
0237 }
0238 }
0239
0240
0241 unsigned int grctm_get_dat_fine(void *grctm, int dat)
0242 {
0243 struct grctm_priv *priv = grctm;
0244
0245 switch (dat) {
0246 case 0 : return (priv->regs->dfr0 & 0xffffff00) >> 8;
0247 case 1 : return (priv->regs->dfr1 & 0xffffff00) >> 8;
0248 case 2 : return (priv->regs->dfr2 & 0xffffff00) >> 8;
0249 default: return -1;
0250 }
0251 }
0252
0253
0254
0255 unsigned long long grctm_get_dat_et(void *grctm, int dat)
0256 {
0257 return (((unsigned long)grctm_get_dat_coarse(grctm, dat)) << 24) |
0258 grctm_get_dat_fine(grctm, dat);
0259 }
0260
0261
0262
0263 unsigned int grctm_get_pulse_reg(void *grctm, int pulse)
0264 {
0265 struct grctm_priv *priv = grctm;
0266
0267 return priv->regs->pdr[pulse];
0268 }
0269
0270
0271 void grctm_set_pulse_reg(void *grctm, int pulse, unsigned int val)
0272 {
0273 struct grctm_priv *priv = grctm;
0274
0275 priv->regs->pdr[pulse] = val;
0276 }
0277
0278
0279 void grctm_cfg_pulse(void *grctm, int pulse, int pp, int pw, int pl, int en)
0280 {
0281 grctm_set_pulse_reg(grctm, pulse, (pp&0xf)<<20 | (pw&0xf)<<16 | (pl&1)<<10 | (en&1)<<1);
0282 }
0283
0284
0285 void grctm_enable_pulse(void *grctm, int pulse)
0286 {
0287 struct grctm_priv *priv = grctm;
0288
0289 priv->regs->pdr[pulse] |= 0x2;
0290 }
0291
0292
0293 void grctm_disable_pulse(void *grctm, int pulse)
0294 {
0295 struct grctm_priv *priv = grctm;
0296
0297 priv->regs->pdr[pulse] &= ~0x2;
0298 }
0299
0300
0301 void grctm_clear_irqs(void *grctm, int irqs)
0302 {
0303 struct grctm_priv *priv = grctm;
0304
0305 priv->regs->picr = irqs;
0306 }
0307
0308
0309 void grctm_enable_irqs(void *grctm, int irqs)
0310 {
0311 struct grctm_priv *priv = grctm;
0312
0313 priv->regs->imr = irqs;
0314 }
0315
0316
0317 void grctm_set_fs_incr(void *grctm, int incr)
0318 {
0319 struct grctm_priv *priv = grctm;
0320
0321 priv->regs->fsir = incr;
0322 }
0323
0324
0325 void grctm_set_et_incr(void *grctm, int incr)
0326 {
0327 struct grctm_priv *priv = grctm;
0328
0329 priv->regs->etir = incr;
0330 }
0331
0332
0333 void grctm_isr(void *data)
0334 {
0335 struct grctm_priv *priv = data;
0336 struct grctm_stats *stats = &priv->stats;
0337 unsigned int pimr = priv->regs->pimr;
0338
0339 if ( pimr == 0 )
0340 return;
0341
0342 stats->nirqs++;
0343 if (pimr & PULSE0_IRQ )
0344 stats->pulse++;
0345
0346
0347 if ( priv->user_isr )
0348 priv->user_isr(pimr, priv->user_isr_arg);
0349 }
0350
0351 struct grctm_regs *grctm_get_regs(void *grctm)
0352 {
0353 struct grctm_priv *priv = (struct grctm_priv *)grctm;
0354
0355 return priv->regs;
0356 }
0357
0358 void grctm_int_register(void *grctm, grctm_isr_t func, void *data)
0359 {
0360 struct grctm_priv *priv = (struct grctm_priv *)grctm;
0361
0362 priv->user_isr = func;
0363 priv->user_isr_arg = data;
0364 }
0365
0366
0367
0368 static int grctm_init2(struct drvmgr_dev *dev)
0369 {
0370 struct amba_dev_info *ambadev;
0371 struct ambapp_core *pnpinfo;
0372 struct grctm_priv *priv;
0373 struct grctm_regs *regs;
0374
0375 priv = grlib_calloc(1, sizeof(*priv));
0376 if ( priv == NULL )
0377 return -1;
0378 priv->dev = dev;
0379 dev->priv = priv;
0380
0381
0382 ambadev = (struct amba_dev_info *)dev->businfo;
0383 if ( ambadev == NULL ) {
0384 return -1;
0385 }
0386 pnpinfo = &ambadev->info;
0387 regs = (struct grctm_regs *)pnpinfo->ahb_slv->start[0];
0388
0389 priv->regs = regs;
0390
0391 grctm_reset(priv);
0392
0393 return 0;
0394 }
0395
0396 struct drvmgr_drv_ops grctm_ops =
0397 {
0398 {NULL, grctm_init2, NULL, NULL},
0399 NULL,
0400 NULL
0401 };
0402
0403 struct amba_dev_id grctm_ids[] =
0404 {
0405 {VENDOR_GAISLER, GAISLER_GRCTM},
0406 {0, 0}
0407 };
0408
0409 struct amba_drv_info grctm_drv_info =
0410 {
0411 {
0412 DRVMGR_OBJ_DRV,
0413 NULL,
0414 NULL,
0415 DRIVER_AMBAPP_GAISLER_GRCTM_ID,
0416 "GRCTM_DRV",
0417 DRVMGR_BUS_TYPE_AMBAPP,
0418 &grctm_ops,
0419 NULL,
0420 0,
0421 0,
0422 },
0423 &grctm_ids[0]
0424 };
0425
0426
0427 void grctm_register(void)
0428 {
0429 drvmgr_drv_register(&grctm_drv_info.general);
0430 }