void mv_sys_xor_init(MV_DRAM_INFO *dram_info) { u32 reg, ui, base, cs_count; xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0)); for (ui = 0; ui < MAX_CS; ui++) xor_regs_base_backup[ui] = reg_read(XOR_BASE_ADDR_REG(0, ui)); for (ui = 0; ui < MAX_CS; ui++) xor_regs_mask_backup[ui] = reg_read(XOR_SIZE_MASK_REG(0, ui)); reg = 0; for (ui = 0; ui < (dram_info->num_cs + 1); ui++) { /* Enable Window x for each CS */ reg |= (0x1 << (ui)); /* Enable Window x for each CS */ reg |= (0x3 << ((ui * 2) + 16)); } reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg); /* Last window - Base - 0x40000000, Attribute 0x1E - SRAM */ base = (SRAM_BASE & 0xFFFF0000) | 0x1E00; reg_write(XOR_BASE_ADDR_REG(0, dram_info->num_cs), base); /* Last window - Size - 64 MB */ reg_write(XOR_SIZE_MASK_REG(0, dram_info->num_cs), 0x03FF0000); cs_count = 0; for (ui = 0; ui < MAX_CS; ui++) { if (dram_info->cs_ena & (1 << ui)) { /* * Window x - Base - 0x00000000, Attribute 0x0E - DRAM */ base = 0; switch (ui) { case 0: base |= 0xE00; break; case 1: base |= 0xD00; break; case 2: base |= 0xB00; break; case 3: base |= 0x700; break; } reg_write(XOR_BASE_ADDR_REG(0, cs_count), base); /* Window x - Size - 256 MB */ reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x0FFF0000); cs_count++; } } mv_xor_hal_init(1); return; }
void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, u32 cs_size, u32 base_delta) { u32 reg, ui, base, cs_count; ui_xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0)); for (ui = 0; ui < MAX_CS; ui++) ui_xor_regs_base_backup[ui] = reg_read(XOR_BASE_ADDR_REG(0, ui)); for (ui = 0; ui < MAX_CS; ui++) ui_xor_regs_mask_backup[ui] = reg_read(XOR_SIZE_MASK_REG(0, ui)); reg = 0; for (ui = 0; ui < (num_of_cs); ui++) { /* Enable Window x for each CS */ reg |= (0x1 << (ui)); /* Enable Window x for each CS */ reg |= (0x3 << ((ui * 2) + 16)); } reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg); cs_count = 0; for (ui = 0; ui < num_of_cs; ui++) { if (cs_ena & (1 << ui)) { /* * window x - Base - 0x00000000, * Attribute 0x0e - DRAM */ base = cs_size * ui + base_delta; switch (ui) { case 0: base |= 0xe00; break; case 1: base |= 0xd00; break; case 2: base |= 0xb00; break; case 3: base |= 0x700; break; } reg_write(XOR_BASE_ADDR_REG(0, cs_count), base); /* window x - Size */ reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x7fff0000); cs_count++; } } mv_xor_hal_init(1); return; }
/******************************************************************************* * mvXorTargetWinWrite - Set XOR target address window * * DESCRIPTION: * This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) * address window. After setting this target window, the XOR will be * able to access the target within the address window. * * INPUT: * winNum - One of the possible XOR memory decode windows. * target - Peripheral target enumerator. * base - Window base address. * size - Window size. * enable - Window enable/disable. * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. * *******************************************************************************/ MV_STATUS mvXorTargetWinWrite(MV_U32 unit, MV_U32 winNum, MV_UNIT_WIN_INFO *pAddrDecWin) { MV_U32 sizeReg, baseReg; MV_U32 chan; /* Parameter checking */ if (winNum >= XOR_MAX_ADDR_DEC_WIN) { DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __func__, winNum)); return MV_BAD_PARAM; } if (pAddrDecWin == NULL) { DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __func__)); return MV_BAD_PTR; } /* Check if the requested window overlaps with current windows */ if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &pAddrDecWin->addrWin)) { DB(mvOsPrintf("%s: ERR. Window %d overlap\n", __func__, winNum)); return MV_ERROR; } if (!MV_IS_POWER_OF_2(pAddrDecWin->addrWin.size)) { mvOsPrintf("%s: ERR. Illegal window size.\n", __func__); return MV_BAD_PARAM; } baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit, winNum)); sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit, winNum)); baseReg = pAddrDecWin->addrWin.baseLow & XEBARX_BASE_MASK; sizeReg = (pAddrDecWin->addrWin.size / XOR_WIN_SIZE_ALIGN) - 1; sizeReg = (sizeReg << XESMRX_SIZE_MASK_OFFS) & XESMRX_SIZE_MASK_MASK; /* set attributes */ baseReg &= ~XEBARX_ATTR_MASK; baseReg |= pAddrDecWin->attrib << XEBARX_ATTR_OFFS; /* set target ID */ baseReg &= ~XEBARX_TARGET_MASK; baseReg |= pAddrDecWin->targetId << XEBARX_TARGET_OFFS; /* Write to address decode Base Address Register */ MV_REG_WRITE(XOR_BASE_ADDR_REG(unit, winNum), baseReg); /* Write to Size Register */ MV_REG_WRITE(XOR_SIZE_MASK_REG(unit, winNum), sizeReg); for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) { if (pAddrDecWin->enable) MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit, chan), XEXWCR_WIN_EN_MASK(winNum)); else MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit, chan), XEXWCR_WIN_EN_MASK(winNum)); } return MV_OK; }
GT_VOID mvSysXorInit(GT_U32 uiNumOfCS, GT_U32 uiCsEna, GT_U32 csSize, GT_U32 baseDelta) { GT_U32 uiReg,ui,uiBase,uiCsCount; uiXorRegsCtrlBackup = MV_REG_READ(XOR_WINDOW_CTRL_REG(0, 0)); for(ui=0;ui<MAX_CS;ui++) uiXorRegsBaseBackup[ui] = MV_REG_READ(XOR_BASE_ADDR_REG(0, ui)); for(ui=0;ui<MAX_CS;ui++) uiXorRegsMaskBackup[ui] = MV_REG_READ(XOR_SIZE_MASK_REG(0, ui)); uiReg = 0; for(ui=0;ui<(uiNumOfCS);ui++) { uiReg |= (0x1 << (ui)); /* Enable Window x for each CS */ uiReg |= (0x3 << ((ui*2)+16)); /* Enable Window x for each CS */ } MV_REG_WRITE(XOR_WINDOW_CTRL_REG(0, 0), uiReg); uiCsCount = 0; for(ui=0;ui<uiNumOfCS;ui++) { if(uiCsEna & (1<<ui)) { /* window x - Base - 0x00000000, Attribute 0x0E - DRAM */ uiBase = csSize*ui + baseDelta; switch(ui) { case 0: uiBase |= 0xE00; break; case 1: uiBase |= 0xD00; break; case 2: uiBase |= 0xB00; break; case 3: uiBase |= 0x700; break; } MV_REG_WRITE(XOR_BASE_ADDR_REG(0, uiCsCount), uiBase); /* window x - Size*/ MV_REG_WRITE(XOR_SIZE_MASK_REG(0, uiCsCount), 0x7FFF0000); uiCsCount++; } } mvXorHalInit(1); return; }
GT_VOID mvSysXorFinish(void) { GT_U32 ui; MV_REG_WRITE(XOR_WINDOW_CTRL_REG(0, 0), uiXorRegsCtrlBackup); for(ui=0;ui<MAX_CS;ui++) MV_REG_WRITE(XOR_BASE_ADDR_REG(0, ui), uiXorRegsBaseBackup[ui]); for(ui=0;ui<MAX_CS;ui++) MV_REG_WRITE(XOR_SIZE_MASK_REG(0, ui), uiXorRegsMaskBackup[ui]); MV_REG_WRITE(XOR_ADDR_OVRD_REG(0, 0), 0); }
void mv_sys_xor_finish(void) { u32 ui; reg_write(XOR_WINDOW_CTRL_REG(0, 0), xor_regs_ctrl_backup); for (ui = 0; ui < MAX_CS; ui++) reg_write(XOR_BASE_ADDR_REG(0, ui), xor_regs_base_backup[ui]); for (ui = 0; ui < MAX_CS; ui++) reg_write(XOR_SIZE_MASK_REG(0, ui), xor_regs_mask_backup[ui]); reg_write(XOR_ADDR_OVRD_REG(0, 0), 0); }
/******************************************************************************* * mvXorTargetWinRead - Get xor peripheral target address window. * * DESCRIPTION: * Get xor peripheral target address window. * * INPUT: * winNum - One of the possible XOR memory decode windows. * * OUTPUT: * base - Window base address. * size - Window size. * enable - window enable/disable. * * RETURN: * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. * *******************************************************************************/ MV_STATUS mvXorTargetWinRead(MV_U32 unit, MV_U32 winNum, MV_UNIT_WIN_INFO *pAddrDecWin) { MV_U32 sizeReg, baseReg; MV_U32 chan = 0, chanWinEn; /* Parameter checking */ if (winNum >= XOR_MAX_ADDR_DEC_WIN) { DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __func__, winNum)); return MV_ERROR; } if (NULL == pAddrDecWin) { DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __func__)); return MV_BAD_PTR; } chanWinEn = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit, 0)) & XEXWCR_WIN_EN_MASK(winNum); for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) { /* we should scan here all channels per unit */ /* Check if enable bit is equal for all channels */ if ((MV_REG_READ(XOR_WINDOW_CTRL_REG(unit, chan)) & XEXWCR_WIN_EN_MASK(winNum)) != chanWinEn) { mvOsPrintf("%s: ERR. Window enable field must be equal in " "all channels(chan=%d)\n", __func__, chan); return MV_ERROR; } } baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit, winNum)); sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit, winNum)); pAddrDecWin->addrWin.size = (sizeReg & XESMRX_SIZE_MASK_MASK) >> XESMRX_SIZE_MASK_OFFS; pAddrDecWin->addrWin.size = (pAddrDecWin->addrWin.size + 1) * XOR_WIN_SIZE_ALIGN; pAddrDecWin->addrWin.baseLow = baseReg & XEBARX_BASE_MASK; pAddrDecWin->addrWin.baseHigh = 0; /* attrib and targetId */ pAddrDecWin->attrib = (baseReg & XEBARX_ATTR_MASK) >> XEBARX_ATTR_OFFS; pAddrDecWin->targetId = (baseReg & XEBARX_TARGET_MASK) >> XEBARX_TARGET_OFFS; if (chanWinEn) pAddrDecWin->enable = MV_TRUE; else pAddrDecWin->enable = MV_FALSE; return MV_OK; }
/******************************************************************************* * mvXorTargetWinGet - Get xor peripheral target address window. * * DESCRIPTION: * Get xor peripheral target address window. * * INPUT: * winNum - One of the possible XOR memory decode windows. * * OUTPUT: * base - Window base address. * size - Window size. * enable - window enable/disable. * * RETURN: * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. * *******************************************************************************/ MV_STATUS mvXorTargetWinGet(MV_U32 unit,MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin) { MV_DEC_REGS xorDecRegs; MV_TARGET_ATTRIB targetAttrib; MV_U32 chan=0,chanWinEn; /* Parameter checking */ if (winNum >= XOR_MAX_ADDR_DEC_WIN) { DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__ , winNum)); return MV_ERROR; } if (NULL == pAddrDecWin) { DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ )); return MV_BAD_PTR; } chanWinEn = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,0)) & XEXWCR_WIN_EN_MASK(winNum); for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) { /* Check if enable bit is equal for all channels */ if ((MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) & XEXWCR_WIN_EN_MASK(winNum)) != chanWinEn) { mvOsPrintf("%s: ERR. Window enable field must be equal in " "all channels\n",__FUNCTION__); return MV_ERROR; } } xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum)); xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum)); if (MV_OK != mvCtrlRegToAddrDec(&xorDecRegs, &pAddrDecWin->addrWin)) { mvOsPrintf("%s: ERR. mvCtrlRegToAddrDec failed\n", __FUNCTION__); return MV_ERROR; } /* attrib and targetId */ targetAttrib.attrib = (xorDecRegs.baseReg & XEBARX_ATTR_MASK) >> XEBARX_ATTR_OFFS; targetAttrib.targetId = (xorDecRegs.baseReg & XEBARX_TARGET_MASK) >> XEBARX_TARGET_OFFS; pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib); if(chanWinEn) { pAddrDecWin->enable = MV_TRUE; } else pAddrDecWin->enable = MV_FALSE; return MV_OK; }
/******************************************************************************* * mvXorTargetWinSet - Set XOR target address window * * DESCRIPTION: * This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) * address window. After setting this target window, the XOR will be * able to access the target within the address window. * * INPUT: * winNum - One of the possible XOR memory decode windows. * target - Peripheral target enumerator. * base - Window base address. * size - Window size. * enable - Window enable/disable. * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. * *******************************************************************************/ MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin) { MV_DEC_REGS xorDecRegs; MV_TARGET_ATTRIB targetAttribs; MV_U32 chan; /* Parameter checking */ if (winNum >= XOR_MAX_ADDR_DEC_WIN) { DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum)); return MV_BAD_PARAM; } if (pAddrDecWin == NULL) { DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ )); return MV_BAD_PTR; } /* Check if the requested window overlaps with current windows */ if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &pAddrDecWin->addrWin)) { DB(mvOsPrintf("%s: ERR. Window %d overlap\n",__FUNCTION__,winNum)); return MV_ERROR; } xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum)); xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum)); /* Get Base Address and size registers values */ if(MV_OK != mvCtrlAddrDecToReg(&pAddrDecWin->addrWin, &xorDecRegs)) { DB(mvOsPrintf("%s: ERR. Invalid addr dec window\n",__FUNCTION__)); return MV_BAD_PARAM; } mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs); /* set attributes */ xorDecRegs.baseReg &= ~XEBARX_ATTR_MASK; xorDecRegs.baseReg |= targetAttribs.attrib << XEBARX_ATTR_OFFS; /* set target ID */ xorDecRegs.baseReg &= ~XEBARX_TARGET_MASK; xorDecRegs.baseReg |= targetAttribs.targetId << XEBARX_TARGET_OFFS; /* Write to address decode Base Address Register */ MV_REG_WRITE(XOR_BASE_ADDR_REG(unit,winNum), xorDecRegs.baseReg); /* Write to Size Register */ MV_REG_WRITE(XOR_SIZE_MASK_REG(unit,winNum), xorDecRegs.sizeReg); for (chan = 0; chan < MV_XOR_MAX_CHAN; chan++) { if (pAddrDecWin->enable) { MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan), XEXWCR_WIN_EN_MASK(winNum)); } else { MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan), XEXWCR_WIN_EN_MASK(winNum)); } } return MV_OK; }