/******************************************************************************* * mvTsuWinEnable - Enable/disable a TS address decode window * * DESCRIPTION: * This function enable/disable a TS address decode window. * * 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 mvTsuWinEnable(MV_U32 winNum, MV_BOOL enable) { MV_UNIT_WIN_INFO addrDecWin; /* Parameter checking */ if (winNum >= TSU_MAX_DECODE_WIN) { DB(mvOsPrintf("%s: ERR. Invalid winNum%d\n", __FUNCTION__, winNum)); return MV_ERROR; } if (enable == MV_TRUE) { /* Get current window */ if (MV_OK != mvTsuWinRead(0, winNum, &addrDecWin)) { DB(mvOsPrintf("%s: ERR. targetWinGet fail\n", __FUNCTION__)); return MV_ERROR; } /* Check for overlapping */ if (MV_TRUE == tsuWinOverlapDetect(winNum, &(addrDecWin.addrWin))) { /* Overlap detected */ DB(mvOsPrintf("%s: ERR. Overlap detected\n", __FUNCTION__)); return MV_ERROR; } /* No Overlap. Enable address decode target window */ MV_REG_BIT_SET(MV_TSU_WIN_CTRL_REG(winNum), TSU_WIN_CTRL_EN_MASK); } else { /* Disable address decode target window */ MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum), TSU_WIN_CTRL_EN_MASK); } return MV_OK; }
/******************************************************************************* * mvTsuWinRead * * DESCRIPTION: * Get TSU peripheral target address window. * * INPUT: * unit - The Unit ID. * winNum - TSU to target address decode window number. * * OUTPUT: * pAddrDecWin - TSU target window data structure. * * RETURN: * MV_ERROR if register parameters are invalid. * *******************************************************************************/ MV_STATUS mvTsuWinRead(MV_U32 unit, MV_U32 winNum, MV_UNIT_WIN_INFO *pAddrDecWin) { MV_U32 baseReg, sizeReg; /* Parameter checking */ if(winNum >= TSU_MAX_DECODE_WIN) { mvOsPrintf("mvTsuWinGet: ERR. Invalid winNum %d\n", winNum); return MV_NOT_SUPPORTED; } baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum)); sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)); pAddrDecWin->addrWin.size = (sizeReg & TSU_WIN_CTRL_SIZE_MASK) >> TSU_WIN_CTRL_SIZE_OFFS; pAddrDecWin->addrWin.size = (pAddrDecWin->addrWin.size + 1) * TSU_WIN_SIZE_ALIGN; pAddrDecWin->addrWin.baseLow = baseReg & TSU_WIN_BASE_MASK; pAddrDecWin->addrWin.baseHigh = 0; /* attrib and targetId */ pAddrDecWin->attrib = (sizeReg & TSU_WIN_CTRL_ATTR_MASK) >> TSU_WIN_CTRL_ATTR_OFFS; pAddrDecWin->targetId = (sizeReg & TSU_WIN_CTRL_TARGET_MASK) >> TSU_WIN_CTRL_TARGET_OFFS; /* Check if window is enabled */ if((MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)) & TSU_WIN_CTRL_EN_MASK)) pAddrDecWin->enable = MV_TRUE; else pAddrDecWin->enable = MV_FALSE; return MV_OK; }
/******************************************************************************* * tsuWinOverlapDetect * * DESCRIPTION: * Detect TSU address windows overlapping * An unpredicted behaviur is expected in case TSU address decode * windows overlapps. * This function detects TSU address decode windows overlapping of a * specified window. The function does not check the window itself for * overlapping. 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 tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin) { MV_U32 ctrlReg; MV_U32 winNumIndex; MV_TSU_DEC_WIN addrDecWin; for(winNumIndex = 0; winNumIndex < TSU_MAX_DECODE_WIN; winNumIndex++) { /* Do not check window itself */ if(winNumIndex == winNum) { continue; } /* Do not check disabled windows */ ctrlReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNumIndex)); if((ctrlReg & TSU_WIN_CTRL_EN_MASK) == 0) { continue; } /* Get window parameters */ if (MV_OK != mvTsuWinGet(winNumIndex, &addrDecWin)) { mvOsPrintf("tsuWinOverlapDetect: ERR. mvTsuWinGet failed\n"); return MV_ERROR; } if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin))) { return MV_TRUE; } } return MV_FALSE; }
/******************************************************************************* * tsuWinOverlapDetect - Detect TS address windows overlaping * * DESCRIPTION: * An unpredicted behaviour is expected in case TS address decode * windows overlaps. * This function detects TS 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 tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin) { MV_U32 baseAddrEnableReg; MV_U32 winNumIndex; MV_UNIT_WIN_INFO addrDecWin; if (pAddrWin == NULL) { DB(mvOsPrintf("%s: ERR. pAddrWin is NULL pointer\n", __FUNCTION__ )); return MV_BAD_PTR; } for (winNumIndex = 0; winNumIndex < TSU_MAX_DECODE_WIN; winNumIndex++) { /* Do not check window itself */ if (winNumIndex == winNum) continue; /* Read base address enable register. Do not check disabled windows */ baseAddrEnableReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNumIndex)); /* Do not check disabled windows */ if ((baseAddrEnableReg & TSU_WIN_CTRL_EN_MASK) == 0) continue; /* Get window parameters */ if (MV_OK != mvTsuWinRead(0, winNumIndex, &addrDecWin)) { DB(mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__ )); return MV_ERROR; } if (MV_TRUE == mvWinOverlapTest(pAddrWin, &(addrDecWin.addrWin))) return MV_TRUE; } return MV_FALSE; }
/******************************************************************************* * mvTsuWinInit * * DESCRIPTION: * Initialize the TSU unit address decode windows. * * INPUT: * addWinMap: An array holding the address decoding information for the * system. * OUTPUT: * None. * RETURN: * MV_OK - on success, * *******************************************************************************/ MV_STATUS mvTsuWinInit(MV_UNIT_WIN_INFO *addrWinMap) { MV_U32 winNum; MV_UNIT_WIN_INFO *addrDecWin; MV_U32 winPrioIndex=0; /* First disable all address decode windows */ for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++) { MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum), TSU_WIN_CTRL_EN_MASK); } /* Go through all windows in user table until table terminator */ for(winNum = 0; ((tsuAddrDecPrioTap[winPrioIndex] != TBL_TERM) && (winNum < TSU_MAX_DECODE_WIN));) { addrDecWin = &addrWinMap[tsuAddrDecPrioTap[winPrioIndex]]; if (addrDecWin->enable == MV_TRUE) { if (MV_OK != mvTsuWinWrite(0, winNum, addrDecWin)) { DB(mvOsPrintf("mvTsuWinInit: ERR. mvTsuWinWrite failed\n")); return MV_ERROR; } winNum++; } winPrioIndex++; } return MV_OK; }
/******************************************************************************* * mvTsuWinWrite * * DESCRIPTION: * This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) * address window, also known as address decode window. * After setting this target window, the TSU will be able to access the * target within the address window. * * INPUT: * unit - The Unit ID. * winNum - TSU to target address decode window number. * pAddrDecWin - TSU target window data structure. * * OUTPUT: * None. * * RETURN: * MV_ERROR - if address window overlapps with other address decode * windows. * MV_BAD_PARAM - if base address is invalid parameter or target is * unknown. * *******************************************************************************/ MV_STATUS mvTsuWinWrite(MV_U32 unit, MV_U32 winNum, MV_UNIT_WIN_INFO *pAddrDecWin) { MV_U32 sizeReg, baseReg; /* Parameter checking */ if(winNum >= TSU_MAX_DECODE_WIN) { mvOsPrintf("mvTsuWinSet: ERR. Invalid win num %d\n",winNum); return MV_BAD_PARAM; } /* Check if the requested window overlapps with current windows */ if(MV_TRUE == tsuWinOverlapDetect(winNum, &pAddrDecWin->addrWin)) { mvOsPrintf("mvTsuWinSet: ERR. Window %d overlap\n", winNum); return MV_ERROR; } /* check if address is aligned to the size */ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow,pAddrDecWin->addrWin.size)) { mvOsPrintf("mvTsuWinSet: Error setting TSU window %d.\n" "Address 0x%08x is unaligned to size 0x%x.\n", winNum, pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size); return MV_ERROR; } baseReg = pAddrDecWin->addrWin.baseLow & TSU_WIN_BASE_MASK; sizeReg = (pAddrDecWin->addrWin.size / TSU_WIN_SIZE_ALIGN) - 1; sizeReg = (sizeReg << TSU_WIN_CTRL_SIZE_OFFS) & TSU_WIN_CTRL_SIZE_MASK; /* set attributes */ baseReg &= ~TSU_WIN_CTRL_ATTR_MASK; baseReg |= pAddrDecWin->attrib << TSU_WIN_CTRL_ATTR_OFFS; /* set target ID */ baseReg &= ~TSU_WIN_CTRL_TARGET_MASK; baseReg |= pAddrDecWin->targetId << TSU_WIN_CTRL_TARGET_OFFS; /* for the safe side we disable the window before writing the new */ /* values */ mvTsuWinEnable(winNum, MV_FALSE); MV_REG_WRITE(MV_TSU_WIN_CTRL_REG(winNum), sizeReg); /* Write to address decode Size Register */ MV_REG_WRITE(MV_TSU_WIN_BASE_REG(winNum), baseReg); /* Enable address decode target window */ if(pAddrDecWin->enable == MV_TRUE) { mvTsuWinEnable(winNum,MV_TRUE); } return MV_OK; }
/******************************************************************************* * mvTsuWinEnable * * DESCRIPTION: * This function enable/disable a TSU to target address window. * According to parameter 'enable' the routine will enable the * window, thus enabling TSU accesses (before enabling the window it is * tested for overlapping). Otherwise, the window will be disabled. * * INPUT: * winNum - TSU to target address decode window number. * enable - Enable / disable parameter. * * OUTPUT: * N/A * * RETURN: * MV_ERROR if decode window number was wrong or enabled window overlapps. * *******************************************************************************/ MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable) { MV_TSU_DEC_WIN addrDecWin; /* Parameter checking */ if(winNum >= TSU_MAX_DECODE_WIN) { mvOsPrintf("mvTsuWinEnable: ERR. Invalid winNum%d\n",winNum); return MV_ERROR; } if(enable == MV_TRUE) { /* First check for overlap with other enabled windows */ /* Get current window. */ if(MV_OK != mvTsuWinGet(winNum,&addrDecWin)) { mvOsPrintf("mvTsuWinEnable: ERR. targetWinGet fail\n"); return MV_ERROR; } /* Check for overlapping. */ if(MV_FALSE == tsuWinOverlapDetect(winNum,&(addrDecWin.addrWin))) { /* No Overlap. Enable address decode target window */ MV_REG_BIT_SET(MV_TSU_WIN_CTRL_REG(winNum), TSU_WIN_CTRL_EN_MASK); } else { /* Overlap detected */ mvOsPrintf("mvTsuWinEnable: ERR. Overlap detected\n"); return MV_ERROR; } } else { /* Disable address decode target window */ MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum), TSU_WIN_CTRL_EN_MASK); } return MV_OK; }
/******************************************************************************* * mvTsuWinGet * * DESCRIPTION: * Get TSU peripheral target address window. * * INPUT: * winNum - TSU to target address decode window number. * * OUTPUT: * pAddrDecWin - TSU target window data structure. * * RETURN: * MV_ERROR if register parameters are invalid. * *******************************************************************************/ MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin) { MV_DEC_REGS decRegs; MV_TARGET_ATTRIB targetAttrib; /* Parameter checking */ if(winNum >= TSU_MAX_DECODE_WIN) { mvOsPrintf("mvTsuWinGet: ERR. Invalid winNum %d\n", winNum); return MV_NOT_SUPPORTED; } decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum)); decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)); if(MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin))) { mvOsPrintf("mvTsuWinGet: mvCtrlRegToAddrDec Failed \n"); return MV_ERROR; } /* attrib and targetId */ targetAttrib.attrib = (decRegs.sizeReg & TSU_WIN_CTRL_ATTR_MASK) >> TSU_WIN_CTRL_ATTR_OFFS; targetAttrib.targetId = (decRegs.sizeReg & TSU_WIN_CTRL_TARGET_MASK) >> TSU_WIN_CTRL_TARGET_OFFS; pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib); /* Check if window is enabled */ if((MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)) & TSU_WIN_CTRL_EN_MASK)) { pAddrDecWin->enable = MV_TRUE; } else { pAddrDecWin->enable = MV_FALSE; } return MV_OK; }
/******************************************************************************* * mvTsuWinInit * * DESCRIPTION: * Initialize the TSU unit address decode windows. * * INPUT: * None. * OUTPUT: * None. * RETURN: * MV_OK - on success, * *******************************************************************************/ MV_STATUS mvTsuWinInit(void) { MV_U32 winNum, status, winPrioIndex=0; MV_TSU_DEC_WIN tsuWin; MV_CPU_DEC_WIN cpuAddrDecWin; /* First disable all address decode windows */ for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++) { MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum), TSU_WIN_CTRL_EN_MASK); } /* Go through all windows in user table until table terminator */ for(winNum = 0; ((tsuAddrDecPrioTap[winPrioIndex] != TBL_TERM) && (winNum < TSU_MAX_DECODE_WIN));) { /* first get attributes from CPU If */ status = mvCpuIfTargetWinGet(tsuAddrDecPrioTap[winPrioIndex], &cpuAddrDecWin); if(MV_NO_SUCH == status) { winPrioIndex++; continue; } if(MV_OK != status) { mvOsPrintf("mvTsuWinInit: ERR. mvCpuIfTargetWinGet failed\n"); return MV_ERROR; } if (cpuAddrDecWin.enable == MV_TRUE) { tsuWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; tsuWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow; tsuWin.addrWin.size = cpuAddrDecWin.addrWin.size; tsuWin.enable = MV_TRUE; tsuWin.target = tsuAddrDecPrioTap[winPrioIndex]; if(MV_OK != mvTsuWinSet(winNum, &tsuWin)) { mvOsPrintf("mvTsuWinInit: ERR. mvTsuWinSet failed winNum=%d\n", winNum); return MV_ERROR; } winNum++; } winPrioIndex ++; } return MV_OK; }
/******************************************************************************* * mvTsuWinSet * * DESCRIPTION: * This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) * address window, also known as address decode window. * After setting this target window, the TSU will be able to access the * target within the address window. * * INPUT: * winNum - TSU to target address decode window number. * pAddrDecWin - TSU target window data structure. * * OUTPUT: * None. * * RETURN: * MV_ERROR - if address window overlapps with other address decode * windows. * MV_BAD_PARAM - if base address is invalid parameter or target is * unknown. * *******************************************************************************/ MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin) { MV_TARGET_ATTRIB targetAttribs; MV_DEC_REGS decRegs; /* Parameter checking */ if(winNum >= TSU_MAX_DECODE_WIN) { mvOsPrintf("mvTsuWinSet: ERR. Invalid win num %d\n",winNum); return MV_BAD_PARAM; } /* Check if the requested window overlapps with current windows */ if(MV_TRUE == tsuWinOverlapDetect(winNum, &pAddrDecWin->addrWin)) { mvOsPrintf("mvTsuWinSet: ERR. Window %d overlap\n", winNum); return MV_ERROR; } /* check if address is aligned to the size */ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow,pAddrDecWin->addrWin.size)) { mvOsPrintf("mvTsuWinSet: Error setting TSU window %d to target " "%s.\nAddress 0x%08x is unaligned to size 0x%x.\n", winNum, mvCtrlTargetNameGet(pAddrDecWin->target), pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size); return MV_ERROR; } decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum)); decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)); if(MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs)) { mvOsPrintf("mvTsuWinSet: mvCtrlAddrDecToReg Failed\n"); return MV_ERROR; } mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs); /* set attributes */ decRegs.sizeReg &= ~TSU_WIN_CTRL_ATTR_MASK; decRegs.sizeReg |= targetAttribs.attrib << TSU_WIN_CTRL_ATTR_OFFS; /* set target ID */ decRegs.sizeReg &= ~TSU_WIN_CTRL_TARGET_MASK; decRegs.sizeReg |= targetAttribs.targetId << TSU_WIN_CTRL_TARGET_OFFS; /* for the safe side we disable the window before writing the new */ /* values */ mvTsuWinEnable(winNum, MV_FALSE); MV_REG_WRITE(MV_TSU_WIN_CTRL_REG(winNum),decRegs.sizeReg); /* Write to address decode Size Register */ MV_REG_WRITE(MV_TSU_WIN_BASE_REG(winNum), decRegs.baseReg); /* Enable address decode target window */ if(pAddrDecWin->enable == MV_TRUE) { mvTsuWinEnable(winNum,MV_TRUE); } return MV_OK; }