Add cmos helper functions for reading/writing a dword
[coreboot.git] / src / include / pc80 / mc146818rtc.h
1 #ifndef PC80_MC146818RTC_H
2 #define PC80_MC146818RTC_H
3
4 #ifndef RTC_BASE_PORT
5 #define RTC_BASE_PORT 0x70
6 #endif
7
8 #define RTC_PORT(x)     (RTC_BASE_PORT + (x))
9
10 /* control registers - Moto names
11  */
12 #define RTC_REG_A               10
13 #define RTC_REG_B               11
14 #define RTC_REG_C               12
15 #define RTC_REG_D               13
16
17
18 /**********************************************************************
19  * register details
20  **********************************************************************/
21 #define RTC_FREQ_SELECT RTC_REG_A
22
23 /* update-in-progress  - set to "1" 244 microsecs before RTC goes off the bus,
24  * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
25  * totalling to a max high interval of 2.228 ms.
26  */
27 # define RTC_UIP                0x80
28 # define RTC_DIV_CTL            0x70
29    /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */
30 #  define RTC_REF_CLCK_4MHZ     0x00
31 #  define RTC_REF_CLCK_1MHZ     0x10
32 #  define RTC_REF_CLCK_32KHZ    0x20
33    /* 2 values for divider stage reset, others for "testing purposes only" */
34 #  define RTC_DIV_RESET1        0x60
35 #  define RTC_DIV_RESET2        0x70
36   /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
37 # define RTC_RATE_SELECT        0x0F
38 #  define RTC_RATE_NONE         0x00
39 #  define RTC_RATE_32786HZ      0x01
40 #  define RTC_RATE_16384HZ      0x02
41 #  define RTC_RATE_8192HZ       0x03
42 #  define RTC_RATE_4096HZ       0x04
43 #  define RTC_RATE_2048HZ       0x05
44 #  define RTC_RATE_1024HZ       0x06
45 #  define RTC_RATE_512HZ        0x07
46 #  define RTC_RATE_256HZ        0x08
47 #  define RTC_RATE_128HZ        0x09
48 #  define RTC_RATE_64HZ         0x0a
49 #  define RTC_RATE_32HZ         0x0b
50 #  define RTC_RATE_16HZ         0x0c
51 #  define RTC_RATE_8HZ          0x0d
52 #  define RTC_RATE_4HZ          0x0e
53 #  define RTC_RATE_2HZ          0x0f
54
55 /**********************************************************************/
56 #define RTC_CONTROL     RTC_REG_B
57 # define RTC_SET 0x80           /* disable updates for clock setting */
58 # define RTC_PIE 0x40           /* periodic interrupt enable */
59 # define RTC_AIE 0x20           /* alarm interrupt enable */
60 # define RTC_UIE 0x10           /* update-finished interrupt enable */
61 # define RTC_SQWE 0x08          /* enable square-wave output */
62 # define RTC_DM_BINARY 0x04     /* all time/date values are BCD if clear */
63 # define RTC_24H 0x02           /* 24 hour mode - else hours bit 7 means pm */
64 # define RTC_DST_EN 0x01        /* auto switch DST - works f. USA only */
65
66 /**********************************************************************/
67 #define RTC_INTR_FLAGS  RTC_REG_C
68 /* caution - cleared by read */
69 # define RTC_IRQF 0x80          /* any of the following 3 is active */
70 # define RTC_PF 0x40
71 # define RTC_AF 0x20
72 # define RTC_UF 0x10
73
74 /**********************************************************************/
75 #define RTC_VALID       RTC_REG_D
76 # define RTC_VRT 0x80           /* valid RAM and time */
77 /**********************************************************************/
78
79 /* On PCs, the checksum is built only over bytes 16..45 */
80 #define PC_CKS_RANGE_START      16
81 #define PC_CKS_RANGE_END        45
82 #define PC_CKS_LOC              46
83
84 #ifndef UTIL_BUILD_OPTION_TABLE
85 #include <arch/io.h>
86 static inline unsigned char cmos_read(unsigned char addr)
87 {
88         int offs = 0;
89         if (addr >= 128) {
90                 offs = 2;
91                 addr -= 128;
92         }
93         outb(addr, RTC_BASE_PORT + offs + 0);
94         return inb(RTC_BASE_PORT + offs + 1);
95 }
96
97 static inline void cmos_write(unsigned char val, unsigned char addr)
98 {
99         int offs = 0;
100         if (addr >= 128) {
101                 offs = 2;
102                 addr -= 128;
103         }
104         outb(addr, RTC_BASE_PORT + offs + 0);
105         outb(val, RTC_BASE_PORT + offs + 1);
106 }
107
108 static inline u32 cmos_read32(u8 offset)
109 {
110         u32 value = 0;
111         u8 i;
112         for (i = 0; i < sizeof(value); ++i)
113                 value |= cmos_read(offset + i) << (i << 3);
114         return value;
115 }
116
117 static inline void cmos_write32(u8 offset, u32 value)
118 {
119         u8 i;
120         for (i = 0; i < sizeof(value); ++i)
121                 cmos_write((value >> (i << 3)) & 0xff, offset + i);
122 }
123 #endif
124
125 #if !defined(__ROMCC__)
126 void rtc_init(int invalid);
127 #if CONFIG_USE_OPTION_TABLE
128 int set_option(const char *name, void *val);
129 int get_option(void *dest, const char *name);
130 unsigned read_option_lowlevel(unsigned start, unsigned size, unsigned def);
131 #else
132 static inline int set_option(const char *name __attribute__((unused)), void *val __attribute__((unused))) { return -2; };
133 static inline int get_option(void *dest __attribute__((unused)),
134         const char *name __attribute__((unused))) { return -2; }
135 #define read_option_lowlevel(start, size, def) def
136 #endif
137 #else
138 #include <pc80/mc146818rtc_early.c>
139 #endif
140 #define read_option(name, default) read_option_lowlevel(CMOS_VSTART_ ##name, CMOS_VLEN_ ##name, (default))
141
142 #endif /*  PC80_MC146818RTC_H */