~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/mti-malta/malta-time.c

Version: ~ [ linux-5.14-rc3 ] ~ [ linux-5.13.5 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.53 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.135 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.198 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.240 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.276 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.276 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Carsten Langgaard, carstenl@mips.com
  3  * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
  4  *
  5  *  This program is free software; you can distribute it and/or modify it
  6  *  under the terms of the GNU General Public License (Version 2) as
  7  *  published by the Free Software Foundation.
  8  *
  9  *  This program is distributed in the hope it will be useful, but WITHOUT
 10  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  *  for more details.
 13  *
 14  *  You should have received a copy of the GNU General Public License along
 15  *  with this program; if not, write to the Free Software Foundation, Inc.,
 16  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 17  *
 18  * Setting up the clock on the MIPS boards.
 19  */
 20 #include <linux/types.h>
 21 #include <linux/i8253.h>
 22 #include <linux/init.h>
 23 #include <linux/kernel_stat.h>
 24 #include <linux/sched.h>
 25 #include <linux/spinlock.h>
 26 #include <linux/interrupt.h>
 27 #include <linux/irqchip/mips-gic.h>
 28 #include <linux/timex.h>
 29 #include <linux/mc146818rtc.h>
 30 
 31 #include <asm/cpu.h>
 32 #include <asm/mipsregs.h>
 33 #include <asm/mipsmtregs.h>
 34 #include <asm/hardirq.h>
 35 #include <asm/irq.h>
 36 #include <asm/div64.h>
 37 #include <asm/setup.h>
 38 #include <asm/time.h>
 39 #include <asm/mc146818-time.h>
 40 #include <asm/msc01_ic.h>
 41 
 42 #include <asm/mips-boards/generic.h>
 43 #include <asm/mips-boards/maltaint.h>
 44 
 45 static int mips_cpu_timer_irq;
 46 static int mips_cpu_perf_irq;
 47 extern int cp0_perfcount_irq;
 48 
 49 static unsigned int gic_frequency;
 50 
 51 static void mips_timer_dispatch(void)
 52 {
 53         do_IRQ(mips_cpu_timer_irq);
 54 }
 55 
 56 static void mips_perf_dispatch(void)
 57 {
 58         do_IRQ(mips_cpu_perf_irq);
 59 }
 60 
 61 static unsigned int freqround(unsigned int freq, unsigned int amount)
 62 {
 63         freq += amount;
 64         freq -= freq % (amount*2);
 65         return freq;
 66 }
 67 
 68 /*
 69  * Estimate CPU and GIC frequencies.
 70  */
 71 static void __init estimate_frequencies(void)
 72 {
 73         unsigned long flags;
 74         unsigned int count, start;
 75         cycle_t giccount = 0, gicstart = 0;
 76 
 77 #if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ
 78         mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000;
 79         return;
 80 #endif
 81 
 82         local_irq_save(flags);
 83 
 84         /* Start counter exactly on falling edge of update flag. */
 85         while (CMOS_READ(RTC_REG_A) & RTC_UIP);
 86         while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 87 
 88         /* Initialize counters. */
 89         start = read_c0_count();
 90         if (gic_present) {
 91                 gic_start_count();
 92                 gicstart = gic_read_count();
 93         }
 94 
 95         /* Read counter exactly on falling edge of update flag. */
 96         while (CMOS_READ(RTC_REG_A) & RTC_UIP);
 97         while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 98 
 99         count = read_c0_count();
100         if (gic_present)
101                 giccount = gic_read_count();
102 
103         local_irq_restore(flags);
104 
105         count -= start;
106         mips_hpt_frequency = count;
107 
108         if (gic_present) {
109                 giccount -= gicstart;
110                 gic_frequency = giccount;
111         }
112 }
113 
114 void read_persistent_clock(struct timespec *ts)
115 {
116         ts->tv_sec = mc146818_get_cmos_time();
117         ts->tv_nsec = 0;
118 }
119 
120 int get_c0_fdc_int(void)
121 {
122         /*
123          * Some cores claim the FDC is routable through the GIC, but it doesn't
124          * actually seem to be connected for those Malta bitstreams.
125          */
126         switch (current_cpu_type()) {
127         case CPU_INTERAPTIV:
128         case CPU_PROAPTIV:
129                 return -1;
130         };
131 
132         if (cpu_has_veic)
133                 return -1;
134         else if (gic_present)
135                 return gic_get_c0_fdc_int();
136         else if (cp0_fdc_irq >= 0)
137                 return MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
138         else
139                 return -1;
140 }
141 
142 int get_c0_perfcount_int(void)
143 {
144         if (cpu_has_veic) {
145                 set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch);
146                 mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
147         } else if (gic_present) {
148                 mips_cpu_perf_irq = gic_get_c0_perfcount_int();
149         } else if (cp0_perfcount_irq >= 0) {
150                 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
151         } else {
152                 mips_cpu_perf_irq = -1;
153         }
154 
155         return mips_cpu_perf_irq;
156 }
157 EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
158 
159 unsigned int get_c0_compare_int(void)
160 {
161         if (cpu_has_veic) {
162                 set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
163                 mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
164         } else if (gic_present) {
165                 mips_cpu_timer_irq = gic_get_c0_compare_int();
166         } else {
167                 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
168         }
169 
170         return mips_cpu_timer_irq;
171 }
172 
173 static void __init init_rtc(void)
174 {
175         unsigned char freq, ctrl;
176 
177         /* Set 32KHz time base if not already set */
178         freq = CMOS_READ(RTC_FREQ_SELECT);
179         if ((freq & RTC_DIV_CTL) != RTC_REF_CLCK_32KHZ)
180                 CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_FREQ_SELECT);
181 
182         /* Ensure SET bit is clear so RTC can run */
183         ctrl = CMOS_READ(RTC_CONTROL);
184         if (ctrl & RTC_SET)
185                 CMOS_WRITE(ctrl & ~RTC_SET, RTC_CONTROL);
186 }
187 
188 void __init plat_time_init(void)
189 {
190         unsigned int prid = read_c0_prid() & (PRID_COMP_MASK | PRID_IMP_MASK);
191         unsigned int freq;
192 
193         init_rtc();
194         estimate_frequencies();
195 
196         freq = mips_hpt_frequency;
197         if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
198             (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
199                 freq *= 2;
200         freq = freqround(freq, 5000);
201         printk("CPU frequency %d.%02d MHz\n", freq/1000000,
202                (freq%1000000)*100/1000000);
203 
204         mips_scroll_message();
205 
206 #ifdef CONFIG_I8253
207         /* Only Malta has a PIT. */
208         setup_pit_timer();
209 #endif
210 
211 #ifdef CONFIG_MIPS_GIC
212         if (gic_present) {
213                 freq = freqround(gic_frequency, 5000);
214                 printk("GIC frequency %d.%02d MHz\n", freq/1000000,
215                        (freq%1000000)*100/1000000);
216 #ifdef CONFIG_CLKSRC_MIPS_GIC
217                 gic_clocksource_init(gic_frequency);
218 #endif
219         }
220 #endif
221 }
222 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp