/******************************************************************************* * mvCpuIfTargetWinGet - Get CPU-to-peripheral target address window * * DESCRIPTION: * Get the CPU peripheral target address window. * * INPUT: * target - Peripheral target enumerator * * OUTPUT: * pAddrDecWin - CPU target window information data structure. * * RETURN: * MV_OK if target exist, MV_ERROR otherwise. * *******************************************************************************/ MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin) { MV_U32 winNum=0xffffffff; MV_AHB_TO_MBUS_DEC_WIN decWin; MV_DRAM_DEC_WIN addrDecWin; target = MV_CHANGE_BOOT_CS(target); /* Check parameters */ if (target >= MAX_TARGETS) { mvOsPrintf("mvCpuIfTargetWinGet: target %d is illegal\n", target); return MV_ERROR; } if (MV_TARGET_IS_DRAM(target)) { if (mvDramIfWinGet(target,&addrDecWin) != MV_OK) { mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n", target); return MV_ERROR; } /* copy relevant data to MV_CPU_DEC_WIN structure */ pAddrDecWin->addrWin.baseLow = addrDecWin.addrWin.baseLow; pAddrDecWin->addrWin.baseHigh = addrDecWin.addrWin.baseHigh; pAddrDecWin->addrWin.size = addrDecWin.addrWin.size; pAddrDecWin->enable = addrDecWin.enable; pAddrDecWin->winNum = 0xffffffff; } else { /* get the Window number associated with this target */ winNum = mvAhbToMbusWinTargetGet(target); if (winNum >= MAX_AHB_TO_MBUS_WINS) { return MV_NO_SUCH; } if (mvAhbToMbusWinGet(winNum , &decWin) != MV_OK) { mvOsPrintf("%s: mvAhbToMbusWinGet Failed at winNum = %d\n", __FUNCTION__, winNum); return MV_ERROR; } /* copy relevant data to MV_CPU_DEC_WIN structure */ pAddrDecWin->addrWin.baseLow = decWin.addrWin.baseLow; pAddrDecWin->addrWin.baseHigh = decWin.addrWin.baseHigh; pAddrDecWin->addrWin.size = decWin.addrWin.size; pAddrDecWin->enable = decWin.enable; pAddrDecWin->winNum = winNum; } return MV_OK; }
/******************************************************************************* * mvDramIfBankSizeGet - Get DRAM interface bank size. * * DESCRIPTION: * This function returns the size of a given DRAM bank. * * INPUT: * bankNum - Bank number. * * OUTPUT: * None. * * RETURN: * DRAM bank size. If bank is disabled the function return '0'. In case * or paramter is invalid, the function returns -1. * *******************************************************************************/ MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum) { MV_DRAM_DEC_WIN addrDecWin; /* Check parameters */ if (!MV_TARGET_IS_DRAM(bankNum)) { mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum); return -1; } /* Get window parameters */ if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin)) { mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n"); return -1; } if (MV_TRUE == addrDecWin.enable) { return addrDecWin.addrWin.size; } else { return 0; } }
/******************************************************************************* * mvDramIfWinEnable - Enable/Disable SDRAM address decode window * * DESCRIPTION: * This function enable/Disable SDRAM address decode window. * * INPUT: * target - System target. Use only SDRAM targets. * * OUTPUT: * None. * * RETURN: * MV_ERROR in case function parameter are invalid, MV_OK otherewise. * *******************************************************************************/ MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable) { MV_DRAM_DEC_WIN addrDecWin; /* Check parameters */ if (!MV_TARGET_IS_DRAM(target)) { mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target); return MV_ERROR; } if (enable == MV_TRUE) { /* First check for overlap with other enabled windows */ if (MV_OK != mvDramIfWinGet(target, &addrDecWin)) { mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n", target); return MV_ERROR; } /* Check for overlapping */ if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin))) { /* No Overlap. Enable address decode winNum window */ MV_REG_BIT_SET(SDRAM_SIZE_REG(target), SCSR_WIN_EN); } else { /* Overlap detected */ mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n", target); return MV_ERROR; } } else { /* Disable address decode winNum window */ MV_REG_BIT_RESET(SDRAM_SIZE_REG(target), SCSR_WIN_EN); } return MV_OK; }
/******************************************************************************* * sdramIfWinOverlap - Check if an address window overlap an SDRAM address window * * DESCRIPTION: * This function scan each SDRAM address decode window to test if it * overlapps the given address windoow * * INPUT: * target - SDRAM target where the function skips checking. * pAddrDecWin - The tested address window for overlapping with * SDRAM windows. * * OUTPUT: * None. * * RETURN: * MV_TRUE if the given address window overlaps any enabled address * decode map, MV_FALSE otherwise. * *******************************************************************************/ static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin) { MV_TARGET targetNum; MV_DRAM_DEC_WIN addrDecWin; for(targetNum = SDRAM_CS0; targetNum < SDRAM_CS3+1 ; targetNum++) { /* don't check our winNum or illegal targets */ if (targetNum == target) { continue; } /* Get window parameters */ if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin)) { mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n"); return MV_ERROR; } /* Do not check disabled windows */ if (MV_FALSE == addrDecWin.enable) { continue; } if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin)) { mvOsPrintf( "sdramIfWinOverlap: Required target %d overlap winNum %d\n", target, targetNum); return MV_TRUE; } } return MV_FALSE; }
/***************************************************************************** * UART ****************************************************************************/ static struct resource mv_uart_resources[] = { { .start = PORT0_BASE, .end = PORT0_BASE + 0xff, .flags = IORESOURCE_MEM, }, { .start = IRQ_UART0, .end = IRQ_UART0, .flags = IORESOURCE_IRQ, }, { .start = PORT1_BASE, .end = PORT1_BASE + 0xff, .flags = IORESOURCE_MEM, }, { .start = IRQ_UART1, .end = IRQ_UART1, .flags = IORESOURCE_IRQ, }, }; static struct plat_serial8250_port mv_uart_data[] = { { .mapbase = PORT0_BASE, .membase = (char *)PORT0_BASE, .irq = IRQ_UART0, .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, }, { .mapbase = PORT1_BASE, .membase = (char *)PORT1_BASE, .irq = IRQ_UART1, .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, }, { }, }; static struct platform_device mv_uart = { .name = "serial8250", .id = PLAT8250_DEV_PLATFORM, .dev = { .platform_data = mv_uart_data, }, .num_resources = ARRAY_SIZE(mv_uart_resources), .resource = mv_uart_resources, }; static void serial_initialize(void) { mv_uart_data[0].uartclk = mv_uart_data[1].uartclk = mvTclk; platform_device_register(&mv_uart); } static void __init mv_vfp_init(void) { #if defined CONFIG_VFP_FASTVFP printk("VFP initialized to Run Fast Mode.\n"); #endif } #if defined(MV_88F6183) #ifdef CONFIG_MV_INCLUDE_AUDIO typedef struct { unsigned int base; unsigned int size; } _audio_mem_info; typedef struct { u32 spdif_rec; u32 spdif_play; u32 i2s_rec; u32 i2s_play; _audio_mem_info mem_array[MV_DRAM_MAX_CS + 1]; } _audio_info; _audio_info audio_info = {1, 1, 1, 1}; static struct resource mv_snd_resources[] = { [0] = { .start = INTER_REGS_BASE + AUDIO_REG_BASE, .end = INTER_REGS_BASE + AUDIO_REG_BASE + SZ_16K -1, .flags = IORESOURCE_MEM, }, [1] = { .start = IRQ_AUDIO_INT, .end = IRQ_AUDIO_INT, .flags = IORESOURCE_IRQ, }, [2] = { .start = NR_IRQS, /* should obtained from board information*/ .end = NR_IRQS, /* should obtained from board information */ .flags = IORESOURCE_IRQ, } }; static u64 mv_snd_dmamask = 0xFFFFFFFFUL; static struct platform_device mv_snd_device = { .name = "mv88fx_snd", .id = -1, .dev = { .dma_mask = &mv_snd_dmamask, .coherent_dma_mask = 0xFFFFFFFF, .platform_data = &audio_info, }, .num_resources = ARRAY_SIZE(mv_snd_resources), .resource = mv_snd_resources, }; #endif /* #ifdef CONFIG_MV_INCLUDE_AUDIO */ #ifdef CONFIG_MV_INCLUDE_SDIO static struct resource mvsdmmc_resources[] = { [0] = { .start = INTER_REGS_BASE + 0x80000, .end = INTER_REGS_BASE + 0x80000 + SZ_1K -1, .flags = IORESOURCE_MEM, }, [1] = { .start = SDIO_IRQ_NUM, .end = SDIO_IRQ_NUM, .flags = IORESOURCE_IRQ, }, [2] = { .start = NR_IRQS, /* should obtained from board information*/ .end = NR_IRQS, /* should obtained from board information */ .flags = IORESOURCE_IRQ, } }; static u64 mvsdmmc_dmamask = 0xffffffffUL; static struct platform_device mvsdmmc_device = { .name = "mvsdmmc", .id = -1, .dev = { .dma_mask = &mvsdmmc_dmamask, .coherent_dma_mask = 0xffffffff, }, .num_resources = ARRAY_SIZE(mvsdmmc_resources), .resource = mvsdmmc_resources, }; #endif /* CONFIG_MV_INCLUDE_SDIO */ static struct platform_device *devices[] __initdata = { #ifdef CONFIG_MV_INCLUDE_AUDIO &mv_snd_device, #endif #ifdef CONFIG_MV_INCLUDE_SDIO &mvsdmmc_device, #endif NULL }; #endif /* #if defined(MV_88F6183) */ static void __init mv_init(void) { unsigned int temp; /* init the Board environment */ if (mvBoardIdGet() != RD_88F6082_MICRO_DAS_NAS) /* excluded for HDD power problem - to be fixed */ mvBoardEnvInit(); /* init the controller environment */ if( mvCtrlEnvInit() ) { printk( "Controller env initialization failed.\n" ); return; } if(mvBoardIdGet() == RD_88F5181_POS_NAS) { temp = MV_REG_READ(GPP_DATA_OUT_REG(0)); temp &= ~(1 << 0x5); /* for host mode should be set to 0 */ if(!mvIsUsbHost) { temp |= (1 << 0x5); } MV_REG_WRITE(GPP_DATA_OUT_REG(0), temp); } /* Init the CPU windows setting and the access protection windows. */ if( mvCpuIfInit(mv_sys_map()) ) { printk( "Cpu Interface initialization failed.\n" ); return; } /* Init Tclk & SysClk */ mvTclk = mvBoardTclkGet(); mvSysclk = mvBoardSysClkGet(); printk("Sys Clk = %d, Tclk = %d\n",mvSysclk ,mvTclk ); if ((mvCtrlModelGet() == MV_5281_DEV_ID) || (mvCtrlModelGet() == MV_1281_DEV_ID) || (mvCtrlModelGet() == MV_6183_DEV_ID)) mv_orion_ver = MV_ORION2; /* Orion II */ else mv_orion_ver = MV_ORION1; /* Orion I */ /* Implement workaround for FEr# CPU-C16: Wait for interrupt command */ /* is not processed properly, the workaround is not to use this command */ /* the erratum is relevant for 5281 devices with revision less than C0 */ if((mvCtrlModelGet() == MV_5281_DEV_ID) && (mvCtrlRevGet() < MV_5281_C0_REV)) { support_wait_for_interrupt = 0; } #ifdef CONFIG_JTAG_DEBUG support_wait_for_interrupt = 0; /* for Lauterbach */ #endif mv_vfp_init(); elf_hwcap &= ~HWCAP_JAVA; serial_initialize(); /* At this point, the CPU windows are configured according to default definitions in mvSysHwConfig.h */ /* and cpuAddrWinMap table in mvCpuIf.c. Now it's time to change defaults for each platform. */ mvCpuIfAddDecShow(); #if defined(CONFIG_MTD_PHYSMAP) mv_mtd_initialize(); #endif print_board_info(); #ifdef CONFIG_MV_INCLUDE_IDMA mvDmaInit(); #endif #if defined(MV_88F6183) #ifdef CONFIG_MV_INCLUDE_SDIO mvsdmmc_resources[2].end = mvBoardSDIOGpioPinGet() + IRQ_GPP_START; mvsdmmc_resources[2].start = mvBoardSDIOGpioPinGet() + IRQ_GPP_START; irq_int_type[mvBoardSDIOGpioPinGet()] = GPP_IRQ_TYPE_CHANGE_LEVEL; #endif /* CONFIG_MV_INCLUDE_SDIO */ #ifdef CONFIG_MV_INCLUDE_AUDIO for (temp=0 ; temp< MV_DRAM_MAX_CS; temp++) { MV_DRAM_DEC_WIN win; audio_info.mem_array[temp].base = 0; audio_info.mem_array[temp].size = 0; mvDramIfWinGet(SDRAM_CS0 + temp, &win); if (win.enable) { audio_info.mem_array[temp].base = win.addrWin.baseLow; audio_info.mem_array[temp].size = win.addrWin.size; } } #endif /* CONFIG_MV_INCLUDE_AUDIO */ if ((temp = ARRAY_SIZE(devices) - 1)) platform_add_devices(devices, temp); #endif /* MV_88F6183 */ return; }
/******************************************************************************* * mvCpuIfTargetWinGet - Get CPU-to-peripheral target address window * * DESCRIPTION: * Get the CPU peripheral target address window. * * INPUT: * target - Peripheral target enumerator * * OUTPUT: * pAddrDecWin - CPU target window information data structure. * * RETURN: * MV_OK if target exist, MV_ERROR otherwise. * *******************************************************************************/ MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin) { MV_U32 winNum = 0xffffffff; MV_AHB_TO_MBUS_DEC_WIN decWin; MV_DRAM_DEC_WIN addrDecWin; MV_U32 dramEn = 0; MV_TARGET i; target = MV_CHANGE_BOOT_CS(target); /* Check parameters */ if (target >= MAX_TARGETS) { mvOsPrintf("mvCpuIfTargetWinGet: target %d is illegal\n", target); return MV_ERROR; } if (MV_TARGET_IS_DRAM(target)) { /* If none of the DRAM windows is enabled, then the CPU DRAM ** access is going through the XBAR. */ for (i = SDRAM_CS0; i < SDRAM_CS3; i++) { if (mvDramIfWinGet(target, &addrDecWin) != MV_OK) { mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n", i); return MV_ERROR; } if (addrDecWin.enable == MV_TRUE) dramEn = 1; } } if ((dramEn == 1) && (MV_TARGET_IS_DRAM(target))) { if (mvDramIfWinGet(target, &addrDecWin) != MV_OK) { mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n", target); return MV_ERROR; } /* copy relevant data to MV_CPU_DEC_WIN structure */ pAddrDecWin->addrWin.baseLow = addrDecWin.addrWin.baseLow; pAddrDecWin->addrWin.baseHigh = addrDecWin.addrWin.baseHigh; pAddrDecWin->addrWin.size = addrDecWin.addrWin.size; pAddrDecWin->enable = addrDecWin.enable; pAddrDecWin->winNum = 0xffffffff; } else { /* get the Window number associated with this target */ winNum = mvAhbToMbusWinTargetGet(target); if (winNum >= MAX_AHB_TO_MBUS_WINS) return MV_NO_SUCH; if (mvAhbToMbusWinGet(winNum, &decWin) != MV_OK) { mvOsPrintf("%s: mvAhbToMbusWinGet Failed at winNum = %d\n", __func__, winNum); return MV_ERROR; } /* copy relevant data to MV_CPU_DEC_WIN structure */ pAddrDecWin->addrWin.baseLow = decWin.addrWin.baseLow; pAddrDecWin->addrWin.baseHigh = decWin.addrWin.baseHigh; pAddrDecWin->addrWin.size = decWin.addrWin.size; pAddrDecWin->enable = decWin.enable; pAddrDecWin->winNum = winNum; } return MV_OK; }