/* * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * HISTORY * $Version $Date $Author $Comment * 2.0 07/05/09 Xu Liang * 1.0 19/07/07 Teh Kok How */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern unsigned int ifx_get_cpu_hz(void); extern void ifx_reboot_setup(void); #ifdef CONFIG_KGDB extern int kgdb_serial_init(void); #endif #ifdef CONFIG_MIPS_APSP_KSPD unsigned long cpu_khz; #endif void __init bus_error_init(void) { /* nothing */ } static inline long get_counter_resolution(void) { #if defined(CONFIG_DANUBE) || defined(CONFIG_AR9) || defined(CONFIG_VR9) || defined(CONFIG_AR10) volatile long res; __asm__ __volatile__( ".set push\n" ".set noreorder\n" ".set mips32r2\n" "rdhwr %0, $3\n" "ehb\n" ".set pop\n" : "=&r" (res) : /* no input */ : "memory"); instruction_hazard(); return res; #else return 2; #endif } void __init plat_time_init(void) { u32 resolution = get_counter_resolution(); mips_hpt_frequency = ifx_get_cpu_hz() / resolution; #ifdef CONFIG_USE_EMULATOR // we do some hacking here to give illusion we have a faster counter // frequency so that the time interrupt happends less frequently mips_hpt_frequency *= 25; #endif /*--- prom_printf("mips_hpt_frequency = %d, counter_resolution = %d\n", mips_hpt_frequency, resolution); ---*/ // timer interrupt is wired to IP7 // no matter what value is read by read_c0_intctl() cp0_compare_irq = 7; #ifdef CONFIG_MIPS_APSP_KSPD cpu_khz = ifx_get_cpu_hz() / 1000; #endif } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) /* * THe CPU counter for System timer, set to HZ * GPTU Timer 6 for high resolution timer, set to hr_time_resolution * Also misuse this routine to print out the CPU type and clock. */ void __init plat_timer_setup(struct irqaction *irq) { /* cpu counter for timer interrupts */ setup_irq(MIPS_CPU_TIMER_IRQ, irq); } #endif void __init device_tree_init(void) { return; } void __init plat_device_tree_setup(void) { struct boot_param_header *dtb; if (IS_ENABLED(CONFIG_AVM_ENHANCED)) { char *subrev_str; int subrev = 0; subrev_str = prom_getenv("HWSubRevision"); if (subrev_str) { if (sscanf(subrev_str, "%u", &subrev) != 1) subrev_str = NULL; } if (!subrev_str) { prom_printf("%s: Unable to read AVM hardware " "subrevision! Identity crisis... who am I?", __func__); } prom_printf("%s: AVM hardware subrevision %d\n", __func__, subrev); if (subrev > avm_subrev_max) { prom_printf("%s: Too many hardware subrevisions!\n", __func__); panic("%s: Too many hardware subrevisions!\n", __func__); } dtb = (struct boot_param_header *)avm_kernel_config_device_tree[subrev]; if(!dtb) { /* fallback auf nächst kleine SubRev */ int i; for(i = subrev - 1; i >= 0; i--){ if(avm_kernel_config_device_tree[i]){ dtb = (struct boot_param_header *) avm_kernel_config_device_tree[i]; prom_printf("%s: using Fallback device-tree of AVM hardware " "subrevision %d \n", __func__, i); break; } } } if (!dtb) { prom_printf("%s: Missing device-tree for AVM hardware " "subrevision %d\n", __func__, subrev); panic("%s: Missing device-tree for AVM hardware " "subrevision %d\n", __func__, subrev); } else { extern struct boot_param_header *initial_boot_params; initial_boot_params = dtb; prom_printf("DT: %02x %02x %02x %02x %02x %02x %02x %02x\n", ((unsigned char *)dtb)[0], ((unsigned char *)dtb)[1], ((unsigned char *)dtb)[2], ((unsigned char *)dtb)[3], ((unsigned char *)dtb)[4], ((unsigned char *)dtb)[5], ((unsigned char *)dtb)[6], ((unsigned char *)dtb)[7]); } } __dt_setup_arch(dtb); } void __init plat_mem_setup(void) { ifx_reboot_setup(); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) board_time_init = plat_time_init; #endif } int __init power_managment_setup(void) { ifx_chipid_t chipID; ifx_get_chipid(&chipID); /*--- prom_printf("[%s] reset 'DSL, DFE, AFE, VOICE, DSLTC, ARC'\n", __FUNCTION__); ---*/ ifx_rcu_rst(IFX_RCU_DOMAIN_DSLDFE, 0); ifx_rcu_rst(IFX_RCU_DOMAIN_DSLAFE, 0); ifx_rcu_rst(IFX_RCU_DOMAIN_VOICE, 0); ifx_rcu_rst(IFX_RCU_DOMAIN_DSLTC, 0); ifx_rcu_rst(IFX_RCU_DOMAIN_ARC, 0); #if defined(CONFIG_AR10) if (chipID.part_number == IFX_PARTNUM_ARX388) { /*--- prom_printf("[%s] reset 'LDO'\n", __FUNCTION__); ---*/ ifx_rcu_rst(IFX_RCU_DOMAIN_LDO, 0); } #else /*--- prom_printf("[%s] reset 'LDO'\n", __FUNCTION__); ---*/ ifx_rcu_rst(IFX_RCU_DOMAIN_LDO, 0); #endif /*--- prom_printf("[%s] power down 'PPE TC, PPE EMA, LEDC, DFEV1, DFEV0'\n", __FUNCTION__); ---*/ ifx_pmu_set(IFX_PMU_MODULE_PPE_TC, 0); ifx_pmu_set(IFX_PMU_MODULE_PPE_EMA, 0); ifx_pmu_set(IFX_PMU_MODULE_LEDC, 0); ifx_pmu_set(IFX_PMU_MODULE_DFEV1, 0); ifx_pmu_set(IFX_PMU_MODULE_DFEV0, 0); /*--- prom_printf("[%s] power down 'MSI1, PDI1 PCIE1 PCIE1_PHY'\n", __FUNCTION__); ---*/ ifx_pmu_set(IFX_PMU_MODULE_PDI1, 0); ifx_pmu_set(IFX_PMU_MODULE_MSI1, 0); ifx_pmu_set(IFX_PMU_MODULE_PCIE1_CTRL, 0); ifx_pmu_set(IFX_PMU_MODULE_PCIE1_PHY, 0); /*--- prom_printf("[%s] power down 'USB CTRL'\n", __FUNCTION__); ---*/ ifx_pmu_set(IFX_PMU_MODULE_USB_CTRL, IFX_PMU_DISABLE); ifx_pmu_set(IFX_PMU_MODULE_USB_PHY, IFX_PMU_DISABLE); ifx_pmu_set(IFX_PMU_MODULE_USB1_CTRL, IFX_PMU_DISABLE); #if ! defined(CONFIG_AR10) ifx_pmu_set(IFX_PMU_MODULE_USB1_PHY, IFX_PMU_DISABLE); #endif /*--- prom_printf("[%s] power down 'GPHY'\n", __FUNCTION__); ---*/ #if ! defined(CONFIG_AR9) ifx_pmu_set(IFX_PMU_MODULE_GPHY0, IFX_PMU_DISABLE); ifx_pmu_set(IFX_PMU_MODULE_GPHY1, IFX_PMU_DISABLE); #if defined(CONIFG_AR10) ifx_pmu_set(IFX_PMU_MODULE_GPHY2, IFX_PMU_DISABLE); if (chipID.part_number == IFX_PARTNUM_ARX388) { ifx_pmu_set(IFX_PMU_MODULE_GPHY3, IFX_PMU_DISABLE); } #endif /*--- #if defined(CONIFG_AR10) ---*/ #endif /*--- #if ! defined(CONFIG_AR9) ---*/ /*--- prom_printf("[%s] disable power domain 'DSL + DFE'\n", __FUNCTION__); ---*/ ifx_pmu_set(IFX_PMU_MODULE_DSL_DFE, 0); ifx_pmu_pg_dsl_dfe_disable(); return 0; } core_initcall(power_managment_setup);