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 #include <stdlib.h>
0036 #include <string.h>
0037 #include <stdio.h>
0038
0039 #include <drvmgr/drvmgr.h>
0040 #include <grlib/ambapp_bus.h>
0041
0042 #include <grlib/mctrl.h>
0043
0044 #include <grlib/grlib_impl.h>
0045
0046 #define MEMSET(priv, start, c, length) memset((void *)start, c, length)
0047
0048 #define DBG(args...)
0049
0050
0051 struct mctrl_regs {
0052 unsigned int mcfg[8];
0053 };
0054
0055 struct mctrl_priv;
0056
0057 struct mctrl_ops {
0058 void (*mcfg_set)(struct mctrl_priv *priv, int index, void *regs, unsigned int regval);
0059 };
0060
0061 struct mctrl_priv {
0062 struct drvmgr_dev *dev;
0063 void *regs;
0064 unsigned int mcfg[8];
0065 unsigned int configured;
0066 struct mctrl_ops *ops;
0067 };
0068
0069 static int mctrl_init1(struct drvmgr_dev *dev);
0070 static int mctrl_remove(struct drvmgr_dev *dev);
0071
0072
0073 static void mctrl_set_std(struct mctrl_priv *priv, int index, void *regs, unsigned int regval);
0074
0075 struct mctrl_ops std_mctrl_ops =
0076 {
0077 mctrl_set_std
0078 };
0079
0080 struct drvmgr_drv_ops mctrl_ops =
0081 {
0082 .init = {mctrl_init1, NULL, NULL, NULL},
0083 .remove = mctrl_remove,
0084 .info = NULL
0085 };
0086
0087 struct amba_dev_id mctrl_ids[] =
0088 {
0089 {VENDOR_ESA, ESA_MCTRL},
0090 {VENDOR_GAISLER, GAISLER_FTMCTRL},
0091 {VENDOR_GAISLER, GAISLER_FTSRCTRL},
0092 {0, 0}
0093 };
0094
0095 struct amba_drv_info mctrl_drv_info =
0096 {
0097 {
0098 DRVMGR_OBJ_DRV,
0099 NULL,
0100 NULL,
0101 DRIVER_AMBAPP_MCTRL_ID,
0102 "MCTRL_DRV",
0103 DRVMGR_BUS_TYPE_AMBAPP,
0104 &mctrl_ops,
0105 NULL,
0106 0,
0107 0,
0108 },
0109 &mctrl_ids[0]
0110 };
0111
0112 void mctrl_register_drv (void)
0113 {
0114 DBG("Registering MCTRL driver\n");
0115 drvmgr_drv_register(&mctrl_drv_info.general);
0116 }
0117
0118 static int mctrl_init1(struct drvmgr_dev *dev)
0119 {
0120 struct mctrl_priv *priv;
0121 struct amba_dev_info *ambadev;
0122 struct ambapp_core *pnpinfo;
0123 int i;
0124 char res_name[16];
0125 union drvmgr_key_value *value;
0126 unsigned int start, length;
0127
0128 DBG("MCTRL[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0129 priv = dev->priv = grlib_calloc(1, sizeof(*priv));
0130 if ( !priv )
0131 return DRVMGR_NOMEM;
0132 priv->dev = dev;
0133
0134
0135 ambadev = (struct amba_dev_info *)priv->dev->businfo;
0136 if ( ambadev == NULL ) {
0137 return DRVMGR_FAIL;
0138 }
0139 pnpinfo = &ambadev->info;
0140 if ( pnpinfo->apb_slv == NULL ) {
0141
0142 priv->regs = (void *)0x80000000;
0143 } else {
0144 priv->regs = (void *)pnpinfo->apb_slv->start;
0145 }
0146
0147
0148 switch ( pnpinfo->vendor ) {
0149 case VENDOR_ESA:
0150 switch ( pnpinfo->device ) {
0151 case ESA_MCTRL:
0152 default:
0153 priv->ops = &std_mctrl_ops;
0154 }
0155 break;
0156
0157 case VENDOR_GAISLER:
0158 switch ( pnpinfo->device ) {
0159 case GAISLER_FTMCTRL:
0160 case GAISLER_FTSRCTRL:
0161 default:
0162 priv->ops = &std_mctrl_ops;
0163 }
0164 break;
0165
0166 default:
0167 priv->ops = &std_mctrl_ops;
0168 break;
0169 }
0170
0171
0172 priv->configured = 0;
0173 strcpy(res_name, "mcfgX");
0174 for(i=0; i<8; i++) {
0175 res_name[4] = '1' + i;
0176 value = drvmgr_dev_key_get(priv->dev, res_name, DRVMGR_KT_INT);
0177 if ( value ) {
0178 priv->mcfg[i] = value->i;
0179 priv->configured |= (1<<i);
0180 }
0181 }
0182
0183
0184
0185
0186 for ( i=0; i<8; i++) {
0187 if ( priv->configured & (1<<i) ) {
0188 DBG("Setting MCFG%d to 0x%08x\n", i+1, priv->mcfg[i]);
0189 priv->ops->mcfg_set(priv, i, priv->regs, priv->mcfg[i]);
0190 }
0191 }
0192
0193
0194 for (i=0; i<9; i++) {
0195 strcpy(res_name, "washXStart");
0196 res_name[4] = '0' + i;
0197 value = drvmgr_dev_key_get(priv->dev, res_name, DRVMGR_KT_INT);
0198 if ( value ) {
0199 start = value->i;
0200 strcpy(res_name, "washXLength");
0201 res_name[4] = '0' + i;
0202 value = drvmgr_dev_key_get(priv->dev, res_name, DRVMGR_KT_INT);
0203 if ( value ) {
0204 length = value->i;
0205
0206 if ( length > 0 ) {
0207 DBG("MCTRL: Washing 0x%08x-0x%08x\n", start, start+length-1);
0208
0209 MEMSET(priv, (void *)start, 0, length);
0210 }
0211 }
0212 }
0213 }
0214
0215 return DRVMGR_OK;
0216 }
0217
0218 static int mctrl_remove(struct drvmgr_dev *dev)
0219 {
0220
0221 DBG("Removing %s\n", dev->name);
0222 return DRVMGR_OK;
0223 }
0224
0225
0226 static void mctrl_set_std(struct mctrl_priv *priv, int index, void *regs, unsigned int regval)
0227 {
0228 struct mctrl_regs *pregs = regs;
0229
0230
0231 pregs->mcfg[index] = regval;
0232 }