diff options
Diffstat (limited to 'board/evb64260/memory.c')
| -rw-r--r-- | board/evb64260/memory.c | 457 | 
1 files changed, 457 insertions, 0 deletions
| diff --git a/board/evb64260/memory.c b/board/evb64260/memory.c new file mode 100644 index 000000000..9d301f86c --- /dev/null +++ b/board/evb64260/memory.c @@ -0,0 +1,457 @@ +/* Memory.c - Memory mappings and remapping functions */ + +/* Copyright - Galileo technology. */ + +/* modified by Josh Huber to clean some things up, and + * fit it into the U-Boot framework */ + +#include <galileo/core.h> +#include <galileo/memory.h> + +/******************************************************************** +* memoryGetBankBaseAddress - Gets the base address of a memory bank +*      - If the memory bank size is 0 then this base address has no meaning!!! +* +* +* INPUTS:   MEMORY_BANK bank - The bank we ask for its base Address. +* OUTPUT:   N/A +* RETURNS: Memory bank base address. +*********************************************************************/ +static unsigned long memoryGetBankRegOffset(MEMORY_BANK bank) +{ +    switch (bank) +    { +	case BANK0: +	    return SCS_0_LOW_DECODE_ADDRESS; +	case BANK1: +	    return SCS_1_LOW_DECODE_ADDRESS; +	case BANK2: +	    return SCS_2_LOW_DECODE_ADDRESS; +	case BANK3: +	    return SCS_3_LOW_DECODE_ADDRESS; +    } +    return SCS_0_LOW_DECODE_ADDRESS; /* default value */ +} + +unsigned int memoryGetBankBaseAddress(MEMORY_BANK bank) +{ +    unsigned int base; +    unsigned int regOffset=memoryGetBankRegOffset(bank); + +    GT_REG_READ(regOffset,&base); +    base = base << 20; +    return base; +} + +/******************************************************************** +* memoryGetDeviceBaseAddress - Gets the base address of a device. +*           - If the device size is 0 then this base address has no meaning!!! +* +* +* INPUT:   DEVICE device - The device we ask for its base address. +* OUTPUT:   N/A +* RETURNS: Device base address. +*********************************************************************/ +static unsigned int memoryGetDeviceRegOffset(DEVICE device) +{ +    switch (device) +    { +	case DEVICE0: +	    return CS_0_LOW_DECODE_ADDRESS; +	case DEVICE1: +	    return CS_1_LOW_DECODE_ADDRESS; +	case DEVICE2: +	    return CS_2_LOW_DECODE_ADDRESS; +	case DEVICE3: +	    return CS_3_LOW_DECODE_ADDRESS; +	case BOOT_DEVICE: +	    return BOOTCS_LOW_DECODE_ADDRESS; +    } +    return CS_0_LOW_DECODE_ADDRESS; /* default value */ +} + +unsigned int memoryGetDeviceBaseAddress(DEVICE device) +{ +    unsigned int regBase; +    unsigned int regEnd; +    unsigned int regOffset=memoryGetDeviceRegOffset(device); + +    GT_REG_READ(regOffset, ®Base); +    GT_REG_READ(regOffset+8, ®End); + +    if(regEnd<=regBase) return 0xffffffff;	/* ERROR !!! */ + +    regBase = regBase << 20; +    return regBase; +} + +/******************************************************************** +* memoryGetBankSize - Returns the size of a memory bank. +* +* +* INPUT:    MEMORY_BANK bank - The bank we ask for its size. +* OUTPUT:   N/A +* RETURNS: Memory bank size. +*********************************************************************/ +unsigned int memoryGetBankSize(MEMORY_BANK bank) +{ +    unsigned int size,base; +    unsigned int highValue; +    unsigned int highAddress=memoryGetBankRegOffset(bank)+8; + +    base = memoryGetBankBaseAddress(bank); +    GT_REG_READ(highAddress,&highValue); +    highValue = (highValue + 1) << 20; +    if(base > highValue) +        size=0; +    else +        size = highValue - base; +    return size; +} + +/******************************************************************** +* memoryGetDeviceSize - Returns the size of a device memory space +* +* +* INPUT:    DEVICE device - The device we ask for its base address. +* OUTPUT:   N/A +* RETURNS:  Size of a device memory space. +*********************************************************************/ +unsigned int memoryGetDeviceSize(DEVICE device) +{ +    unsigned int size,base; +    unsigned int highValue; +    unsigned int highAddress=memoryGetDeviceRegOffset(device)+8; + +    base = memoryGetDeviceBaseAddress(device); +    GT_REG_READ(highAddress,&highValue); +    if (highValue == 0xfff) +    { +        size = (~base) + 1;	/* what the heck is this? */ +        return size; +    } +    else +        highValue = (highValue + 1) << 20; + +    if(base > highValue) +        size=0; +    else +        size = highValue - base; +    return size; +} + +/******************************************************************** +* memoryGetDeviceWidth - A device can be with: 1,2,4 or 8 Bytes data width. +*                  The width is determine in registers: 'Device Parameters' +*                  registers (0x45c, 0x460, 0x464, 0x468, 0x46c - for each device. +*                  at bits: [21:20]. +* +* INPUT:    DEVICE device - Device number +* OUTPUT:   N/A +* RETURNS:  Device width in Bytes (1,2,4 or 8), 0 if error had occurred. +*********************************************************************/ +unsigned int memoryGetDeviceWidth(DEVICE device) +{ +    unsigned int width; +    unsigned int regValue; + +    GT_REG_READ(DEVICE_BANK0PARAMETERS + device*4,®Value); +    width =  (regValue & 0x00300000) >> 20; +    switch (width) +    { +        case 0: +            return 1; +        case 1: +            return 2; +        case 2: +            return 4; +        case 3: +            return 8; +        default: +            return 0; +    } +} + +bool memoryMapBank(MEMORY_BANK bank, unsigned int bankBase,unsigned int bankLength) +{ +    unsigned int low=0xfff; +    unsigned int high=0x0; +    unsigned int regOffset=memoryGetBankRegOffset(bank); + +    if(bankLength!=0) { +	low = (bankBase >> 20) & 0xffff; +	high=((bankBase+bankLength)>>20)-1; +    } + +#ifdef DEBUG +    { +	unsigned int oldLow, oldHigh; +	GT_REG_READ(regOffset,&oldLow); +	GT_REG_READ(regOffset+8,&oldHigh); + +	printf("b%d %x-%x->%x-%x\n", bank, oldLow, oldHigh, low, high); +    } +#endif + +    GT_REG_WRITE(regOffset,low); +    GT_REG_WRITE(regOffset+8,high); + +    return true; +} +bool memoryMapDeviceSpace(DEVICE device, unsigned int deviceBase,unsigned int deviceLength) +{ +    /* TODO: what are appropriate "unmapped" values? */ +    unsigned int low=0xfff; +    unsigned int high=0x0; +    unsigned int regOffset=memoryGetDeviceRegOffset(device); + +    if(deviceLength != 0) { +	low=deviceBase>>20; +	high=((deviceBase+deviceLength)>>20)-1; +    } else { +	/* big problems in here... */ +	/* this will HANG */ +    } + +    GT_REG_WRITE(regOffset,low); +    GT_REG_WRITE(regOffset+8,high); + +    return true; +} + + +/******************************************************************** +* memoryMapInternalRegistersSpace - Sets new base address for the internals +*                                   registers. +* +* INPUTS:  unsigned int internalRegBase - The new base address. +* RETURNS: true on success, false on failure +*********************************************************************/ +bool memoryMapInternalRegistersSpace(unsigned int internalRegBase) +{ +    unsigned int currentValue; +    unsigned int internalValue = internalRegBase; + +    internalRegBase = (internalRegBase >> 20); +    GT_REG_READ(INTERNAL_SPACE_DECODE,¤tValue); +    internalRegBase = (currentValue & 0xffff0000) | internalRegBase; +    GT_REG_WRITE(INTERNAL_SPACE_DECODE,internalRegBase); +    INTERNAL_REG_BASE_ADDR = internalValue; +    return true; +} + +/******************************************************************** +* memoryGetInternalRegistersSpace - Gets internal registers Base Address. +* +* INPUTS:  unsigned int internalRegBase - The new base address. +* RETURNS: true on success, false on failure +*********************************************************************/ +unsigned int memoryGetInternalRegistersSpace(void) +{ +    return INTERNAL_REG_BASE_ADDR; +} + +/******************************************************************** +* memorySetProtectRegion - This function modifys one of the 8 regions with +*                          one of the three protection mode. +*                        - Be advised to check the spec before modifying them. +* +* +* Inputs: CPU_PROTECT_REGION - one of the eight regions. +*         CPU_ACCESS - general access. +*         CPU_WRITE - read only access. +*         CPU_CACHE_PROTECT - chache access. +*      we defining CPU because there is another protect from the pci SIDE. +* Returns: false if one of the parameters is wrong and true else +*********************************************************************/ +bool memorySetProtectRegion(MEMORY_PROTECT_REGION region, +                            MEMORY_ACCESS memAccess, +                            MEMORY_ACCESS_WRITE memWrite, +                            MEMORY_CACHE_PROTECT cacheProtection, +                            unsigned int baseAddress, +                            unsigned int regionLength) +{ +    unsigned int protectHigh = baseAddress + regionLength; + +    if(regionLength == 0) /* closing the region */ +    { +        GT_REG_WRITE(CPU_LOW_PROTECT_ADDRESS_0 + 0x10*region,0x0000ffff); +        GT_REG_WRITE(CPU_HIGH_PROTECT_ADDRESS_0 + 0x10*region,0); +        return true; +    } +    baseAddress =  (baseAddress & 0xfff00000) >> 20; +    baseAddress = baseAddress | memAccess << 16 |  memWrite << 17 +                     | cacheProtection << 18; +    GT_REG_WRITE(CPU_LOW_PROTECT_ADDRESS_0 + 0x10*region,baseAddress); +    protectHigh = (protectHigh & 0xfff00000) >> 20; +    GT_REG_WRITE(CPU_HIGH_PROTECT_ADDRESS_0 + 0x10*region,protectHigh - 1); +    return true; +} + +/******************************************************************** +* memorySetRegionSnoopMode - This function modifys one of the 4 regions which +*                            supports Cache Coherency. +* +* +* Inputs: SNOOP_REGION region - One of the four regions. +*         SNOOP_TYPE snoopType - There is four optional Types: +*                               1. No Snoop. +*                               2. Snoop to WT region. +*                               3. Snoop to WB region. +*                               4. Snoop & Invalidate to WB region. +*         unsigned int baseAddress - Base Address of this region. +*         unsigned int topAddress - Top Address of this region. +* Returns: false if one of the parameters is wrong and true else +*********************************************************************/ +bool memorySetRegionSnoopMode(MEMORY_SNOOP_REGION region, +                              MEMORY_SNOOP_TYPE snoopType, +                              unsigned int baseAddress, +                              unsigned int regionLength) +{ +    unsigned int snoopXbaseAddress; +    unsigned int snoopXtopAddress; +    unsigned int data; +    unsigned int snoopHigh = baseAddress + regionLength; + +    if( (region > MEM_SNOOP_REGION3) || (snoopType > MEM_SNOOP_WB) ) +        return false; +    snoopXbaseAddress = SNOOP_BASE_ADDRESS_0 + 0x10 * region; +    snoopXtopAddress = SNOOP_TOP_ADDRESS_0 + 0x10 * region; +    if(regionLength == 0) /* closing the region */ +    { +        GT_REG_WRITE(snoopXbaseAddress,0x0000ffff); +        GT_REG_WRITE(snoopXtopAddress,0); +        return true; +    } +    baseAddress = baseAddress & 0xffff0000; +    data = (baseAddress >> 16) | snoopType << 16; +    GT_REG_WRITE(snoopXbaseAddress,data); +    snoopHigh = (snoopHigh & 0xfff00000) >> 20; +    GT_REG_WRITE(snoopXtopAddress,snoopHigh - 1); +    return true; +} + +/******************************************************************** +* memoryRemapAddress - This fubction used for address remapping. +* +* +* Inputs: regOffset: remap register +*         remapValue : +* Returns: false if one of the parameters is erroneous,true otherwise. +*********************************************************************/ +bool memoryRemapAddress(unsigned int remapReg, unsigned int remapValue) +{ +    unsigned int valueForReg; +    valueForReg = (remapValue & 0xfff00000) >> 20; +    GT_REG_WRITE(remapReg, valueForReg); +    return true; +} + +/******************************************************************** +* memoryGetDeviceParam - This function used for getting device parameters from +*                        DEVICE BANK PARAMETERS REGISTER +* +* +* Inputs:        - deviceParam: STRUCT with paramiters for DEVICE BANK +*                  PARAMETERS REGISTER +*                - deviceNum : number of device +* Returns: false if one of the parameters is erroneous,true otherwise. +*********************************************************************/ +bool memoryGetDeviceParam(DEVICE_PARAM *deviceParam, DEVICE deviceNum) +{ +    unsigned int valueOfReg; +    unsigned int calcData; + +    GT_REG_READ(DEVICE_BANK0PARAMETERS + 4 * deviceNum, &valueOfReg); +    calcData = (0x7 & valueOfReg) + ((0x400000 & valueOfReg) >> 19); +    deviceParam -> turnOff = calcData;          /* Turn Off */ + +    calcData = ((0x78 & valueOfReg) >> 3) + ((0x800000 & valueOfReg) >> 19); +    deviceParam -> acc2First = calcData;        /* Access To First */ + +    calcData = ((0x780 & valueOfReg) >> 7) + ((0x1000000 & valueOfReg) >> 20); +    deviceParam -> acc2Next = calcData;         /* Access To Next */ + +    calcData = ((0x3800 & valueOfReg) >> 11) + ((0x2000000 & valueOfReg) >> 22); +    deviceParam -> ale2Wr = calcData;           /* Ale To Write */ + +    calcData = ((0x1c000 & valueOfReg) >> 14) + ((0x4000000 & valueOfReg) >> 23); +    deviceParam -> wrLow = calcData;            /* Write Active */ + +    calcData = ((0xe0000 & valueOfReg) >> 17) + ((0x8000000 & valueOfReg) >> 24); +    deviceParam -> wrHigh = calcData;           /* Write High */ + +    calcData = ((0x300000 & valueOfReg) >> 20); +    switch (calcData) +    { +    case 0: +        deviceParam -> deviceWidth = 1;         /* one Byte - 8-bit */ +        break; +    case 1: +        deviceParam -> deviceWidth = 2;         /* two Bytes - 16-bit */ +        break; +    case 2: +        deviceParam -> deviceWidth = 4;         /* four Bytes - 32-bit */ +        break; +    case 3: +        deviceParam -> deviceWidth = 8;         /* eight Bytes - 64-bit */ +        break; +    default: +        deviceParam -> deviceWidth = 1; +        break; +    } +    return true; +} + +/******************************************************************** +* memorySetDeviceParam - This function used for setting device parameters to +*                        DEVICE BANK PARAMETERS REGISTER +* +* +* Inputs:        - deviceParam: STRUCT for store paramiters from DEVICE BANK +*                  PARAMETERS REGISTER +*                - deviceNum : number of device +* Returns: false if one of the parameters is erroneous,true otherwise. +*********************************************************************/ +bool memorySetDeviceParam(DEVICE_PARAM *deviceParam, DEVICE deviceNum) +{ +    unsigned int valueForReg; + +    if((deviceParam -> turnOff >= 0xf) || (deviceParam -> acc2First >= 0x1f) || +       (deviceParam -> acc2Next >= 0x1f) || (deviceParam -> ale2Wr >= 0xf) || +        (deviceParam -> wrLow >= 0xf) || (deviceParam -> wrHigh >= 0xf)) +        return false; +    valueForReg = (((deviceParam -> turnOff) & 0x7) | +                   (((deviceParam -> turnOff) & 0x8) << 19) | +                   (((deviceParam -> acc2First) & 0xf) << 3) | +                   (((deviceParam -> acc2First) & 0x10) << 19) | +                   (((deviceParam -> acc2Next) & 0xf) << 7) | +                   (((deviceParam -> acc2Next) & 0x10) << 20) | +                   (((deviceParam -> ale2Wr) & 0x7) << 11) | +                   (((deviceParam -> ale2Wr) & 0xf) << 22) | +                   (((deviceParam -> wrLow) & 0x7) << 14) | +                   (((deviceParam -> wrLow) & 0xf) << 23) | +                   (((deviceParam -> wrHigh) & 0x7) << 17) | +                   (((deviceParam -> wrHigh) & 0xf) << 24)); +    /* insert the device width: */ +    switch(deviceParam->deviceWidth) +    { +    case 1: +        valueForReg = valueForReg | _8BIT; +        break; +    case 2: +        valueForReg = valueForReg | _16BIT; +        break; +    case 4: +        valueForReg = valueForReg | _32BIT; +        break; +    case 8: +        valueForReg = valueForReg | _64BIT; +        break; +    default: +        valueForReg = valueForReg | _8BIT; +        break; +    } +    GT_REG_WRITE(DEVICE_BANK0PARAMETERS + 4 * deviceNum, valueForReg); +    return true; +} |