13070033a16edcc21688d5ea8967c89522f833862Steven J. Hill/* 23070033a16edcc21688d5ea8967c89522f833862Steven J. Hill * This file is subject to the terms and conditions of the GNU General Public 33070033a16edcc21688d5ea8967c89522f833862Steven J. Hill * License. See the file "COPYING" in the main directory of this archive 43070033a16edcc21688d5ea8967c89522f833862Steven J. Hill * for more details. 53070033a16edcc21688d5ea8967c89522f833862Steven J. Hill * 63070033a16edcc21688d5ea8967c89522f833862Steven J. Hill * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. 73070033a16edcc21688d5ea8967c89522f833862Steven J. Hill */ 83070033a16edcc21688d5ea8967c89522f833862Steven J. Hill#include <linux/init.h> 93070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 108ff374b9c296b96484d5e63b45b22d0862ffee8fMaciej W. Rozycki#include <asm/cpu.h> 113070033a16edcc21688d5ea8967c89522f833862Steven J. Hill#include <asm/setup.h> 123070033a16edcc21688d5ea8967c89522f833862Steven J. Hill#include <asm/time.h> 133070033a16edcc21688d5ea8967c89522f833862Steven J. Hill#include <asm/irq.h> 143070033a16edcc21688d5ea8967c89522f833862Steven J. Hill#include <asm/mips-boards/generic.h> 153070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 163070033a16edcc21688d5ea8967c89522f833862Steven J. Hillstatic int mips_cpu_timer_irq; 173070033a16edcc21688d5ea8967c89522f833862Steven J. Hillstatic int mips_cpu_perf_irq; 183070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 193070033a16edcc21688d5ea8967c89522f833862Steven J. Hillstatic void mips_timer_dispatch(void) 203070033a16edcc21688d5ea8967c89522f833862Steven J. Hill{ 213070033a16edcc21688d5ea8967c89522f833862Steven J. Hill do_IRQ(mips_cpu_timer_irq); 223070033a16edcc21688d5ea8967c89522f833862Steven J. Hill} 233070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 243070033a16edcc21688d5ea8967c89522f833862Steven J. Hillstatic void mips_perf_dispatch(void) 253070033a16edcc21688d5ea8967c89522f833862Steven J. Hill{ 263070033a16edcc21688d5ea8967c89522f833862Steven J. Hill do_IRQ(mips_cpu_perf_irq); 273070033a16edcc21688d5ea8967c89522f833862Steven J. Hill} 283070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 293070033a16edcc21688d5ea8967c89522f833862Steven J. Hillstatic void __iomem *status_reg = (void __iomem *)0xbf000410; 303070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 313070033a16edcc21688d5ea8967c89522f833862Steven J. Hill/* 323070033a16edcc21688d5ea8967c89522f833862Steven J. Hill * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect. 333070033a16edcc21688d5ea8967c89522f833862Steven J. Hill */ 343070033a16edcc21688d5ea8967c89522f833862Steven J. Hillstatic unsigned int __init estimate_cpu_frequency(void) 353070033a16edcc21688d5ea8967c89522f833862Steven J. Hill{ 368ff374b9c296b96484d5e63b45b22d0862ffee8fMaciej W. Rozycki unsigned int prid = read_c0_prid() & (PRID_COMP_MASK | PRID_IMP_MASK); 373070033a16edcc21688d5ea8967c89522f833862Steven J. Hill unsigned int tick = 0; 383070033a16edcc21688d5ea8967c89522f833862Steven J. Hill unsigned int freq; 393070033a16edcc21688d5ea8967c89522f833862Steven J. Hill unsigned int orig; 403070033a16edcc21688d5ea8967c89522f833862Steven J. Hill unsigned long flags; 413070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 423070033a16edcc21688d5ea8967c89522f833862Steven J. Hill local_irq_save(flags); 433070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 447034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle orig = readl(status_reg) & 0x2; /* get original sample */ 453070033a16edcc21688d5ea8967c89522f833862Steven J. Hill /* wait for transition */ 463070033a16edcc21688d5ea8967c89522f833862Steven J. Hill while ((readl(status_reg) & 0x2) == orig) 473070033a16edcc21688d5ea8967c89522f833862Steven J. Hill ; 487034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle orig = orig ^ 0x2; /* flip the bit */ 493070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 503070033a16edcc21688d5ea8967c89522f833862Steven J. Hill write_c0_count(0); 513070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 523070033a16edcc21688d5ea8967c89522f833862Steven J. Hill /* wait 1 second (the sampling clock transitions every 10ms) */ 533070033a16edcc21688d5ea8967c89522f833862Steven J. Hill while (tick < 100) { 543070033a16edcc21688d5ea8967c89522f833862Steven J. Hill /* wait for transition */ 553070033a16edcc21688d5ea8967c89522f833862Steven J. Hill while ((readl(status_reg) & 0x2) == orig) 563070033a16edcc21688d5ea8967c89522f833862Steven J. Hill ; 577034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle orig = orig ^ 0x2; /* flip the bit */ 583070033a16edcc21688d5ea8967c89522f833862Steven J. Hill tick++; 593070033a16edcc21688d5ea8967c89522f833862Steven J. Hill } 603070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 613070033a16edcc21688d5ea8967c89522f833862Steven J. Hill freq = read_c0_count(); 623070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 633070033a16edcc21688d5ea8967c89522f833862Steven J. Hill local_irq_restore(flags); 643070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 653070033a16edcc21688d5ea8967c89522f833862Steven J. Hill mips_hpt_frequency = freq; 663070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 673070033a16edcc21688d5ea8967c89522f833862Steven J. Hill /* Adjust for processor */ 683070033a16edcc21688d5ea8967c89522f833862Steven J. Hill if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && 693070033a16edcc21688d5ea8967c89522f833862Steven J. Hill (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) 703070033a16edcc21688d5ea8967c89522f833862Steven J. Hill freq *= 2; 713070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 727034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle freq += 5000; /* rounding */ 733070033a16edcc21688d5ea8967c89522f833862Steven J. Hill freq -= freq%10000; 743070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 753070033a16edcc21688d5ea8967c89522f833862Steven J. Hill return freq ; 763070033a16edcc21688d5ea8967c89522f833862Steven J. Hill} 773070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 783070033a16edcc21688d5ea8967c89522f833862Steven J. Hillvoid read_persistent_clock(struct timespec *ts) 793070033a16edcc21688d5ea8967c89522f833862Steven J. Hill{ 803070033a16edcc21688d5ea8967c89522f833862Steven J. Hill ts->tv_sec = 0; 813070033a16edcc21688d5ea8967c89522f833862Steven J. Hill ts->tv_nsec = 0; 823070033a16edcc21688d5ea8967c89522f833862Steven J. Hill} 833070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 843070033a16edcc21688d5ea8967c89522f833862Steven J. Hillstatic void __init plat_perf_setup(void) 853070033a16edcc21688d5ea8967c89522f833862Steven J. Hill{ 863070033a16edcc21688d5ea8967c89522f833862Steven J. Hill if (cp0_perfcount_irq >= 0) { 873070033a16edcc21688d5ea8967c89522f833862Steven J. Hill if (cpu_has_vint) 883070033a16edcc21688d5ea8967c89522f833862Steven J. Hill set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); 893070033a16edcc21688d5ea8967c89522f833862Steven J. Hill mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; 903070033a16edcc21688d5ea8967c89522f833862Steven J. Hill } 913070033a16edcc21688d5ea8967c89522f833862Steven J. Hill} 923070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 93078a55fc824c1633b3a507e4ad48b4637c1dfc18Paul Gortmakerunsigned int get_c0_compare_int(void) 943070033a16edcc21688d5ea8967c89522f833862Steven J. Hill{ 953070033a16edcc21688d5ea8967c89522f833862Steven J. Hill if (cpu_has_vint) 963070033a16edcc21688d5ea8967c89522f833862Steven J. Hill set_vi_handler(cp0_compare_irq, mips_timer_dispatch); 973070033a16edcc21688d5ea8967c89522f833862Steven J. Hill mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; 983070033a16edcc21688d5ea8967c89522f833862Steven J. Hill return mips_cpu_timer_irq; 993070033a16edcc21688d5ea8967c89522f833862Steven J. Hill} 1003070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 1013070033a16edcc21688d5ea8967c89522f833862Steven J. Hillvoid __init plat_time_init(void) 1023070033a16edcc21688d5ea8967c89522f833862Steven J. Hill{ 1033070033a16edcc21688d5ea8967c89522f833862Steven J. Hill unsigned int est_freq; 1043070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 1053070033a16edcc21688d5ea8967c89522f833862Steven J. Hill est_freq = estimate_cpu_frequency(); 1063070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 1073070033a16edcc21688d5ea8967c89522f833862Steven J. Hill pr_debug("CPU frequency %d.%02d MHz\n", (est_freq / 1000000), 1083070033a16edcc21688d5ea8967c89522f833862Steven J. Hill (est_freq % 1000000) * 100 / 1000000); 1093070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 1103070033a16edcc21688d5ea8967c89522f833862Steven J. Hill mips_scroll_message(); 1113070033a16edcc21688d5ea8967c89522f833862Steven J. Hill 1123070033a16edcc21688d5ea8967c89522f833862Steven J. Hill plat_perf_setup(); 1133070033a16edcc21688d5ea8967c89522f833862Steven J. Hill} 114