/*********************************************************** * mv_eth_bm_init -- * * initialize BM pool to bu used by all ports * ***********************************************************/ static int mv_eth_bm_init(MV_VOID) { MV_STATUS status; unsigned char *pool_addr, *pool_addr_phys; mvBmInit(); pool_addr = mvOsIoUncachedMalloc(NULL, (sizeof(MV_U32) * EGIGA_BM_SIZE) + MV_BM_POOL_PTR_ALIGN, (MV_ULONG *)&pool_addr_phys, NULL); if (!pool_addr) { printf("Can't alloc %d bytes for pool #%d\n", sizeof(MV_U32) * EGIGA_BM_SIZE, EGIGA_BM_POOL); return -1; } if (MV_IS_NOT_ALIGN((MV_ULONG)pool_addr_phys, MV_BM_POOL_PTR_ALIGN)) pool_addr_phys = (unsigned char *)MV_ALIGN_UP((MV_ULONG)pool_addr_phys, MV_BM_POOL_PTR_ALIGN); status = mvBmPoolInit(EGIGA_BM_POOL, (MV_U32 *)pool_addr, (MV_ULONG)pool_addr_phys, EGIGA_BM_SIZE); if (status != MV_OK) { printf("Can't init #%d BM pool. status=%d\n", EGIGA_BM_POOL, status); return -1; } #ifdef CONFIG_MV_ETH_PP2_1 /* Disable BM priority */ mvPp2WrReg(MV_BM_PRIO_CTRL_REG, 0); #endif mvBmPoolControl(EGIGA_BM_POOL, MV_START); mvPp2BmPoolBufSizeSet(EGIGA_BM_POOL, RX_BUFFER_SIZE); return 0; }
/******************************************************************************* * mvAudioWinSet - Set AUDIO target address window * * 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 AUDIO will be able to access the * target within the address window. * * INPUT: * winNum - AUDIO target address decode window number. * pAddrDecWin - AUDIO 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 mvAudioWinSet(int unit, MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin) { MV_TARGET_ATTRIB targetAttribs; MV_DEC_REGS decRegs; /* Parameter checking */ if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN) { mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum); return MV_BAD_PARAM; } /* check if address is aligned to the size */ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size)) { mvOsPrintf("mvAudioWinSet:Error setting AUDIO 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 = 0; decRegs.sizeReg = 0; if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs)) { mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__); return MV_ERROR; } mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs); /* set attributes */ decRegs.sizeReg &= ~MV_AUDIO_WIN_ATTR_MASK; decRegs.sizeReg |= (targetAttribs.attrib << MV_AUDIO_WIN_ATTR_OFFSET); /* set target ID */ decRegs.sizeReg &= ~MV_AUDIO_WIN_TARGET_MASK; decRegs.sizeReg |= (targetAttribs.targetId << MV_AUDIO_WIN_TARGET_OFFSET); if (pAddrDecWin->enable == MV_TRUE) { decRegs.sizeReg |= MV_AUDIO_WIN_ENABLE_MASK; } else { decRegs.sizeReg &= ~MV_AUDIO_WIN_ENABLE_MASK; } MV_REG_WRITE( MV_AUDIO_WIN_CTRL_REG(unit, winNum), decRegs.sizeReg); MV_REG_WRITE( MV_AUDIO_WIN_BASE_REG(unit, winNum), decRegs.baseReg); 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; }
/******************************************************************************* * mvPexTargetWinRemap - Set PEX to target address window remap. * * DESCRIPTION: * The PEX interface supports remap of the BAR original address window. * For each BAR it is possible to define a remap address. For example * an address 0x12345678 that hits BAR 0x10 (SDRAM CS[0]) will be modified * according to remap register but will also be targeted to the * SDRAM CS[0]. * * INPUT: * pexIf - PEX interface number. * bar - Peripheral target enumerator accessed by slave. * pAddrWin - Address window to be checked. * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK * *******************************************************************************/ MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum, MV_PEX_REMAP_WIN *pAddrWin) { PEX_WIN_REG_INFO winRegInfo; /* Parameter checking */ if (pexIf >= mvCtrlPexMaxIfGet()) { mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n", pexIf); return MV_BAD_PARAM; } if (MV_PEX_WIN_DEFAULT == winNum) { mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n", winNum); return MV_BAD_PARAM; } if (MV_IS_NOT_ALIGN(pAddrWin->addrWin.baseLow, PXWRR_REMAP_ALIGNMENT)) { mvOsPrintf("mvPexTargetWinRemap: Error remap PEX interface %d win %d."\ "\nAddress 0x%08x is unaligned to size 0x%x.\n", pexIf, winNum, pAddrWin->addrWin.baseLow, pAddrWin->addrWin.size); return MV_ERROR; } pexWinRegInfoGet(pexIf, winNum, &winRegInfo); /* Set remap low register value */ MV_REG_WRITE(winRegInfo.remapLowRegOffs, pAddrWin->addrWin.baseLow); /* Skip base high settings if the BAR has only base low (32-bit) */ if (0 != winRegInfo.remapHighRegOffs) { MV_REG_WRITE(winRegInfo.remapHighRegOffs, pAddrWin->addrWin.baseHigh); } if (pAddrWin->enable == MV_TRUE) { MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN); } else { MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN); } return MV_OK; }
/******************************************************************************* * mvAudioWinWrite * * DESCRIPTION: * This function writes the address decoding registers according to the * given window configuration. * * INPUT: * unit - The Audio unit number to configure. * winNum - AUDIO target address decode window number. * pAddrDecWin - AUDIO target window data structure. * * OUTPUT: * None. * * RETURN: * MV_OK on success, * MV_BAD_PARAM if winNum is invalid. * MV_ERROR otherwise. * *******************************************************************************/ MV_STATUS mvAudioWinWrite(MV_U32 unit, MV_U32 winNum, MV_UNIT_WIN_INFO *pAddrDecWin) { MV_U32 baseReg; MV_U32 sizeReg; MV_U32 size; MV_U32 alignment; /* Parameter checking */ if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN) { mvOsPrintf("%s: ERR. Invalid win num %d\n", __func__, winNum); return MV_BAD_PARAM; } /* check if address is aligned to the size */ if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size)) { mvOsPrintf("mvAudioWinWrite:Error setting AUDIO window %d to " "Address 0x%08x is unaligned to size 0x%x.\n", winNum, pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size); return MV_ERROR; } size = pAddrDecWin->addrWin.size; if (!MV_IS_POWER_OF_2(size)) { mvOsPrintf("mvAudioWinWrite: Error setting AUDIO window %d. " "Window size is not a power to 2.", winNum); return MV_BAD_PARAM; } alignment = 1 << MV_AUDIO_WIN_SIZE_OFFSET; sizeReg = (size / alignment - 1) << MV_AUDIO_WIN_SIZE_OFFSET; /* BaseLow[31:16] => base register [31:16] */ baseReg = pAddrDecWin->addrWin.baseLow & MV_AUDIO_WIN_BASE_MASK; /* set attributes */ sizeReg &= ~MV_AUDIO_WIN_ATTR_MASK; sizeReg |= (pAddrDecWin->attrib << MV_AUDIO_WIN_ATTR_OFFSET); /* set target ID */ sizeReg &= ~MV_AUDIO_WIN_TARGET_MASK; sizeReg |= (pAddrDecWin->targetId << MV_AUDIO_WIN_TARGET_OFFSET); if (pAddrDecWin->enable == MV_TRUE) sizeReg |= MV_AUDIO_WIN_ENABLE_MASK; else sizeReg &= ~MV_AUDIO_WIN_ENABLE_MASK; MV_REG_WRITE(MV_AUDIO_WIN_CTRL_REG(unit, winNum), sizeReg); MV_REG_WRITE(MV_AUDIO_WIN_BASE_REG(unit, winNum), baseReg); return MV_OK; }
/******************************************************************************* * mvSataWinWrite - Set SATA target address window * * 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 SATA will be able to access the * target within the address window. * * INPUT: * winNum - SATA target address decode window number. * pAddrDecWin - SATA 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 mvSataWinWrite(MV_U32 dev, MV_U32 winNum, MV_UNIT_WIN_INFO *pAddrDecWin) { MV_U32 sizeReg, baseReg; /* Parameter checking */ if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN) { mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum); return MV_BAD_PARAM; } /* Check if the requested window overlapps with current windows */ if (MV_TRUE == sataWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin)) { mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum); return MV_ERROR; } /* check if address is aligned to the size */ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size)) { mvOsPrintf("mvSataWinSet:Error setting SATA 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 & MV_SATA_WIN_BASE_MASK; sizeReg = (pAddrDecWin->addrWin.size / MV_SATA_WIN_SIZE_ALIGN) - 1; sizeReg = sizeReg << MV_SATA_WIN_SIZE_OFFSET; /* set attributes */ sizeReg &= ~MV_SATA_WIN_ATTR_MASK; sizeReg |= (pAddrDecWin->attrib << MV_SATA_WIN_ATTR_OFFSET); /* set target ID */ sizeReg &= ~MV_SATA_WIN_TARGET_MASK; sizeReg |= (pAddrDecWin->targetId << MV_SATA_WIN_TARGET_OFFSET); if (pAddrDecWin->enable == MV_TRUE) sizeReg |= MV_SATA_WIN_ENABLE_MASK; else sizeReg &= ~MV_SATA_WIN_ENABLE_MASK; MV_REG_WRITE( MV_SATA_WIN_CTRL_REG(dev, winNum), sizeReg); MV_REG_WRITE( MV_SATA_WIN_BASE_REG(dev, winNum), baseReg); return MV_OK; }
/* Configure BM specific pool of "capacity" size. */ MV_STATUS mvBmPoolInit(int pool, MV_ULONG poolBase, int capacity) { /* validate poolId */ if ((pool < 0) || (pool >= MV_BM_POOLS)) { mvOsPrintf("bmPoolId = %d is invalid \n", pool); return MV_BAD_PARAM; } /* poolBase must be 4 byte aligned */ if (MV_IS_NOT_ALIGN(poolBase, MV_BM_POOL_PTR_ALIGN)) { mvOsPrintf("bmPoolBase = 0x%lx is not aligned 4 bytes\n", poolBase); return MV_NOT_ALIGNED; } /* Minimum pool capacity is 128 entries */ if (capacity < MV_BM_POOL_CAP_MIN) { mvOsPrintf("bmPool capacity = %d is smaller than minimum (%d)\n", capacity, MV_BM_POOL_CAP_MIN); return MV_BAD_SIZE; } /* Maximum pool capacity is 16K entries (2^14) */ if (capacity > MV_BM_POOL_CAP_MAX) { mvOsPrintf("bmPool capacity = %d is larger than maximum (%d)\n", capacity, MV_BM_POOL_CAP_MAX); return MV_BAD_SIZE; } /* Set poolBase address */ MV_REG_WRITE(MV_BM_POOL_BASE_REG(pool), poolBase); /* Set Read pointer to 0 */ MV_REG_WRITE(MV_BM_POOL_READ_PTR_REG(pool), 0); /* Set Read pointer to 0 */ MV_REG_WRITE(MV_BM_POOL_WRITE_PTR_REG(pool), 0); /* Set Pool size */ MV_REG_WRITE(MV_BM_POOL_SIZE_REG(pool), MV_BM_POOL_SIZE_VAL(capacity)); return MV_OK; }
/******************************************************************************* * mvDmaWinSet - Set DMA target address window * * 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 DMA will be able to access the * target within the address window. * * INPUT: * winNum - IDMA to target address decode window number. * pAddrDecWin - IDMA 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 mvDmaWinSet(MV_U32 winNum, MV_DMA_DEC_WIN *pAddrDecWin) { MV_TARGET_ATTRIB targetAttribs; MV_DEC_REGS decRegs; /* Parameter checking */ if (winNum >= IDMA_MAX_ADDR_DEC_WIN) { mvOsPrintf("mvDmaWinSet: ERR. Invalid win num %d\n",winNum); return MV_BAD_PARAM; } /* Check if the requested window overlapps with current windows */ if (MV_TRUE == dmaWinOverlapDetect(winNum, &pAddrDecWin->addrWin)) { mvOsPrintf("mvDmaWinSet: 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("mvDmaWinSet: Error setting IDMA 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(IDMA_BASE_ADDR_REG(winNum)); decRegs.sizeReg = MV_REG_READ(IDMA_SIZE_REG(winNum)); if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs)) { mvOsPrintf("mvDmaWinSet: mvCtrlAddrDecToReg Failed\n"); return MV_ERROR; } mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs); #if defined(MV_88F5182) || defined(MV_88F5181L) /* See BTS Nastore #19.*/ /* To access Tunit SRAM from IDMA use targetId = 0x5 */ /* To access Tunit SRAM from the CPU use targetId = 0x9 */ if(pAddrDecWin->target == CRYPT_ENG) targetAttribs.targetId = 5; #endif /* defined(MV_88F5182) || defined(MV_88F5181L) */ /* set attributes */ decRegs.baseReg &= ~IDMA_WIN_ATTR_MASK; decRegs.baseReg |= targetAttribs.attrib << IDMA_WIN_ATTR_OFFS; /* set target ID */ decRegs.baseReg &= ~IDMA_WIN_TARGET_MASK; decRegs.baseReg |= targetAttribs.targetId << IDMA_WIN_TARGET_OFFS; /* for the safe side we disable the window before writing the new values */ mvDmaWinEnable(winNum,MV_FALSE); MV_REG_WRITE(IDMA_BASE_ADDR_REG(winNum), decRegs.baseReg); /* Write to address decode Size Register */ MV_REG_WRITE(IDMA_SIZE_REG(winNum), decRegs.sizeReg); /* Enable address decode target window */ if (pAddrDecWin->enable == MV_TRUE) { mvDmaWinEnable(winNum, MV_TRUE); } 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; }
/******************************************************************************* * mvPp2WinWrite * * DESCRIPTION: * This function writes the address decoding registers according to the * given window configuration. * * INPUT: * unit - The Ethernet unit number to configure. * winNum - ETH target address decode window number. * pAddrDecWin - ETH target window data structure. * * OUTPUT: * None. * * RETURN: * MV_OK on success, * MV_BAD_PARAM if winNum is invalid. * MV_ERROR otherwise. * *******************************************************************************/ MV_STATUS mvPp2WinWrite(MV_U32 dummy/*backward compability*/, MV_U32 winNum, MV_UNIT_WIN_INFO *pAddrDecWin) { MV_U32 size, alignment; MV_U32 baseReg, sizeReg; /* Parameter checking */ if (winNum >= ETH_MAX_DECODE_WIN) { mvOsPrintf("mvPp2WinSet: ERR. Invalid win num %d\n", winNum); return MV_BAD_PARAM; } /* Check if the requested window overlapps with current windows */ if (MV_TRUE == ethWinOverlapDetect(winNum, &pAddrDecWin->addrWin)) { mvOsPrintf("mvPp2WinWrite: 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("mvPp2WinSet: Error setting Ethernet window %d.\n" "Address 0x%08x is unaligned to size 0x%x.\n", winNum, pAddrDecWin->addrWin.baseLow, (MV_U32)pAddrDecWin->addrWin.size); return MV_ERROR; } size = pAddrDecWin->addrWin.size; if (!MV_IS_POWER_OF_2(size)) { mvOsPrintf("mvPp2WinWrite: Error setting AUDIO window %d. " "Window size is not a power to 2.", winNum); return MV_BAD_PARAM; } baseReg = (pAddrDecWin->addrWin.baseLow & ETH_WIN_BASE_MASK); sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(winNum)); /* set size */ alignment = 1 << ETH_WIN_SIZE_OFFS; sizeReg &= ~ETH_WIN_SIZE_MASK; sizeReg |= (((size / alignment) - 1) << ETH_WIN_SIZE_OFFS); /* set attributes */ baseReg &= ~ETH_WIN_ATTR_MASK; baseReg |= pAddrDecWin->attrib << ETH_WIN_ATTR_OFFS; /* set target ID */ baseReg &= ~ETH_WIN_TARGET_MASK; baseReg |= pAddrDecWin->targetId << ETH_WIN_TARGET_OFFS; /* for the safe side we disable the window before writing the new values */ mvPp2WinEnable(0, winNum, MV_FALSE); mvPp2WrReg(ETH_WIN_BASE_REG(winNum), baseReg); /* Write to address decode Size Register */ mvPp2WrReg(ETH_WIN_SIZE_REG(winNum), sizeReg); /* Enable address decode target window */ if (pAddrDecWin->enable == MV_TRUE) mvPp2WinEnable(0, winNum, MV_TRUE); return MV_OK; }
/******************************************************************************* * mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window * * DESCRIPTION: * This function sets * address window, also known as address decode window. * A new address decode window is set for specified winNum address window. * If address decode window parameter structure enables the window, * the routine will also enable the winNum window, allowing CPU to access * the winNum window. * * INPUT: * winNum - Windows number. * pAddrDecWin - CPU winNum window data structure. * * OUTPUT: * N/A * * RETURN: * MV_OK if CPU winNum window was set correctly, MV_ERROR in case of * address window overlapps with other active CPU winNum window or * trying to assign 36bit base address while CPU does not support that. * The function returns MV_NOT_SUPPORTED, if the winNum is unsupported. * *******************************************************************************/ MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin) { MV_TARGET_ATTRIB targetAttribs; MV_DEC_REGS decRegs; /* Parameter checking */ if (winNum >= MAX_AHB_TO_MBUS_WINS) { mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum); return MV_NOT_SUPPORTED; } /* read base register*/ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) { decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum)); } else { decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG); } /* check if address is aligned to the size */ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size)) { mvOsPrintf("mvAhbToMbusWinSet:Error setting AHB to MBUS 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; } /* read control register*/ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) { decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum)); } if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs)) { mvOsPrintf("mvAhbToMbusWinSet:mvCtrlAddrDecToReg Failed\n"); return MV_ERROR; } /* enable\Disable */ if (MV_TRUE == pAddrDecWin->enable) { decRegs.sizeReg |= ATMWCR_WIN_ENABLE; } else { decRegs.sizeReg &= ~ATMWCR_WIN_ENABLE; } mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs); /* set attributes */ decRegs.sizeReg &= ~ATMWCR_WIN_ATTR_MASK; decRegs.sizeReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS; /* set target ID */ decRegs.sizeReg &= ~ATMWCR_WIN_TARGET_MASK; decRegs.sizeReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS; #if !defined(MV_RUN_FROM_FLASH) /* To be on the safe side we disable the window before writing the */ /* new values. */ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) { mvAhbToMbusWinEnable(winNum,MV_FALSE); } #endif /* 3) Write to address decode Base Address Register */ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) { MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg); } else { MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg); } /* Internal register space have no size */ /* register. Do not perform size register assigment for those targets */ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) { /* Write to address decode Size Register */ MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.sizeReg); } return MV_OK; }
/******************************************************************************* * mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window * * DESCRIPTION: * This function sets * address window, also known as address decode window. * A new address decode window is set for specified winNum address window. * If address decode window parameter structure enables the window, * the routine will also enable the winNum window, allowing CPU to access * the winNum window. * * INPUT: * winNum - Windows number. * pAddrDecWin - CPU winNum window data structure. * * OUTPUT: * N/A * * RETURN: * MV_OK if CPU winNum window was set correctly, MV_ERROR in case of * address window overlapps with other active CPU winNum window or * trying to assign 36bit base address while CPU does not support that. * The function returns MV_NOT_SUPPORTED, if the winNum is unsupported. * *******************************************************************************/ MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin) { MV_TARGET_ATTRIB targetAttribs; MV_DEC_REGS decRegs; MV_U32 sizeToReg; /* Parameter checking */ if (winNum >= MAX_AHB_TO_MBUS_WINS) { mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum); return MV_NOT_SUPPORTED; } /* check if address is aligned to the size */ if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size)) { mvOsPrintf("mvAhbToMbusWinSet:Error setting AHB to MBUS window %d to " "target %s.\nAddress 0x%08x is unaligned to size 0x%llx.\n", winNum, mvCtrlTargetNameGet(pAddrDecWin->target), pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size); return MV_ERROR; } /* Size parameter validity check. */ if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.size, ATMWCR_WIN_SIZE_ALIGNMENT)) { mvOsPrintf("mvAhbToMbusWinSet: Failed, size not aligned to 0x%x.\n", ATMWCR_WIN_SIZE_ALIGNMENT); return MV_BAD_PARAM; } /* Write to address decode Base Address Register */ decRegs.baseReg = (pAddrDecWin->addrWin.baseLow & ATMWBR_BASE_MASK); /* Get size register value according to window size */ sizeToReg = (pAddrDecWin->addrWin.size / ATMWCR_WIN_SIZE_ALIGNMENT) - 1; /* set size */ decRegs.ctrlReg = (sizeToReg << ATMWCR_WIN_SIZE_OFFS); /* enable\Disable */ if (MV_TRUE == pAddrDecWin->enable) decRegs.ctrlReg |= ATMWCR_WIN_ENABLE; else decRegs.ctrlReg &= ~ATMWCR_WIN_ENABLE; mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs); /* set attributes */ decRegs.ctrlReg &= ~ATMWCR_WIN_ATTR_MASK; decRegs.ctrlReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS; /* set target ID */ decRegs.ctrlReg &= ~ATMWCR_WIN_TARGET_MASK; decRegs.ctrlReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS; #if !defined(MV_RUN_FROM_FLASH) /* To be on the safe side we disable the window before writing the */ /* new values. */ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) mvAhbToMbusWinEnable(winNum, MV_FALSE); #endif /* 3) Write to address decode Base Address Register */ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg); else MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg); /* Internal register space have no size */ /* register. Do not perform size register assigment for those targets */ if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) { /* Write to address decode Size Register */ MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.ctrlReg); } return MV_OK; }
/******************************************************************************* * mvUsbWinSet - Set USB target address window * * 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 USB will be able to access the * target within the address window. * * INPUT: * winNum - USB target address decode window number. * pAddrDecWin - USB 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 mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin) { MV_DEC_WIN_PARAMS winParams; MV_U32 sizeReg, baseReg; /* Parameter checking */ if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN) { mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum); return MV_BAD_PARAM; } /* Check if the requested window overlapps with current windows */ if (MV_TRUE == usbWinOverlapDetect(dev, winNum, &pDecWin->addrWin)) { mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum); return MV_ERROR; } /* check if address is aligned to the size */ if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size)) { mvOsPrintf("mvUsbWinSet:Error setting USB window %d to "\ "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n", winNum, mvCtrlTargetNameGet(pDecWin->target), pDecWin->addrWin.baseLow, pDecWin->addrWin.size); return MV_ERROR; } if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams)) { mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__); return MV_ERROR; } /* set Size, Attributes and TargetID */ sizeReg = (((winParams.targetId << MV_USB_WIN_TARGET_OFFSET) & MV_USB_WIN_TARGET_MASK) | ((winParams.attrib << MV_USB_WIN_ATTR_OFFSET) & MV_USB_WIN_ATTR_MASK) | ((winParams.size << MV_USB_WIN_SIZE_OFFSET) & MV_USB_WIN_SIZE_MASK)); #if defined(MV645xx) || defined(MV646xx) /* If window is DRAM with HW cache coherency, make sure bit2 is set */ sizeReg &= ~MV_USB_WIN_BURST_WR_LIMIT_MASK; if((MV_TARGET_IS_DRAM(pDecWin->target)) && (pDecWin->addrWinAttr.cachePolicy != NO_COHERENCY)) { sizeReg |= MV_USB_WIN_BURST_WR_32BIT_LIMIT; } else { sizeReg |= MV_USB_WIN_BURST_WR_NO_LIMIT; } #endif /* MV645xx || MV646xx */ if (pDecWin->enable == MV_TRUE) { sizeReg |= MV_USB_WIN_ENABLE_MASK; } else { sizeReg &= ~MV_USB_WIN_ENABLE_MASK; } /* Update Base value */ baseReg = (winParams.baseAddr & MV_USB_WIN_BASE_MASK); MV_REG_WRITE( MV_USB_WIN_CTRL_REG(dev, winNum), sizeReg); MV_REG_WRITE( MV_USB_WIN_BASE_REG(dev, winNum), baseReg); return MV_OK; }
/******************************************************************************* * mvDramIfWinSet - Set DRAM interface address decode window * * DESCRIPTION: * This function sets DRAM interface address decode window. * * INPUT: * target - System target. Use only SDRAM targets. * pAddrDecWin - SDRAM address window structure. * * OUTPUT: * None * * RETURN: * MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK * otherwise. *******************************************************************************/ MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin) { MV_U32 baseReg=0,sizeReg=0; MV_U32 baseToReg=0 , sizeToReg=0; /* Check parameters */ if (!MV_TARGET_IS_DRAM(target)) { mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target); return MV_BAD_PARAM; } /* Check if the requested window overlaps with current enabled windows */ if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin)) { mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target); return MV_BAD_PARAM; } /* check if address is aligned to the size */ if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size)) { mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\ "\nAddress 0x%08x is unaligned to size 0x%x.\n", target, pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size); return MV_ERROR; } /* read base register*/ baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target)); /* read size register */ sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target)); /* BaseLow[31:16] => base register [31:16] */ baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK; /* Write to address decode Base Address Register */ baseReg &= ~SCBAR_BASE_MASK; baseReg |= baseToReg; /* Translate the given window size to register format */ sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT); /* Size parameter validity check. */ if (-1 == sizeToReg) { mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target); return MV_BAD_PARAM; } /* set size */ sizeReg &= ~SCSR_SIZE_MASK; /* Size is located at upper 16 bits */ sizeReg |= (sizeToReg << SCSR_SIZE_OFFS); /* enable/Disable */ if (MV_TRUE == pAddrDecWin->enable) { sizeReg |= SCSR_WIN_EN; } else { sizeReg &= ~SCSR_WIN_EN; } /* 3) Write to address decode Base Address Register */ MV_REG_WRITE(SDRAM_BASE_ADDR_REG(target), baseReg); /* Write to address decode Size Register */ MV_REG_WRITE(SDRAM_SIZE_REG(target), sizeReg); return MV_OK; }
/******************************************************************************* * mvUsbWinWrite - Set USB target address window * * 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 USB will be able to access the * target within the address window. * * INPUT: * winNum - USB target address decode window number. * pAddrDecWin - USB 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 mvUsbWinWrite(MV_U32 dev, MV_U32 winNum, MV_UNIT_WIN_INFO *pDecWin) { MV_U32 sizeReg, baseReg; MV_U32 size; /* Parameter checking */ if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN) { mvOsPrintf("%s: ERR. Invalid win num %d\n", __func__, winNum); return MV_BAD_PARAM; } /* Check if the requested window overlapps with current windows */ if (MV_TRUE == usbWinOverlapDetect(dev, winNum, &pDecWin->addrWin)) { mvOsPrintf("%s: ERR. Window %d overlap\n", __func__, winNum); return MV_ERROR; } /* check if address is aligned to the size */ if (MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size)) { mvOsPrintf("mvUsbWinWrite:Error setting USB window %d.\n" "Address 0x%08x is unaligned to size 0x%x.\n", winNum, pDecWin->addrWin.baseLow, pDecWin->addrWin.size); return MV_ERROR; } if (!MV_IS_POWER_OF_2(pDecWin->addrWin.size)) { mvOsPrintf("mvUsbWinWrite: Bad windows size.\n"); return MV_BAD_PARAM; } size = pDecWin->addrWin.size / MV_USB_WIN_SIZE_ALIGN - 1; /* set Size, Attributes and TargetID */ sizeReg = (((pDecWin->targetId << MV_USB_WIN_TARGET_OFFSET) & MV_USB_WIN_TARGET_MASK) | ((pDecWin->attrib << MV_USB_WIN_ATTR_OFFSET) & MV_USB_WIN_ATTR_MASK) | ((size << MV_USB_WIN_SIZE_OFFSET) & MV_USB_WIN_SIZE_MASK)); #if defined(MV645xx) || defined(MV646xx) /* If window is DRAM with HW cache coherency, make sure bit2 is set */ sizeReg &= ~MV_USB_WIN_BURST_WR_LIMIT_MASK; if ((MV_TARGET_IS_DRAM(pDecWin->target)) && (pDecWin->addrWinAttr.cachePolicy != NO_COHERENCY)) sizeReg |= MV_USB_WIN_BURST_WR_32BIT_LIMIT; else sizeReg |= MV_USB_WIN_BURST_WR_NO_LIMIT; #endif /* MV645xx || MV646xx */ if (pDecWin->enable == MV_TRUE) sizeReg |= MV_USB_WIN_ENABLE_MASK; else sizeReg &= ~MV_USB_WIN_ENABLE_MASK; /* Update Base value */ baseReg = (pDecWin->addrWin.baseLow & MV_USB_WIN_BASE_MASK); MV_REG_WRITE(MV_USB_WIN_CTRL_REG(dev, winNum), sizeReg); MV_REG_WRITE(MV_USB_WIN_BASE_REG(dev, winNum), baseReg); return MV_OK; }
* mvTdmWinSet - Set TDM target address window * * 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 TDM will be able to access the * target within the address window. * * INPUT: * winNum - TDM to target address decode window number. * pAddrDecWin - TDM 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 mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin) { MV_TARGET_ATTRIB targetAttribs; MV_DEC_REGS decRegs; MV_U32 ctrlReg = 0; /* Parameter checking */ if (winNum >= TDM_MBUS_MAX_WIN) { mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum); return MV_BAD_PARAM; } /* Check if the requested window overlapps with current windows */ if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin)) { mvOsPrintf("mvTdmWinSet: 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("mvTdmWinSet: Error setting TDM 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(TDM_WIN_BASE_REG(winNum)); decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS; if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs)) { mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n"); return MV_ERROR; } mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs); /* for the safe side we disable the window before writing the new values */ mvTdmWinEnable(winNum, MV_FALSE); ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS); ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS); ctrlReg |= (decRegs.sizeReg & TDM_WIN_SIZE_MASK); /* Write to address base and control registers */ MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg); MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg); /* Enable address decode target window */ if (pAddrDecWin->enable == MV_TRUE) { mvTdmWinEnable(winNum, MV_TRUE); } return MV_OK; }