/****************************************************************************** ** ** FILE NAME : ifxmips_prom.c ** PROJECT : IFX UEIP ** MODULES : BSP Basic ** ** DATE : 27 May 2009 ** AUTHOR : Xu Liang ** DESCRIPTION : common source file ** COPYRIGHT : Copyright (c) 2009 ** Infineon Technologies AG ** Am Campeon 1-12, 85579 Neubiberg, Germany ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** HISTORY ** $Date $Author $Comment ** 27 May 2009 Xu Liang The first UEIP release *******************************************************************************/ /* * PROM interface routines. */ #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY unsigned int wlan_mem_start = 0; #endif #include #include #include #include #include #include /* access to the ebu needs to be locked between different drivers */ DEFINE_SPINLOCK(ebu_lock); EXPORT_SYMBOL_GPL(ebu_lock); extern void prom_printf(const char * fmt, ...); extern void ifx_chip_setup(void); #ifdef CONFIG_AR9 extern void ifx_enhance_phy_clock(void); #endif static unsigned int fw3_save[8]; /* for Multithreading (APRP), vpe.c will use it */ static unsigned long physical_memsize = 0; static unsigned long cp0_memsize = 0; /* Glag to indicate whether the user put mem= in the command line */ #ifdef CONFIG_BLK_DEV_INITRD extern unsigned long initrd_start, initrd_end; #endif static unsigned int *chip_cp1_base = NULL; static unsigned int chip_cp1_size = 0; static struct callvectors *debug_vectors; void init_gpio_config(void); /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static unsigned int* ifx_get_cp1_base(void) { return chip_cp1_base; } EXPORT_SYMBOL(ifx_get_cp1_base); /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static unsigned int ifx_get_cp1_size(void) { return chip_cp1_size; } EXPORT_SYMBOL(ifx_get_cp1_size); // #define DEBUG_PROM /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void __init mips_nmi_setup(void) { void *base; extern char except_vec_nmi; base = cpu_has_veic ? (void *)(CAC_BASE + 0xa80) : (void *)(CAC_BASE + 0x380); memcpy(base, &except_vec_nmi, 0x80); flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ static void __init mips_ejtag_setup(void) { void *base; extern char except_vec_ejtag_debug; base = cpu_has_veic ? (void *)(CAC_BASE + 0xa00) : (void *)(CAC_BASE + 0x300); memcpy(base, &except_vec_ejtag_debug, 0x80); flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void __init prom_init(void) { int argc = fw_arg0; char **argv = (char **) fw_arg1; char **envp = (char **) fw_arg2; struct callvectors *cv = (struct callvectors *) fw_arg3; int i; #ifdef CONFIG_BLK_DEV_INITRD unsigned long rdstart = 0, rdsize = 0; #endif char *scr __attribute__((unused)); prom_printf("\nLantiq xDSL CPE " BOARD_SYSTEM_TYPE "\n"); ifx_chip_setup(); #ifdef CONFIG_USE_EMULATOR prom_printf("press any key to continue...\n"); while (((*IFX_ASC1_FSTAT)& 0x003F /* ASCFSTAT_RXFFLMASK */) == 0x00) ; #endif debug_vectors = cv; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) mips_machgroup = MACH_GROUP_IFX; #else mips_machtype = MACH_TYPE_IFX; #endif board_nmi_handler_setup = mips_nmi_setup; board_ejtag_handler_setup = mips_ejtag_setup; argv = (char **)KSEG1ADDR((unsigned long)argv); envp = (char **)KSEG1ADDR((unsigned long)envp); env_init((int*)envp, ENV_LOCATION_PHY_RAM); #ifdef CONFIG_AR9 ifx_enhance_phy_clock(); #endif #if !defined(CONFIG_AR10) /*--- Configure 25MHz Clk-Out on GPIO3 ---*/ ifx_gpio_register(IFX_GPIO_MODULE_EXTPHY_25MHZ_CLOCK); #endif memcpy(fw3_save, (const void *)fw_arg3, sizeof(fw3_save)); #ifdef DEBUG_PROM prom_printf("[%s %s %d]: argc %d, fw_arg0 %p, fw_arg1 %p, fw_arg2 %p fw_arg3 %p\n", __FILE__, __func__, __LINE__, argc, fw_arg0, fw_arg1, fw_arg2, fw_arg3); #endif /* arg[0] is "g", the rest is boot parameters */ arcs_cmdline[0] = '\0'; for (i = 1; i < argc; i++) { argv[i] = (char *)KSEG1ADDR(argv[i]); if (!argv[i]) continue; if (strlen(arcs_cmdline) + strlen(argv[i] + 1) >= sizeof(arcs_cmdline)) break; strcat(arcs_cmdline, argv[i]); strcat(arcs_cmdline, " "); } #ifdef DEBUG_PROM prom_printf("[%s %d]: arcs_cmdline - %s\n", __func__, __LINE__, arcs_cmdline); #endif { char *arg = NULL; cp0_memsize = 0; physical_memsize = 0; if((arg = prom_getenv("memsize")) != NULL) { physical_memsize = simple_strtoul(arg, NULL, 0); cp0_memsize = physical_memsize; } } if ( physical_memsize == 0 ) physical_memsize = cp0_memsize; else if ( cp0_memsize == 0 ) cp0_memsize = physical_memsize; max_pfn = PFN_DOWN(cp0_memsize); prom_printf("phym = %08lx, mem = %08lx, max_pfn = %08lx\n", physical_memsize, cp0_memsize, max_pfn); chip_cp1_base = (unsigned int*)(KSEG1 | cp0_memsize); chip_cp1_size = physical_memsize - cp0_memsize; prom_printf("Reserving memory for CP1 @0x%08x, size 0x%08x\n", (unsigned int)chip_cp1_base, chip_cp1_size); #ifdef CONFIG_BLK_DEV_INITRD /* u-boot always passes a non-zero start, but a 0 size if there */ /* is no ramdisk */ if (rdstart != 0 && rdsize != 0) { initrd_start = rdstart; initrd_end = rdstart + rdsize; } #endif /* Set the I/O base address */ set_io_port_base(0); /* Set memory regions */ ioport_resource.start = 0; /* Should be KSEGx ??? */ ioport_resource.end = 0xffffffff; /* Should be ??? */ #ifdef CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY wlan_mem_start = (cp0_memsize - (CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY_SIZE << 10)) & PAGE_MASK; printk("wlan_mem_start = 0x%08x\n", wlan_mem_start); add_memory_region(0, wlan_mem_start, BOOT_MEM_RAM); #else add_memory_region(0, cp0_memsize, BOOT_MEM_RAM); #endif #ifdef CONFIG_MIPS_CMP if (register_cmp_smp_ops()) panic("failed to register_cmp_smp_ops()"); #endif #ifdef CONFIG_MIPS_MT_SMP if (register_vsmp_smp_ops()) panic("failed to register_vsmp_smp_ops()"); #endif #ifdef CONFIG_MIPS_MT_SMTC register_smp_ops(&lsmtc_smp_ops); #endif #ifdef DEBUG_PROM prom_printf("[%s %s %d]: finished\n", __FILE__, __func__, __LINE__); #endif } void __init prom_free_prom_memory(void) { return; } const char *get_system_type(void) { return BOARD_SYSTEM_TYPE; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #ifdef CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int prom_wlan_get_base_memory(unsigned int *base, unsigned int *len) { if(base) *base = wlan_mem_start; if(len) *len = (CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY_SIZE << 10); return 0; } EXPORT_SYMBOL(prom_wlan_get_base_memory); #endif int __init prom_init_config(void) { unsigned int *config = (unsigned int*)fw3_save; int i; for (i = 0; i < 8; i++) { unsigned int c = config[i] & ((128 << 10) - 1); avm_prom_load_config_entry(c); } return 0; } late_initcall(prom_init_config);