blob: de139773ead29bf8d67da1d9ca4555534ed28fef [file] [log] [blame]
wdenkc7de8292002-11-19 11:04:11 +00001#include "memio.h"
2#include "articiaS.h"
3
4#ifndef FALSE
5#define FALSE 0
6#endif
7
8#ifndef TRUE
9#define TRUE 1
10#endif
11
12
13void sm_write_mode(void)
14{
15 out_byte(0xA539, 0x00);
16 out_byte(0xA53A, 0x03);
17}
18
19void sm_read_mode(void)
20{
21 out_byte(0xA53A, 0x02);
22 out_byte(0xA539, 0x02);
23}
24
25void sm_write_byte(uint8 writeme)
26{
27 int i;
28 int level;
wdenk8bde7f72003-06-27 21:31:46 +000029
wdenkc7de8292002-11-19 11:04:11 +000030 out_byte(0xA539, 0x00);
31
32 level = 0;
33
34 for (i=0; i<8; i++)
35 {
wdenk8bde7f72003-06-27 21:31:46 +000036 if ((writeme & 0x80) == (level<<7))
37 {
wdenkc7de8292002-11-19 11:04:11 +000038 /* Bit did not change, rewrite strobe */
39 out_byte(0xA539, level | 0x02);
wdenk8bde7f72003-06-27 21:31:46 +000040 out_byte(0xA539, level);
wdenkc7de8292002-11-19 11:04:11 +000041 }
42 else
43 {
44 /* Bit changed, set bit, then strobe */
45 level = (writeme & 0x80) >> 7;
46 out_byte(0xA539, level);
47 out_byte(0xA539, level | 0x02);
48 out_byte(0xA539, level);
49 }
50 writeme <<= 1;
51 }
52 out_byte(0xA539, 0x00);
53}
54
55uint8 sm_read_byte(void)
56{
57 uint8 retme, r;
58 int i;
59
60 retme = 0;
61 for (i=0; i<8; i++)
62 {
63 retme <<= 1;
64 out_byte(0xA539, 0x00);
65 out_byte(0xA539, 0x02);
66 r = in_byte(0xA538) & 0x01;
67 retme |= r;
68 }
69
70 return retme;
wdenk8bde7f72003-06-27 21:31:46 +000071}
wdenkc7de8292002-11-19 11:04:11 +000072
73int sm_get_ack(void)
74{
75 uint8 r;
76 r = in_byte(0xA538);
77 if ((r&0x01) == 0) return TRUE;
78 else return FALSE;
79}
80
81void sm_write_ack(void)
82{
83 out_byte(0xA539, 0x00);
84 out_byte(0xA539, 0x02);
85 out_byte(0xA539, 0x00);
86}
87
88void sm_write_nack(void)
89{
90 out_byte(0xA539, 0x01);
91 out_byte(0xA539, 0x03);
92 out_byte(0xA539, 0x01);
93}
94
95void sm_send_start(void)
96{
97 out_byte(0xA539, 0x03);
98 out_byte(0xA539, 0x02);
99}
100
101void sm_send_stop(void)
102{
103 out_byte(0xA539, 0x02);
104 out_byte(0xA539, 0x03);
105}
106
107int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage)
108{
wdenk8bde7f72003-06-27 21:31:46 +0000109 /* S Addr Wr */
wdenkc7de8292002-11-19 11:04:11 +0000110 sm_write_mode();
111 sm_send_start();
112 sm_write_byte((addr<<1));
wdenk8bde7f72003-06-27 21:31:46 +0000113
114 /* [A] */
wdenkc7de8292002-11-19 11:04:11 +0000115 sm_read_mode();
116 if (sm_get_ack() == FALSE) return FALSE;
117
wdenk8bde7f72003-06-27 21:31:46 +0000118 /* Comm */
wdenkc7de8292002-11-19 11:04:11 +0000119 sm_write_mode();
120 sm_write_byte(reg);
wdenk8bde7f72003-06-27 21:31:46 +0000121
122 /* [A] */
wdenkc7de8292002-11-19 11:04:11 +0000123 sm_read_mode();
124 if (sm_get_ack() == FALSE) return FALSE;
125
wdenk8bde7f72003-06-27 21:31:46 +0000126 /* S Addr Rd */
wdenkc7de8292002-11-19 11:04:11 +0000127 sm_write_mode();
128 sm_send_start();
129 sm_write_byte((addr<<1)|1);
wdenk8bde7f72003-06-27 21:31:46 +0000130
131 /* [A] */
wdenkc7de8292002-11-19 11:04:11 +0000132 sm_read_mode();
133 if (sm_get_ack() == FALSE) return FALSE;
134
wdenk8bde7f72003-06-27 21:31:46 +0000135 /* [Data] */
wdenkc7de8292002-11-19 11:04:11 +0000136 *storage = sm_read_byte();
wdenk8bde7f72003-06-27 21:31:46 +0000137
138 /* NA */
wdenkc7de8292002-11-19 11:04:11 +0000139 sm_write_mode();
140 sm_write_nack();
141 sm_send_stop();
142
143 return TRUE;
144}
145
146void sm_init(void)
wdenk8bde7f72003-06-27 21:31:46 +0000147{
wdenkc7de8292002-11-19 11:04:11 +0000148 /* Switch to PMC mode */
149 pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
wdenk8bde7f72003-06-27 21:31:46 +0000150
wdenkc7de8292002-11-19 11:04:11 +0000151 /* Set GPIO Base */
152 pci_write_cfg_long(0, 0, 0x40, 0xa500);
153
154 /* Enable GPIO */
155 pci_write_cfg_byte(0, 0, 0x44, 0x11);
156
157 /* Set both GPIO 0 and 1 as output */
wdenk8bde7f72003-06-27 21:31:46 +0000158 out_byte(0xA53A, 0x03);
wdenkc7de8292002-11-19 11:04:11 +0000159}
160
161
162void sm_term(void)
wdenk8bde7f72003-06-27 21:31:46 +0000163{
wdenkc7de8292002-11-19 11:04:11 +0000164 /* Switch to normal mode */
165 pci_write_cfg_byte(0, 0, REG_GROUP, 0);
166}
167
168
169int sm_get_data(uint8 *DataArray, int dimm_socket)
170{
171 int j;
172
173#if 0
174 /* Switch to PMC mode */
175 pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER));
wdenk8bde7f72003-06-27 21:31:46 +0000176
wdenkc7de8292002-11-19 11:04:11 +0000177 /* Set GPIO Base */
178 pci_write_cfg_long(0, 0, 0x40, 0xa500);
179
180 /* Enable GPIO */
181 pci_write_cfg_byte(0, 0, 0x44, 0x11);
182
183 /* Set both GPIO 0 and 1 as output */
wdenk8bde7f72003-06-27 21:31:46 +0000184 out_byte(0xA53A, 0x03);
wdenkc7de8292002-11-19 11:04:11 +0000185#endif
186
187 sm_init();
188 /* Start reading the rom */
189
190 j = 0;
191
192 do
193 {
194 if (sm_read_byte_from_device(dimm_socket, (uint8)j, DataArray) == FALSE)
195 {
196 sm_term();
197 return FALSE;
198 }
199
200 DataArray++;
201 j++;
202 } while (j < 128);
203
204 sm_term();
205 return TRUE;
206}