90782d9fbfe1c443790e47eae485295fee0b97ce
[coreboot.git] / src / mainboard / intel / jarrell / watchdog.c
1 #include <device/pnp_def.h>
2
3 #define NSC_WD_DEV PNP_DEV(0x2e, 0xa)
4 #define NSC_WDBASE 0x600
5 #define ICH5_WDBASE 0x400
6 #define ICH5_GPIOBASE 0x500
7
8 static void disable_sio_watchdog(device_t dev)
9 {
10         /* FIXME move me somewhere more appropriate */
11         pnp_set_logical_device(dev);
12         pnp_set_enable(dev, 1);
13         pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE);
14         /* disable the sio watchdog */
15         outb(0, NSC_WDBASE + 0);
16         pnp_set_enable(dev, 0);
17 }
18
19 static void disable_ich5_watchdog(void)
20 {
21         /* FIXME move me somewhere more appropriate */
22         device_t dev;
23         unsigned long value, base;
24         dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
25         if (dev == PCI_DEV_INVALID) {
26                 die("Missing ich5?");
27         }
28         /* Enable I/O space */
29         value = pci_read_config16(dev, 0x04);
30         value |= (1 << 10);
31         pci_write_config16(dev, 0x04, value);
32         
33         /* Set and enable acpibase */
34         pci_write_config32(dev, 0x40, ICH5_WDBASE | 1);
35         pci_write_config8(dev, 0x44, 0x10);
36         base = ICH5_WDBASE + 0x60;
37         
38         /* Set bit 11 in TCO1_CNT */
39         value = inw(base + 0x08);
40         value |= 1 << 11;
41         outw(value, base + 0x08);
42         
43         /* Clear TCO timeout status */
44         outw(0x0008, base + 0x04);
45         outw(0x0002, base + 0x06);
46 }
47
48 static void disable_jarell_frb3(void)
49 {
50         device_t dev;
51         unsigned long value, base;
52         dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
53         if (dev == PCI_DEV_INVALID) {
54                 die("Missing ich5?");
55         }
56         /* Enable I/O space */
57         value = pci_read_config16(dev, 0x04);
58         value |= (1 << 0);
59         pci_write_config16(dev, 0x04, value);
60
61         /* Set gpio base */
62         pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1);
63         base = ICH5_GPIOBASE;
64
65         /* Enable GPIO Bar */
66         value = pci_read_config32(dev, 0x5c);
67         value |= 0x10;
68         pci_write_config32(dev, 0x5c, value);
69
70         /* Configure GPIO 48 and 40 as GPIO */
71         value = inl(base + 0x30);
72         value |= (1 << 16) | ( 1 << 8);
73         outl(value, base + 0x30);
74
75         /* Configure GPIO 48 as Output */
76         value = inl(base + 0x34);
77         value &= ~(1 << 16);
78         outl(value, base + 0x34);
79
80         /* Toggle GPIO 48 high to low */
81         value = inl(base + 0x38);
82         value |= (1 << 16);
83         outl(value, base + 0x38);
84         value &= ~(1 << 16);
85         outl(value, base + 0x38);
86                                   
87 }
88
89 static void disable_watchdogs(void)
90 {
91         disable_sio_watchdog(NSC_WD_DEV);
92         disable_ich5_watchdog();
93         disable_jarell_frb3();
94         print_debug("Watchdogs disabled\n");
95 }
96
97 static void ich5_watchdog_on(void)
98 {
99         device_t dev;
100         unsigned long value, base;
101         unsigned char byte;
102
103         /* check cmos options */
104         byte = cmos_read(RTC_BOOT_BYTE-1);
105         if(!(byte & 1)) return; /* no boot watchdog */
106         byte = cmos_read(RTC_BOOT_BYTE);
107         if(!(byte & 2)) return; /* fallback so ignore */
108
109         dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0);
110         if (dev == PCI_DEV_INVALID) {
111                 die("Missing ich5?");
112         }
113         /* Enable I/O space */
114         value = pci_read_config16(dev, 0x04);
115         value |= (1 << 10);
116         pci_write_config16(dev, 0x04, value);
117         
118         /* Set and enable acpibase */
119         pci_write_config32(dev, 0x40, ICH5_WDBASE | 1);
120         pci_write_config8(dev, 0x44, 0x10);
121         base = ICH5_WDBASE + 0x60;
122         
123         /* Clear TCO timeout status */
124         outw(0x0008, base + 0x04);
125         outw(0x0002, base + 0x06);
126
127         /* set the time value 1 cnt = .6 sec */
128         outw(0x0010, base + 0x01);
129         /* reload the timer with the value */
130         outw(0x0001, base + 0x00);
131
132         /* clear bit 11 in TCO1_CNT to start watchdog */
133         value = inw(base + 0x08);
134         value &= ~(1 << 11);
135         outw(value, base + 0x08);       
136
137         print_debug("Watchdog ICH5 enabled\n");
138 }