/** * Copyright (C) 2006-2014 Ikanos Communications. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(CONFIG_FUSIV_VX585) #include #endif /* CONFIG_FUSIV_VX585 */ #if defined(CONFIG_FUSIV_VX185) #include #include #endif /* CONFIG_FUSIV_VX185 */ #if defined(CONFIG_FUSIV_VX585) #include #endif #if defined(CONFIG_FUSIV_VX585) #define GCMP_BASE_ADDR 0x19900000 #define GCMP_ADDRSPACE_SZ ( 256 * 1024) extern int gcmp_probe(unsigned long addr, unsigned long size); phys_t mips_cpc_default_phys_base(void); #endif /* CONFIG_FUSIV_VX585 */ //AVMbk unsigned int xtensa_mem_start = 0; unsigned int xtensa_mem_size = 0; #ifdef CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY unsigned int wlan_mem_start = 0; #endif //end AVMbk static unsigned int fw3_save[8]; int board_memsize = 0; int board_flash_start, board_flash_size; extern int plat_setup(void); void __init prom_init(void) { char *arg_env = NULL; int argc = fw_arg0; char **arg = (char **) (fw_arg1); int i; prom_printf("prom_init()\n"); arcs_cmdline[0] = '\0'; env_init((int*)fw_arg2, ENV_LOCATION_PHY_RAM); if((arg_env = prom_getenv("memsize")) != NULL) { board_memsize = simple_strtoul((const char*)arg_env, NULL, 0); board_memsize = board_memsize & 0x1FFFFFFF; #ifdef CONFIG_FUSIV_VX185 prom_printf("memsize board_memsize = %d\n",board_memsize); #else printk("memsize board_memsize = %d\n",board_memsize); #endif #if defined(CONFIG_FUSIV_KERNEL_BME_DRIVER_VX180_MODULE) || defined(CONFIG_FUSIV_KERNEL_BME_DRIVER_VX180) { #ifdef CONFIG_FUSIV_VX185 volatile scu_reg_t *scu = scu_regs; xtensa_mem_start = scu->bme_map0 & 0x1FFFFFFF; xtensa_mem_size = 8 << 20; //((psb_value << 16) | 0xFFFF) + 1; prom_printf("scu->bme_map0 = 0x%08x scu->bme_mask0 = %08x memsize = 0x%08x xtensa_mem_start = 0x%08x xtensa_mem_size 0x%08x\n", scu->bme_map0, scu->bme_mask0, board_memsize, xtensa_mem_start, xtensa_mem_size); #else /*CONFIG_FUSIV_VX185*/ #define PSB_CTL 0xb90000EC unsigned int psb_value = *(volatile unsigned int *)PSB_CTL; xtensa_mem_start = psb_value & 0x1FFF0000; xtensa_mem_size = ((psb_value << 16) | 0xFFFF) + 1; printk("psb_value = 0x%08x memsize = 0x%08x xtensa_mem_start = 0x%08x xtensa_mem_size 0x%08x\n", psb_value, board_memsize, xtensa_mem_start, xtensa_mem_size); #endif if(xtensa_mem_start + xtensa_mem_size > board_memsize) { panic("xtensa memory not in avalible memory space, update boot loader\n"); } } #ifdef CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY wlan_mem_start = (xtensa_mem_start - (CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY_SIZE << 10)) & PAGE_MASK; #ifdef CONFIG_FUSIV_VX185 prom_printf("wlan_mem_start = 0x%08x\n", wlan_mem_start); #else printk("wlan_mem_start = 0x%08x\n", wlan_mem_start); #endif #endif #else board_memsize = simple_strtoul((const char*)arg_env, NULL, 0); #ifdef CONFIG_FUSIV_VX185 prom_printf("memsize board_memsize = %d\n",board_memsize); #else printk("memsize board_memsize = %d\n",board_memsize); #endif #endif } for(i = 1; i < argc; i++){ if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= sizeof(arcs_cmdline)) break; strcat(arcs_cmdline, arg[i]); strcat(arcs_cmdline, " "); } #ifdef CONFIG_FUSIV_VX185 if((arg_env = prom_getenv("kernel_args")) != NULL){ strcat(arcs_cmdline, arg_env); strcat(arcs_cmdline, " "); } if((arg_env = prom_getenv("kernel_args1")) != NULL){ strcat(arcs_cmdline, arg_env); strcat(arcs_cmdline, " "); } #else if((arg_env = prom_getenv("flashsize")) != NULL) { char tmp_buf[20]; board_flash_size = simple_strtoul((const char*)arg_env, NULL, 16); printk("board_flash_size 0x%08x\n",board_flash_size); snprintf(tmp_buf, 20, "nor_size=%u ", board_flash_size); strcat(arcs_cmdline, (const char*)tmp_buf); strcat(arcs_cmdline, "nand_size=512MB "); } #endif memcpy(fw3_save, (const void *)fw_arg3, sizeof(fw3_save)); /* anyone need this ? , OEM board parameters */ //mips_machgroup = 0x1234; /* TODO: Need to understand the reason for this dummy value -- VB */ mips_machtype = 0x5678; #if defined(CONFIG_FUSIV_KERNEL_BME_DRIVER_VX180_MODULE) || defined(CONFIG_FUSIV_KERNEL_BME_DRIVER_VX180) /* Since smartcpe/insight feature is enabled by default in the BME firmware, the default memory requirement is set to 16MB * even if smartcpe/insight feature is disabled on the Host */ #if defined(CONFIG_FUSIV_VX185) //#ifdef CONFIG_FUSIV_KERNEL_SMCPE_MODULE scu_regs->cmips_map0 = 0xaf000000; #else // defined(CONFIG_FUSIV_VX185) // scu_regs->bme_map0 = 0xaf000000 ; // printk("BMIPS MAP0:0x%x\n",scu_regs->bme_map0); /* Check the DDR Controller setting if it configured in 32-bit or 16-bit DDR mode and appropriately configure the BME memory map */ if (*(volatile unsigned int *)(0xb9100050) == 0x16){ *(volatile unsigned int *)(0xb9000374) = 0x07000000; /* 128 MB */ } else if (*(volatile unsigned int *)(0xb9100050) == 0x14){ *(volatile unsigned int *)(0xb9000374) = 0x0f000000; /* 256 MB */ } printk("BMIPS MAP0:0x%x\n", *(volatile unsigned int *)(0xb9000374)); #endif // defined(CONFIG_FUSIV_VX185) #ifdef CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY add_memory_region(0, wlan_mem_start, BOOT_MEM_RAM); #else // CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY add_memory_region(0, xtensa_mem_start, BOOT_MEM_RAM); #endif // CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY if(xtensa_mem_start + xtensa_mem_size < board_memsize) { add_memory_region(xtensa_mem_start + xtensa_mem_size, board_memsize - (xtensa_mem_start + xtensa_mem_size), BOOT_MEM_RAM); /*--- normal RAM ---*/ } #else // defined(CONFIG_FUSIV_KERNEL_BME_DRIVER_VX180_MODULE) || defined(CONFIG_FUSIV_KERNEL_BME_DRIVER_VX180) board_memsize=board_memsize - (16 << 20); //reserve 16MB for VDSL BME add_memory_region(0, board_memsize, BOOT_MEM_RAM); #endif // defined(CONFIG_FUSIV_KERNEL_BME_DRIVER_VX180_MODULE) || defined(CONFIG_FUSIV_KERNEL_BME_DRIVER_VX180) #if defined (CONFIG_FUSIV_VX585) /* TODO: Can gcmp_probe fail? If yes, then what is to be done? -- VB */ gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); mips_cpc_probe(); #endif /* CONFIG_FUSIV_VX585 */ change_c0_status(ST0_BEV, 0); plat_setup(); } void __init prom_free_prom_memory(void) { } #if defined (CONFIG_FUSIV_VX585) phys_t mips_cpc_default_phys_base(void) { return 0x19960000; } #endif /* CONFIG_FUSIV_VX585 */ /*TODO: board_memsize is not used anywhere except this file and drivers/bmedriver/bmedriver.c. * but bmedriver is not doing anything with it -- VB */ EXPORT_SYMBOL(board_memsize); #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; } #endif static 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); #ifdef CONFIG_AVM_ARCH_STATIC_WLAN_MEMORY EXPORT_SYMBOL(prom_wlan_get_base_memory); #endif //AVMbk EXPORT_SYMBOL(xtensa_mem_start); EXPORT_SYMBOL(xtensa_mem_size); //end AVMbk