File indexing completed on 2025-05-11 08:24:05
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 <stdlib.h>
0031 #include <grlib/ambapp_bus.h>
0032
0033 #include <grlib/gr1553b.h>
0034
0035 #include <grlib/grlib_impl.h>
0036
0037
0038
0039 #define GR1553B_WRITE_REG(adr, val) *(volatile uint32_t *)(adr) = (val)
0040 #define GR1553B_READ_REG(adr) (*(volatile uint32_t *)(adr))
0041
0042 #define FEAT_BC 0x1
0043 #define FEAT_RT 0x2
0044 #define FEAT_BM 0x4
0045
0046 #define ALLOC_BC 0x1
0047 #define ALLOC_RT 0x2
0048 #define ALLOC_BM 0x4
0049
0050 struct gr1553_device {
0051 struct drvmgr_dev *dev;
0052 int features;
0053 int alloc;
0054 };
0055
0056 struct gr1553_device_feature {
0057 struct gr1553_device_feature *next;
0058 struct gr1553_device *dev;
0059 int minor;
0060 };
0061
0062
0063 static struct gr1553_device_feature *gr1553_bm_root = NULL;
0064 static struct gr1553_device_feature *gr1553_rt_root = NULL;
0065 static struct gr1553_device_feature *gr1553_bc_root = NULL;
0066
0067
0068 static int gr1553_driver_registerd = 0;
0069
0070
0071 static void gr1553_list_add
0072 (
0073 struct gr1553_device_feature **root,
0074 struct gr1553_device_feature *feat
0075 )
0076 {
0077 int minor;
0078 struct gr1553_device_feature *curr;
0079
0080 if ( *root == NULL ) {
0081 *root = feat;
0082 feat->next = NULL;
0083 feat->minor = 0;
0084 return;
0085 }
0086
0087 minor = 0;
0088 retry_new_minor:
0089 curr = *root;
0090 while ( curr->next ) {
0091 if ( curr->minor == minor ) {
0092 minor++;
0093 goto retry_new_minor;
0094 }
0095 curr = curr->next;
0096 }
0097
0098 feat->next = NULL;
0099 feat->minor = minor;
0100 curr->next = feat;
0101 }
0102
0103 static struct gr1553_device_feature *gr1553_list_find
0104 (
0105 struct gr1553_device_feature *root,
0106 int minor
0107 )
0108 {
0109 struct gr1553_device_feature *curr = root;
0110 while ( curr ) {
0111 if ( curr->minor == minor ) {
0112 return curr;
0113 }
0114 curr = curr->next;
0115 }
0116 return NULL;
0117 }
0118
0119 struct drvmgr_dev **gr1553_bc_open(int minor)
0120 {
0121 struct gr1553_device_feature *feat;
0122
0123 feat = gr1553_list_find(gr1553_bc_root, minor);
0124 if ( feat == NULL )
0125 return NULL;
0126
0127
0128
0129
0130
0131 if ( feat->dev->alloc & (ALLOC_BC|ALLOC_RT) )
0132 return NULL;
0133
0134
0135 feat->dev->alloc |= ALLOC_BC;
0136
0137 return &feat->dev->dev;
0138 }
0139
0140 void gr1553_bc_close(struct drvmgr_dev **dev)
0141 {
0142 struct gr1553_device *d = (struct gr1553_device *)dev;
0143
0144 d->alloc &= ~ALLOC_BC;
0145 }
0146
0147 struct drvmgr_dev **gr1553_rt_open(int minor)
0148 {
0149 struct gr1553_device_feature *feat;
0150
0151 feat = gr1553_list_find(gr1553_rt_root, minor);
0152 if ( feat == NULL )
0153 return NULL;
0154
0155
0156
0157
0158
0159 if ( feat->dev->alloc & (ALLOC_BC|ALLOC_RT) )
0160 return NULL;
0161
0162
0163 feat->dev->alloc |= ALLOC_RT;
0164
0165 return &feat->dev->dev;
0166 }
0167
0168 void gr1553_rt_close(struct drvmgr_dev **dev)
0169 {
0170 struct gr1553_device *d = (struct gr1553_device *)dev;
0171
0172 d->alloc &= ~ALLOC_RT;
0173 }
0174
0175 struct drvmgr_dev **gr1553_bm_open(int minor)
0176 {
0177 struct gr1553_device_feature *feat;
0178
0179 feat = gr1553_list_find(gr1553_bm_root, minor);
0180 if ( feat == NULL )
0181 return NULL;
0182
0183
0184
0185
0186
0187 if ( feat->dev->alloc & ALLOC_BM )
0188 return NULL;
0189
0190
0191 feat->dev->alloc |= ALLOC_BM;
0192
0193 return &feat->dev->dev;
0194 }
0195
0196 void gr1553_bm_close(struct drvmgr_dev **dev)
0197 {
0198 struct gr1553_device *d = (struct gr1553_device *)dev;
0199
0200 d->alloc &= ~ALLOC_BM;
0201 }
0202
0203 static int gr1553_init2(struct drvmgr_dev *dev)
0204 {
0205 struct amba_dev_info *ambadev;
0206 struct ambapp_core *pnpinfo;
0207 struct gr1553b_regs *regs;
0208
0209
0210 ambadev = (struct amba_dev_info *)dev->businfo;
0211 if ( ambadev == NULL ) {
0212 return DRVMGR_FAIL;
0213 }
0214 pnpinfo = &ambadev->info;
0215 if ( pnpinfo->apb_slv == NULL )
0216 return DRVMGR_EIO;
0217 regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
0218
0219
0220 GR1553B_WRITE_REG(®s->imask, 0);
0221 GR1553B_WRITE_REG(®s->irq, 0xffffffff);
0222
0223 GR1553B_WRITE_REG(®s->bc_ctrl, 0x15520204);
0224
0225 GR1553B_WRITE_REG(®s->rt_cfg, 0x15530000);
0226
0227 GR1553B_WRITE_REG(®s->bm_ctrl, 0);
0228
0229
0230
0231 GR1553B_WRITE_REG(®s->hwcfg, 1<<12);
0232
0233 return DRVMGR_OK;
0234 }
0235
0236
0237
0238
0239 static int gr1553_init3(struct drvmgr_dev *dev)
0240 {
0241 struct amba_dev_info *ambadev;
0242 struct ambapp_core *pnpinfo;
0243 struct gr1553_device *priv;
0244 struct gr1553_device_feature *feat;
0245 struct gr1553b_regs *regs;
0246
0247 priv = grlib_malloc(sizeof(*priv));
0248 if ( priv == NULL )
0249 return DRVMGR_NOMEM;
0250 priv->dev = dev;
0251 priv->alloc = 0;
0252 priv->features = 0;
0253 dev->priv = NULL;
0254
0255
0256 ambadev = (struct amba_dev_info *)dev->businfo;
0257 pnpinfo = &ambadev->info;
0258 regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
0259
0260 if ( GR1553B_READ_REG(®s->bm_stat) & GR1553B_BM_STAT_BMSUP ) {
0261 priv->features |= FEAT_BM;
0262 feat = grlib_malloc(sizeof(*feat));
0263 feat->dev = priv;
0264
0265 gr1553_list_add(&gr1553_bm_root, feat);
0266 }
0267
0268 if ( GR1553B_READ_REG(®s->bc_stat) & GR1553B_BC_STAT_BCSUP ) {
0269 priv->features |= FEAT_BC;
0270 feat = grlib_malloc(sizeof(*feat));
0271 feat->dev = priv;
0272
0273 gr1553_list_add(&gr1553_bc_root, feat);
0274 }
0275
0276 if ( GR1553B_READ_REG(®s->rt_stat) & GR1553B_RT_STAT_RTSUP ) {
0277 priv->features |= FEAT_RT;
0278 feat = grlib_malloc(sizeof(*feat));
0279 feat->dev = priv;
0280
0281 gr1553_list_add(&gr1553_rt_root, feat);
0282 }
0283
0284 if ( priv->features == 0 ) {
0285
0286 free(priv);
0287 return DRVMGR_EIO;
0288 }
0289
0290 return DRVMGR_OK;
0291 }
0292
0293 struct drvmgr_drv_ops gr1553_ops =
0294 {
0295 {NULL, gr1553_init2, gr1553_init3, NULL},
0296 NULL,
0297 NULL
0298 };
0299
0300 struct amba_dev_id gr1553_ids[] =
0301 {
0302 {VENDOR_GAISLER, GAISLER_GR1553B},
0303 {0, 0}
0304 };
0305
0306 struct amba_drv_info gr1553_drv_info =
0307 {
0308 {
0309 DRVMGR_OBJ_DRV,
0310 NULL,
0311 NULL,
0312 DRIVER_AMBAPP_GAISLER_GR1553B_ID,
0313 "GR1553_DRV",
0314 DRVMGR_BUS_TYPE_AMBAPP,
0315 &gr1553_ops,
0316 NULL,
0317 0,
0318 0,
0319 },
0320 &gr1553_ids[0]
0321 };
0322
0323
0324
0325
0326
0327
0328
0329 void gr1553_register(void)
0330 {
0331 if ( gr1553_driver_registerd == 0 ) {
0332 gr1553_driver_registerd = 1;
0333 drvmgr_drv_register(&gr1553_drv_info.general);
0334 }
0335 }