/******************************************************************************* * mvXorTargetWinEnable - Enable/disable a Xor address decode window * * DESCRIPTION: * This function enable/disable a XOR address decode window. * if parameter 'enable' == MV_TRUE the routine will enable the * window, thus enabling XOR accesses (before enabling the window it is * tested for overlapping). Otherwise, the window will be disabled. * * INPUT: * winNum - Decode window number. * enable - Enable/disable parameter. * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. * *******************************************************************************/ MV_STATUS mvXorTargetWinEnable(MV_U32 unit, MV_U32 winNum, MV_BOOL enable) { MV_UNIT_WIN_INFO addrDecWin; MV_U32 chan; /* Parameter checking */ if (winNum >= XOR_MAX_ADDR_DEC_WIN) { DB(mvOsPrintf("%s: ERR. Invalid winNum%d\n", __func__, winNum)); return MV_ERROR; } if (enable == MV_TRUE) { /* Get current window */ if (MV_OK != mvXorTargetWinRead(unit, winNum, &addrDecWin)) { DB(mvOsPrintf("%s: ERR. targetWinGet fail\n", __func__)); return MV_ERROR; } /* Check for overlapping */ if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &(addrDecWin.addrWin))) { /* Overlap detected */ DB(mvOsPrintf("%s: ERR. Overlap detected\n", __func__)); return MV_ERROR; } /* No Overlap. Enable address decode target window */ for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit, chan), XEXWCR_WIN_EN_MASK(winNum)); } else { /* Disable address decode target window */ for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit, chan), XEXWCR_WIN_EN_MASK(winNum)); } return MV_OK; }
/******************************************************************************* * 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; }
/******************************************************************************* * 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; }
/******************************************************************************* * xorWinOverlapDetect - Detect XOR address windows overlaping * * DESCRIPTION: * An unpredicted behaviour is expected in case XOR address decode * windows overlaps. * This function detects XOR address decode windows overlaping of a * specified window. The function does not check the window itself for * overlaping. The function also skipps disabled address decode windows. * * INPUT: * winNum - address decode window number. * pAddrDecWin - An address decode window struct. * * OUTPUT: * None. * * RETURN: * MV_TRUE if the given address window overlap current address * decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data * from registers. * *******************************************************************************/ static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin) { MV_U32 baseAddrEnableReg; MV_U32 winNumIndex,chan; MV_XOR_DEC_WIN addrDecWin; if (pAddrWin == NULL) { DB(mvOsPrintf("%s: ERR. pAddrWin is NULL pointer\n", __FUNCTION__ )); return MV_BAD_PTR; } for (chan = 0; chan < MV_XOR_MAX_CHAN; chan++) { /* Read base address enable register. Do not check disabled windows */ baseAddrEnableReg = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)); for (winNumIndex = 0; winNumIndex < XOR_MAX_ADDR_DEC_WIN; winNumIndex++) { /* Do not check window itself */ if (winNumIndex == winNum) { continue; } /* Do not check disabled windows */ if ((baseAddrEnableReg & XEXWCR_WIN_EN_MASK(winNumIndex)) == 0) { continue; } /* Get window parameters */ if (MV_OK != mvXorTargetWinGet(unit,winNumIndex, &addrDecWin)) { DB(mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__ )); return MV_ERROR; } if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin))) { return MV_TRUE; } } } return MV_FALSE; }
/******************************************************************************* * 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; }