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 #include <stdlib.h>
0032 #include <string.h>
0033 #include <drvmgr/drvmgr.h>
0034 #include <grlib/ambapp_bus.h>
0035 #include <grlib/ambapp.h>
0036 #include <rtems.h>
0037 #include <rtems/bspIo.h>
0038 #include <grlib/grlib.h>
0039 #include <bsp.h>
0040 #include <grlib/l2c.h>
0041 #include <grlib/grlib_impl.h>
0042
0043 #if RTEMS_INTERRUPT_LOCK_NEEDS_OBJECT
0044 extern rtems_interrupt_lock leon3_l2c_lock;
0045 #endif
0046
0047
0048 #define STATIC static
0049
0050
0051 #define INLINE inline
0052
0053 #define UNUSED __attribute__((unused))
0054
0055
0056
0057 #ifdef DEBUG
0058 #define DBG(x...) printk(x)
0059 #else
0060 #define DBG(x...)
0061 #endif
0062
0063
0064
0065
0066 #define L2C_CTRL_EN (0x1 << L2C_CTRL_EN_BIT)
0067 #define L2C_CTRL_EDAC (0x1 << L2C_CTRL_EDAC_BIT)
0068 #define L2C_CTRL_REPL (0x3 << L2C_CTRL_REPL_BIT)
0069 #define L2C_CTRL_IWAY (0xf << L2C_CTRL_IWAY_BIT)
0070 #define L2C_CTRL_LOCK (0xf << L2C_CTRL_LOCK_BIT)
0071 #define L2C_CTRL_HPRHB (0x1 << L2C_CTRL_HPRHB_BIT)
0072 #define L2C_CTRL_HPB (0x1 << L2C_CTRL_HPB_BIT)
0073 #define L2C_CTRL_UC (0x1 << L2C_CTRL_UC_BIT)
0074 #define L2C_CTRL_HC (0x1 << L2C_CTRL_HC_BIT)
0075 #define L2C_CTRL_WP (0x1 << L2C_CTRL_WP_BIT)
0076 #define L2C_CTRL_HP (0x1 << L2C_CTRL_HP_BIT)
0077
0078 #define L2C_CTRL_EN_BIT 31
0079 #define L2C_CTRL_EDAC_BIT 30
0080 #define L2C_CTRL_REPL_BIT 28
0081 #define L2C_CTRL_IWAY_BIT 12
0082 #define L2C_CTRL_LOCK_BIT 8
0083 #define L2C_CTRL_HPRHB_BIT 5
0084 #define L2C_CTRL_HPB_BIT 4
0085 #define L2C_CTRL_UC_BIT 3
0086 #define L2C_CTRL_HC_BIT 2
0087 #define L2C_CTRL_WP_BIT 1
0088 #define L2C_CTRL_HP_BIT 0
0089
0090
0091
0092
0093 #define L2C_STAT_LS (0x1 << L2C_STAT_LS_BIT)
0094 #define L2C_STAT_AT (0x1 << L2C_STAT_AT_BIT)
0095 #define L2C_STAT_MP (0x1 << L2C_STAT_MP_BIT)
0096 #define L2C_STAT_MTRR (0x3f << L2C_STAT_MTRR_BIT)
0097 #define L2C_STAT_BBUSW (0x7 << L2C_STAT_BBUSW_BIT)
0098 #define L2C_STAT_WAYSIZE (0x7ff << L2C_STAT_WAYSIZE_BIT)
0099 #define L2C_STAT_WAY (0x3 << L2C_STAT_WAY_BIT)
0100
0101 #define L2C_STAT_LS_BIT 24
0102 #define L2C_STAT_AT_BIT 23
0103 #define L2C_STAT_MP_BIT 22
0104 #define L2C_STAT_MTRR_BIT 16
0105 #define L2C_STAT_BBUSW_BIT 13
0106 #define L2C_STAT_WAYSIZE_BIT 2
0107 #define L2C_STAT_WAY_BIT 0
0108
0109
0110
0111
0112 #define L2C_MTRR_ADDR (0x3fff << L2C_MTRR_ADDR_BIT)
0113 #define L2C_MTRR_ACC (0x3 << L2C_MTRR_ACC_BIT)
0114 #define L2C_MTRR_MASK (0x3fff << L2C_MTRR_MASK_BIT)
0115 #define L2C_MTRR_WP (0x1 << L2C_MTRR_WP_BIT)
0116 #define L2C_MTRR_AC (0x1 << L2C_MTRR_AC_BIT)
0117
0118 #define L2C_MTRR_ADDR_BIT 18
0119 #define L2C_MTRR_ACC_BIT 16
0120 #define L2C_MTRR_MASK_BIT 2
0121 #define L2C_MTRR_WP_BIT 1
0122 #define L2C_MTRR_AC_BIT 0
0123
0124 #define L2C_MTRR_UNCACHED 0
0125 #define L2C_MTRR_WRITETHROUGH (0x1 << L2C_MTRR_ACC_BIT)
0126 #define L2C_MTRR_WRITEPROT_ENABLE L2C_MTRR_WP
0127 #define L2C_MTRR_WRITEPROT_DISABLE 0
0128 #define L2C_MTRR_ACCESSCONTROL_ENABLE L2C_MTRR_AC
0129 #define L2C_MTRR_ACCESSCONTROL_DISABLE 0
0130
0131
0132
0133
0134 #define L2C_FLUSH_ADDR (0x7ffffff << L2C_FLUSH_ADDR_BIT)
0135 #define L2C_FLUSH_DI (0x1 << L2C_FLUSH_DI_BIT)
0136 #define L2C_FLUSH_FMODE (0x7 << L2C_FLUSH_FMODE_BIT)
0137
0138 #define L2C_FLUSH_ADDR_BIT 5
0139 #define L2C_FLUSH_DI_BIT 3
0140 #define L2C_FLUSH_FMODE_BIT 0
0141
0142 #define L2C_FLUSH_FMODE_INV_ONE (0x1 << L2C_FLUSH_FMODE_BIT)
0143 #define L2C_FLUSH_FMODE_WB_ONE (0x2 << L2C_FLUSH_FMODE_BIT)
0144 #define L2C_FLUSH_FMODE_INV_WB_ONE (0x3 << L2C_FLUSH_FMODE_BIT)
0145 #define L2C_FLUSH_FMODE_INV_ALL (0x5 << L2C_FLUSH_FMODE_BIT)
0146 #define L2C_FLUSH_FMODE_WB_ALL (0x6 << L2C_FLUSH_FMODE_BIT)
0147 #define L2C_FLUSH_FMODE_INV_WB_ALL (0x7 << L2C_FLUSH_FMODE_BIT)
0148
0149
0150
0151
0152 #define L2C_FLUSHSI_INDEX (0xffff << L2C_FLUSHSI_INDEX_BIT)
0153 #define L2C_FLUSHSI_TAG (0x3fffff << L2C_FLUSHSI_TAG_BIT)
0154 #define L2C_FLUSHSI_FL (0x1 << L2C_FLUSHSI_FL_BIT)
0155 #define L2C_FLUSHSI_VB (0x1 << L2C_FLUSHSI_VB_BIT)
0156 #define L2C_FLUSHSI_DB (0x1 << L2C_FLUSHSI_DB_BIT)
0157 #define L2C_FLUSHSI_WAY (0x3 << L2C_FLUSHSI_WAY_BIT)
0158 #define L2C_FLUSHSI_DI (0x1 << L2C_FLUSHSI_DI_BIT)
0159 #define L2C_FLUSHSI_WF (0x1 << L2C_FLUSHSI_WF_BIT)
0160 #define L2C_FLUSHSI_FMODE (0x3 << L2C_FLUSHSI_FMODE_BIT)
0161
0162 #define L2C_FLUSHSI_INDEX_BIT 16
0163 #define L2C_FLUSHSI_TAG_BIT 10
0164 #define L2C_FLUSHSI_FL_BIT 9
0165 #define L2C_FLUSHSI_VB_BIT 8
0166 #define L2C_FLUSHSI_DB_BIT 7
0167 #define L2C_FLUSHSI_WAY_BIT 4
0168 #define L2C_FLUSHSI_DI_BIT 3
0169 #define L2C_FLUSHSI_WF_BIT 2
0170 #define L2C_FLUSHSI_FMODE_BIT 0
0171
0172 #define L2C_FLUSHSI_FMODE_SET_INV_ONE (0x1 << L2C_FLUSHSI_FMODE_BIT)
0173 #define L2C_FLUSHSI_FMODE_SET_WB_ONE (0x2 << L2C_FLUSHSI_FMODE_BIT)
0174 #define L2C_FLUSHSI_FMODE_SET_INV_WB_ONE (0x3 << L2C_FLUSHSI_FMODE_BIT)
0175 #define L2C_FLUSHSI_FMODE_WAY_UPDATE (0x1 << L2C_FLUSHSI_FMODE_BIT)
0176 #define L2C_FLUSHSI_FMODE_WAY_WB (0x2 << L2C_FLUSHSI_FMODE_BIT)
0177 #define L2C_FLUSHSI_FMODE_WAY_UPDATE_WB_ALL (0x3 << L2C_FLUSHSI_FMODE_BIT)
0178
0179
0180
0181
0182 #define L2C_ERROR_AHBM (0xf << L2C_ERROR_AHBM_BIT)
0183 #define L2C_ERROR_SCRUB (0x1 << L2C_ERROR_SCRUB_BIT)
0184 #define L2C_ERROR_TYPE (0x7 << L2C_ERROR_TYPE_BIT)
0185 #define L2C_ERROR_TAG (0x1 << L2C_ERROR_TAG_BIT)
0186 #define L2C_ERROR_COR (0x1 << L2C_ERROR_COR_BIT)
0187 #define L2C_ERROR_MULTI (0x1 << L2C_ERROR_MULTI_BIT)
0188 #define L2C_ERROR_VALID (0x1 << L2C_ERROR_VALID_BIT)
0189 #define L2C_ERROR_DISERESP (0x1 << L2C_ERROR_DISERESP_BIT)
0190 #define L2C_ERROR_CEC (0x7 << L2C_ERROR_CEC_BIT)
0191 #define L2C_ERROR_IRQP (0xf << L2C_ERROR_IRQP_BIT)
0192 #define L2C_ERROR_IRQM (0xf << L2C_ERROR_IRQM_BIT)
0193 #define L2C_ERROR_IRQM_BCKEND (0x1 << L2C_ERROR_IRQM_BCKEND_BIT)
0194 #define L2C_ERROR_IRQM_WPROT (0x1 << L2C_ERROR_IRQM_WPROT_BIT)
0195 #define L2C_ERROR_IRQM_UNCORR (0x1 << L2C_ERROR_IRQM_UNCORR_BIT)
0196 #define L2C_ERROR_IRQM_CORR (0x1 << L2C_ERROR_IRQM_CORR_BIT)
0197 #define L2C_ERROR_SCB (0x3 << L2C_ERROR_SCB_BIT)
0198 #define L2C_ERROR_STCB (0x3 << L2C_ERROR_STCB_BIT)
0199 #define L2C_ERROR_XCB (0x1 << L2C_ERROR_XCB_BIT)
0200 #define L2C_ERROR_RCB (0x1 << L2C_ERROR_RCB_BIT)
0201 #define L2C_ERROR_COMP (0x1 << L2C_ERROR_COMP_BIT)
0202 #define L2C_ERROR_RST (0x1 << L2C_ERROR_RST_BIT)
0203
0204 #define L2C_ERROR_AHBM_BIT 28
0205 #define L2C_ERROR_SCRUB_BIT 27
0206 #define L2C_ERROR_TYPE_BIT 24
0207 #define L2C_ERROR_TAG_BIT 23
0208 #define L2C_ERROR_COR_BIT 22
0209 #define L2C_ERROR_MULTI_BIT 21
0210 #define L2C_ERROR_VALID_BIT 20
0211 #define L2C_ERROR_DISERESP_BIT 19
0212 #define L2C_ERROR_CEC_BIT 16
0213 #define L2C_ERROR_IRQP_BIT 12
0214 #define L2C_ERROR_IRQM_BCKEND_BIT 11
0215 #define L2C_ERROR_IRQM_WPROT_BIT 10
0216 #define L2C_ERROR_IRQM_UNCORR_BIT 9
0217 #define L2C_ERROR_IRQM_CORR_BIT 8
0218 #define L2C_ERROR_IRQM_BIT 8
0219 #define L2C_ERROR_SCB_BIT 6
0220 #define L2C_ERROR_STCB_BIT 4
0221 #define L2C_ERROR_XCB_BIT 3
0222 #define L2C_ERROR_RCB_BIT 2
0223 #define L2C_ERROR_COMP_BIT 1
0224 #define L2C_ERROR_RST_BIT 0
0225
0226
0227
0228
0229 #define L2C_DCB_CB (0xfffffff << L2C_DCB_CB_BIT)
0230
0231 #define L2C_DCB_CB_BIT 0
0232
0233
0234
0235
0236 #define L2C_SCRUB_INDEX (0xffff << L2C_SCRUB_INDEX_BIT)
0237 #define L2C_SCRUB_WAY (0x3 << L2C_SCRUB_WAY_BIT)
0238 #define L2C_SCRUB_PEN (0x1 << L2C_SCRUB_PEN_BIT)
0239 #define L2C_SCRUB_EN (0x1 << L2C_SCRUB_EN_BIT)
0240
0241 #define L2C_SCRUB_INDEX_BIT 16
0242 #define L2C_SCRUB_WAY_BIT 2
0243 #define L2C_SCRUB_PEN_BIT 1
0244 #define L2C_SCRUB_EN_BIT 0
0245
0246
0247
0248
0249 #define L2C_SCRUB_DEL (0xffff << L2C_SCRUB_DEL_BIT)
0250
0251 #define L2C_SCRUB_DEL_BIT 0
0252
0253
0254
0255
0256 #define L2C_ERRINJ_ADDR (0x3fffffff << L2C_ERRINJ_ADDR_BIT)
0257 #define L2C_ERRINJ_EN (0x1 << L2C_ERRINJ_EN_BIT)
0258
0259 #define L2C_ERRINJ_ADDR_BIT 2
0260 #define L2C_ERRINJ_EN_BIT 0
0261
0262
0263
0264
0265 #define L2C_ACCCTRL_DSC (0x1 << L2C_ACCCTRL_DSC_BIT)
0266 #define L2C_ACCCTRL_SH (0x1 << L2C_ACCCTRL_SH_BIT)
0267 #define L2C_ACCCTRL_SPLITQ (0x1 << L2C_ACCCTRL_SPLITQ_BIT)
0268 #define L2C_ACCCTRL_NHM (0x1 << L2C_ACCCTRL_NHM_BIT)
0269 #define L2C_ACCCTRL_BERR (0x1 << L2C_ACCCTRL_BERR_BIT)
0270 #define L2C_ACCCTRL_OAPM (0x1 << L2C_ACCCTRL_OAPM_BIT)
0271 #define L2C_ACCCTRL_FLINE (0x1 << L2C_ACCCTRL_FLINE_BIT)
0272 #define L2C_ACCCTRL_DBPF (0x1 << L2C_ACCCTRL_DBPF_BIT)
0273 #define L2C_ACCCTRL_128WF (0x1 << L2C_ACCCTRL_128WF_BIT)
0274 #define L2C_ACCCTRL_DBPWS (0x1 << L2C_ACCCTRL_DBPWS_BIT)
0275 #define L2C_ACCCTRL_SPLIT (0x1 << L2C_ACCCTRL_SPLIT_BIT)
0276
0277 #define L2C_ACCCTRL_DSC_BIT 14
0278 #define L2C_ACCCTRL_SH_BIT 13
0279 #define L2C_ACCCTRL_SPLITQ_BIT 10
0280 #define L2C_ACCCTRL_NHM_BIT 9
0281 #define L2C_ACCCTRL_BERR_BIT 8
0282 #define L2C_ACCCTRL_OAPM_BIT 7
0283 #define L2C_ACCCTRL_FLINE_BIT 6
0284 #define L2C_ACCCTRL_DBPF_BIT 5
0285 #define L2C_ACCCTRL_128WF_BIT 4
0286 #define L2C_ACCCTRL_DBPWS_BIT 2
0287 #define L2C_ACCCTRL_SPLIT_BIT 1
0288
0289 #ifdef TEST_L2CACHE
0290
0291
0292
0293 #define L2C_TAG_TAG (0xfffffc << L2C_TAG_TAG_BIT)
0294 #define L2C_TAG_VALID (0x3 << L2C_TAG_VALID_BIT)
0295 #define L2C_TAG_DIRTY (0x3 << L2C_TAG_DIRTY_BIT)
0296 #define L2C_TAG_LRU (0x3 << L2C_TAG_LRU_BIT)
0297
0298 #define L2C_TAG_TAG_BIT 10
0299 #define L2C_TAG_VALID_BIT 8
0300 #define L2C_TAG_DIRTY_BIT 6
0301 #define L2C_TAG_LRU_BIT 0
0302
0303 #endif
0304
0305 #define DEVNAME_LEN 9
0306
0307
0308
0309 struct l2cache_priv {
0310 struct drvmgr_dev *dev;
0311 char devname[DEVNAME_LEN];
0312
0313
0314 struct l2c_regs *regs;
0315
0316
0317 int ways;
0318 int waysize;
0319 int linesize;
0320 int index;
0321 int mtrr;
0322 int ft_support;
0323 int split_support;
0324 int atomic_flush;
0325
0326
0327 l2cache_isr_t isr;
0328 void *isr_arg;
0329 };
0330
0331
0332
0333
0334
0335 STATIC INLINE int l2cache_reg_ctrl_enable(void);
0336 STATIC INLINE int l2cache_reg_ctrl_disable(void);
0337 STATIC INLINE int l2cache_reg_ctrl_locked_set(int locked);
0338 STATIC INLINE int l2cache_reg_ctrl_edac_set(int edac);
0339 STATIC INLINE int l2cache_reg_ctrl_repl(int policy);
0340 STATIC INLINE int l2cache_reg_ctrl_iway(int way);
0341 STATIC INLINE int l2cache_reg_ctrl_writep(int policy);
0342 STATIC INLINE unsigned int l2cache_reg_ctrl(void);
0343 STATIC INLINE unsigned int l2cache_reg_status(void);
0344 STATIC INLINE int l2cache_reg_mtrr_set(int index, unsigned int addr,
0345 unsigned int mask, int options);
0346 UNUSED STATIC INLINE unsigned int l2cache_reg_mtrr_get(int index);
0347 STATIC INLINE int l2cache_reg_flushmem(unsigned int addr, int options);
0348 STATIC INLINE int l2cache_reg_flushline(int way, int index, int options);
0349 STATIC INLINE int l2cache_reg_flushway(unsigned int tag, int way, int options);
0350 STATIC INLINE unsigned int l2cache_reg_error(void);
0351 STATIC INLINE int l2cache_reg_error_reset(void);
0352 STATIC INLINE int l2cache_reg_error_irqmask(int mask);
0353 STATIC INLINE unsigned int l2cache_reg_error_addr(void);
0354 STATIC INLINE unsigned int l2cache_reg_scrub(void);
0355 STATIC INLINE int l2cache_reg_scrub_enable(int delay);
0356 STATIC INLINE int l2cache_reg_scrub_disable(void);
0357 STATIC INLINE unsigned int l2cache_reg_scrub_delay(void);
0358 STATIC INLINE int l2cache_reg_scrub_line(int way, int index);
0359 STATIC INLINE unsigned int l2cache_reg_accctrl(void);
0360 STATIC INLINE int l2cache_reg_accctrl_split_disable(void);
0361 STATIC INLINE int l2cache_reg_accctrl_split_enable(void);
0362 #ifdef TEST_L2CACHE
0363 STATIC INLINE int l2cache_reg_error_dcb(unsigned int cb);
0364 STATIC INLINE int l2cache_reg_error_inject(unsigned int addr);
0365 STATIC INLINE unsigned int l2cache_reg_diagtag(int way, int index);
0366 STATIC INLINE unsigned int l2cache_reg_diagdata(int way, int index, int word);
0367 STATIC unsigned int log2int(unsigned int v);
0368 #endif
0369
0370
0371 STATIC int l2cache_ctrl_status(void);
0372 STATIC void l2cache_flushwait(void);
0373
0374
0375 STATIC int l2cache_init(struct l2cache_priv *priv);
0376
0377
0378 int l2cache_init1(struct drvmgr_dev *dev);
0379
0380
0381 void l2cache_isr(void *arg);
0382
0383
0384
0385
0386 static struct l2cache_priv *l2cachepriv = NULL;
0387 #ifdef DEBUG
0388 static char * repl_names[4] = {"LRU","Random","Master-Idx-1","Master-IDx-2"};
0389 #endif
0390
0391 static void REG_WRITE(volatile unsigned int *addr, unsigned int val) {
0392 SPIN_IRQFLAGS(irqflags);
0393
0394 SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
0395 *addr = val;
0396 SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
0397 }
0398
0399 static unsigned int REG_READ(volatile unsigned int *addr) {
0400 SPIN_IRQFLAGS(irqflags);
0401 unsigned int val;
0402
0403 SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
0404 val = *addr;
0405 SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
0406 return val;
0407 }
0408
0409 #if defined(__sparc__)
0410 static inline uint32_t atomic_swap32(uint32_t *addr, uint32_t val) {
0411 __asm__ volatile (
0412 "swapa [%1] 1, %0\n" :
0413 "+r" (val) :
0414 "r" (addr) :
0415 "memory"
0416 );
0417 return val;
0418 }
0419
0420 static void REG_WRITE_ATOMIC(volatile unsigned int *addr, unsigned int val) {
0421 SPIN_IRQFLAGS(irqflags);
0422
0423 SPIN_LOCK_IRQ(&leon3_l2c_lock, irqflags);
0424 atomic_swap32((uint32_t *) addr, val);
0425 SPIN_UNLOCK_IRQ(&leon3_l2c_lock, irqflags);
0426 }
0427
0428 #else
0429 #define REG_WRITE_ATOMIC(addr, val) REG_WRITE(addr, val)
0430 #endif
0431
0432
0433
0434 struct drvmgr_drv_ops l2cache_ops =
0435 {
0436 .init = {l2cache_init1, NULL, NULL, NULL},
0437 .remove = NULL,
0438 .info = NULL
0439 };
0440
0441 struct amba_dev_id l2cache_ids[] =
0442 {
0443 {VENDOR_GAISLER, GAISLER_L2CACHE},
0444 {0, 0}
0445 };
0446
0447 struct amba_drv_info l2cache_info =
0448 {
0449 {
0450 DRVMGR_OBJ_DRV,
0451 NULL,
0452 NULL,
0453 DRIVER_AMBAPP_GAISLER_L2CACHE_ID,
0454 "L2CACHE_DRV",
0455 DRVMGR_BUS_TYPE_AMBAPP,
0456 &l2cache_ops,
0457 NULL,
0458 0,
0459 sizeof(struct l2cache_priv),
0460 },
0461 &l2cache_ids[0]
0462 };
0463
0464 void l2cache_register_drv(void)
0465 {
0466 DBG("Registering L2CACHE driver\n");
0467 drvmgr_drv_register(&l2cache_info.general);
0468 }
0469
0470
0471
0472
0473
0474
0475 STATIC int l2cache_init(struct l2cache_priv *priv)
0476 {
0477 struct ambapp_ahb_info *ahb;
0478 struct amba_dev_info *ainfo = priv->dev->businfo;
0479
0480
0481 ahb = ainfo->info.ahb_slv;
0482
0483
0484 priv->regs = (struct l2c_regs *)ahb->start[1];
0485
0486
0487 unsigned int status = l2cache_reg_status();
0488 priv->ways = (status & L2C_STAT_WAY) + 1;
0489 priv->waysize =
0490 ((status & L2C_STAT_WAYSIZE) >> L2C_STAT_WAYSIZE_BIT) * 1024;
0491 priv->linesize = ((status & L2C_STAT_LS)? 64 : 32);
0492 priv->index = ((priv->waysize)/(priv->linesize));
0493 priv->mtrr = (status & L2C_STAT_MTRR) >> L2C_STAT_MTRR_BIT;
0494 priv->ft_support = (status & L2C_STAT_MP) >> L2C_STAT_MP_BIT;
0495
0496 priv->atomic_flush = 1;
0497
0498
0499 int split_old = 0;
0500 int split_new = 0;
0501 split_old = (l2cache_reg_accctrl() & L2C_ACCCTRL_SPLIT);
0502 if (split_old){
0503 l2cache_reg_accctrl_split_disable();
0504 }else{
0505 l2cache_reg_accctrl_split_enable();
0506 }
0507 split_new = (l2cache_reg_accctrl() & L2C_ACCCTRL_SPLIT);
0508 if (split_old){
0509 l2cache_reg_accctrl_split_enable();
0510 }else{
0511 l2cache_reg_accctrl_split_disable();
0512 }
0513 priv->split_support =
0514 ((split_new ^ split_old) >> L2C_ACCCTRL_SPLIT_BIT) & 1;
0515
0516 DBG("L2CACHE driver initialized\n");
0517
0518 return 0;
0519 }
0520
0521
0522
0523
0524 int l2cache_init1(struct drvmgr_dev *dev)
0525 {
0526 int status;
0527 struct l2cache_priv *priv;
0528
0529 DBG("L2CACHE[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0530
0531 if (l2cachepriv) {
0532 DBG("Driver only supports one L2CACHE core\n");
0533 return DRVMGR_FAIL;
0534 }
0535
0536 priv = dev->priv;
0537 if (!priv)
0538 return DRVMGR_NOMEM;
0539
0540 priv->dev = dev;
0541 strncpy(&priv->devname[0], "l2cache0", DEVNAME_LEN);
0542 l2cachepriv = priv;
0543
0544
0545 status = l2cache_init(priv);
0546 if (status) {
0547 printk("Failed to initialize l2cache driver %d\n", status);
0548 return -1;
0549 }
0550
0551 return DRVMGR_OK;
0552 }
0553
0554 STATIC INLINE int l2cache_reg_ctrl_enable(void)
0555 {
0556 struct l2cache_priv *priv = l2cachepriv;
0557
0558 unsigned int ctrl = REG_READ(&priv->regs->control);
0559 REG_WRITE(&priv->regs->control, (ctrl | L2C_CTRL_EN));
0560 return 0;
0561 }
0562
0563 STATIC INLINE int l2cache_reg_ctrl_disable(void)
0564 {
0565 struct l2cache_priv *priv = l2cachepriv;
0566
0567 unsigned int ctrl = REG_READ(&priv->regs->control);
0568 REG_WRITE(&priv->regs->control, (ctrl & ~(L2C_CTRL_EN)));
0569 return 0;
0570 }
0571
0572 STATIC INLINE int l2cache_reg_ctrl_repl(int policy)
0573 {
0574 struct l2cache_priv *priv = l2cachepriv;
0575
0576 unsigned int ctrl = REG_READ(&priv->regs->control);
0577 REG_WRITE(&priv->regs->control,
0578 ((ctrl & ~(L2C_CTRL_REPL)) |
0579 ((policy << L2C_CTRL_REPL_BIT) & L2C_CTRL_REPL))
0580 );
0581 return 0;
0582 }
0583
0584 STATIC INLINE int l2cache_reg_ctrl_iway(int way)
0585 {
0586 struct l2cache_priv *priv = l2cachepriv;
0587
0588 unsigned int ctrl = REG_READ(&priv->regs->control);
0589 REG_WRITE(&priv->regs->control,
0590 ((ctrl & ~(L2C_CTRL_IWAY)) |
0591 ((way << L2C_CTRL_IWAY_BIT) & L2C_CTRL_IWAY))
0592 );
0593 return 0;
0594 }
0595
0596 STATIC INLINE int l2cache_reg_ctrl_writep(int policy)
0597 {
0598 struct l2cache_priv *priv = l2cachepriv;
0599
0600 unsigned int ctrl = REG_READ(&priv->regs->control);
0601 REG_WRITE(&priv->regs->control,
0602 ((ctrl & ~(L2C_CTRL_WP)) | ((policy << L2C_CTRL_WP_BIT) & L2C_CTRL_WP))
0603 );
0604 return 0;
0605 }
0606
0607 STATIC INLINE int l2cache_reg_ctrl_locked_set(int locked)
0608 {
0609 struct l2cache_priv *priv = l2cachepriv;
0610
0611 unsigned int ctrl = REG_READ(&priv->regs->control);
0612 ctrl = (ctrl & ~(L2C_CTRL_LOCK));
0613 REG_WRITE(&priv->regs->control,
0614 ctrl |
0615 ((locked << L2C_CTRL_LOCK_BIT) & L2C_CTRL_LOCK));
0616 return 0;
0617 }
0618
0619 STATIC INLINE int l2cache_reg_ctrl_edac_set(int edac)
0620 {
0621 struct l2cache_priv *priv = l2cachepriv;
0622
0623 unsigned int ctrl = REG_READ(&priv->regs->control);
0624 REG_WRITE(&priv->regs->control,
0625 (ctrl & ~(L2C_CTRL_EDAC)) |
0626 (edac? L2C_CTRL_EDAC:0));
0627 return 0;
0628 }
0629
0630 STATIC INLINE unsigned int l2cache_reg_ctrl(void)
0631 {
0632 struct l2cache_priv *priv = l2cachepriv;
0633
0634 return REG_READ(&priv->regs->control);
0635 }
0636
0637 STATIC INLINE unsigned int l2cache_reg_status(void)
0638 {
0639 struct l2cache_priv *priv = l2cachepriv;
0640
0641 return REG_READ(&priv->regs->status);
0642 }
0643
0644 STATIC INLINE int l2cache_reg_mtrr_set(int index, unsigned int addr,
0645 unsigned int mask, int options)
0646 {
0647 struct l2cache_priv *priv = l2cachepriv;
0648
0649
0650 addr = addr & L2C_MTRR_ADDR;
0651 mask = (mask >> 16) & L2C_MTRR_MASK;
0652 options = ((options & ~(L2C_MTRR_ADDR)) & ~(L2C_MTRR_MASK));
0653 unsigned int mtrr = 0 | addr | mask | options;
0654 REG_WRITE(&priv->regs->mtrr[index], mtrr);
0655 return 0;
0656 }
0657
0658 UNUSED STATIC INLINE unsigned int l2cache_reg_mtrr_get(int index)
0659 {
0660 struct l2cache_priv *priv = l2cachepriv;
0661
0662 return REG_READ(&priv->regs->mtrr[index]);
0663 }
0664
0665 STATIC INLINE int l2cache_reg_flushmem(unsigned int addr, int options)
0666 {
0667 struct l2cache_priv *priv = l2cachepriv;
0668 unsigned int val;
0669
0670 options = (options & ~(L2C_FLUSH_ADDR));
0671 val = (addr & L2C_FLUSH_ADDR) | options;
0672
0673 if (priv->atomic_flush)
0674 REG_WRITE_ATOMIC(&priv->regs->flush_mem_addr, val);
0675 else
0676 REG_WRITE(&priv->regs->flush_mem_addr, val);
0677
0678 return 0;
0679 }
0680
0681 STATIC INLINE int l2cache_reg_flushline(int way, int index, int options)
0682 {
0683 struct l2cache_priv *priv = l2cachepriv;
0684 unsigned int val;
0685
0686 options = 0 | (options & (L2C_FLUSHSI_FMODE));
0687 val = ((index << L2C_FLUSHSI_INDEX_BIT) & L2C_FLUSHSI_INDEX) |
0688 ((way << L2C_FLUSHSI_WAY_BIT) & L2C_FLUSHSI_WAY) |
0689 options;
0690
0691 if (priv->atomic_flush)
0692 REG_WRITE_ATOMIC(&priv->regs->flush_set_index, val);
0693 else
0694 REG_WRITE(&priv->regs->flush_set_index, val);
0695
0696 return 0;
0697 }
0698
0699 STATIC INLINE int l2cache_reg_flushway(unsigned int tag, int way, int options)
0700 {
0701 struct l2cache_priv *priv = l2cachepriv;
0702 unsigned int val;
0703
0704 options = (options & ~(L2C_FLUSHSI_TAG | L2C_FLUSHSI_WAY))
0705 | L2C_FLUSHSI_WF;
0706 val = (tag & L2C_FLUSHSI_TAG) |
0707 ( (way << L2C_FLUSHSI_WAY_BIT) & L2C_FLUSHSI_WAY) |
0708 options;
0709 if (priv->atomic_flush)
0710 REG_WRITE_ATOMIC(&priv->regs->flush_set_index, val);
0711 else
0712 REG_WRITE(&priv->regs->flush_set_index, val);
0713
0714 return 0;
0715 }
0716
0717 STATIC INLINE unsigned int l2cache_reg_error(void)
0718 {
0719 struct l2cache_priv *priv = l2cachepriv;
0720
0721 return REG_READ(&priv->regs->error_status_control);
0722 }
0723
0724 STATIC INLINE int l2cache_reg_error_reset(void)
0725 {
0726 struct l2cache_priv *priv = l2cachepriv;
0727
0728 unsigned int ctrl = REG_READ(&priv->regs->error_status_control);
0729 REG_WRITE(&priv->regs->error_status_control, ctrl | L2C_ERROR_RST);
0730 return 0;
0731 }
0732
0733 STATIC INLINE int l2cache_reg_error_irqmask(int mask)
0734 {
0735 struct l2cache_priv *priv = l2cachepriv;
0736
0737 unsigned int ctrl = REG_READ(&priv->regs->error_status_control);
0738 REG_WRITE(&priv->regs->error_status_control,
0739 (ctrl & ~(L2C_ERROR_IRQM)) | (mask & L2C_ERROR_IRQM));
0740 return 0;
0741 }
0742
0743 STATIC INLINE unsigned int l2cache_reg_error_addr(void)
0744 {
0745 struct l2cache_priv *priv = l2cachepriv;
0746
0747 return REG_READ(&priv->regs->error_addr);
0748 }
0749
0750 STATIC INLINE unsigned int l2cache_reg_scrub(void)
0751 {
0752 struct l2cache_priv *priv = l2cachepriv;
0753
0754 return REG_READ(&priv->regs->scrub_control_status);
0755 }
0756
0757 STATIC INLINE int l2cache_reg_scrub_enable(int delay)
0758 {
0759 struct l2cache_priv *priv = l2cachepriv;
0760
0761 unsigned int accc = REG_READ(&priv->regs->access_control);
0762 REG_WRITE(&priv->regs->access_control,
0763 accc | L2C_ACCCTRL_DSC | L2C_ACCCTRL_SH);
0764
0765 unsigned int ctrl = REG_READ(&priv->regs->scrub_control_status);
0766 REG_WRITE(&priv->regs->scrub_delay,
0767 (delay << L2C_SCRUB_DEL_BIT) & L2C_SCRUB_DEL);
0768 REG_WRITE(&priv->regs->scrub_control_status, ctrl | L2C_SCRUB_EN);
0769 return 0;
0770 }
0771
0772 STATIC INLINE int l2cache_reg_scrub_disable(void)
0773 {
0774 struct l2cache_priv *priv = l2cachepriv;
0775
0776 unsigned int ctrl = REG_READ(&priv->regs->scrub_control_status);
0777 REG_WRITE(&priv->regs->scrub_control_status, ctrl & ~(L2C_SCRUB_EN));
0778 return 0;
0779 }
0780
0781 STATIC INLINE int l2cache_reg_scrub_line(int way, int index)
0782 {
0783 struct l2cache_priv *priv = l2cachepriv;
0784
0785 REG_WRITE(&priv->regs->scrub_control_status,
0786 ((index << L2C_SCRUB_INDEX_BIT) & L2C_SCRUB_INDEX) |
0787 ((way << L2C_SCRUB_WAY_BIT) & L2C_SCRUB_WAY) |
0788 L2C_SCRUB_PEN);
0789 return 0;
0790 }
0791
0792 STATIC INLINE unsigned int l2cache_reg_scrub_delay(void)
0793 {
0794 struct l2cache_priv *priv = l2cachepriv;
0795
0796 return REG_READ(&priv->regs->scrub_delay);
0797 }
0798
0799 STATIC INLINE unsigned int l2cache_reg_accctrl(void){
0800 struct l2cache_priv *priv = l2cachepriv;
0801
0802 return REG_READ(&priv->regs->access_control);
0803 }
0804
0805 STATIC INLINE int l2cache_reg_accctrl_split_disable(void)
0806 {
0807 struct l2cache_priv *priv = l2cachepriv;
0808
0809
0810 unsigned int ctrl = REG_READ(&priv->regs->access_control);
0811 REG_WRITE(&priv->regs->access_control, (ctrl & ~(L2C_ACCCTRL_SPLIT)));
0812 return 0;
0813 }
0814
0815 STATIC INLINE int l2cache_reg_accctrl_split_enable(void)
0816 {
0817 struct l2cache_priv *priv = l2cachepriv;
0818
0819
0820 unsigned int ctrl = REG_READ(&priv->regs->access_control);
0821 REG_WRITE(&priv->regs->access_control, (ctrl | (L2C_ACCCTRL_SPLIT)));
0822 return 0;
0823 }
0824
0825 STATIC INLINE int l2cache_ctrl_status(void)
0826 {
0827 return ((l2cache_reg_ctrl() >> L2C_CTRL_EN_BIT) & 0x1);
0828 }
0829
0830 STATIC void l2cache_flushwait(void)
0831 {
0832
0833
0834
0835
0836 (void) l2cache_reg_status();
0837 return;
0838 }
0839
0840 #ifdef TEST_L2CACHE
0841 STATIC INLINE int l2cache_reg_error_dcb(unsigned int cb)
0842 {
0843 struct l2cache_priv *priv = l2cachepriv;
0844
0845 REG_WRITE(&priv->regs->data_check_bit, (cb & L2C_DCB_CB));
0846 return 0;
0847 }
0848
0849 STATIC INLINE int l2cache_reg_error_inject(unsigned int addr)
0850 {
0851 struct l2cache_priv *priv = l2cachepriv;
0852
0853 REG_WRITE(&priv->regs->error_injection,
0854 (addr & L2C_ERRINJ_ADDR) | L2C_ERRINJ_EN);
0855 return 0;
0856 }
0857
0858 STATIC INLINE unsigned int l2cache_reg_diagtag(int way, int index)
0859 {
0860 struct l2cache_priv *priv = l2cachepriv;
0861
0862 int offset = (index*8 + way);
0863 return REG_READ(&priv->regs->diag_iface_tag[offset]);
0864 }
0865
0866 STATIC INLINE unsigned int l2cache_reg_diagdata(int way, int index, int word)
0867 {
0868 struct l2cache_priv *priv = l2cachepriv;
0869
0870 int offset = (index*(priv->linesize/4) + way*0x20000 + word);
0871 return REG_READ(&priv->regs->diag_iface_data[offset]);
0872 }
0873
0874 STATIC unsigned int log2int(unsigned int v)
0875 {
0876 unsigned r = 0;
0877 while (v >>= 1) {
0878 r++;
0879 }
0880 return r;
0881 }
0882
0883
0884 int l2cache_get_index( uint32_t addr)
0885 {
0886 struct l2cache_priv * priv = l2cachepriv;
0887
0888 if (priv == NULL){
0889 DBG("L2CACHE not initialized.\n");
0890 return L2CACHE_ERR_NOINIT;
0891 }
0892
0893 return (addr % priv->waysize)/(priv->linesize);
0894 }
0895
0896
0897 uint32_t l2cache_get_tag( uint32_t addr)
0898 {
0899 struct l2cache_priv * priv = l2cachepriv;
0900
0901 if (priv == NULL){
0902 DBG("L2CACHE not initialized.\n");
0903 return L2CACHE_ERR_NOINIT;
0904 }
0905
0906 uint32_t tmp;
0907 int i = log2int(priv->waysize);
0908 tmp = (addr >> i);
0909 tmp = (tmp << i);
0910 return tmp;
0911 }
0912
0913 int l2cache_lookup(uint32_t addr, int * way)
0914 {
0915 struct l2cache_priv * priv = l2cachepriv;
0916 int i;
0917 struct l2cache_tag gottag;
0918 int ret;
0919
0920 if (priv == NULL){
0921 DBG("L2CACHE not initialized.\n");
0922 return L2CACHE_ERR_NOINIT;
0923 }
0924
0925 uint32_t exptag = l2cache_get_tag(addr);
0926 int index = l2cache_get_index(addr);
0927
0928
0929 for(i=0; i< priv->ways; i++){
0930 ret = l2cache_diag_tag(i, index, &gottag);
0931 if (ret != L2CACHE_ERR_OK){
0932 return ret;
0933 }
0934
0935
0936
0937 if (gottag.valid){
0938
0939 if (gottag.tag == exptag){
0940
0941 if (way){
0942 *way = i;
0943 }
0944 DBG("L2CACHE lookup: index=%d, tag=0x%08x HIT way=%d.\n",
0945 index, (unsigned int) exptag, i);
0946 return L2CACHE_HIT;
0947 }
0948 }
0949 }
0950 DBG("L2CACHE lookup: index=%d, tag=0x%08x MISS.\n",
0951 index, (unsigned int) exptag);
0952
0953 return L2CACHE_MISS;
0954 }
0955
0956
0957 #define l2cache_tag_valid(val) ((val & L2C_TAG_VALID) >> L2C_TAG_VALID_BIT)
0958 #define l2cache_tag_dirty(val) ((val & L2C_TAG_DIRTY) >> L2C_TAG_DIRTY_BIT)
0959 #define l2cache_tag_lru(val) ((val & L2C_TAG_LRU) >> L2C_TAG_LRU_BIT)
0960 int l2cache_diag_tag( int way, int index, struct l2cache_tag * tag)
0961 {
0962 struct l2cache_priv * priv = l2cachepriv;
0963
0964 if (priv == NULL){
0965 DBG("L2CACHE not initialized.\n");
0966 return L2CACHE_ERR_NOINIT;
0967 }
0968
0969 if (way >= priv->ways){
0970 DBG("L2CACHE has only %d ways.\n", priv->ways);
0971 return L2CACHE_ERR_EINVAL;
0972 }
0973
0974 if (index >= priv->index){
0975 DBG("L2CACHE has only %d lines.\n", priv->index);
0976 return L2CACHE_ERR_EINVAL;
0977 }
0978
0979 if (tag){
0980 unsigned int val = l2cache_reg_diagtag(way,index);
0981
0982 tag->tag = l2cache_get_tag(val);
0983 tag->valid = l2cache_tag_valid(val);
0984 tag->dirty = l2cache_tag_dirty(val);
0985 tag->lru = l2cache_tag_lru(val);
0986 }else{
0987 return L2CACHE_ERR_EINVAL;
0988 }
0989 return L2CACHE_ERR_OK;
0990 }
0991
0992 int l2cache_diag_line( int way, int index, struct l2cache_dataline * dataline)
0993 {
0994 struct l2cache_priv * priv = l2cachepriv;
0995 int i;
0996
0997 if (priv == NULL){
0998 DBG("L2CACHE not initialized.\n");
0999 return L2CACHE_ERR_NOINIT;
1000 }
1001
1002 if (way >= priv->ways){
1003 DBG("L2CACHE has only %d ways.\n", priv->ways);
1004 return L2CACHE_ERR_EINVAL;
1005 }
1006
1007 if (index >= priv->index){
1008 DBG("L2CACHE has only %d lines.\n", priv->index);
1009 return L2CACHE_ERR_EINVAL;
1010 }
1011
1012 if (dataline){
1013 dataline->words = (priv->linesize/4);
1014 for (i=0; i< (priv->linesize/4); i++){
1015 dataline->data[i] = l2cache_reg_diagdata(way,index,i);
1016 }
1017 }else{
1018 return L2CACHE_ERR_EINVAL;
1019 }
1020 return L2CACHE_ERR_OK;
1021 }
1022
1023
1024 int l2cache_error_inject_address( uint32_t addr, uint32_t mask)
1025 {
1026 struct l2cache_priv * priv = l2cachepriv;
1027 int word;
1028
1029 if (priv == NULL){
1030 DBG("L2CACHE not initialized.\n");
1031 return L2CACHE_ERR_NOINIT;
1032 }
1033
1034 if (!priv->ft_support){
1035 DBG("L2CACHE does not have EDAC support.\n");
1036 return L2CACHE_ERR_ERROR;
1037 }
1038
1039 if (addr & 0x3){
1040 DBG("Address not aligned to 32-bit.\n");
1041 return L2CACHE_ERR_EINVAL;
1042 }
1043
1044
1045 word = (addr % priv->linesize)/4;
1046
1047
1048 mask = (mask << (7*(priv->ways - word - 1)));
1049
1050
1051 l2cache_reg_error_dcb(mask);
1052
1053
1054 l2cache_reg_error_inject(addr);
1055
1056 DBG("L2CACHE error injected in 0x%08x (0x%08x).\n",
1057 (unsigned int) addr, (unsigned int) mask);
1058
1059 return L2CACHE_ERR_OK;
1060 }
1061
1062 #endif
1063
1064
1065
1066 void l2cache_isr(void *arg)
1067 {
1068 struct l2cache_priv *priv = arg;
1069 unsigned int sts = l2cache_reg_error();
1070 unsigned int addr = l2cache_reg_error_addr();
1071
1072
1073
1074
1075 if ( ((sts & L2C_ERROR_IRQP) >> L2C_ERROR_IRQP_BIT) &
1076 ((sts & L2C_ERROR_IRQM) >> L2C_ERROR_IRQM_BIT)){
1077
1078 l2cache_reg_error_reset();
1079
1080
1081 (priv->isr)(priv->isr_arg, (addr & ~(0x1f)), sts);
1082 }
1083 }
1084
1085
1086
1087 int l2cache_enable(int flush)
1088 {
1089 int ret;
1090
1091
1092 ret = l2cache_flush(flush);
1093 if (ret < 0){
1094 return ret;
1095 }
1096
1097 l2cache_reg_ctrl_enable();
1098
1099 DBG("L2CACHE enabled\n");
1100 return L2CACHE_ERR_OK;
1101 }
1102
1103
1104
1105 int l2cache_disable(int flush)
1106 {
1107 struct l2cache_priv * priv = l2cachepriv;
1108
1109 if (priv == NULL){
1110 DBG("L2CACHE not initialized.\n");
1111 return L2CACHE_ERR_NOINIT;
1112 }
1113
1114 if ((flush < 0) ||
1115 (flush >
1116 (L2CACHE_OPTIONS_FLUSH_INVALIDATE | L2CACHE_OPTIONS_FLUSH_WAIT))
1117 ){
1118 DBG("L2CACHE wrong flush option.\n");
1119 return L2CACHE_ERR_EINVAL;
1120 }
1121
1122
1123 switch(flush & 0x3){
1124 case L2CACHE_OPTIONS_FLUSH_NONE:
1125 l2cache_reg_ctrl_disable();
1126 break;
1127 case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1128 l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_INV_WB_ALL | L2C_FLUSH_DI);
1129 break;
1130 case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1131 l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_WB_ALL | L2C_FLUSH_DI);
1132 break;
1133 case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1134 default:
1135 l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_INV_ALL | L2C_FLUSH_DI);
1136 break;
1137 }
1138
1139 if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1140 l2cache_flushwait();
1141 }
1142
1143 DBG("L2CACHE disabled\n");
1144 return L2CACHE_ERR_OK;
1145 }
1146
1147
1148
1149 int l2cache_status(void)
1150 {
1151 struct l2cache_priv * priv = l2cachepriv;
1152 int status;
1153
1154 if (priv == NULL){
1155 DBG("L2CACHE not initialized.\n");
1156 return L2CACHE_ERR_NOINIT;
1157 }
1158
1159 unsigned int ctrl = l2cache_reg_ctrl();
1160 int locked = (ctrl & L2C_CTRL_LOCK) >> L2C_CTRL_LOCK_BIT;
1161 int enabled = ((ctrl & L2C_CTRL_EN) >> L2C_CTRL_EN_BIT) & 0x1;
1162 int edac = (ctrl & L2C_CTRL_EDAC) >> L2C_CTRL_EDAC_BIT;
1163 int repl = (ctrl & L2C_CTRL_REPL) >> L2C_CTRL_REPL_BIT;
1164 int writep = (ctrl & L2C_CTRL_WP) >> L2C_CTRL_WP_BIT;
1165
1166 unsigned int acc = l2cache_reg_accctrl();
1167 int split = (acc & L2C_ACCCTRL_SPLIT) >> L2C_ACCCTRL_SPLIT_BIT;
1168
1169 unsigned int err = l2cache_reg_error();
1170 int interrupts = (err & L2C_ERROR_IRQM) >> L2C_ERROR_IRQM_BIT;
1171
1172 unsigned int scr = l2cache_reg_scrub();
1173 int scrub = (scr & L2C_SCRUB_EN) >> L2C_SCRUB_EN_BIT;
1174
1175 unsigned int dly = l2cache_reg_scrub_delay();
1176 int delay = (dly & L2C_SCRUB_DEL) >> L2C_SCRUB_DEL_BIT;
1177
1178 status = 0|
1179 (enabled? L2CACHE_STATUS_ENABLED: 0) |
1180 (split? L2CACHE_STATUS_SPLIT_ENABLED: 0) |
1181 (edac? L2CACHE_STATUS_EDAC_ENABLED: 0) |
1182 ((repl & 0x3) << L2CACHE_STATUS_REPL_BIT) |
1183 (writep? L2CACHE_STATUS_WRITETHROUGH: 0) |
1184 ((locked & 0xf) << L2CACHE_STATUS_LOCK_BIT) |
1185 ((interrupts & 0xf) << L2CACHE_STATUS_INT_BIT) |
1186 (scrub? L2CACHE_STATUS_SCRUB_ENABLED: 0) |
1187 ((delay & 0xffff) << L2CACHE_STATUS_SCRUB_DELAY_BIT);
1188
1189 return status;
1190 }
1191
1192
1193
1194 int l2cache_flush(int flush)
1195 {
1196 struct l2cache_priv * priv = l2cachepriv;
1197
1198 if (priv == NULL){
1199 DBG("L2CACHE not initialized.\n");
1200 return L2CACHE_ERR_NOINIT;
1201 }
1202
1203 if ((flush < 0) ||
1204 (flush >
1205 (L2CACHE_OPTIONS_FLUSH_INVALIDATE | L2CACHE_OPTIONS_FLUSH_WAIT))
1206 ){
1207 DBG("L2CACHE wrong flush option.\n");
1208 return L2CACHE_ERR_EINVAL;
1209 }
1210
1211 switch(flush & 0x3){
1212 case L2CACHE_OPTIONS_FLUSH_NONE:
1213 break;
1214 case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1215 l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_INV_WB_ALL);
1216 break;
1217 case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1218 l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_WB_ALL);
1219 break;
1220 case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1221 default:
1222 l2cache_reg_flushmem(0, L2C_FLUSH_FMODE_INV_ALL);
1223 break;
1224 }
1225
1226 if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1227 l2cache_flushwait();
1228 }
1229
1230 DBG("L2CACHE flushed\n");
1231 return L2CACHE_ERR_OK;
1232 }
1233
1234
1235
1236 int l2cache_flush_address(uint32_t addr, int size, int flush)
1237 {
1238 struct l2cache_priv * priv = l2cachepriv;
1239 uint32_t endaddr;
1240 int options;
1241
1242 if (priv == NULL){
1243 DBG("L2CACHE not initialized.\n");
1244 return L2CACHE_ERR_NOINIT;
1245 }
1246
1247 if ((flush < 0) ||
1248 (flush >
1249 (L2CACHE_OPTIONS_FLUSH_INVALIDATE | L2CACHE_OPTIONS_FLUSH_WAIT))
1250 ){
1251 DBG("L2CACHE wrong flush option.\n");
1252 return L2CACHE_ERR_EINVAL;
1253 }
1254
1255 if (size <= 0){
1256 DBG("L2CACHE wrong size.\n");
1257 return L2CACHE_ERR_EINVAL;
1258 }
1259
1260 switch(flush & 0x3){
1261 case L2CACHE_OPTIONS_FLUSH_NONE:
1262 break;
1263 case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1264 options=L2C_FLUSH_FMODE_INV_WB_ONE;
1265 break;
1266 case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1267 options=L2C_FLUSH_FMODE_WB_ONE;
1268 break;
1269 case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1270 default:
1271 options=L2C_FLUSH_FMODE_INV_ONE;
1272 break;
1273 }
1274
1275 if ( (flush & 0x3) == L2CACHE_OPTIONS_FLUSH_NONE){
1276 return L2CACHE_ERR_OK;
1277 }
1278
1279
1280 endaddr = (addr + size);
1281
1282
1283 addr = addr - (addr % priv->linesize);
1284 while( addr < endaddr){
1285
1286 l2cache_reg_flushmem(addr, options);
1287
1288 addr += priv->linesize;
1289 }
1290
1291 if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1292 l2cache_flushwait();
1293 }
1294
1295 DBG("L2CACHE address range flushed\n");
1296 return L2CACHE_ERR_OK;
1297 }
1298
1299
1300
1301 int l2cache_flush_line(int way, int index, int flush)
1302 {
1303 struct l2cache_priv * priv = l2cachepriv;
1304
1305 if (priv == NULL){
1306 DBG("L2CACHE not initialized.\n");
1307 return L2CACHE_ERR_NOINIT;
1308 }
1309
1310 if ((flush < 0) ||
1311 (flush >
1312 (L2CACHE_OPTIONS_FLUSH_INVALIDATE | L2CACHE_OPTIONS_FLUSH_WAIT))
1313 ){
1314 DBG("L2CACHE wrong flush option.\n");
1315 return L2CACHE_ERR_EINVAL;
1316 }
1317
1318 if ((index < 0) || (index >= priv->index)){
1319 DBG("L2CACHE only has %d lines.\n", priv->index);
1320 return L2CACHE_ERR_EINVAL;
1321 }
1322
1323 if ((way < 0 ) || (way >= priv->ways)){
1324 DBG("L2CACHE only has %d ways.\n", priv->ways);
1325 return L2CACHE_ERR_EINVAL;
1326 }
1327
1328 switch(flush & 0x3){
1329 case L2CACHE_OPTIONS_FLUSH_NONE:
1330 break;
1331 case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1332 l2cache_reg_flushline(way, index,
1333 L2C_FLUSHSI_FMODE_SET_INV_WB_ONE);
1334 break;
1335 case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1336 l2cache_reg_flushline(way, index, L2C_FLUSHSI_FMODE_SET_WB_ONE);
1337 break;
1338 case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1339 default:
1340 l2cache_reg_flushline(way, index, L2C_FLUSHSI_FMODE_SET_INV_ONE);
1341 break;
1342 }
1343
1344 if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1345 l2cache_flushwait();
1346 }
1347
1348 DBG("L2CACHE line [%d,%d] flushed\n", way, index);
1349 return L2CACHE_ERR_OK;
1350 }
1351
1352
1353
1354 int l2cache_flush_way(int way, int flush)
1355 {
1356 struct l2cache_priv * priv = l2cachepriv;
1357
1358 if (priv == NULL){
1359 DBG("L2CACHE not initialized.\n");
1360 return L2CACHE_ERR_NOINIT;
1361 }
1362
1363 if ((flush < 0) ||
1364 (flush >
1365 (L2CACHE_OPTIONS_FLUSH_INVALIDATE | L2CACHE_OPTIONS_FLUSH_WAIT))
1366 ){
1367 DBG("L2CACHE wrong flush option.\n");
1368 return L2CACHE_ERR_EINVAL;
1369 }
1370
1371 if ((way < 0 ) || (way >= priv->ways)){
1372 DBG("L2CACHE only has %d ways.\n", priv->ways);
1373 return L2CACHE_ERR_EINVAL;
1374 }
1375
1376 switch(flush & 0x3){
1377 case L2CACHE_OPTIONS_FLUSH_NONE:
1378 break;
1379 case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1380 l2cache_reg_flushway(0, way, L2C_FLUSHSI_FMODE_WAY_UPDATE);
1381 break;
1382 case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1383 l2cache_reg_flushway(0, way, L2C_FLUSHSI_FMODE_WAY_WB);
1384 break;
1385 case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1386 default:
1387 l2cache_reg_flushway(0, way, L2C_FLUSHSI_FMODE_WAY_UPDATE_WB_ALL);
1388 break;
1389 }
1390
1391 if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1392 l2cache_flushwait();
1393 }
1394
1395 DBG("L2CACHE way [%d] flushed\n",way);
1396 return L2CACHE_ERR_OK;
1397 }
1398
1399
1400
1401 int l2cache_fill_way(int way, uint32_t tag, int options, int flush)
1402 {
1403 struct l2cache_priv * priv = l2cachepriv;
1404 int flags;
1405
1406 if (priv == NULL){
1407 DBG("L2CACHE not initialized.\n");
1408 return L2CACHE_ERR_NOINIT;
1409 }
1410
1411 if ((way < 0 ) || (way >= priv->ways)){
1412 DBG("L2CACHE only has %d ways.\n", priv->ways);
1413 return L2CACHE_ERR_EINVAL;
1414 }
1415
1416
1417 if (tag & 0x000003ff){
1418 DBG("Only using bits 31:10 of Addr/Mask\n");
1419 return L2CACHE_ERR_EINVAL;
1420 }
1421
1422
1423 flags = ((options & L2CACHE_OPTIONS_FETCH)? L2C_FLUSHSI_FL:0) |
1424 ((options & L2CACHE_OPTIONS_VALID)? L2C_FLUSHSI_VB:0) |
1425 ((options & L2CACHE_OPTIONS_DIRTY)? L2C_FLUSHSI_DB:0);
1426
1427
1428
1429
1430 switch(flush & 0x3){
1431 case L2CACHE_OPTIONS_FLUSH_NONE:
1432 break;
1433 case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1434 l2cache_reg_flushway(tag, way,
1435 flags | L2C_FLUSHSI_FMODE_WAY_UPDATE);
1436 break;
1437 case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1438 l2cache_reg_flushway(tag, way, flags | L2C_FLUSHSI_FMODE_WAY_WB);
1439 break;
1440 case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1441 default:
1442 l2cache_reg_flushway(tag, way,
1443 flags | L2C_FLUSHSI_FMODE_WAY_UPDATE_WB_ALL);
1444 break;
1445 }
1446
1447 if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1448 l2cache_flushwait();
1449 }
1450
1451 DBG("Way[%d] filled with Tag 0x%08x\n", way, (unsigned int) tag);
1452
1453 return L2CACHE_ERR_OK;
1454 }
1455
1456
1457
1458 int l2cache_lock_way(uint32_t tag, int options, int flush, int enable)
1459 {
1460 struct l2cache_priv * priv = l2cachepriv;
1461 int enabled;
1462 int way;
1463 int locked;
1464 int flags;
1465 int ret;
1466
1467 if (priv == NULL){
1468 DBG("L2CACHE not initialized.\n");
1469 return L2CACHE_ERR_NOINIT;
1470 }
1471
1472 locked = L2CACHE_LOCKED_WAYS(l2cache_status());
1473 if (locked >= priv->ways){
1474 DBG("L2CACHE only has %d ways.\n", priv->ways);
1475 return L2CACHE_ERR_TOOMANY;
1476 }
1477
1478
1479 if (tag & 0x000003ff){
1480 DBG("Only using bits 31:10 of Addr/Mask\n");
1481 return L2CACHE_ERR_EINVAL;
1482 }
1483
1484
1485 enabled = l2cache_ctrl_status();
1486
1487
1488 ret = l2cache_disable(flush);
1489 if (ret < 0){
1490 return ret;
1491 }
1492
1493
1494 locked++;
1495 way = priv->ways - locked;
1496 l2cache_reg_ctrl_locked_set(locked);
1497
1498
1499 flags = ((options & L2CACHE_OPTIONS_FETCH)? L2C_FLUSHSI_FL:0) |
1500 ((options & L2CACHE_OPTIONS_VALID)? L2C_FLUSHSI_VB:0) |
1501 ((options & L2CACHE_OPTIONS_DIRTY)? L2C_FLUSHSI_DB:0);
1502
1503
1504
1505
1506 switch(flush & 0x3){
1507 case L2CACHE_OPTIONS_FLUSH_NONE:
1508 break;
1509 case L2CACHE_OPTIONS_FLUSH_INVALIDATE:
1510 l2cache_reg_flushway(tag, way,
1511 flags | L2C_FLUSHSI_FMODE_WAY_UPDATE);
1512 break;
1513 case L2CACHE_OPTIONS_FLUSH_WRITEBACK:
1514 l2cache_reg_flushway(tag, way, flags | L2C_FLUSHSI_FMODE_WAY_WB);
1515 break;
1516 case L2CACHE_OPTIONS_FLUSH_INV_WBACK:
1517 default:
1518 l2cache_reg_flushway(tag, way,
1519 flags | L2C_FLUSHSI_FMODE_WAY_UPDATE_WB_ALL);
1520 break;
1521 }
1522
1523
1524 switch(enable){
1525 case L2CACHE_OPTIONS_ENABLE:
1526 l2cache_reg_ctrl_enable();
1527 break;
1528 case L2CACHE_OPTIONS_DISABLE:
1529 break;
1530 case L2CACHE_OPTIONS_NONE:
1531 default:
1532 if (enabled) {
1533 l2cache_reg_ctrl_enable();
1534 }
1535 break;
1536 }
1537
1538 if (flush & L2CACHE_OPTIONS_FLUSH_WAIT){
1539 l2cache_flushwait();
1540 }
1541
1542 DBG("Way[%d] locked with Tag 0x%08x\n", way, (unsigned int) tag);
1543
1544 return L2CACHE_ERR_OK;
1545 }
1546
1547
1548
1549 int l2cache_unlock()
1550 {
1551 struct l2cache_priv * priv = l2cachepriv;
1552
1553 if (priv == NULL){
1554 DBG("L2CACHE not initialized.\n");
1555 return L2CACHE_ERR_NOINIT;
1556 }
1557
1558
1559 l2cache_reg_ctrl_locked_set(0);
1560
1561 DBG("L2CACHE ways unlocked\n");
1562
1563 return L2CACHE_ERR_OK;
1564 }
1565
1566
1567
1568
1569
1570 int l2cache_mtrr_enable(int index, uint32_t addr, uint32_t mask, int options,
1571 int flush)
1572 {
1573 struct l2cache_priv * priv = l2cachepriv;
1574 int enabled;
1575 int flags;
1576 int ret;
1577
1578 if (priv == NULL){
1579 DBG("L2CACHE not initialized.\n");
1580 return L2CACHE_ERR_NOINIT;
1581 }
1582
1583 if (index < 0){
1584 DBG("Wrong index\n");
1585 return L2CACHE_ERR_EINVAL;
1586 }
1587
1588 if (index >= priv->mtrr){
1589 DBG("Not enough MTRR registers\n");
1590 return L2CACHE_ERR_TOOMANY;
1591 }
1592
1593
1594 if ((addr & 0x0003ffff) || (mask & 0x0003ffff)){
1595 DBG("Only using bits 31:18 of Addr/Mask\n");
1596 return L2CACHE_ERR_EINVAL;
1597 }
1598
1599
1600 enabled = l2cache_ctrl_status();
1601
1602
1603 ret = l2cache_disable(flush);
1604 if (ret < 0){
1605 return ret;
1606 }
1607
1608
1609 flags = 0 |
1610 (options & L2CACHE_OPTIONS_MTRR_ACCESS_WRITETHROUGH?
1611 L2C_MTRR_WRITETHROUGH :
1612 L2C_MTRR_UNCACHED) |
1613 (options & L2CACHE_OPTIONS_MTRR_WRITEPROT_ENABLE?
1614 L2C_MTRR_WRITEPROT_ENABLE :
1615 L2C_MTRR_WRITEPROT_DISABLE) |
1616 L2C_MTRR_ACCESSCONTROL_ENABLE;
1617
1618
1619 l2cache_reg_mtrr_set(index, addr, mask, flags);
1620
1621
1622 if (enabled){
1623 l2cache_reg_ctrl_enable();
1624 }
1625
1626 DBG("MTRR[%d] succesfully configured for 0x%08x (mask 0x%08x), "
1627 "access=%s, wprot=%s\n",
1628 index, (unsigned int) addr, (unsigned int) mask,
1629 (options & L2CACHE_OPTIONS_MTRR_ACCESS_WRITETHROUGH?
1630 "WRITETHROUGH":"UNCACHED"),
1631 (options & L2CACHE_OPTIONS_MTRR_WRITEPROT_ENABLE? "ENABLE":"DISABLE")
1632 );
1633
1634 return L2CACHE_ERR_OK;
1635 }
1636
1637
1638
1639
1640
1641 int l2cache_mtrr_disable(int index)
1642 {
1643 struct l2cache_priv * priv = l2cachepriv;
1644
1645 if (priv == NULL){
1646 DBG("L2CACHE not initialized.\n");
1647 return L2CACHE_ERR_NOINIT;
1648 }
1649
1650 if (index < 0){
1651 DBG("Wrong index\n");
1652 return L2CACHE_ERR_EINVAL;
1653 }
1654
1655 if (index >= priv->mtrr){
1656 DBG("Not enough MTRR registers\n");
1657 return L2CACHE_ERR_TOOMANY;
1658 }
1659
1660
1661 l2cache_reg_mtrr_set(index, 0, 0, L2C_MTRR_ACCESSCONTROL_DISABLE);
1662
1663 DBG("MTRR[%d] disabled\n", index);
1664
1665 return L2CACHE_ERR_OK;
1666 }
1667
1668
1669
1670
1671 int l2cache_print(void)
1672 {
1673 struct l2cache_priv * priv = l2cachepriv;
1674
1675 if (priv == NULL){
1676 DBG("L2CACHE not initialized.\n");
1677 return L2CACHE_ERR_NOINIT;
1678 }
1679
1680 #ifdef DEBUG
1681 int status = l2cache_status();
1682 if (status < 0){
1683 return status;
1684 }
1685 printf("L2cache: Ways:%d. Waysize:%d, Linesize:%d, Lines:%d\n"
1686 " MTRR:%d, FT:%s, Locked:%d, Split:%s\n"
1687 " REPL:%s, WP:%s, EDAC:%s, Enabled:%s\n"
1688 " Scrub:%s, S-Delay:%d\n",
1689 priv->ways,
1690 priv->waysize,
1691 priv->linesize,
1692 (priv->index * priv->ways),
1693 priv->mtrr,
1694 (priv->ft_support? "Available":"N/A"),
1695 L2CACHE_LOCKED_WAYS(status),
1696 (priv->split_support? (L2CACHE_SPLIT_ENABLED(status)?
1697 "Enabled":"Disabled"):"N/A"),
1698 repl_names[L2CACHE_REPL(status)],
1699 (L2CACHE_WRITETHROUGH(status)? "Write-through":"Write-back"),
1700 (L2CACHE_EDAC_ENABLED(status)? "Enabled":"Disabled"),
1701 (L2CACHE_ENABLED(status)? "Yes":"No"),
1702 (L2CACHE_SCRUB_ENABLED(status)? "Enabled":"Disabled"),
1703 L2CACHE_SCRUB_DELAY(status)
1704 );
1705 if (l2cache_ctrl_status()){
1706 printf("L2cache enabled.\n");
1707 }else{
1708 printf("L2cache disabled.\n");
1709 }
1710 #endif
1711 return L2CACHE_ERR_OK;
1712 }
1713
1714 int l2cache_split_enable(void)
1715 {
1716 struct l2cache_priv * priv = l2cachepriv;
1717
1718 if (priv == NULL){
1719 DBG("L2CACHE not initialized.\n");
1720 return L2CACHE_ERR_NOINIT;
1721 }
1722
1723 if (!priv->split_support){
1724 DBG("L2CACHE does not have split support.\n");
1725 return L2CACHE_ERR_ERROR;
1726 }
1727
1728 l2cache_reg_accctrl_split_enable();
1729 DBG("L2CACHE split is now enabled\n");
1730
1731 return L2CACHE_ERR_OK;
1732 }
1733
1734 int l2cache_split_disable(void)
1735 {
1736 struct l2cache_priv * priv = l2cachepriv;
1737
1738 if (priv == NULL){
1739 DBG("L2CACHE not initialized.\n");
1740 return L2CACHE_ERR_NOINIT;
1741 }
1742
1743 if (!priv->split_support){
1744 DBG("L2CACHE does not have split support.\n");
1745 return L2CACHE_ERR_ERROR;
1746 }
1747
1748 l2cache_reg_accctrl_split_disable();
1749 DBG("L2CACHE split is now disabled\n");
1750
1751 return L2CACHE_ERR_OK;
1752 }
1753
1754 int l2cache_edac_enable(int flush)
1755 {
1756 struct l2cache_priv * priv = l2cachepriv;
1757 int enabled;
1758 int ret;
1759
1760 if (priv == NULL){
1761 DBG("L2CACHE not initialized.\n");
1762 return L2CACHE_ERR_NOINIT;
1763 }
1764
1765 if (!priv->ft_support){
1766 DBG("L2CACHE does not have EDAC support.\n");
1767 return L2CACHE_ERR_ERROR;
1768 }
1769
1770
1771 enabled = l2cache_ctrl_status();
1772
1773
1774 ret = l2cache_disable(flush);
1775 if (ret < 0){
1776 return ret;
1777 }
1778
1779
1780 l2cache_reg_error_reset();
1781
1782
1783 l2cache_reg_ctrl_edac_set(1);
1784
1785
1786 if (enabled){
1787 l2cache_reg_ctrl_enable();
1788 }
1789
1790 DBG("L2CACHE EDAC is now enabled\n");
1791
1792 return L2CACHE_ERR_OK;
1793 }
1794
1795 int l2cache_edac_disable(int flush)
1796 {
1797 struct l2cache_priv * priv = l2cachepriv;
1798 int enabled;
1799 int ret;
1800
1801 if (priv == NULL){
1802 DBG("L2CACHE not initialized.\n");
1803 return L2CACHE_ERR_NOINIT;
1804 }
1805
1806 if (!priv->ft_support){
1807 DBG("L2CACHE does not have EDAC support.\n");
1808 return L2CACHE_ERR_ERROR;
1809 }
1810
1811
1812 enabled = l2cache_ctrl_status();
1813
1814
1815 ret = l2cache_disable(flush);
1816 if (ret < 0){
1817 return ret;
1818 }
1819
1820
1821 l2cache_reg_ctrl_edac_set(0);
1822
1823
1824 l2cache_reg_error_reset();
1825
1826
1827 if (enabled){
1828 l2cache_reg_ctrl_enable();
1829 }
1830
1831 DBG("L2CACHE EDAC is now disabled\n");
1832
1833 return L2CACHE_ERR_OK;
1834 }
1835
1836 int l2cache_scrub_enable(int delay)
1837 {
1838 struct l2cache_priv * priv = l2cachepriv;
1839
1840 if (priv == NULL){
1841 DBG("L2CACHE not initialized.\n");
1842 return L2CACHE_ERR_NOINIT;
1843 }
1844
1845 if (!priv->ft_support){
1846 DBG("L2CACHE does not have EDAC support.\n");
1847 return L2CACHE_ERR_ERROR;
1848 }
1849
1850
1851 l2cache_reg_scrub_enable(delay);
1852
1853 DBG("L2CACHE Scrub is now enabled\n");
1854
1855 return L2CACHE_ERR_OK;
1856 }
1857
1858 int l2cache_scrub_disable(void)
1859 {
1860 struct l2cache_priv * priv = l2cachepriv;
1861
1862 if (priv == NULL){
1863 DBG("L2CACHE not initialized.\n");
1864 return L2CACHE_ERR_NOINIT;
1865 }
1866
1867 if (!priv->ft_support){
1868 DBG("L2CACHE does not have EDAC support.\n");
1869 return L2CACHE_ERR_ERROR;
1870 }
1871
1872
1873 l2cache_reg_scrub_disable();
1874
1875 DBG("L2CACHE Scrub is now disabled\n");
1876
1877 return L2CACHE_ERR_OK;
1878 }
1879
1880 int l2cache_scrub_line(int way, int index)
1881 {
1882 struct l2cache_priv * priv = l2cachepriv;
1883 unsigned int scrub;
1884
1885 if (priv == NULL){
1886 DBG("L2CACHE not initialized.\n");
1887 return L2CACHE_ERR_NOINIT;
1888 }
1889
1890 if (!priv->ft_support){
1891 DBG("L2CACHE does not have EDAC support.\n");
1892 return L2CACHE_ERR_ERROR;
1893 }
1894
1895 if ((index < 0) || (index >= priv->index)){
1896 DBG("L2CACHE only has %d lines.\n", priv->index);
1897 return L2CACHE_ERR_EINVAL;
1898 }
1899
1900 if ((way < 0) || (way >= priv->ways)){
1901 DBG("L2CACHE only has %d ways.\n", priv->ways);
1902 return L2CACHE_ERR_EINVAL;
1903 }
1904
1905
1906 scrub = l2cache_reg_scrub();
1907 if ( (scrub & L2C_SCRUB_PEN) || (scrub & L2C_SCRUB_EN) ){
1908 DBG("L2CACHE already scrubbing.\n");
1909 return L2CACHE_ERR_ERROR;
1910 }
1911
1912
1913 l2cache_reg_scrub_line(way, index);
1914
1915 DBG("L2CACHE Scrub line [%d,%d]\n",way,index);
1916
1917 return L2CACHE_ERR_OK;
1918 }
1919
1920 int l2cache_writethrough(int flush)
1921 {
1922 struct l2cache_priv * priv = l2cachepriv;
1923 int enabled;
1924 int ret;
1925
1926 if (priv == NULL){
1927 DBG("L2CACHE not initialized.\n");
1928 return L2CACHE_ERR_NOINIT;
1929 }
1930
1931
1932 enabled = l2cache_ctrl_status();
1933
1934
1935 ret = l2cache_disable(flush);
1936 if (ret < 0){
1937 return ret;
1938 }
1939
1940
1941 l2cache_reg_ctrl_writep(1);
1942
1943
1944 if (enabled){
1945 l2cache_reg_ctrl_enable();
1946 }
1947
1948 DBG("L2CACHE now is writethrough\n");
1949
1950 return L2CACHE_ERR_OK;
1951 }
1952
1953 int l2cache_writeback(int flush)
1954 {
1955 struct l2cache_priv * priv = l2cachepriv;
1956 int enabled;
1957 int ret;
1958
1959 if (priv == NULL){
1960 DBG("L2CACHE not initialized.\n");
1961 return L2CACHE_ERR_NOINIT;
1962 }
1963
1964
1965 enabled = l2cache_ctrl_status();
1966
1967
1968 ret = l2cache_disable(flush);
1969 if (ret < 0){
1970 return ret;
1971 }
1972
1973
1974 l2cache_reg_ctrl_writep(0);
1975
1976
1977 if (enabled){
1978 l2cache_reg_ctrl_enable();
1979 }
1980
1981 DBG("L2CACHE now is writeback\n");
1982
1983 return L2CACHE_ERR_OK;
1984 }
1985
1986 int l2cache_replacement(int options, int flush)
1987 {
1988 struct l2cache_priv * priv = l2cachepriv;
1989 int enabled;
1990 int ret;
1991 int way;
1992
1993 if (priv == NULL){
1994 DBG("L2CACHE not initialized.\n");
1995 return L2CACHE_ERR_NOINIT;
1996 }
1997
1998
1999 enabled = l2cache_ctrl_status();
2000
2001
2002 ret = l2cache_disable(flush);
2003 if (ret < 0){
2004 return ret;
2005 }
2006
2007 if ( (options & 0x3) == L2CACHE_OPTIONS_REPL_MASTERIDX_IDX){
2008
2009 way = (options >> 2) & 0x3;
2010 l2cache_reg_ctrl_iway(way);
2011 }
2012
2013
2014 l2cache_reg_ctrl_repl(options & 0x3);
2015
2016
2017 if (enabled){
2018 l2cache_reg_ctrl_enable();
2019 }
2020
2021 DBG("L2CACHE replacement set to %d\n", (options & 0x3));
2022
2023 return L2CACHE_ERR_OK;
2024
2025 }
2026
2027 int l2cache_isr_register(l2cache_isr_t isr, void * arg, int options)
2028 {
2029 struct l2cache_priv *priv = l2cachepriv;
2030 unsigned int mask;
2031
2032 if (priv == NULL){
2033 DBG("L2CACHE not initialized.\n");
2034 return L2CACHE_ERR_NOINIT;
2035 }
2036
2037 if (isr == NULL){
2038 DBG("L2CACHE wrong isr.\n");
2039 return L2CACHE_ERR_EINVAL;
2040 }
2041
2042
2043 mask = 0 |
2044 ((options & L2CACHE_INTERRUPT_BACKENDERROR)? L2C_ERROR_IRQM_BCKEND:0) |
2045 ((options & L2CACHE_INTERRUPT_WPROTHIT)? L2C_ERROR_IRQM_WPROT:0) |
2046 ((options & L2CACHE_INTERRUPT_CORRERROR)? L2C_ERROR_IRQM_CORR:0) |
2047 ((options & L2CACHE_INTERRUPT_UNCORRERROR)? L2C_ERROR_IRQM_UNCORR:0);
2048
2049
2050 l2cache_reg_error_reset();
2051 l2cache_reg_error_irqmask(0);
2052
2053
2054 if (priv->isr == NULL){
2055
2056 drvmgr_interrupt_register(priv->dev, 0, priv->devname, l2cache_isr,
2057 priv);
2058 }
2059
2060
2061 priv->isr=isr;
2062 priv->isr_arg=arg;
2063
2064
2065 l2cache_reg_error_irqmask(mask);
2066
2067 return L2CACHE_ERR_OK;
2068 }
2069
2070 int l2cache_isr_unregister(void)
2071 {
2072 struct l2cache_priv *priv = l2cachepriv;
2073
2074 if (priv == NULL){
2075 DBG("L2CACHE not initialized.\n");
2076 return L2CACHE_ERR_NOINIT;
2077 }
2078
2079 if (priv->isr == NULL){
2080 DBG("L2CACHE wrong isr.\n");
2081 return L2CACHE_ERR_EINVAL;
2082 }
2083
2084
2085 l2cache_reg_error_reset();
2086 l2cache_reg_error_irqmask(0);
2087
2088
2089 drvmgr_interrupt_unregister(priv->dev, 0, l2cache_isr, priv);
2090
2091
2092 priv->isr=NULL;
2093 priv->isr_arg=NULL;
2094
2095 return L2CACHE_ERR_OK;
2096 }
2097
2098 int l2cache_interrupt_unmask(int options)
2099 {
2100 struct l2cache_priv *priv = l2cachepriv;
2101 unsigned int mask, irq;
2102
2103 if (priv == NULL){
2104 DBG("L2CACHE not initialized.\n");
2105 return L2CACHE_ERR_NOINIT;
2106 }
2107
2108 if (priv->isr == NULL){
2109 DBG("L2CACHE wrong isr.\n");
2110 return L2CACHE_ERR_EINVAL;
2111 }
2112
2113
2114 mask = 0 |
2115 ((options & L2CACHE_INTERRUPT_BACKENDERROR)? L2C_ERROR_IRQM_BCKEND:0) |
2116 ((options & L2CACHE_INTERRUPT_WPROTHIT)? L2C_ERROR_IRQM_WPROT:0) |
2117 ((options & L2CACHE_INTERRUPT_CORRERROR)? L2C_ERROR_IRQM_CORR:0) |
2118 ((options & L2CACHE_INTERRUPT_UNCORRERROR)? L2C_ERROR_IRQM_UNCORR:0);
2119
2120
2121 l2cache_reg_error_reset();
2122
2123
2124 irq = ((l2cache_reg_error() & L2C_ERROR_IRQM) >> L2C_ERROR_IRQM_BIT);
2125
2126
2127 l2cache_reg_error_irqmask(irq | mask);
2128
2129 return L2CACHE_ERR_OK;
2130 }
2131
2132 int l2cache_interrupt_mask(int options)
2133 {
2134 struct l2cache_priv *priv = l2cachepriv;
2135 unsigned int mask, irq;
2136
2137 if (priv == NULL){
2138 DBG("L2CACHE not initialized.\n");
2139 return L2CACHE_ERR_NOINIT;
2140 }
2141
2142
2143 mask = 0 |
2144 ((options & L2CACHE_INTERRUPT_BACKENDERROR)? L2C_ERROR_IRQM_BCKEND:0) |
2145 ((options & L2CACHE_INTERRUPT_WPROTHIT)? L2C_ERROR_IRQM_WPROT:0) |
2146 ((options & L2CACHE_INTERRUPT_CORRERROR)? L2C_ERROR_IRQM_CORR:0) |
2147 ((options & L2CACHE_INTERRUPT_UNCORRERROR)? L2C_ERROR_IRQM_UNCORR:0);
2148
2149
2150 l2cache_reg_error_reset();
2151
2152
2153 irq = ((l2cache_reg_error() & L2C_ERROR_IRQM) >> L2C_ERROR_IRQM_BIT);
2154
2155
2156 l2cache_reg_error_irqmask(irq & ~(mask));
2157
2158 return L2CACHE_ERR_OK;
2159 }
2160
2161 int l2cache_error_status(uint32_t * addr, uint32_t * status)
2162 {
2163 struct l2cache_priv *priv = l2cachepriv;
2164 unsigned int sts;
2165 unsigned int erraddr;
2166
2167 if (priv == NULL){
2168 DBG("L2CACHE not initialized.\n");
2169 return L2CACHE_ERR_NOINIT;
2170 }
2171
2172
2173 sts = l2cache_reg_error();
2174 erraddr = l2cache_reg_error_addr();
2175
2176
2177 if (sts & L2C_ERROR_VALID){
2178
2179 l2cache_reg_error_reset();
2180
2181
2182 if (addr != NULL){
2183 *addr = (erraddr & ~(0x1f));
2184 }
2185
2186 if(status != NULL){
2187 *status = sts;
2188 }
2189
2190
2191 if (sts & L2C_ERROR_MULTI){
2192 return L2CACHE_STATUS_MULTIPLEERRORS;
2193 }else{
2194 return L2CACHE_STATUS_NEWERROR;
2195 }
2196 }else{
2197
2198 return L2CACHE_STATUS_NOERROR;
2199 }
2200 }