0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/kernel.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/init.h>
0017 #include <linux/time.h>
0018 #include <linux/rtc.h>
0019 #include <linux/fsl_devices.h>
0020 #include <linux/of.h>
0021 #include <linux/of_irq.h>
0022
0023 #include <asm/io.h>
0024 #include <asm/8xx_immap.h>
0025 #include <asm/fs_pd.h>
0026 #include <mm/mmu_decl.h>
0027
0028 #include "pic.h"
0029
0030 #include "mpc8xx.h"
0031
0032
0033 static irqreturn_t timebase_interrupt(int irq, void *dev)
0034 {
0035 printk ("timebase_interrupt()\n");
0036
0037 return IRQ_HANDLED;
0038 }
0039
0040
0041 void __init __attribute__ ((weak))
0042 init_internal_rtc(void)
0043 {
0044 sit8xx_t __iomem *sys_tmr = immr_map(im_sit);
0045
0046
0047 clrbits16(&sys_tmr->sit_rtcsc, (RTCSC_SIE | RTCSC_ALE));
0048
0049
0050 setbits16(&sys_tmr->sit_rtcsc, (RTCSC_RTF | RTCSC_RTE));
0051 immr_unmap(sys_tmr);
0052 }
0053
0054 static int __init get_freq(char *name, unsigned long *val)
0055 {
0056 struct device_node *cpu;
0057 const unsigned int *fp;
0058 int found = 0;
0059
0060
0061 cpu = of_get_cpu_node(0, NULL);
0062
0063 if (cpu) {
0064 fp = of_get_property(cpu, name, NULL);
0065 if (fp) {
0066 found = 1;
0067 *val = *fp;
0068 }
0069
0070 of_node_put(cpu);
0071 }
0072
0073 return found;
0074 }
0075
0076
0077
0078
0079
0080 void __init mpc8xx_calibrate_decr(void)
0081 {
0082 struct device_node *cpu;
0083 cark8xx_t __iomem *clk_r1;
0084 car8xx_t __iomem *clk_r2;
0085 sitk8xx_t __iomem *sys_tmr1;
0086 sit8xx_t __iomem *sys_tmr2;
0087 int irq, virq;
0088
0089 clk_r1 = immr_map(im_clkrstk);
0090
0091
0092 out_be32(&clk_r1->cark_sccrk, ~KAPWR_KEY);
0093 out_be32(&clk_r1->cark_sccrk, KAPWR_KEY);
0094 immr_unmap(clk_r1);
0095
0096
0097 clk_r2 = immr_map(im_clkrst);
0098 setbits32(&clk_r2->car_sccr, 0x02000000);
0099 immr_unmap(clk_r2);
0100
0101
0102
0103 ppc_proc_freq = 50000000;
0104 if (!get_freq("clock-frequency", &ppc_proc_freq))
0105 printk(KERN_ERR "WARNING: Estimating processor frequency "
0106 "(not found)\n");
0107
0108 ppc_tb_freq = ppc_proc_freq / 16;
0109 printk("Decrementer Frequency = 0x%lx\n", ppc_tb_freq);
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 sys_tmr1 = immr_map(im_sitk);
0127 out_be32(&sys_tmr1->sitk_tbscrk, ~KAPWR_KEY);
0128 out_be32(&sys_tmr1->sitk_rtcsck, ~KAPWR_KEY);
0129 out_be32(&sys_tmr1->sitk_tbk, ~KAPWR_KEY);
0130 out_be32(&sys_tmr1->sitk_tbscrk, KAPWR_KEY);
0131 out_be32(&sys_tmr1->sitk_rtcsck, KAPWR_KEY);
0132 out_be32(&sys_tmr1->sitk_tbk, KAPWR_KEY);
0133 immr_unmap(sys_tmr1);
0134
0135 init_internal_rtc();
0136
0137
0138
0139
0140
0141
0142 cpu = of_get_cpu_node(0, NULL);
0143 virq= irq_of_parse_and_map(cpu, 0);
0144 of_node_put(cpu);
0145 irq = virq_to_hw(virq);
0146
0147 sys_tmr2 = immr_map(im_sit);
0148 out_be16(&sys_tmr2->sit_tbscr, ((1 << (7 - (irq/2))) << 8) |
0149 (TBSCR_TBF | TBSCR_TBE));
0150 immr_unmap(sys_tmr2);
0151
0152 if (request_irq(virq, timebase_interrupt, IRQF_NO_THREAD, "tbint",
0153 NULL))
0154 panic("Could not allocate timer IRQ!");
0155 }
0156
0157
0158
0159
0160
0161
0162 int mpc8xx_set_rtc_time(struct rtc_time *tm)
0163 {
0164 sitk8xx_t __iomem *sys_tmr1;
0165 sit8xx_t __iomem *sys_tmr2;
0166 time64_t time;
0167
0168 sys_tmr1 = immr_map(im_sitk);
0169 sys_tmr2 = immr_map(im_sit);
0170 time = rtc_tm_to_time64(tm);
0171
0172 out_be32(&sys_tmr1->sitk_rtck, KAPWR_KEY);
0173 out_be32(&sys_tmr2->sit_rtc, (u32)time);
0174 out_be32(&sys_tmr1->sitk_rtck, ~KAPWR_KEY);
0175
0176 immr_unmap(sys_tmr2);
0177 immr_unmap(sys_tmr1);
0178 return 0;
0179 }
0180
0181 void mpc8xx_get_rtc_time(struct rtc_time *tm)
0182 {
0183 unsigned long data;
0184 sit8xx_t __iomem *sys_tmr = immr_map(im_sit);
0185
0186
0187 data = in_be32(&sys_tmr->sit_rtc);
0188 rtc_time64_to_tm(data, tm);
0189 immr_unmap(sys_tmr);
0190 return;
0191 }
0192
0193 void __noreturn mpc8xx_restart(char *cmd)
0194 {
0195 car8xx_t __iomem *clk_r = immr_map(im_clkrst);
0196
0197
0198 local_irq_disable();
0199
0200 setbits32(&clk_r->car_plprcr, 0x00000080);
0201
0202
0203 mtmsr(mfmsr() & ~0x1000);
0204
0205 in_8(&clk_r->res[0]);
0206 panic("Restart failed\n");
0207 }