ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / mips / hp-lj / setup.c
1 /*
2  * Setup pointers to hardware-dependent routines.
3  *
4  * This file is subject to the terms and conditions of the GNU General Public
5  * License.  See the file "COPYING" in the main directory of this archive
6  * for more details.
7  *
8  * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
9  */
10 #include <linux/config.h>
11 #include <linux/hdreg.h>
12 #include <linux/init.h>
13 #include <linux/mm.h>
14 #include <linux/interrupt.h>
15 #include <linux/ide.h>
16 #include <linux/bootmem.h>
17 #include <asm/reboot.h>
18 #include <asm/time.h>
19 #include <asm/hp-lj/asic.h>
20 #include "utils.h"
21
22 extern char CommandLine[];
23 extern void pci_setup(void);
24
25 #ifdef CONFIG_KGDB
26 int remote_debug = 0;
27 #endif
28
29 const char *get_system_type(void)
30 {
31         return "HP LaserJet";   /* But which exactly?  */
32 }
33
34 static void (*timer_interrupt_service) (int irq, void *dev_id,
35                                         struct pt_regs * regs) = NULL;
36
37
38 static void andros_timer_interrupt(int irq, void *dev_id,
39                                    struct pt_regs *regs)
40 {
41         if (!(*((volatile unsigned int *) 0xbfea0010) & 0x20))  // mask = pend & en
42                 return;
43
44         /* clear timer interrupt */
45         {
46                 unsigned int tmr = *((volatile unsigned int *) 0xbfe90040);     // ctl bits
47                 *((volatile unsigned int *) 0xbfe90040) = tmr;  // write to ack
48                 *((volatile unsigned int *) 0xbfea000c) = 0x20; // sys int ack
49         }
50
51         /* service interrupt */
52         timer_interrupt_service(irq, dev_id, regs);
53 }
54
55 static void harmony_timer_interrupt(int irq, void *dev_id,
56                                     struct pt_regs *regs)
57 {
58         if (!(*((volatile unsigned int *) 0xbff63000) & 0x01))
59                 return;         // big sys     int reg, 01-timer  did it
60         if (!(*((volatile unsigned int *) 0xbff610a4) & 0x01))
61                 return;         // local small int reg, 01-timer0 did it
62
63         *((volatile unsigned int *) 0xbff610a4) = 1;    // ack local timer0 bit
64         *((volatile unsigned int *) 0xbff63000) = 1;    // ack global timer bit
65
66         /* service interrupt */
67         timer_interrupt_service(irq, dev_id, regs);
68 }
69
70
71 #define ASIC_IRQ_NUMBER  2
72
73
74 static void __init hp_time_init(struct irqaction *irq)
75 {
76         timer_interrupt_service = irq->handler;
77
78         if (GetAsicId() == AndrosAsic) {
79                 //*((volatile unsigned int*)0xbfe90000) = 0x2f;  // set by bootloader to 0x20              // prescaler
80                 *((volatile unsigned int *) 0xbfe90040) = 0x21; // 20-res of 1kHz,1-int ack                // control
81                 *((volatile unsigned int *) 0xbfe90048) = 0x09; // 09-reload val                          // reload
82                 *((volatile unsigned int *) 0xbfe90044) = 0x09; // 09-count val                           // count
83                 *((volatile unsigned int *) 0xbfe90040) = 0x2f; // 8-int enable,4-reload en,2-count down en,1-int-ack
84
85                 irq->handler = andros_timer_interrupt;
86                 irq->flags |= SA_INTERRUPT | SA_SHIRQ;
87                 printk("setting up timer in hp_time_init\n");
88                 setup_irq(ASIC_IRQ_NUMBER, irq);
89
90                 // enable timer interrupt
91                 *((volatile unsigned int *) 0xbfea0000) = 0x20;
92
93         } else if (GetAsicId() == HarmonyAsic) {
94
95                 *((volatile unsigned int *) 0xbff61000) = 99;   // prescaler, 100Mz sys clk
96                 *((volatile unsigned int *) 0xbff61028) = 0x09; // reload reg
97                 *((volatile unsigned int *) 0xbff61024) = 0x09; // count reg
98                 *((volatile unsigned int *) 0xbff61020) = 0x0b; // 80-1khz res on timer, 2 reload en, 1 - count down en
99
100                 irq->handler = harmony_timer_interrupt;
101                 irq->flags |= SA_INTERRUPT | SA_SHIRQ;
102                 setup_irq(ASIC_IRQ_NUMBER, irq);
103
104                 *((volatile unsigned int *) 0xbff610a0) |= 1;   // turn on timer0
105
106         } else if (GetAsicId() == UnknownAsic)
107                 printk("Unknown asic in hp_time_init()\n");
108         else
109                 printk("Unsupported asic in hp_time_init()\n");
110 }
111
112
113 static void hplj_restart(void)
114 {
115         if (GetAsicId() == AndrosAsic)
116                 *((volatile unsigned int *) 0xbfe900c0) = 0;
117
118
119         if (GetAsicId() == HarmonyAsic)
120                 *((volatile unsigned int *) 0xbff62030) = 0;
121
122         printk("Restart Failed ... halting instead\n");
123         while (1);
124 }
125
126 static void hplj_halt(void)
127 {
128         while (1);
129 }
130
131 static void __init hp_setup(void)
132 {
133 #ifdef CONFIG_PCI
134         pci_setup();
135 #endif
136
137         _machine_restart = (void (*)(char *)) hplj_restart;
138         _machine_halt = hplj_halt;
139         _machine_power_off = hplj_halt;
140
141         board_timer_setup = hp_time_init;
142
143 #ifdef CONFIG_KGDB
144         remote_debug = (strstr(CommandLine, "kgdb") != NULL);
145 #endif
146
147         printk("HP SETUP\n");
148 }
149
150 early_initcall(hp_setup);