Commit 198ea9e294e38cea49f9f2d9b911bdfdd20e48dc

Authored by wdenk
1 parent b2daeb8e0f

Last minute fixes / cleanup.

Showing 3 changed files with 9 additions and 8 deletions Inline Diff

board/evb64260/pci.c
1 /* PCI.c - PCI functions */ 1 /* PCI.c - PCI functions */
2 2
3 /* Copyright - Galileo technology. */ 3 /* Copyright - Galileo technology. */
4 4
5 #include <common.h> 5 #include <common.h>
6 #include <pci.h> 6 #include <pci.h>
7 7
8 #include <galileo/pci.h> 8 #include <galileo/pci.h>
9 9
10 static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = { 10 static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
11 #ifdef CONFIG_ZUMA_V2 11 #ifdef CONFIG_ZUMA_V2
12 {0, 0, 0, 0, 0, 0, 0, 29,[8...PCI_MAX_DEVICES - 1] = 0}, 12 {0, 0, 0, 0, 0, 0, 0, 29,[8 ... PCI_MAX_DEVICES - 1] = 0},
13 {0, 0, 0, 0, 0, 0, 0, 28,[8...PCI_MAX_DEVICES - 1] = 0} 13 {0, 0, 0, 0, 0, 0, 0, 28,[8 ... PCI_MAX_DEVICES - 1] = 0}
14 #else /* EVB??? This is a guess */ 14 #else /* EVB??? This is a guess */
15 {0, 0, 0, 0, 0, 0, 0, 27, 27,[9...PCI_MAX_DEVICES - 1] = 0}, 15 {0, 0, 0, 0, 0, 0, 0, 27, 27,[9 ... PCI_MAX_DEVICES - 1] = 0},
16 {0, 0, 0, 0, 0, 0, 0, 29, 29,[9...PCI_MAX_DEVICES - 1] = 0} 16 {0, 0, 0, 0, 0, 0, 0, 29, 29,[9 ... PCI_MAX_DEVICES - 1] = 0}
17 #endif 17 #endif
18 }; 18 };
19 19
20 static const unsigned int pci_p2p_configuration_reg[] = { 20 static const unsigned int pci_p2p_configuration_reg[] = {
21 PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION 21 PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
22 }; 22 };
23 23
24 static const unsigned int pci_configuration_address[] = { 24 static const unsigned int pci_configuration_address[] = {
25 PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS 25 PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS
26 }; 26 };
27 27
28 static const unsigned int pci_configuration_data[] = { 28 static const unsigned int pci_configuration_data[] = {
29 PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER, 29 PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
30 PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER 30 PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER
31 }; 31 };
32 32
33 static const unsigned int pci_error_cause_reg[] = { 33 static const unsigned int pci_error_cause_reg[] = {
34 PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE 34 PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE
35 }; 35 };
36 36
37 static const unsigned int pci_arbiter_control[] = { 37 static const unsigned int pci_arbiter_control[] = {
38 PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL 38 PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL
39 }; 39 };
40 40
41 static const unsigned int pci_snoop_control_base_0_low[] = { 41 static const unsigned int pci_snoop_control_base_0_low[] = {
42 PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW 42 PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW
43 }; 43 };
44 static const unsigned int pci_snoop_control_top_0[] = { 44 static const unsigned int pci_snoop_control_top_0[] = {
45 PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0 45 PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0
46 }; 46 };
47 47
48 static const unsigned int pci_access_control_base_0_low[] = { 48 static const unsigned int pci_access_control_base_0_low[] = {
49 PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW 49 PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW
50 }; 50 };
51 static const unsigned int pci_access_control_top_0[] = { 51 static const unsigned int pci_access_control_top_0[] = {
52 PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0 52 PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0
53 }; 53 };
54 54
55 static const unsigned int pci_scs_bank_size[2][4] = { 55 static const unsigned int pci_scs_bank_size[2][4] = {
56 {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE, 56 {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
57 PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE}, 57 PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
58 {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE, 58 {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
59 PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE} 59 PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}
60 }; 60 };
61 61
62 static const unsigned int pci_p2p_configuration[] = { 62 static const unsigned int pci_p2p_configuration[] = {
63 PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION 63 PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
64 }; 64 };
65 65
66 static unsigned int local_buses[] = { 0, 0 }; 66 static unsigned int local_buses[] = { 0, 0 };
67 67
68 /******************************************************************** 68 /********************************************************************
69 * pciWriteConfigReg - Write to a PCI configuration register 69 * pciWriteConfigReg - Write to a PCI configuration register
70 * - Make sure the GT is configured as a master before writing 70 * - Make sure the GT is configured as a master before writing
71 * to another device on the PCI. 71 * to another device on the PCI.
72 * - The function takes care of Big/Little endian conversion. 72 * - The function takes care of Big/Little endian conversion.
73 * 73 *
74 * 74 *
75 * Inputs: unsigned int regOffset: The register offset as it apears in the GT spec 75 * Inputs: unsigned int regOffset: The register offset as it apears in the GT spec
76 * (or any other PCI device spec) 76 * (or any other PCI device spec)
77 * pciDevNum: The device number needs to be addressed. 77 * pciDevNum: The device number needs to be addressed.
78 * 78 *
79 * Configuration Address 0xCF8: 79 * Configuration Address 0xCF8:
80 * 80 *
81 * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number 81 * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
82 * |congif|Reserved| Bus |Device|Function|Register|00| 82 * |congif|Reserved| Bus |Device|Function|Register|00|
83 * |Enable| |Number|Number| Number | Number | | <=field Name 83 * |Enable| |Number|Number| Number | Number | | <=field Name
84 * 84 *
85 *********************************************************************/ 85 *********************************************************************/
86 void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset, 86 void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset,
87 unsigned int pciDevNum, unsigned int data) 87 unsigned int pciDevNum, unsigned int data)
88 { 88 {
89 volatile unsigned int DataForAddrReg; 89 volatile unsigned int DataForAddrReg;
90 unsigned int functionNum; 90 unsigned int functionNum;
91 unsigned int busNum = PCI_BUS (pciDevNum); 91 unsigned int busNum = PCI_BUS (pciDevNum);
92 unsigned int addr; 92 unsigned int addr;
93 93
94 if (pciDevNum > 32) /* illegal device Number */ 94 if (pciDevNum > 32) /* illegal device Number */
95 return; 95 return;
96 if (pciDevNum == SELF) { /* configure our configuration space. */ 96 if (pciDevNum == SELF) { /* configure our configuration space. */
97 pciDevNum = 97 pciDevNum =
98 (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) & 98 (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
99 0x1f; 99 0x1f;
100 busNum = GTREGREAD (pci_p2p_configuration_reg[host]) & 100 busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
101 0xff0000; 101 0xff0000;
102 } 102 }
103 functionNum = regOffset & 0x00000700; 103 functionNum = regOffset & 0x00000700;
104 pciDevNum = pciDevNum << 11; 104 pciDevNum = pciDevNum << 11;
105 regOffset = regOffset & 0xfc; 105 regOffset = regOffset & 0xfc;
106 DataForAddrReg = 106 DataForAddrReg =
107 (regOffset | pciDevNum | functionNum | busNum) | BIT31; 107 (regOffset | pciDevNum | functionNum | busNum) | BIT31;
108 GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg); 108 GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
109 GT_REG_READ (pci_configuration_address[host], &addr); 109 GT_REG_READ (pci_configuration_address[host], &addr);
110 if (addr != DataForAddrReg) 110 if (addr != DataForAddrReg)
111 return; 111 return;
112 GT_REG_WRITE (pci_configuration_data[host], data); 112 GT_REG_WRITE (pci_configuration_data[host], data);
113 } 113 }
114 114
115 /******************************************************************** 115 /********************************************************************
116 * pciReadConfigReg - Read from a PCI0 configuration register 116 * pciReadConfigReg - Read from a PCI0 configuration register
117 * - Make sure the GT is configured as a master before reading 117 * - Make sure the GT is configured as a master before reading
118 * from another device on the PCI. 118 * from another device on the PCI.
119 * - The function takes care of Big/Little endian conversion. 119 * - The function takes care of Big/Little endian conversion.
120 * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI 120 * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
121 * spec) 121 * spec)
122 * pciDevNum: The device number needs to be addressed. 122 * pciDevNum: The device number needs to be addressed.
123 * RETURNS: data , if the data == 0xffffffff check the master abort bit in the 123 * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
124 * cause register to make sure the data is valid 124 * cause register to make sure the data is valid
125 * 125 *
126 * Configuration Address 0xCF8: 126 * Configuration Address 0xCF8:
127 * 127 *
128 * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number 128 * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
129 * |congif|Reserved| Bus |Device|Function|Register|00| 129 * |congif|Reserved| Bus |Device|Function|Register|00|
130 * |Enable| |Number|Number| Number | Number | | <=field Name 130 * |Enable| |Number|Number| Number | Number | | <=field Name
131 * 131 *
132 *********************************************************************/ 132 *********************************************************************/
133 unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset, 133 unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,
134 unsigned int pciDevNum) 134 unsigned int pciDevNum)
135 { 135 {
136 volatile unsigned int DataForAddrReg; 136 volatile unsigned int DataForAddrReg;
137 unsigned int data; 137 unsigned int data;
138 unsigned int functionNum; 138 unsigned int functionNum;
139 unsigned int busNum = PCI_BUS (pciDevNum); 139 unsigned int busNum = PCI_BUS (pciDevNum);
140 140
141 if (pciDevNum > 32) /* illegal device Number */ 141 if (pciDevNum > 32) /* illegal device Number */
142 return 0xffffffff; 142 return 0xffffffff;
143 if (pciDevNum == SELF) { /* configure our configuration space. */ 143 if (pciDevNum == SELF) { /* configure our configuration space. */
144 pciDevNum = 144 pciDevNum =
145 (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) & 145 (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
146 0x1f; 146 0x1f;
147 busNum = GTREGREAD (pci_p2p_configuration_reg[host]) & 147 busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
148 0xff0000; 148 0xff0000;
149 } 149 }
150 functionNum = regOffset & 0x00000700; 150 functionNum = regOffset & 0x00000700;
151 pciDevNum = pciDevNum << 11; 151 pciDevNum = pciDevNum << 11;
152 regOffset = regOffset & 0xfc; 152 regOffset = regOffset & 0xfc;
153 DataForAddrReg = 153 DataForAddrReg =
154 (regOffset | pciDevNum | functionNum | busNum) | BIT31; 154 (regOffset | pciDevNum | functionNum | busNum) | BIT31;
155 GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg); 155 GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
156 GT_REG_READ (pci_configuration_address[host], &data); 156 GT_REG_READ (pci_configuration_address[host], &data);
157 if (data != DataForAddrReg) 157 if (data != DataForAddrReg)
158 return 0xffffffff; 158 return 0xffffffff;
159 GT_REG_READ (pci_configuration_data[host], &data); 159 GT_REG_READ (pci_configuration_data[host], &data);
160 return data; 160 return data;
161 } 161 }
162 162
163 /******************************************************************** 163 /********************************************************************
164 * pciOverBridgeWriteConfigReg - Write to a PCI configuration register where 164 * pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
165 * the agent is placed on another Bus. For more 165 * the agent is placed on another Bus. For more
166 * information read P2P in the PCI spec. 166 * information read P2P in the PCI spec.
167 * 167 *
168 * Inputs: unsigned int regOffset - The register offset as it apears in the 168 * Inputs: unsigned int regOffset - The register offset as it apears in the
169 * GT spec (or any other PCI device spec). 169 * GT spec (or any other PCI device spec).
170 * unsigned int pciDevNum - The device number needs to be addressed. 170 * unsigned int pciDevNum - The device number needs to be addressed.
171 * unsigned int busNum - On which bus does the Target agent connect 171 * unsigned int busNum - On which bus does the Target agent connect
172 * to. 172 * to.
173 * unsigned int data - data to be written. 173 * unsigned int data - data to be written.
174 * 174 *
175 * Configuration Address 0xCF8: 175 * Configuration Address 0xCF8:
176 * 176 *
177 * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number 177 * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
178 * |congif|Reserved| Bus |Device|Function|Register|01| 178 * |congif|Reserved| Bus |Device|Function|Register|01|
179 * |Enable| |Number|Number| Number | Number | | <=field Name 179 * |Enable| |Number|Number| Number | Number | | <=field Name
180 * 180 *
181 * The configuration Address is configure as type-I (bits[1:0] = '01') due to 181 * The configuration Address is configure as type-I (bits[1:0] = '01') due to
182 * PCI spec referring to P2P. 182 * PCI spec referring to P2P.
183 * 183 *
184 *********************************************************************/ 184 *********************************************************************/
185 void pciOverBridgeWriteConfigReg (PCI_HOST host, 185 void pciOverBridgeWriteConfigReg (PCI_HOST host,
186 unsigned int regOffset, 186 unsigned int regOffset,
187 unsigned int pciDevNum, 187 unsigned int pciDevNum,
188 unsigned int busNum, unsigned int data) 188 unsigned int busNum, unsigned int data)
189 { 189 {
190 unsigned int DataForReg; 190 unsigned int DataForReg;
191 unsigned int functionNum; 191 unsigned int functionNum;
192 192
193 functionNum = regOffset & 0x00000700; 193 functionNum = regOffset & 0x00000700;
194 pciDevNum = pciDevNum << 11; 194 pciDevNum = pciDevNum << 11;
195 regOffset = regOffset & 0xff; 195 regOffset = regOffset & 0xff;
196 busNum = busNum << 16; 196 busNum = busNum << 16;
197 if (pciDevNum == SELF) { /* This board */ 197 if (pciDevNum == SELF) { /* This board */
198 DataForReg = (regOffset | pciDevNum | functionNum) | BIT0; 198 DataForReg = (regOffset | pciDevNum | functionNum) | BIT0;
199 } else { 199 } else {
200 DataForReg = (regOffset | pciDevNum | functionNum | busNum) | 200 DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
201 BIT31 | BIT0; 201 BIT31 | BIT0;
202 } 202 }
203 GT_REG_WRITE (pci_configuration_address[host], DataForReg); 203 GT_REG_WRITE (pci_configuration_address[host], DataForReg);
204 if (pciDevNum == SELF) { /* This board */ 204 if (pciDevNum == SELF) { /* This board */
205 GT_REG_WRITE (pci_configuration_data[host], data); 205 GT_REG_WRITE (pci_configuration_data[host], data);
206 } else { /* configuration Transaction over the pci. */ 206 } else { /* configuration Transaction over the pci. */
207 207
208 /* The PCI is working in LE Mode So it swap the Data. */ 208 /* The PCI is working in LE Mode So it swap the Data. */
209 GT_REG_WRITE (pci_configuration_data[host], WORD_SWAP (data)); 209 GT_REG_WRITE (pci_configuration_data[host], WORD_SWAP (data));
210 } 210 }
211 } 211 }
212 212
213 213
214 /******************************************************************** 214 /********************************************************************
215 * pciOverBridgeReadConfigReg - Read from a PCIn configuration register where 215 * pciOverBridgeReadConfigReg - Read from a PCIn configuration register where
216 * the agent target locate on another PCI bus. 216 * the agent target locate on another PCI bus.
217 * - Make sure the GT is configured as a master 217 * - Make sure the GT is configured as a master
218 * before reading from another device on the PCI. 218 * before reading from another device on the PCI.
219 * - The function takes care of Big/Little endian 219 * - The function takes care of Big/Little endian
220 * conversion. 220 * conversion.
221 * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI 221 * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
222 * spec). (configuration register offset.) 222 * spec). (configuration register offset.)
223 * pciDevNum: The device number needs to be addressed. 223 * pciDevNum: The device number needs to be addressed.
224 * busNum: the Bus number where the agent is place. 224 * busNum: the Bus number where the agent is place.
225 * RETURNS: data , if the data == 0xffffffff check the master abort bit in the 225 * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
226 * cause register to make sure the data is valid 226 * cause register to make sure the data is valid
227 * 227 *
228 * Configuration Address 0xCF8: 228 * Configuration Address 0xCF8:
229 * 229 *
230 * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number 230 * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
231 * |congif|Reserved| Bus |Device|Function|Register|01| 231 * |congif|Reserved| Bus |Device|Function|Register|01|
232 * |Enable| |Number|Number| Number | Number | | <=field Name 232 * |Enable| |Number|Number| Number | Number | | <=field Name
233 * 233 *
234 *********************************************************************/ 234 *********************************************************************/
235 unsigned int pciOverBridgeReadConfigReg (PCI_HOST host, 235 unsigned int pciOverBridgeReadConfigReg (PCI_HOST host,
236 unsigned int regOffset, 236 unsigned int regOffset,
237 unsigned int pciDevNum, 237 unsigned int pciDevNum,
238 unsigned int busNum) 238 unsigned int busNum)
239 { 239 {
240 unsigned int DataForReg; 240 unsigned int DataForReg;
241 unsigned int data; 241 unsigned int data;
242 unsigned int functionNum; 242 unsigned int functionNum;
243 243
244 functionNum = regOffset & 0x00000700; 244 functionNum = regOffset & 0x00000700;
245 pciDevNum = pciDevNum << 11; 245 pciDevNum = pciDevNum << 11;
246 regOffset = regOffset & 0xff; 246 regOffset = regOffset & 0xff;
247 busNum = busNum << 16; 247 busNum = busNum << 16;
248 if (pciDevNum == SELF) { /* This board */ 248 if (pciDevNum == SELF) { /* This board */
249 DataForReg = (regOffset | pciDevNum | functionNum) | BIT31; 249 DataForReg = (regOffset | pciDevNum | functionNum) | BIT31;
250 } else { /* agent on another bus */ 250 } else { /* agent on another bus */
251 251
252 DataForReg = (regOffset | pciDevNum | functionNum | busNum) | 252 DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
253 BIT0 | BIT31; 253 BIT0 | BIT31;
254 } 254 }
255 GT_REG_WRITE (pci_configuration_address[host], DataForReg); 255 GT_REG_WRITE (pci_configuration_address[host], DataForReg);
256 if (pciDevNum == SELF) { /* This board */ 256 if (pciDevNum == SELF) { /* This board */
257 GT_REG_READ (pci_configuration_data[host], &data); 257 GT_REG_READ (pci_configuration_data[host], &data);
258 return data; 258 return data;
259 } else { /* The PCI is working in LE Mode So it swap the Data. */ 259 } else { /* The PCI is working in LE Mode So it swap the Data. */
260 260
261 GT_REG_READ (pci_configuration_data[host], &data); 261 GT_REG_READ (pci_configuration_data[host], &data);
262 return WORD_SWAP (data); 262 return WORD_SWAP (data);
263 } 263 }
264 } 264 }
265 265
266 /******************************************************************** 266 /********************************************************************
267 * pciGetRegOffset - Gets the register offset for this region config. 267 * pciGetRegOffset - Gets the register offset for this region config.
268 * 268 *
269 * INPUT: Bus, Region - The bus and region we ask for its base address. 269 * INPUT: Bus, Region - The bus and region we ask for its base address.
270 * OUTPUT: N/A 270 * OUTPUT: N/A
271 * RETURNS: PCI register base address 271 * RETURNS: PCI register base address
272 *********************************************************************/ 272 *********************************************************************/
273 static unsigned int pciGetRegOffset (PCI_HOST host, PCI_REGION region) 273 static unsigned int pciGetRegOffset (PCI_HOST host, PCI_REGION region)
274 { 274 {
275 switch (host) { 275 switch (host) {
276 case PCI_HOST0: 276 case PCI_HOST0:
277 switch (region) { 277 switch (region) {
278 case PCI_IO: 278 case PCI_IO:
279 return PCI_0I_O_LOW_DECODE_ADDRESS; 279 return PCI_0I_O_LOW_DECODE_ADDRESS;
280 case PCI_REGION0: 280 case PCI_REGION0:
281 return PCI_0MEMORY0_LOW_DECODE_ADDRESS; 281 return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
282 case PCI_REGION1: 282 case PCI_REGION1:
283 return PCI_0MEMORY1_LOW_DECODE_ADDRESS; 283 return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
284 case PCI_REGION2: 284 case PCI_REGION2:
285 return PCI_0MEMORY2_LOW_DECODE_ADDRESS; 285 return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
286 case PCI_REGION3: 286 case PCI_REGION3:
287 return PCI_0MEMORY3_LOW_DECODE_ADDRESS; 287 return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
288 } 288 }
289 case PCI_HOST1: 289 case PCI_HOST1:
290 switch (region) { 290 switch (region) {
291 case PCI_IO: 291 case PCI_IO:
292 return PCI_1I_O_LOW_DECODE_ADDRESS; 292 return PCI_1I_O_LOW_DECODE_ADDRESS;
293 case PCI_REGION0: 293 case PCI_REGION0:
294 return PCI_1MEMORY0_LOW_DECODE_ADDRESS; 294 return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
295 case PCI_REGION1: 295 case PCI_REGION1:
296 return PCI_1MEMORY1_LOW_DECODE_ADDRESS; 296 return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
297 case PCI_REGION2: 297 case PCI_REGION2:
298 return PCI_1MEMORY2_LOW_DECODE_ADDRESS; 298 return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
299 case PCI_REGION3: 299 case PCI_REGION3:
300 return PCI_1MEMORY3_LOW_DECODE_ADDRESS; 300 return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
301 } 301 }
302 } 302 }
303 return PCI_0MEMORY0_LOW_DECODE_ADDRESS; 303 return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
304 } 304 }
305 305
306 static unsigned int pciGetRemapOffset (PCI_HOST host, PCI_REGION region) 306 static unsigned int pciGetRemapOffset (PCI_HOST host, PCI_REGION region)
307 { 307 {
308 switch (host) { 308 switch (host) {
309 case PCI_HOST0: 309 case PCI_HOST0:
310 switch (region) { 310 switch (region) {
311 case PCI_IO: 311 case PCI_IO:
312 return PCI_0I_O_ADDRESS_REMAP; 312 return PCI_0I_O_ADDRESS_REMAP;
313 case PCI_REGION0: 313 case PCI_REGION0:
314 return PCI_0MEMORY0_ADDRESS_REMAP; 314 return PCI_0MEMORY0_ADDRESS_REMAP;
315 case PCI_REGION1: 315 case PCI_REGION1:
316 return PCI_0MEMORY1_ADDRESS_REMAP; 316 return PCI_0MEMORY1_ADDRESS_REMAP;
317 case PCI_REGION2: 317 case PCI_REGION2:
318 return PCI_0MEMORY2_ADDRESS_REMAP; 318 return PCI_0MEMORY2_ADDRESS_REMAP;
319 case PCI_REGION3: 319 case PCI_REGION3:
320 return PCI_0MEMORY3_ADDRESS_REMAP; 320 return PCI_0MEMORY3_ADDRESS_REMAP;
321 } 321 }
322 case PCI_HOST1: 322 case PCI_HOST1:
323 switch (region) { 323 switch (region) {
324 case PCI_IO: 324 case PCI_IO:
325 return PCI_1I_O_ADDRESS_REMAP; 325 return PCI_1I_O_ADDRESS_REMAP;
326 case PCI_REGION0: 326 case PCI_REGION0:
327 return PCI_1MEMORY0_ADDRESS_REMAP; 327 return PCI_1MEMORY0_ADDRESS_REMAP;
328 case PCI_REGION1: 328 case PCI_REGION1:
329 return PCI_1MEMORY1_ADDRESS_REMAP; 329 return PCI_1MEMORY1_ADDRESS_REMAP;
330 case PCI_REGION2: 330 case PCI_REGION2:
331 return PCI_1MEMORY2_ADDRESS_REMAP; 331 return PCI_1MEMORY2_ADDRESS_REMAP;
332 case PCI_REGION3: 332 case PCI_REGION3:
333 return PCI_1MEMORY3_ADDRESS_REMAP; 333 return PCI_1MEMORY3_ADDRESS_REMAP;
334 } 334 }
335 } 335 }
336 return PCI_0MEMORY0_ADDRESS_REMAP; 336 return PCI_0MEMORY0_ADDRESS_REMAP;
337 } 337 }
338 338
339 bool pciMapSpace (PCI_HOST host, PCI_REGION region, unsigned int remapBase, 339 bool pciMapSpace (PCI_HOST host, PCI_REGION region, unsigned int remapBase,
340 unsigned int bankBase, unsigned int bankLength) 340 unsigned int bankBase, unsigned int bankLength)
341 { 341 {
342 unsigned int low = 0xfff; 342 unsigned int low = 0xfff;
343 unsigned int high = 0x0; 343 unsigned int high = 0x0;
344 unsigned int regOffset = pciGetRegOffset (host, region); 344 unsigned int regOffset = pciGetRegOffset (host, region);
345 unsigned int remapOffset = pciGetRemapOffset (host, region); 345 unsigned int remapOffset = pciGetRemapOffset (host, region);
346 346
347 if (bankLength != 0) { 347 if (bankLength != 0) {
348 low = (bankBase >> 20) & 0xfff; 348 low = (bankBase >> 20) & 0xfff;
349 high = ((bankBase + bankLength) >> 20) - 1; 349 high = ((bankBase + bankLength) >> 20) - 1;
350 } 350 }
351 351
352 GT_REG_WRITE (regOffset, low | (1 << 24)); /* no swapping */ 352 GT_REG_WRITE (regOffset, low | (1 << 24)); /* no swapping */
353 GT_REG_WRITE (regOffset + 8, high); 353 GT_REG_WRITE (regOffset + 8, high);
354 354
355 if (bankLength != 0) { /* must do AFTER writing maps */ 355 if (bankLength != 0) { /* must do AFTER writing maps */
356 GT_REG_WRITE (remapOffset, remapBase >> 20); /* sorry, 32 bits only. 356 GT_REG_WRITE (remapOffset, remapBase >> 20); /* sorry, 32 bits only.
357 dont support upper 32 357 dont support upper 32
358 in this driver */ 358 in this driver */
359 } 359 }
360 return true; 360 return true;
361 } 361 }
362 362
363 unsigned int pciGetSpaceBase (PCI_HOST host, PCI_REGION region) 363 unsigned int pciGetSpaceBase (PCI_HOST host, PCI_REGION region)
364 { 364 {
365 unsigned int low; 365 unsigned int low;
366 unsigned int regOffset = pciGetRegOffset (host, region); 366 unsigned int regOffset = pciGetRegOffset (host, region);
367 367
368 GT_REG_READ (regOffset, &low); 368 GT_REG_READ (regOffset, &low);
369 return (low & 0xfff) << 20; 369 return (low & 0xfff) << 20;
370 } 370 }
371 371
372 unsigned int pciGetSpaceSize (PCI_HOST host, PCI_REGION region) 372 unsigned int pciGetSpaceSize (PCI_HOST host, PCI_REGION region)
373 { 373 {
374 unsigned int low, high; 374 unsigned int low, high;
375 unsigned int regOffset = pciGetRegOffset (host, region); 375 unsigned int regOffset = pciGetRegOffset (host, region);
376 376
377 GT_REG_READ (regOffset, &low); 377 GT_REG_READ (regOffset, &low);
378 GT_REG_READ (regOffset + 8, &high); 378 GT_REG_READ (regOffset + 8, &high);
379 high &= 0xfff; 379 high &= 0xfff;
380 low &= 0xfff; 380 low &= 0xfff;
381 if (high <= low) 381 if (high <= low)
382 return 0; 382 return 0;
383 return (high + 1 - low) << 20; 383 return (high + 1 - low) << 20;
384 } 384 }
385 385
386 /******************************************************************** 386 /********************************************************************
387 * pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave. 387 * pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
388 * 388 *
389 * Inputs: base and size of PCI SCS 389 * Inputs: base and size of PCI SCS
390 *********************************************************************/ 390 *********************************************************************/
391 void pciMapMemoryBank (PCI_HOST host, MEMORY_BANK bank, 391 void pciMapMemoryBank (PCI_HOST host, MEMORY_BANK bank,
392 unsigned int pciDramBase, unsigned int pciDramSize) 392 unsigned int pciDramBase, unsigned int pciDramSize)
393 { 393 {
394 pciDramBase = pciDramBase & 0xfffff000; 394 pciDramBase = pciDramBase & 0xfffff000;
395 pciDramBase = pciDramBase | (pciReadConfigReg (host, 395 pciDramBase = pciDramBase | (pciReadConfigReg (host,
396 PCI_SCS_0_BASE_ADDRESS 396 PCI_SCS_0_BASE_ADDRESS
397 + 4 * bank, 397 + 4 * bank,
398 SELF) & 0x00000fff); 398 SELF) & 0x00000fff);
399 pciWriteConfigReg (host, PCI_SCS_0_BASE_ADDRESS + 4 * bank, SELF, 399 pciWriteConfigReg (host, PCI_SCS_0_BASE_ADDRESS + 4 * bank, SELF,
400 pciDramBase); 400 pciDramBase);
401 if (pciDramSize == 0) 401 if (pciDramSize == 0)
402 pciDramSize++; 402 pciDramSize++;
403 GT_REG_WRITE (pci_scs_bank_size[host][bank], pciDramSize - 1); 403 GT_REG_WRITE (pci_scs_bank_size[host][bank], pciDramSize - 1);
404 } 404 }
405 405
406 406
407 /******************************************************************** 407 /********************************************************************
408 * pciSetRegionFeatures - This function modifys one of the 8 regions with 408 * pciSetRegionFeatures - This function modifys one of the 8 regions with
409 * feature bits given as an input. 409 * feature bits given as an input.
410 * - Be advised to check the spec before modifying them. 410 * - Be advised to check the spec before modifying them.
411 * Inputs: PCI_PROTECT_REGION region - one of the eight regions. 411 * Inputs: PCI_PROTECT_REGION region - one of the eight regions.
412 * unsigned int features - See file: pci.h there are defintion for those 412 * unsigned int features - See file: pci.h there are defintion for those
413 * region features. 413 * region features.
414 * unsigned int baseAddress - The region base Address. 414 * unsigned int baseAddress - The region base Address.
415 * unsigned int topAddress - The region top Address. 415 * unsigned int topAddress - The region top Address.
416 * Returns: false if one of the parameters is erroneous true otherwise. 416 * Returns: false if one of the parameters is erroneous true otherwise.
417 *********************************************************************/ 417 *********************************************************************/
418 bool pciSetRegionFeatures (PCI_HOST host, PCI_ACCESS_REGIONS region, 418 bool pciSetRegionFeatures (PCI_HOST host, PCI_ACCESS_REGIONS region,
419 unsigned int features, unsigned int baseAddress, 419 unsigned int features, unsigned int baseAddress,
420 unsigned int regionLength) 420 unsigned int regionLength)
421 { 421 {
422 unsigned int accessLow; 422 unsigned int accessLow;
423 unsigned int accessHigh; 423 unsigned int accessHigh;
424 unsigned int accessTop = baseAddress + regionLength; 424 unsigned int accessTop = baseAddress + regionLength;
425 425
426 if (regionLength == 0) { /* close the region. */ 426 if (regionLength == 0) { /* close the region. */
427 pciDisableAccessRegion (host, region); 427 pciDisableAccessRegion (host, region);
428 return true; 428 return true;
429 } 429 }
430 /* base Address is store is bits [11:0] */ 430 /* base Address is store is bits [11:0] */
431 accessLow = (baseAddress & 0xfff00000) >> 20; 431 accessLow = (baseAddress & 0xfff00000) >> 20;
432 /* All the features are update according to the defines in pci.h (to be on 432 /* All the features are update according to the defines in pci.h (to be on
433 the safe side we disable bits: [11:0] */ 433 the safe side we disable bits: [11:0] */
434 accessLow = accessLow | (features & 0xfffff000); 434 accessLow = accessLow | (features & 0xfffff000);
435 /* write to the Low Access Region register */ 435 /* write to the Low Access Region register */
436 GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region, 436 GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
437 accessLow); 437 accessLow);
438 438
439 accessHigh = (accessTop & 0xfff00000) >> 20; 439 accessHigh = (accessTop & 0xfff00000) >> 20;
440 440
441 /* write to the High Access Region register */ 441 /* write to the High Access Region register */
442 GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region, 442 GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region,
443 accessHigh - 1); 443 accessHigh - 1);
444 return true; 444 return true;
445 } 445 }
446 446
447 /******************************************************************** 447 /********************************************************************
448 * pciDisableAccessRegion - Disable The given Region by writing MAX size 448 * pciDisableAccessRegion - Disable The given Region by writing MAX size
449 * to its low Address and MIN size to its high Address. 449 * to its low Address and MIN size to its high Address.
450 * 450 *
451 * Inputs: PCI_ACCESS_REGIONS region - The region we to be Disabled. 451 * Inputs: PCI_ACCESS_REGIONS region - The region we to be Disabled.
452 * Returns: N/A. 452 * Returns: N/A.
453 *********************************************************************/ 453 *********************************************************************/
454 void pciDisableAccessRegion (PCI_HOST host, PCI_ACCESS_REGIONS region) 454 void pciDisableAccessRegion (PCI_HOST host, PCI_ACCESS_REGIONS region)
455 { 455 {
456 /* writing back the registers default values. */ 456 /* writing back the registers default values. */
457 GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region, 457 GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
458 0x01001fff); 458 0x01001fff);
459 GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region, 0); 459 GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region, 0);
460 } 460 }
461 461
462 /******************************************************************** 462 /********************************************************************
463 * pciArbiterEnable - Enables PCI-0`s Arbitration mechanism. 463 * pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
464 * 464 *
465 * Inputs: N/A 465 * Inputs: N/A
466 * Returns: true. 466 * Returns: true.
467 *********************************************************************/ 467 *********************************************************************/
468 bool pciArbiterEnable (PCI_HOST host) 468 bool pciArbiterEnable (PCI_HOST host)
469 { 469 {
470 unsigned int regData; 470 unsigned int regData;
471 471
472 GT_REG_READ (pci_arbiter_control[host], &regData); 472 GT_REG_READ (pci_arbiter_control[host], &regData);
473 GT_REG_WRITE (pci_arbiter_control[host], regData | BIT31); 473 GT_REG_WRITE (pci_arbiter_control[host], regData | BIT31);
474 return true; 474 return true;
475 } 475 }
476 476
477 /******************************************************************** 477 /********************************************************************
478 * pciArbiterDisable - Disable PCI-0`s Arbitration mechanism. 478 * pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
479 * 479 *
480 * Inputs: N/A 480 * Inputs: N/A
481 * Returns: true 481 * Returns: true
482 *********************************************************************/ 482 *********************************************************************/
483 bool pciArbiterDisable (PCI_HOST host) 483 bool pciArbiterDisable (PCI_HOST host)
484 { 484 {
485 unsigned int regData; 485 unsigned int regData;
486 486
487 GT_REG_READ (pci_arbiter_control[host], &regData); 487 GT_REG_READ (pci_arbiter_control[host], &regData);
488 GT_REG_WRITE (pci_arbiter_control[host], regData & 0x7fffffff); 488 GT_REG_WRITE (pci_arbiter_control[host], regData & 0x7fffffff);
489 return true; 489 return true;
490 } 490 }
491 491
492 /******************************************************************** 492 /********************************************************************
493 * pciParkingDisable - Park on last option disable, with this function you can 493 * pciParkingDisable - Park on last option disable, with this function you can
494 * disable the park on last mechanism for each agent. 494 * disable the park on last mechanism for each agent.
495 * disabling this option for all agents results parking 495 * disabling this option for all agents results parking
496 * on the internal master. 496 * on the internal master.
497 * 497 *
498 * Inputs: PCI_AGENT_PARK internalAgent - parking Disable for internal agent. 498 * Inputs: PCI_AGENT_PARK internalAgent - parking Disable for internal agent.
499 * PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent. 499 * PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
500 * PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent. 500 * PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
501 * PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent. 501 * PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
502 * PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent. 502 * PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
503 * PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent. 503 * PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
504 * PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent. 504 * PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
505 * Returns: true 505 * Returns: true
506 *********************************************************************/ 506 *********************************************************************/
507 bool pciParkingDisable (PCI_HOST host, PCI_AGENT_PARK internalAgent, 507 bool pciParkingDisable (PCI_HOST host, PCI_AGENT_PARK internalAgent,
508 PCI_AGENT_PARK externalAgent0, 508 PCI_AGENT_PARK externalAgent0,
509 PCI_AGENT_PARK externalAgent1, 509 PCI_AGENT_PARK externalAgent1,
510 PCI_AGENT_PARK externalAgent2, 510 PCI_AGENT_PARK externalAgent2,
511 PCI_AGENT_PARK externalAgent3, 511 PCI_AGENT_PARK externalAgent3,
512 PCI_AGENT_PARK externalAgent4, 512 PCI_AGENT_PARK externalAgent4,
513 PCI_AGENT_PARK externalAgent5) 513 PCI_AGENT_PARK externalAgent5)
514 { 514 {
515 unsigned int regData; 515 unsigned int regData;
516 unsigned int writeData; 516 unsigned int writeData;
517 517
518 GT_REG_READ (pci_arbiter_control[host], &regData); 518 GT_REG_READ (pci_arbiter_control[host], &regData);
519 writeData = (internalAgent << 14) + (externalAgent0 << 15) + 519 writeData = (internalAgent << 14) + (externalAgent0 << 15) +
520 (externalAgent1 << 16) + (externalAgent2 << 17) + 520 (externalAgent1 << 16) + (externalAgent2 << 17) +
521 (externalAgent3 << 18) + (externalAgent4 << 19) + 521 (externalAgent3 << 18) + (externalAgent4 << 19) +
522 (externalAgent5 << 20); 522 (externalAgent5 << 20);
523 regData = (regData & ~(0x7f << 14)) | writeData; 523 regData = (regData & ~(0x7f << 14)) | writeData;
524 GT_REG_WRITE (pci_arbiter_control[host], regData); 524 GT_REG_WRITE (pci_arbiter_control[host], regData);
525 return true; 525 return true;
526 } 526 }
527 527
528 /******************************************************************** 528 /********************************************************************
529 * pciSetRegionSnoopMode - This function modifys one of the 4 regions which 529 * pciSetRegionSnoopMode - This function modifys one of the 4 regions which
530 * supports Cache Coherency in the PCI_n interface. 530 * supports Cache Coherency in the PCI_n interface.
531 * Inputs: region - One of the four regions. 531 * Inputs: region - One of the four regions.
532 * snoopType - There is four optional Types: 532 * snoopType - There is four optional Types:
533 * 1. No Snoop. 533 * 1. No Snoop.
534 * 2. Snoop to WT region. 534 * 2. Snoop to WT region.
535 * 3. Snoop to WB region. 535 * 3. Snoop to WB region.
536 * 4. Snoop & Invalidate to WB region. 536 * 4. Snoop & Invalidate to WB region.
537 * baseAddress - Base Address of this region. 537 * baseAddress - Base Address of this region.
538 * regionLength - Region length. 538 * regionLength - Region length.
539 * Returns: false if one of the parameters is wrong otherwise return true. 539 * Returns: false if one of the parameters is wrong otherwise return true.
540 *********************************************************************/ 540 *********************************************************************/
541 bool pciSetRegionSnoopMode (PCI_HOST host, PCI_SNOOP_REGION region, 541 bool pciSetRegionSnoopMode (PCI_HOST host, PCI_SNOOP_REGION region,
542 PCI_SNOOP_TYPE snoopType, 542 PCI_SNOOP_TYPE snoopType,
543 unsigned int baseAddress, 543 unsigned int baseAddress,
544 unsigned int regionLength) 544 unsigned int regionLength)
545 { 545 {
546 unsigned int snoopXbaseAddress; 546 unsigned int snoopXbaseAddress;
547 unsigned int snoopXtopAddress; 547 unsigned int snoopXtopAddress;
548 unsigned int data; 548 unsigned int data;
549 unsigned int snoopHigh = baseAddress + regionLength; 549 unsigned int snoopHigh = baseAddress + regionLength;
550 550
551 if ((region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB)) 551 if ((region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB))
552 return false; 552 return false;
553 snoopXbaseAddress = 553 snoopXbaseAddress =
554 pci_snoop_control_base_0_low[host] + 0x10 * region; 554 pci_snoop_control_base_0_low[host] + 0x10 * region;
555 snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region; 555 snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
556 if (regionLength == 0) { /* closing the region */ 556 if (regionLength == 0) { /* closing the region */
557 GT_REG_WRITE (snoopXbaseAddress, 0x0000ffff); 557 GT_REG_WRITE (snoopXbaseAddress, 0x0000ffff);
558 GT_REG_WRITE (snoopXtopAddress, 0); 558 GT_REG_WRITE (snoopXtopAddress, 0);
559 return true; 559 return true;
560 } 560 }
561 baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */ 561 baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
562 data = (baseAddress >> 20) | snoopType << 12; 562 data = (baseAddress >> 20) | snoopType << 12;
563 GT_REG_WRITE (snoopXbaseAddress, data); 563 GT_REG_WRITE (snoopXbaseAddress, data);
564 snoopHigh = (snoopHigh & 0xfff00000) >> 20; 564 snoopHigh = (snoopHigh & 0xfff00000) >> 20;
565 GT_REG_WRITE (snoopXtopAddress, snoopHigh - 1); 565 GT_REG_WRITE (snoopXtopAddress, snoopHigh - 1);
566 return true; 566 return true;
567 } 567 }
568 568
569 /* 569 /*
570 * 570 *
571 */ 571 */
572 572
573 static int gt_read_config_dword (struct pci_controller *hose, 573 static int gt_read_config_dword (struct pci_controller *hose,
574 pci_dev_t dev, int offset, u32 * value) 574 pci_dev_t dev, int offset, u32 * value)
575 { 575 {
576 int bus = PCI_BUS (dev); 576 int bus = PCI_BUS (dev);
577 577
578 if ((bus == local_buses[0]) || (bus == local_buses[1])) { 578 if ((bus == local_buses[0]) || (bus == local_buses[1])) {
579 *value = pciReadConfigReg ((PCI_HOST) hose->cfg_addr, offset, 579 *value = pciReadConfigReg ((PCI_HOST) hose->cfg_addr, offset,
580 PCI_DEV (dev)); 580 PCI_DEV (dev));
581 } else { 581 } else {
582 *value = pciOverBridgeReadConfigReg ((PCI_HOST) hose-> 582 *value = pciOverBridgeReadConfigReg ((PCI_HOST) hose->
583 cfg_addr, offset, 583 cfg_addr, offset,
584 PCI_DEV (dev), bus); 584 PCI_DEV (dev), bus);
585 } 585 }
586 return 0; 586 return 0;
587 } 587 }
588 588
589 static int gt_write_config_dword (struct pci_controller *hose, 589 static int gt_write_config_dword (struct pci_controller *hose,
590 pci_dev_t dev, int offset, u32 value) 590 pci_dev_t dev, int offset, u32 value)
591 { 591 {
592 int bus = PCI_BUS (dev); 592 int bus = PCI_BUS (dev);
593 593
594 if ((bus == local_buses[0]) || (bus == local_buses[1])) { 594 if ((bus == local_buses[0]) || (bus == local_buses[1])) {
595 pciWriteConfigReg ((PCI_HOST) hose->cfg_addr, offset, 595 pciWriteConfigReg ((PCI_HOST) hose->cfg_addr, offset,
596 PCI_DEV (dev), value); 596 PCI_DEV (dev), value);
597 } else { 597 } else {
598 pciOverBridgeWriteConfigReg ((PCI_HOST) hose->cfg_addr, 598 pciOverBridgeWriteConfigReg ((PCI_HOST) hose->cfg_addr,
599 offset, PCI_DEV (dev), value, 599 offset, PCI_DEV (dev), value,
600 bus); 600 bus);
601 } 601 }
602 return 0; 602 return 0;
603 } 603 }
604 604
605 /* 605 /*
606 * 606 *
607 */ 607 */
608 608
609 static void gt_setup_ide (struct pci_controller *hose, 609 static void gt_setup_ide (struct pci_controller *hose,
610 pci_dev_t dev, struct pci_config_table *entry) 610 pci_dev_t dev, struct pci_config_table *entry)
611 { 611 {
612 static const int ide_bar[] = { 8, 4, 8, 4, 0, 0 }; 612 static const int ide_bar[] = { 8, 4, 8, 4, 0, 0 };
613 u32 bar_response, bar_value; 613 u32 bar_response, bar_value;
614 int bar; 614 int bar;
615 615
616 for (bar = 0; bar < 6; bar++) { 616 for (bar = 0; bar < 6; bar++) {
617 pci_write_config_dword (dev, PCI_BASE_ADDRESS_0 + bar * 4, 617 pci_write_config_dword (dev, PCI_BASE_ADDRESS_0 + bar * 4,
618 0x0); 618 0x0);
619 pci_read_config_dword (dev, PCI_BASE_ADDRESS_0 + bar * 4, 619 pci_read_config_dword (dev, PCI_BASE_ADDRESS_0 + bar * 4,
620 &bar_response); 620 &bar_response);
621 621
622 pciauto_region_allocate (bar_response & 622 pciauto_region_allocate (bar_response &
623 PCI_BASE_ADDRESS_SPACE_IO ? hose-> 623 PCI_BASE_ADDRESS_SPACE_IO ? hose->
624 pci_io : hose->pci_mem, ide_bar[bar], 624 pci_io : hose->pci_mem, ide_bar[bar],
625 &bar_value); 625 &bar_value);
626 626
627 pci_write_config_dword (dev, PCI_BASE_ADDRESS_0 + bar * 4, 627 pci_write_config_dword (dev, PCI_BASE_ADDRESS_0 + bar * 4,
628 bar_value); 628 bar_value);
629 } 629 }
630 } 630 }
631 631
632 static void gt_fixup_irq (struct pci_controller *hose, pci_dev_t dev) 632 static void gt_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
633 { 633 {
634 unsigned char pin, irq; 634 unsigned char pin, irq;
635 635
636 pci_read_config_byte (dev, PCI_INTERRUPT_PIN, &pin); 636 pci_read_config_byte (dev, PCI_INTERRUPT_PIN, &pin);
637 637
638 if (pin == 1) { /* only allow INT A */ 638 if (pin == 1) { /* only allow INT A */
639 irq = pci_irq_swizzle[(PCI_HOST) hose-> 639 irq = pci_irq_swizzle[(PCI_HOST) hose->
640 cfg_addr][PCI_DEV (dev)]; 640 cfg_addr][PCI_DEV (dev)];
641 if (irq) 641 if (irq)
642 pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq); 642 pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
643 } 643 }
644 } 644 }
645 645
646 struct pci_config_table gt_config_table[] = { 646 struct pci_config_table gt_config_table[] = {
647 {PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, 647 {PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
648 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide}, 648 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
649 649
650 {} 650 {}
651 }; 651 };
652 652
653 struct pci_controller pci0_hose = { 653 struct pci_controller pci0_hose = {
654 fixup_irq:gt_fixup_irq, 654 fixup_irq:gt_fixup_irq,
655 config_table:gt_config_table, 655 config_table:gt_config_table,
656 }; 656 };
657 657
658 struct pci_controller pci1_hose = { 658 struct pci_controller pci1_hose = {
659 fixup_irq:gt_fixup_irq, 659 fixup_irq:gt_fixup_irq,
660 config_table:gt_config_table, 660 config_table:gt_config_table,
661 }; 661 };
662 662
663 void pci_init_board (void) 663 void pci_init_board (void)
664 { 664 {
665 unsigned int command; 665 unsigned int command;
666 666
667 pci0_hose.first_busno = 0; 667 pci0_hose.first_busno = 0;
668 pci0_hose.last_busno = 0xff; 668 pci0_hose.last_busno = 0xff;
669 local_buses[0] = pci0_hose.first_busno; 669 local_buses[0] = pci0_hose.first_busno;
670 /* PCI memory space */ 670 /* PCI memory space */
671 pci_set_region (pci0_hose.regions + 0, 671 pci_set_region (pci0_hose.regions + 0,
672 CFG_PCI0_0_MEM_SPACE, 672 CFG_PCI0_0_MEM_SPACE,
673 CFG_PCI0_0_MEM_SPACE, 673 CFG_PCI0_0_MEM_SPACE,
674 CFG_PCI0_MEM_SIZE, PCI_REGION_MEM); 674 CFG_PCI0_MEM_SIZE, PCI_REGION_MEM);
675 675
676 /* PCI I/O space */ 676 /* PCI I/O space */
677 pci_set_region (pci0_hose.regions + 1, 677 pci_set_region (pci0_hose.regions + 1,
678 CFG_PCI0_IO_SPACE_PCI, 678 CFG_PCI0_IO_SPACE_PCI,
679 CFG_PCI0_IO_SPACE, CFG_PCI0_IO_SIZE, PCI_REGION_IO); 679 CFG_PCI0_IO_SPACE, CFG_PCI0_IO_SIZE, PCI_REGION_IO);
680 680
681 pci_set_ops (&pci0_hose, 681 pci_set_ops (&pci0_hose,
682 pci_hose_read_config_byte_via_dword, 682 pci_hose_read_config_byte_via_dword,
683 pci_hose_read_config_word_via_dword, 683 pci_hose_read_config_word_via_dword,
684 gt_read_config_dword, 684 gt_read_config_dword,
685 pci_hose_write_config_byte_via_dword, 685 pci_hose_write_config_byte_via_dword,
686 pci_hose_write_config_word_via_dword, 686 pci_hose_write_config_word_via_dword,
687 gt_write_config_dword); 687 gt_write_config_dword);
688 688
689 pci0_hose.region_count = 2; 689 pci0_hose.region_count = 2;
690 690
691 pci0_hose.cfg_addr = (unsigned int *) PCI_HOST0; 691 pci0_hose.cfg_addr = (unsigned int *) PCI_HOST0;
692 692
693 pci_register_hose (&pci0_hose); 693 pci_register_hose (&pci0_hose);
694 694
695 pciArbiterEnable (PCI_HOST0); 695 pciArbiterEnable (PCI_HOST0);
696 pciParkingDisable (PCI_HOST0, 1, 1, 1, 1, 1, 1, 1); 696 pciParkingDisable (PCI_HOST0, 1, 1, 1, 1, 1, 1, 1);
697 697
698 command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF); 698 command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
699 command |= PCI_COMMAND_MASTER; 699 command |= PCI_COMMAND_MASTER;
700 pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command); 700 pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
701 701
702 pci0_hose.last_busno = pci_hose_scan (&pci0_hose); 702 pci0_hose.last_busno = pci_hose_scan (&pci0_hose);
703 703
704 command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF); 704 command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
705 command |= PCI_COMMAND_MEMORY; 705 command |= PCI_COMMAND_MEMORY;
706 pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command); 706 pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
707 707
708 pci1_hose.first_busno = pci0_hose.last_busno + 1; 708 pci1_hose.first_busno = pci0_hose.last_busno + 1;
709 pci1_hose.last_busno = 0xff; 709 pci1_hose.last_busno = 0xff;
710 pci1_hose.current_busno = pci0_hose.current_busno; 710 pci1_hose.current_busno = pci0_hose.current_busno;
711 local_buses[1] = pci1_hose.first_busno; 711 local_buses[1] = pci1_hose.first_busno;
712 712
713 /* PCI memory space */ 713 /* PCI memory space */
714 pci_set_region (pci1_hose.regions + 0, 714 pci_set_region (pci1_hose.regions + 0,
715 CFG_PCI1_0_MEM_SPACE, 715 CFG_PCI1_0_MEM_SPACE,
716 CFG_PCI1_0_MEM_SPACE, 716 CFG_PCI1_0_MEM_SPACE,
717 CFG_PCI1_MEM_SIZE, PCI_REGION_MEM); 717 CFG_PCI1_MEM_SIZE, PCI_REGION_MEM);
718 718
719 /* PCI I/O space */ 719 /* PCI I/O space */
720 pci_set_region (pci1_hose.regions + 1, 720 pci_set_region (pci1_hose.regions + 1,
721 CFG_PCI1_IO_SPACE_PCI, 721 CFG_PCI1_IO_SPACE_PCI,
722 CFG_PCI1_IO_SPACE, CFG_PCI1_IO_SIZE, PCI_REGION_IO); 722 CFG_PCI1_IO_SPACE, CFG_PCI1_IO_SIZE, PCI_REGION_IO);
723 723
724 pci_set_ops (&pci1_hose, 724 pci_set_ops (&pci1_hose,
725 pci_hose_read_config_byte_via_dword, 725 pci_hose_read_config_byte_via_dword,
726 pci_hose_read_config_word_via_dword, 726 pci_hose_read_config_word_via_dword,
727 gt_read_config_dword, 727 gt_read_config_dword,
728 pci_hose_write_config_byte_via_dword, 728 pci_hose_write_config_byte_via_dword,
729 pci_hose_write_config_word_via_dword, 729 pci_hose_write_config_word_via_dword,
730 gt_write_config_dword); 730 gt_write_config_dword);
731 731
732 pci1_hose.region_count = 2; 732 pci1_hose.region_count = 2;
733 733
734 pci1_hose.cfg_addr = (unsigned int *) PCI_HOST1; 734 pci1_hose.cfg_addr = (unsigned int *) PCI_HOST1;
735 735
736 pci_register_hose (&pci1_hose); 736 pci_register_hose (&pci1_hose);
737 737
738 pciArbiterEnable (PCI_HOST1); 738 pciArbiterEnable (PCI_HOST1);
739 pciParkingDisable (PCI_HOST1, 1, 1, 1, 1, 1, 1, 1); 739 pciParkingDisable (PCI_HOST1, 1, 1, 1, 1, 1, 1, 1);
740 740
741 command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF); 741 command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
742 command |= PCI_COMMAND_MASTER; 742 command |= PCI_COMMAND_MASTER;
743 pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command); 743 pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
744 744
745 pci1_hose.last_busno = pci_hose_scan (&pci1_hose); 745 pci1_hose.last_busno = pci_hose_scan (&pci1_hose);
746 746
747 command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF); 747 command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
748 command |= PCI_COMMAND_MEMORY; 748 command |= PCI_COMMAND_MEMORY;
749 pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command); 749 pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
750 } 750 }
751 751
board/omap1610inn/flash.c
1 /* 1 /*
2 * (C) Copyright 2001 2 * (C) Copyright 2001
3 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net 3 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4 * 4 *
5 * (C) Copyright 2001 5 * (C) Copyright 2001-2004
6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7 * 7 *
8 * (C) Copyright 2003 8 * (C) Copyright 2003
9 * Texas Instruments, <www.ti.com> 9 * Texas Instruments, <www.ti.com>
10 * Kshitij Gupta <Kshitij@ti.com> 10 * Kshitij Gupta <Kshitij@ti.com>
11 * 11 *
12 * See file CREDITS for list of people who contributed to this 12 * See file CREDITS for list of people who contributed to this
13 * project. 13 * project.
14 * 14 *
15 * This program is free software; you can redistribute it and/or 15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as 16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of 17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version. 18 * the License, or (at your option) any later version.
19 * 19 *
20 * This program is distributed in the hope that it will be useful, 20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details. 23 * GNU General Public License for more details.
24 * 24 *
25 * You should have received a copy of the GNU General Public License 25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software 26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA 28 * MA 02111-1307 USA
29 */ 29 */
30 30
31 #include <common.h> 31 #include <common.h>
32 #include <linux/byteorder/swab.h> 32 #include <linux/byteorder/swab.h>
33 33
34 #define PHYS_FLASH_SECT_SIZE 0x00020000 /* 256 KB sectors (x2) */ 34 #define PHYS_FLASH_SECT_SIZE 0x00020000 /* 256 KB sectors (x2) */
35 flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ 35 flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
36 36
37 /* Board support for 1 or 2 flash devices */ 37 /* Board support for 1 or 2 flash devices */
38 #undef FLASH_PORT_WIDTH32 38 #undef FLASH_PORT_WIDTH32
39 #define FLASH_PORT_WIDTH16 39 #define FLASH_PORT_WIDTH16
40 40
41 #ifdef FLASH_PORT_WIDTH16 41 #ifdef FLASH_PORT_WIDTH16
42 #define FLASH_PORT_WIDTH ushort 42 #define FLASH_PORT_WIDTH ushort
43 #define FLASH_PORT_WIDTHV vu_short 43 #define FLASH_PORT_WIDTHV vu_short
44 #define SWAP(x) __swab16(x) 44 #define SWAP(x) __swab16(x)
45 #else 45 #else
46 #define FLASH_PORT_WIDTH ulong 46 #define FLASH_PORT_WIDTH ulong
47 #define FLASH_PORT_WIDTHV vu_long 47 #define FLASH_PORT_WIDTHV vu_long
48 #define SWAP(x) __swab32(x) 48 #define SWAP(x) __swab32(x)
49 #endif 49 #endif
50 50
51 #define FPW FLASH_PORT_WIDTH 51 #define FPW FLASH_PORT_WIDTH
52 #define FPWV FLASH_PORT_WIDTHV 52 #define FPWV FLASH_PORT_WIDTHV
53 53
54 #define mb() __asm__ __volatile__ ("" : : : "memory") 54 #define mb() __asm__ __volatile__ ("" : : : "memory")
55 55
56 56
57 /* Flash Organization Structure */ 57 /* Flash Organization Structure */
58 typedef struct OrgDef { 58 typedef struct OrgDef {
59 unsigned int sector_number; 59 unsigned int sector_number;
60 unsigned int sector_size; 60 unsigned int sector_size;
61 } OrgDef; 61 } OrgDef;
62 62
63 63
64 /* Flash Organizations */ 64 /* Flash Organizations */
65 OrgDef OrgIntel_28F256L18T[] = { 65 OrgDef OrgIntel_28F256L18T[] = {
66 {4, 32 * 1024}, /* 4 * 32kBytes sectors */ 66 {4, 32 * 1024}, /* 4 * 32kBytes sectors */
67 {255, 128 * 1024}, /* 255 * 128kBytes sectors */ 67 {255, 128 * 1024}, /* 255 * 128kBytes sectors */
68 }; 68 };
69 69
70 70
71 /*----------------------------------------------------------------------- 71 /*-----------------------------------------------------------------------
72 * Functions 72 * Functions
73 */ 73 */
74 unsigned long flash_init (void); 74 unsigned long flash_init (void);
75 static ulong flash_get_size (FPW * addr, flash_info_t * info); 75 static ulong flash_get_size (FPW * addr, flash_info_t * info);
76 static int write_data (flash_info_t * info, ulong dest, FPW data); 76 static int write_data (flash_info_t * info, ulong dest, FPW data);
77 static void flash_get_offsets (ulong base, flash_info_t * info); 77 static void flash_get_offsets (ulong base, flash_info_t * info);
78 void inline spin_wheel (void); 78 void inline spin_wheel (void);
79 void flash_print_info (flash_info_t * info); 79 void flash_print_info (flash_info_t * info);
80 void flash_unprotect_sectors (FPWV * addr); 80 void flash_unprotect_sectors (FPWV * addr);
81 int flash_erase (flash_info_t * info, int s_first, int s_last); 81 int flash_erase (flash_info_t * info, int s_first, int s_last);
82 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt); 82 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt);
83 void flash_unlock(flash_info_t * info);
83 84
84 /*----------------------------------------------------------------------- 85 /*-----------------------------------------------------------------------
85 */ 86 */
86 87
87 unsigned long flash_init (void) 88 unsigned long flash_init (void)
88 { 89 {
89 int i; 90 int i;
90 ulong size = 0; 91 ulong size = 0;
91 for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { 92 for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
92 switch (i) { 93 switch (i) {
93 case 0: 94 case 0:
94 flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]); 95 flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
95 flash_get_offsets (PHYS_FLASH_1, &flash_info[i]); 96 flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
96 /* to reset the lock bit */ 97 /* to reset the lock bit */
97 flash_unlock(&flash_info[i]); 98 flash_unlock(&flash_info[i]);
98 break; 99 break;
99 default: 100 default:
100 panic ("configured too many flash banks!\n"); 101 panic ("configured too many flash banks!\n");
101 break; 102 break;
102 } 103 }
103 size += flash_info[i].size; 104 size += flash_info[i].size;
104 } 105 }
105 106
106 /* Protect monitor and environment sectors 107 /* Protect monitor and environment sectors
107 */ 108 */
108 flash_protect (FLAG_PROTECT_SET, 109 flash_protect (FLAG_PROTECT_SET,
109 CFG_FLASH_BASE, 110 CFG_FLASH_BASE,
110 CFG_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]); 111 CFG_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]);
111 112
112 flash_protect (FLAG_PROTECT_SET, 113 flash_protect (FLAG_PROTECT_SET,
113 CFG_ENV_ADDR, 114 CFG_ENV_ADDR,
114 CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]); 115 CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
115 116
116 return size; 117 return size;
117 } 118 }
118 119
119 /*----------------------------------------------------------------------- 120 /*-----------------------------------------------------------------------
120 */ 121 */
121 flash_unlock(flash_info_t * info) 122 void flash_unlock(flash_info_t * info)
122 { 123 {
123 int j; 124 int j;
124 for (j=2;j<CFG_MAX_FLASH_SECT;j++){ 125 for (j=2;j<CFG_MAX_FLASH_SECT;j++){
125 FPWV *addr = (FPWV *) (info->start[j]); 126 FPWV *addr = (FPWV *) (info->start[j]);
126 flash_unprotect_sectors (addr); 127 flash_unprotect_sectors (addr);
127 *addr = (FPW) 0x00500050;/* clear status register */ 128 *addr = (FPW) 0x00500050;/* clear status register */
128 *addr = (FPW) 0x00FF00FF;/* resest to read mode */ 129 *addr = (FPW) 0x00FF00FF;/* resest to read mode */
129 } 130 }
130 } 131 }
131 132
132 /*----------------------------------------------------------------------- 133 /*-----------------------------------------------------------------------
133 */ 134 */
134 static void flash_get_offsets (ulong base, flash_info_t * info) 135 static void flash_get_offsets (ulong base, flash_info_t * info)
135 { 136 {
136 int i; 137 int i;
137 OrgDef *pOrgDef; 138 OrgDef *pOrgDef;
138 139
139 pOrgDef = OrgIntel_28F256L18T; 140 pOrgDef = OrgIntel_28F256L18T;
140 if (info->flash_id == FLASH_UNKNOWN) { 141 if (info->flash_id == FLASH_UNKNOWN) {
141 return; 142 return;
142 } 143 }
143 144
144 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { 145 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
145 for (i = 0; i < info->sector_count; i++) { 146 for (i = 0; i < info->sector_count; i++) {
146 if (i > 255) { 147 if (i > 255) {
147 info->start[i] = base + (i * 0x8000); 148 info->start[i] = base + (i * 0x8000);
148 info->protect[i] = 0; 149 info->protect[i] = 0;
149 } else { 150 } else {
150 info->start[i] = base + 151 info->start[i] = base +
151 (i * PHYS_FLASH_SECT_SIZE); 152 (i * PHYS_FLASH_SECT_SIZE);
152 info->protect[i] = 0; 153 info->protect[i] = 0;
153 } 154 }
154 } 155 }
155 } 156 }
156 } 157 }
157 158
158 /*----------------------------------------------------------------------- 159 /*-----------------------------------------------------------------------
159 */ 160 */
160 void flash_print_info (flash_info_t * info) 161 void flash_print_info (flash_info_t * info)
161 { 162 {
162 int i; 163 int i;
163 164
164 if (info->flash_id == FLASH_UNKNOWN) { 165 if (info->flash_id == FLASH_UNKNOWN) {
165 printf ("missing or unknown FLASH type\n"); 166 printf ("missing or unknown FLASH type\n");
166 return; 167 return;
167 } 168 }
168 169
169 switch (info->flash_id & FLASH_VENDMASK) { 170 switch (info->flash_id & FLASH_VENDMASK) {
170 case FLASH_MAN_INTEL: 171 case FLASH_MAN_INTEL:
171 printf ("INTEL "); 172 printf ("INTEL ");
172 break; 173 break;
173 default: 174 default:
174 printf ("Unknown Vendor "); 175 printf ("Unknown Vendor ");
175 break; 176 break;
176 } 177 }
177 178
178 switch (info->flash_id & FLASH_TYPEMASK) { 179 switch (info->flash_id & FLASH_TYPEMASK) {
179 case FLASH_28F256L18T: 180 case FLASH_28F256L18T:
180 printf ("FLASH 28F256L18T\n"); 181 printf ("FLASH 28F256L18T\n");
181 break; 182 break;
182 default: 183 default:
183 printf ("Unknown Chip Type\n"); 184 printf ("Unknown Chip Type\n");
184 break; 185 break;
185 } 186 }
186 187
187 printf (" Size: %ld MB in %d Sectors\n", 188 printf (" Size: %ld MB in %d Sectors\n",
188 info->size >> 20, info->sector_count); 189 info->size >> 20, info->sector_count);
189 190
190 printf (" Sector Start Addresses:"); 191 printf (" Sector Start Addresses:");
191 for (i = 0; i < info->sector_count; ++i) { 192 for (i = 0; i < info->sector_count; ++i) {
192 if ((i % 5) == 0) 193 if ((i % 5) == 0)
193 printf ("\n "); 194 printf ("\n ");
194 printf (" %08lX%s", 195 printf (" %08lX%s",
195 info->start[i], info->protect[i] ? " (RO)" : " "); 196 info->start[i], info->protect[i] ? " (RO)" : " ");
196 } 197 }
197 printf ("\n"); 198 printf ("\n");
198 return; 199 return;
199 } 200 }
200 201
201 /* 202 /*
202 * The following code cannot be run from FLASH! 203 * The following code cannot be run from FLASH!
203 */ 204 */
204 static ulong flash_get_size (FPW * addr, flash_info_t * info) 205 static ulong flash_get_size (FPW * addr, flash_info_t * info)
205 { 206 {
206 volatile FPW value; 207 volatile FPW value;
207 208
208 /* Write auto select command: read Manufacturer ID */ 209 /* Write auto select command: read Manufacturer ID */
209 addr[0x5555] = (FPW) 0x00AA00AA; 210 addr[0x5555] = (FPW) 0x00AA00AA;
210 addr[0x2AAA] = (FPW) 0x00550055; 211 addr[0x2AAA] = (FPW) 0x00550055;
211 addr[0x5555] = (FPW) 0x00900090; 212 addr[0x5555] = (FPW) 0x00900090;
212 213
213 mb (); 214 mb ();
214 value = addr[0]; 215 value = addr[0];
215 216
216 switch (value) { 217 switch (value) {
217 218
218 case (FPW) INTEL_MANUFACT: 219 case (FPW) INTEL_MANUFACT:
219 info->flash_id = FLASH_MAN_INTEL; 220 info->flash_id = FLASH_MAN_INTEL;
220 break; 221 break;
221 222
222 default: 223 default:
223 info->flash_id = FLASH_UNKNOWN; 224 info->flash_id = FLASH_UNKNOWN;
224 info->sector_count = 0; 225 info->sector_count = 0;
225 info->size = 0; 226 info->size = 0;
226 addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ 227 addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
227 return (0); /* no or unknown flash */ 228 return (0); /* no or unknown flash */
228 } 229 }
229 230
230 mb (); 231 mb ();
231 value = addr[1]; /* device ID */ 232 value = addr[1]; /* device ID */
232 switch (value) { 233 switch (value) {
233 234
234 case (FPW) (INTEL_ID_28F256L18T): 235 case (FPW) (INTEL_ID_28F256L18T):
235 info->flash_id += FLASH_28F256L18T; 236 info->flash_id += FLASH_28F256L18T;
236 info->sector_count = 259; 237 info->sector_count = 259;
237 info->size = 0x02000000; 238 info->size = 0x02000000;
238 break; /* => 32 MB */ 239 break; /* => 32 MB */
239 240
240 default: 241 default:
241 info->flash_id = FLASH_UNKNOWN; 242 info->flash_id = FLASH_UNKNOWN;
242 break; 243 break;
243 } 244 }
244 245
245 if (info->sector_count > CFG_MAX_FLASH_SECT) { 246 if (info->sector_count > CFG_MAX_FLASH_SECT) {
246 printf ("** ERROR: sector count %d > max (%d) **\n", 247 printf ("** ERROR: sector count %d > max (%d) **\n",
247 info->sector_count, CFG_MAX_FLASH_SECT); 248 info->sector_count, CFG_MAX_FLASH_SECT);
248 info->sector_count = CFG_MAX_FLASH_SECT; 249 info->sector_count = CFG_MAX_FLASH_SECT;
249 } 250 }
250 251
251 addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ 252 addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
252 253
253 return (info->size); 254 return (info->size);
254 } 255 }
255 256
256 257
257 /* unprotects a sector for write and erase 258 /* unprotects a sector for write and erase
258 * on some intel parts, this unprotects the entire chip, but it 259 * on some intel parts, this unprotects the entire chip, but it
259 * wont hurt to call this additional times per sector... 260 * wont hurt to call this additional times per sector...
260 */ 261 */
261 void flash_unprotect_sectors (FPWV * addr) 262 void flash_unprotect_sectors (FPWV * addr)
262 { 263 {
263 #define PD_FINTEL_WSMS_READY_MASK 0x0080 264 #define PD_FINTEL_WSMS_READY_MASK 0x0080
264 265
265 *addr = (FPW) 0x00500050; /* clear status register */ 266 *addr = (FPW) 0x00500050; /* clear status register */
266 267
267 /* this sends the clear lock bit command */ 268 /* this sends the clear lock bit command */
268 *addr = (FPW) 0x00600060; 269 *addr = (FPW) 0x00600060;
269 *addr = (FPW) 0x00D000D0; 270 *addr = (FPW) 0x00D000D0;
270 } 271 }
271 272
272 273
273 /*----------------------------------------------------------------------- 274 /*-----------------------------------------------------------------------
274 */ 275 */
275 276
276 int flash_erase (flash_info_t * info, int s_first, int s_last) 277 int flash_erase (flash_info_t * info, int s_first, int s_last)
277 { 278 {
278 int flag, prot, sect; 279 int flag, prot, sect;
279 ulong type, start, last; 280 ulong type, start, last;
280 int rcode = 0; 281 int rcode = 0;
281 282
282 if ((s_first < 0) || (s_first > s_last)) { 283 if ((s_first < 0) || (s_first > s_last)) {
283 if (info->flash_id == FLASH_UNKNOWN) { 284 if (info->flash_id == FLASH_UNKNOWN) {
284 printf ("- missing\n"); 285 printf ("- missing\n");
285 } else { 286 } else {
286 printf ("- no sectors to erase\n"); 287 printf ("- no sectors to erase\n");
287 } 288 }
288 return 1; 289 return 1;
289 } 290 }
290 291
291 type = (info->flash_id & FLASH_VENDMASK); 292 type = (info->flash_id & FLASH_VENDMASK);
292 if ((type != FLASH_MAN_INTEL)) { 293 if ((type != FLASH_MAN_INTEL)) {
293 printf ("Can't erase unknown flash type %08lx - aborted\n", 294 printf ("Can't erase unknown flash type %08lx - aborted\n",
294 info->flash_id); 295 info->flash_id);
295 return 1; 296 return 1;
296 } 297 }
297 298
298 prot = 0; 299 prot = 0;
299 for (sect = s_first; sect <= s_last; ++sect) { 300 for (sect = s_first; sect <= s_last; ++sect) {
300 if (info->protect[sect]) { 301 if (info->protect[sect]) {
301 prot++; 302 prot++;
302 } 303 }
303 } 304 }
304 305
305 if (prot) { 306 if (prot) {
306 printf ("- Warning: %d protected sectors will not be erased!\n", 307 printf ("- Warning: %d protected sectors will not be erased!\n",
307 prot); 308 prot);
308 } else { 309 } else {
309 printf ("\n"); 310 printf ("\n");
310 } 311 }
311 312
312 313
313 start = get_timer (0); 314 start = get_timer (0);
314 last = start; 315 last = start;
315 316
316 /* Disable interrupts which might cause a timeout here */ 317 /* Disable interrupts which might cause a timeout here */
317 flag = disable_interrupts (); 318 flag = disable_interrupts ();
318 319
319 /* Start erase on unprotected sectors */ 320 /* Start erase on unprotected sectors */
320 for (sect = s_first; sect <= s_last; sect++) { 321 for (sect = s_first; sect <= s_last; sect++) {
321 if (info->protect[sect] == 0) { /* not protected */ 322 if (info->protect[sect] == 0) { /* not protected */
322 FPWV *addr = (FPWV *) (info->start[sect]); 323 FPWV *addr = (FPWV *) (info->start[sect]);
323 FPW status; 324 FPW status;
324 325
325 printf ("Erasing sector %2d ... ", sect); 326 printf ("Erasing sector %2d ... ", sect);
326 327
327 flash_unprotect_sectors (addr); 328 flash_unprotect_sectors (addr);
328 329
329 /* arm simple, non interrupt dependent timer */ 330 /* arm simple, non interrupt dependent timer */
330 reset_timer_masked (); 331 reset_timer_masked ();
331 332
332 *addr = (FPW) 0x00500050;/* clear status register */ 333 *addr = (FPW) 0x00500050;/* clear status register */
333 *addr = (FPW) 0x00200020;/* erase setup */ 334 *addr = (FPW) 0x00200020;/* erase setup */
334 *addr = (FPW) 0x00D000D0;/* erase confirm */ 335 *addr = (FPW) 0x00D000D0;/* erase confirm */
335 336
336 while (((status = 337 while (((status =
337 *addr) & (FPW) 0x00800080) != 338 *addr) & (FPW) 0x00800080) !=
338 (FPW) 0x00800080) { 339 (FPW) 0x00800080) {
339 if (get_timer_masked () > 340 if (get_timer_masked () >
340 CFG_FLASH_ERASE_TOUT) { 341 CFG_FLASH_ERASE_TOUT) {
341 printf ("Timeout\n"); 342 printf ("Timeout\n");
342 /* suspend erase */ 343 /* suspend erase */
343 *addr = (FPW) 0x00B000B0; 344 *addr = (FPW) 0x00B000B0;
344 /* reset to read mode */ 345 /* reset to read mode */
345 *addr = (FPW) 0x00FF00FF; 346 *addr = (FPW) 0x00FF00FF;
346 rcode = 1; 347 rcode = 1;
347 break; 348 break;
348 } 349 }
349 } 350 }
350 351
351 /* clear status register cmd. */ 352 /* clear status register cmd. */
352 *addr = (FPW) 0x00500050; 353 *addr = (FPW) 0x00500050;
353 *addr = (FPW) 0x00FF00FF;/* resest to read mode */ 354 *addr = (FPW) 0x00FF00FF;/* resest to read mode */
354 printf (" done\n"); 355 printf (" done\n");
355 } 356 }
356 } 357 }
357 return rcode; 358 return rcode;
358 } 359 }
359 360
360 /*----------------------------------------------------------------------- 361 /*-----------------------------------------------------------------------
361 * Copy memory to flash, returns: 362 * Copy memory to flash, returns:
362 * 0 - OK 363 * 0 - OK
363 * 1 - write timeout 364 * 1 - write timeout
364 * 2 - Flash not erased 365 * 2 - Flash not erased
365 * 4 - Flash not identified 366 * 4 - Flash not identified
366 */ 367 */
367 368
368 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) 369 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
369 { 370 {
370 ulong cp, wp; 371 ulong cp, wp;
371 FPW data; 372 FPW data;
372 int count, i, l, rc, port_width; 373 int count, i, l, rc, port_width;
373 374
374 if (info->flash_id == FLASH_UNKNOWN) { 375 if (info->flash_id == FLASH_UNKNOWN) {
375 return 4; 376 return 4;
376 } 377 }
377 /* get lower word aligned address */ 378 /* get lower word aligned address */
378 #ifdef FLASH_PORT_WIDTH16 379 #ifdef FLASH_PORT_WIDTH16
379 wp = (addr & ~1); 380 wp = (addr & ~1);
380 port_width = 2; 381 port_width = 2;
381 #else 382 #else
382 wp = (addr & ~3); 383 wp = (addr & ~3);
383 port_width = 4; 384 port_width = 4;
384 #endif 385 #endif
385 386
386 /* 387 /*
387 * handle unaligned start bytes 388 * handle unaligned start bytes
388 */ 389 */
389 if ((l = addr - wp) != 0) { 390 if ((l = addr - wp) != 0) {
390 data = 0; 391 data = 0;
391 for (i = 0, cp = wp; i < l; ++i, ++cp) { 392 for (i = 0, cp = wp; i < l; ++i, ++cp) {
392 data = (data << 8) | (*(uchar *) cp); 393 data = (data << 8) | (*(uchar *) cp);
393 } 394 }
394 for (; i < port_width && cnt > 0; ++i) { 395 for (; i < port_width && cnt > 0; ++i) {
395 data = (data << 8) | *src++; 396 data = (data << 8) | *src++;
396 --cnt; 397 --cnt;
397 ++cp; 398 ++cp;
398 } 399 }
399 for (; cnt == 0 && i < port_width; ++i, ++cp) { 400 for (; cnt == 0 && i < port_width; ++i, ++cp) {
400 data = (data << 8) | (*(uchar *) cp); 401 data = (data << 8) | (*(uchar *) cp);
401 } 402 }
402 403
403 if ((rc = write_data (info, wp, SWAP (data))) != 0) { 404 if ((rc = write_data (info, wp, SWAP (data))) != 0) {
404 return (rc); 405 return (rc);
405 } 406 }
406 wp += port_width; 407 wp += port_width;
407 } 408 }
408 409
409 /* 410 /*
410 * handle word aligned part 411 * handle word aligned part
411 */ 412 */
412 count = 0; 413 count = 0;
413 while (cnt >= port_width) { 414 while (cnt >= port_width) {
414 data = 0; 415 data = 0;
415 for (i = 0; i < port_width; ++i) { 416 for (i = 0; i < port_width; ++i) {
416 data = (data << 8) | *src++; 417 data = (data << 8) | *src++;
417 } 418 }
418 if ((rc = write_data (info, wp, SWAP (data))) != 0) { 419 if ((rc = write_data (info, wp, SWAP (data))) != 0) {
419 return (rc); 420 return (rc);
420 } 421 }
421 wp += port_width; 422 wp += port_width;
422 cnt -= port_width; 423 cnt -= port_width;
423 if (count++ > 0x800) { 424 if (count++ > 0x800) {
424 spin_wheel (); 425 spin_wheel ();
425 count = 0; 426 count = 0;
426 } 427 }
427 } 428 }
428 429
429 if (cnt == 0) { 430 if (cnt == 0) {
430 return (0); 431 return (0);
431 } 432 }
432 433
433 /* 434 /*
434 * handle unaligned tail bytes 435 * handle unaligned tail bytes
435 */ 436 */
436 data = 0; 437 data = 0;
437 for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { 438 for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
438 data = (data << 8) | *src++; 439 data = (data << 8) | *src++;
439 --cnt; 440 --cnt;
440 } 441 }
441 for (; i < port_width; ++i, ++cp) { 442 for (; i < port_width; ++i, ++cp) {
442 data = (data << 8) | (*(uchar *) cp); 443 data = (data << 8) | (*(uchar *) cp);
443 } 444 }
444 445
445 return (write_data (info, wp, SWAP (data))); 446 return (write_data (info, wp, SWAP (data)));
446 } 447 }
447 448
448 /*----------------------------------------------------------------------- 449 /*-----------------------------------------------------------------------
449 * Write a word or halfword to Flash, returns: 450 * Write a word or halfword to Flash, returns:
450 * 0 - OK 451 * 0 - OK
451 * 1 - write timeout 452 * 1 - write timeout
452 * 2 - Flash not erased 453 * 2 - Flash not erased
453 */ 454 */
454 static int write_data (flash_info_t * info, ulong dest, FPW data) 455 static int write_data (flash_info_t * info, ulong dest, FPW data)
455 { 456 {
456 FPWV *addr = (FPWV *) dest; 457 FPWV *addr = (FPWV *) dest;
457 ulong status; 458 ulong status;
458 int flag; 459 int flag;
459 460
460 /* Check if Flash is (sufficiently) erased */ 461 /* Check if Flash is (sufficiently) erased */
461 if ((*addr & data) != data) { 462 if ((*addr & data) != data) {
462 printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr); 463 printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr);
463 return (2); 464 return (2);
464 } 465 }
465 /* Disable interrupts which might cause a timeout here */ 466 /* Disable interrupts which might cause a timeout here */
466 flag = disable_interrupts (); 467 flag = disable_interrupts ();
467 *addr = (FPW) 0x00400040; /* write setup */ 468 *addr = (FPW) 0x00400040; /* write setup */
468 *addr = data; 469 *addr = data;
469 470
470 /* arm simple, non interrupt dependent timer */ 471 /* arm simple, non interrupt dependent timer */
471 reset_timer_masked (); 472 reset_timer_masked ();
472 473
473 /* wait while polling the status register */ 474 /* wait while polling the status register */
474 while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { 475 while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
475 if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) { 476 if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
476 *addr = (FPW) 0x00FF00FF; /* restore read mode */ 477 *addr = (FPW) 0x00FF00FF; /* restore read mode */
477 return (1); 478 return (1);
478 } 479 }
479 } 480 }
480 *addr = (FPW) 0x00FF00FF; /* restore read mode */ 481 *addr = (FPW) 0x00FF00FF; /* restore read mode */
481 return (0); 482 return (0);
482 } 483 }
483 484
484 void inline spin_wheel (void) 485 void inline spin_wheel (void)
485 { 486 {
486 static int p = 0; 487 static int p = 0;
487 static char w[] = "\\/-"; 488 static char w[] = "\\/-";
488 489
489 printf ("\010%c", w[p]); 490 printf ("\010%c", w[p]);
490 (++p == 3) ? (p = 0) : 0; 491 (++p == 3) ? (p = 0) : 0;
491 } 492 }
492 493
1 /* 1 /*
2 * (C) Copyright 2002 SIXNET, dge@sixnetio.com. 2 * (C) Copyright 2002 SIXNET, dge@sixnetio.com.
3 * 3 *
4 * (C) Copyright 2004, Li-Pro.Net <www.li-pro.net> 4 * (C) Copyright 2004, Li-Pro.Net <www.li-pro.net>
5 * Stephan Linz <linz@li-pro.net> 5 * Stephan Linz <linz@li-pro.net>
6 * 6 *
7 * See file CREDITS for list of people who contributed to this 7 * See file CREDITS for list of people who contributed to this
8 * project. 8 * project.
9 * 9 *
10 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as 11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of 12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version. 13 * the License, or (at your option) any later version.
14 * 14 *
15 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details. 18 * GNU General Public License for more details.
19 * 19 *
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA 23 * MA 02111-1307 USA
24 */ 24 */
25 25
26 /* 26 /*
27 * Date & Time support for DS1306 RTC using SPI: 27 * Date & Time support for DS1306 RTC using SPI:
28 * 28 *
29 * - SXNI855T: it uses its own soft SPI here in this file 29 * - SXNI855T: it uses its own soft SPI here in this file
30 * - all other: use the external spi_xfer() function 30 * - all other: use the external spi_xfer() function
31 * (see include/spi.h) 31 * (see include/spi.h)
32 */ 32 */
33 33
34 #include <common.h> 34 #include <common.h>
35 #include <command.h> 35 #include <command.h>
36 #include <rtc.h> 36 #include <rtc.h>
37 #include <spi.h> 37 #include <spi.h>
38 38
39 #if defined(CONFIG_RTC_DS1306) && (CONFIG_COMMANDS & CFG_CMD_DATE) 39 #if defined(CONFIG_RTC_DS1306) && (CONFIG_COMMANDS & CFG_CMD_DATE)
40 40
41 #define RTC_SECONDS 0x00 41 #define RTC_SECONDS 0x00
42 #define RTC_MINUTES 0x01 42 #define RTC_MINUTES 0x01
43 #define RTC_HOURS 0x02 43 #define RTC_HOURS 0x02
44 #define RTC_DAY_OF_WEEK 0x03 44 #define RTC_DAY_OF_WEEK 0x03
45 #define RTC_DATE_OF_MONTH 0x04 45 #define RTC_DATE_OF_MONTH 0x04
46 #define RTC_MONTH 0x05 46 #define RTC_MONTH 0x05
47 #define RTC_YEAR 0x06 47 #define RTC_YEAR 0x06
48 48
49 #define RTC_SECONDS_ALARM0 0x07 49 #define RTC_SECONDS_ALARM0 0x07
50 #define RTC_MINUTES_ALARM0 0x08 50 #define RTC_MINUTES_ALARM0 0x08
51 #define RTC_HOURS_ALARM0 0x09 51 #define RTC_HOURS_ALARM0 0x09
52 #define RTC_DAY_OF_WEEK_ALARM0 0x0a 52 #define RTC_DAY_OF_WEEK_ALARM0 0x0a
53 53
54 #define RTC_SECONDS_ALARM1 0x0b 54 #define RTC_SECONDS_ALARM1 0x0b
55 #define RTC_MINUTES_ALARM1 0x0c 55 #define RTC_MINUTES_ALARM1 0x0c
56 #define RTC_HOURS_ALARM1 0x0d 56 #define RTC_HOURS_ALARM1 0x0d
57 #define RTC_DAY_OF_WEEK_ALARM1 0x0e 57 #define RTC_DAY_OF_WEEK_ALARM1 0x0e
58 58
59 #define RTC_CONTROL 0x0f 59 #define RTC_CONTROL 0x0f
60 #define RTC_STATUS 0x10 60 #define RTC_STATUS 0x10
61 #define RTC_TRICKLE_CHARGER 0x11 61 #define RTC_TRICKLE_CHARGER 0x11
62 62
63 #define RTC_USER_RAM_BASE 0x20 63 #define RTC_USER_RAM_BASE 0x20
64 64
65 /* 65 /*
66 * External table of chip select functions (see the appropriate board 66 * External table of chip select functions (see the appropriate board
67 * support for the actual definition of the table). 67 * support for the actual definition of the table).
68 */ 68 */
69 extern spi_chipsel_type spi_chipsel[]; 69 extern spi_chipsel_type spi_chipsel[];
70 extern int spi_chipsel_cnt; 70 extern int spi_chipsel_cnt;
71 71
72 static unsigned int bin2bcd (unsigned int n); 72 static unsigned int bin2bcd (unsigned int n);
73 static unsigned char bcd2bin (unsigned char c); 73 static unsigned char bcd2bin (unsigned char c);
74 static unsigned char rtc_read (unsigned char reg);
75 static void rtc_write (unsigned char reg, unsigned char val);
76 74
77 /* ************************************************************************* */ 75 /* ************************************************************************* */
78 #ifdef CONFIG_SXNI855T /* !!! SHOULD BE CHANGED TO NEW CODE !!! */ 76 #ifdef CONFIG_SXNI855T /* !!! SHOULD BE CHANGED TO NEW CODE !!! */
79 77
78 static unsigned char rtc_read (unsigned char reg);
79 static void rtc_write (unsigned char reg, unsigned char val);
80 static void soft_spi_send (unsigned char n); 80 static void soft_spi_send (unsigned char n);
81 static unsigned char soft_spi_read (void); 81 static unsigned char soft_spi_read (void);
82 static void init_spi (void); 82 static void init_spi (void);
83 83
84 /*----------------------------------------------------------------------- 84 /*-----------------------------------------------------------------------
85 * Definitions 85 * Definitions
86 */ 86 */
87 87
88 #define PB_SPISCK 0x00000002 /* PB 30 */ 88 #define PB_SPISCK 0x00000002 /* PB 30 */
89 #define PB_SPIMOSI 0x00000004 /* PB 29 */ 89 #define PB_SPIMOSI 0x00000004 /* PB 29 */
90 #define PB_SPIMISO 0x00000008 /* PB 28 */ 90 #define PB_SPIMISO 0x00000008 /* PB 28 */
91 #define PB_SPI_CE 0x00010000 /* PB 15 */ 91 #define PB_SPI_CE 0x00010000 /* PB 15 */
92 92
93 /* ------------------------------------------------------------------------- */ 93 /* ------------------------------------------------------------------------- */
94 94
95 /* read clock time from DS1306 and return it in *tmp */ 95 /* read clock time from DS1306 and return it in *tmp */
96 void rtc_get (struct rtc_time *tmp) 96 void rtc_get (struct rtc_time *tmp)
97 { 97 {
98 volatile immap_t *immap = (immap_t *) CFG_IMMR; 98 volatile immap_t *immap = (immap_t *) CFG_IMMR;
99 unsigned char spi_byte; /* Data Byte */ 99 unsigned char spi_byte; /* Data Byte */
100 100
101 init_spi (); /* set port B for software SPI */ 101 init_spi (); /* set port B for software SPI */
102 102
103 /* Now we can enable the DS1306 RTC */ 103 /* Now we can enable the DS1306 RTC */
104 immap->im_cpm.cp_pbdat |= PB_SPI_CE; 104 immap->im_cpm.cp_pbdat |= PB_SPI_CE;
105 udelay (10); 105 udelay (10);
106 106
107 /* Shift out the address (0) of the time in the Clock Chip */ 107 /* Shift out the address (0) of the time in the Clock Chip */
108 soft_spi_send (0); 108 soft_spi_send (0);
109 109
110 /* Put the clock readings into the rtc_time structure */ 110 /* Put the clock readings into the rtc_time structure */
111 tmp->tm_sec = bcd2bin (soft_spi_read ()); /* Read seconds */ 111 tmp->tm_sec = bcd2bin (soft_spi_read ()); /* Read seconds */
112 tmp->tm_min = bcd2bin (soft_spi_read ()); /* Read minutes */ 112 tmp->tm_min = bcd2bin (soft_spi_read ()); /* Read minutes */
113 113
114 /* Hours are trickier */ 114 /* Hours are trickier */
115 spi_byte = soft_spi_read (); /* Read Hours into temporary value */ 115 spi_byte = soft_spi_read (); /* Read Hours into temporary value */
116 if (spi_byte & 0x40) { 116 if (spi_byte & 0x40) {
117 /* 12 hour mode bit is set (time is in 1-12 format) */ 117 /* 12 hour mode bit is set (time is in 1-12 format) */
118 if (spi_byte & 0x20) { 118 if (spi_byte & 0x20) {
119 /* since PM we add 11 to get 0-23 for hours */ 119 /* since PM we add 11 to get 0-23 for hours */
120 tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11; 120 tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11;
121 } else { 121 } else {
122 /* since AM we subtract 1 to get 0-23 for hours */ 122 /* since AM we subtract 1 to get 0-23 for hours */
123 tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1; 123 tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1;
124 } 124 }
125 } else { 125 } else {
126 /* Otherwise, 0-23 hour format */ 126 /* Otherwise, 0-23 hour format */
127 tmp->tm_hour = (bcd2bin (spi_byte & 0x3F)); 127 tmp->tm_hour = (bcd2bin (spi_byte & 0x3F));
128 } 128 }
129 129
130 soft_spi_read (); /* Read and discard Day of week */ 130 soft_spi_read (); /* Read and discard Day of week */
131 tmp->tm_mday = bcd2bin (soft_spi_read ()); /* Read Day of the Month */ 131 tmp->tm_mday = bcd2bin (soft_spi_read ()); /* Read Day of the Month */
132 tmp->tm_mon = bcd2bin (soft_spi_read ()); /* Read Month */ 132 tmp->tm_mon = bcd2bin (soft_spi_read ()); /* Read Month */
133 133
134 /* Read Year and convert to this century */ 134 /* Read Year and convert to this century */
135 tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000; 135 tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000;
136 136
137 /* Now we can disable the DS1306 RTC */ 137 /* Now we can disable the DS1306 RTC */
138 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */ 138 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */
139 udelay (10); 139 udelay (10);
140 140
141 GregorianDay (tmp); /* Determine the day of week */ 141 GregorianDay (tmp); /* Determine the day of week */
142 142
143 debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 143 debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
144 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 144 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
145 tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 145 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
146 } 146 }
147 147
148 /* ------------------------------------------------------------------------- */ 148 /* ------------------------------------------------------------------------- */
149 149
150 /* set clock time in DS1306 RTC and in MPC8xx RTC */ 150 /* set clock time in DS1306 RTC and in MPC8xx RTC */
151 void rtc_set (struct rtc_time *tmp) 151 void rtc_set (struct rtc_time *tmp)
152 { 152 {
153 volatile immap_t *immap = (immap_t *) CFG_IMMR; 153 volatile immap_t *immap = (immap_t *) CFG_IMMR;
154 154
155 init_spi (); /* set port B for software SPI */ 155 init_spi (); /* set port B for software SPI */
156 156
157 /* Now we can enable the DS1306 RTC */ 157 /* Now we can enable the DS1306 RTC */
158 immap->im_cpm.cp_pbdat |= PB_SPI_CE; /* Enable DS1306 Chip */ 158 immap->im_cpm.cp_pbdat |= PB_SPI_CE; /* Enable DS1306 Chip */
159 udelay (10); 159 udelay (10);
160 160
161 /* First disable write protect in the clock chip control register */ 161 /* First disable write protect in the clock chip control register */
162 soft_spi_send (0x8F); /* send address of the control register */ 162 soft_spi_send (0x8F); /* send address of the control register */
163 soft_spi_send (0x00); /* send control register contents */ 163 soft_spi_send (0x00); /* send control register contents */
164 164
165 /* Now disable the DS1306 to terminate the write */ 165 /* Now disable the DS1306 to terminate the write */
166 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; 166 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
167 udelay (10); 167 udelay (10);
168 168
169 /* Now enable the DS1306 to initiate a new write */ 169 /* Now enable the DS1306 to initiate a new write */
170 immap->im_cpm.cp_pbdat |= PB_SPI_CE; 170 immap->im_cpm.cp_pbdat |= PB_SPI_CE;
171 udelay (10); 171 udelay (10);
172 172
173 /* Next, send the address of the clock time write registers */ 173 /* Next, send the address of the clock time write registers */
174 soft_spi_send (0x80); /* send address of the first time register */ 174 soft_spi_send (0x80); /* send address of the first time register */
175 175
176 /* Use Burst Mode to send all of the time data to the clock */ 176 /* Use Burst Mode to send all of the time data to the clock */
177 bin2bcd (tmp->tm_sec); 177 bin2bcd (tmp->tm_sec);
178 soft_spi_send (bin2bcd (tmp->tm_sec)); /* Send Seconds */ 178 soft_spi_send (bin2bcd (tmp->tm_sec)); /* Send Seconds */
179 soft_spi_send (bin2bcd (tmp->tm_min)); /* Send Minutes */ 179 soft_spi_send (bin2bcd (tmp->tm_min)); /* Send Minutes */
180 soft_spi_send (bin2bcd (tmp->tm_hour)); /* Send Hour */ 180 soft_spi_send (bin2bcd (tmp->tm_hour)); /* Send Hour */
181 soft_spi_send (bin2bcd (tmp->tm_wday)); /* Send Day of the Week */ 181 soft_spi_send (bin2bcd (tmp->tm_wday)); /* Send Day of the Week */
182 soft_spi_send (bin2bcd (tmp->tm_mday)); /* Send Day of Month */ 182 soft_spi_send (bin2bcd (tmp->tm_mday)); /* Send Day of Month */
183 soft_spi_send (bin2bcd (tmp->tm_mon)); /* Send Month */ 183 soft_spi_send (bin2bcd (tmp->tm_mon)); /* Send Month */
184 soft_spi_send (bin2bcd (tmp->tm_year - 2000)); /* Send Year */ 184 soft_spi_send (bin2bcd (tmp->tm_year - 2000)); /* Send Year */
185 185
186 /* Now we can disable the Clock chip to terminate the burst write */ 186 /* Now we can disable the Clock chip to terminate the burst write */
187 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */ 187 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */
188 udelay (10); 188 udelay (10);
189 189
190 /* Now we can enable the Clock chip to initiate a new write */ 190 /* Now we can enable the Clock chip to initiate a new write */
191 immap->im_cpm.cp_pbdat |= PB_SPI_CE; /* Enable DS1306 Chip */ 191 immap->im_cpm.cp_pbdat |= PB_SPI_CE; /* Enable DS1306 Chip */
192 udelay (10); 192 udelay (10);
193 193
194 /* First we Enable write protect in the clock chip control register */ 194 /* First we Enable write protect in the clock chip control register */
195 soft_spi_send (0x8F); /* send address of the control register */ 195 soft_spi_send (0x8F); /* send address of the control register */
196 soft_spi_send (0x40); /* send out Control Register contents */ 196 soft_spi_send (0x40); /* send out Control Register contents */
197 197
198 /* Now disable the DS1306 */ 198 /* Now disable the DS1306 */
199 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */ 199 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */
200 udelay (10); 200 udelay (10);
201 201
202 /* Set standard MPC8xx clock to the same time so Linux will 202 /* Set standard MPC8xx clock to the same time so Linux will
203 * see the time even if it doesn't have a DS1306 clock driver. 203 * see the time even if it doesn't have a DS1306 clock driver.
204 * This helps with experimenting with standard kernels. 204 * This helps with experimenting with standard kernels.
205 */ 205 */
206 { 206 {
207 ulong tim; 207 ulong tim;
208 208
209 tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday, 209 tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
210 tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 210 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
211 211
212 immap->im_sitk.sitk_rtck = KAPWR_KEY; 212 immap->im_sitk.sitk_rtck = KAPWR_KEY;
213 immap->im_sit.sit_rtc = tim; 213 immap->im_sit.sit_rtc = tim;
214 } 214 }
215 215
216 debug ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 216 debug ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
217 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 217 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
218 tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 218 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
219 } 219 }
220 220
221 /* ------------------------------------------------------------------------- */ 221 /* ------------------------------------------------------------------------- */
222 222
223 /* Initialize Port B for software SPI */ 223 /* Initialize Port B for software SPI */
224 static void init_spi (void) 224 static void init_spi (void)
225 { 225 {
226 volatile immap_t *immap = (immap_t *) CFG_IMMR; 226 volatile immap_t *immap = (immap_t *) CFG_IMMR;
227 227
228 /* Force output pins to begin at logic 0 */ 228 /* Force output pins to begin at logic 0 */
229 immap->im_cpm.cp_pbdat &= ~(PB_SPI_CE | PB_SPIMOSI | PB_SPISCK); 229 immap->im_cpm.cp_pbdat &= ~(PB_SPI_CE | PB_SPIMOSI | PB_SPISCK);
230 230
231 /* Set these 3 signals as outputs */ 231 /* Set these 3 signals as outputs */
232 immap->im_cpm.cp_pbdir |= (PB_SPIMOSI | PB_SPI_CE | PB_SPISCK); 232 immap->im_cpm.cp_pbdir |= (PB_SPIMOSI | PB_SPI_CE | PB_SPISCK);
233 233
234 immap->im_cpm.cp_pbdir &= ~PB_SPIMISO; /* Make MISO pin an input */ 234 immap->im_cpm.cp_pbdir &= ~PB_SPIMISO; /* Make MISO pin an input */
235 udelay (10); 235 udelay (10);
236 } 236 }
237 237
238 /* ------------------------------------------------------------------------- */ 238 /* ------------------------------------------------------------------------- */
239 239
240 /* NOTE: soft_spi_send() assumes that the I/O lines are configured already */ 240 /* NOTE: soft_spi_send() assumes that the I/O lines are configured already */
241 static void soft_spi_send (unsigned char n) 241 static void soft_spi_send (unsigned char n)
242 { 242 {
243 volatile immap_t *immap = (immap_t *) CFG_IMMR; 243 volatile immap_t *immap = (immap_t *) CFG_IMMR;
244 unsigned char bitpos; /* bit position to receive */ 244 unsigned char bitpos; /* bit position to receive */
245 unsigned char i; /* Loop Control */ 245 unsigned char i; /* Loop Control */
246 246
247 /* bit position to send, start with most significant bit */ 247 /* bit position to send, start with most significant bit */
248 bitpos = 0x80; 248 bitpos = 0x80;
249 249
250 /* Send 8 bits to software SPI */ 250 /* Send 8 bits to software SPI */
251 for (i = 0; i < 8; i++) { /* Loop for 8 bits */ 251 for (i = 0; i < 8; i++) { /* Loop for 8 bits */
252 immap->im_cpm.cp_pbdat |= PB_SPISCK; /* Raise SCK */ 252 immap->im_cpm.cp_pbdat |= PB_SPISCK; /* Raise SCK */
253 253
254 if (n & bitpos) 254 if (n & bitpos)
255 immap->im_cpm.cp_pbdat |= PB_SPIMOSI; /* Set MOSI to 1 */ 255 immap->im_cpm.cp_pbdat |= PB_SPIMOSI; /* Set MOSI to 1 */
256 else 256 else
257 immap->im_cpm.cp_pbdat &= ~PB_SPIMOSI; /* Set MOSI to 0 */ 257 immap->im_cpm.cp_pbdat &= ~PB_SPIMOSI; /* Set MOSI to 0 */
258 udelay (10); 258 udelay (10);
259 259
260 immap->im_cpm.cp_pbdat &= ~PB_SPISCK; /* Lower SCK */ 260 immap->im_cpm.cp_pbdat &= ~PB_SPISCK; /* Lower SCK */
261 udelay (10); 261 udelay (10);
262 262
263 bitpos >>= 1; /* Shift for next bit position */ 263 bitpos >>= 1; /* Shift for next bit position */
264 } 264 }
265 } 265 }
266 266
267 /* ------------------------------------------------------------------------- */ 267 /* ------------------------------------------------------------------------- */
268 268
269 /* NOTE: soft_spi_read() assumes that the I/O lines are configured already */ 269 /* NOTE: soft_spi_read() assumes that the I/O lines are configured already */
270 static unsigned char soft_spi_read (void) 270 static unsigned char soft_spi_read (void)
271 { 271 {
272 volatile immap_t *immap = (immap_t *) CFG_IMMR; 272 volatile immap_t *immap = (immap_t *) CFG_IMMR;
273 273
274 unsigned char spi_byte = 0; /* Return value, assume success */ 274 unsigned char spi_byte = 0; /* Return value, assume success */
275 unsigned char bitpos; /* bit position to receive */ 275 unsigned char bitpos; /* bit position to receive */
276 unsigned char i; /* Loop Control */ 276 unsigned char i; /* Loop Control */
277 277
278 /* bit position to receive, start with most significant bit */ 278 /* bit position to receive, start with most significant bit */
279 bitpos = 0x80; 279 bitpos = 0x80;
280 280
281 /* Read 8 bits here */ 281 /* Read 8 bits here */
282 for (i = 0; i < 8; i++) { /* Do 8 bits in loop */ 282 for (i = 0; i < 8; i++) { /* Do 8 bits in loop */
283 immap->im_cpm.cp_pbdat |= PB_SPISCK; /* Raise SCK */ 283 immap->im_cpm.cp_pbdat |= PB_SPISCK; /* Raise SCK */
284 udelay (10); 284 udelay (10);
285 if (immap->im_cpm.cp_pbdat & PB_SPIMISO) /* Get a bit of data */ 285 if (immap->im_cpm.cp_pbdat & PB_SPIMISO) /* Get a bit of data */
286 spi_byte |= bitpos; /* Set data accordingly */ 286 spi_byte |= bitpos; /* Set data accordingly */
287 immap->im_cpm.cp_pbdat &= ~PB_SPISCK; /* Lower SCK */ 287 immap->im_cpm.cp_pbdat &= ~PB_SPISCK; /* Lower SCK */
288 udelay (10); 288 udelay (10);
289 bitpos >>= 1; /* Shift for next bit position */ 289 bitpos >>= 1; /* Shift for next bit position */
290 } 290 }
291 291
292 return spi_byte; /* Return the byte read */ 292 return spi_byte; /* Return the byte read */
293 } 293 }
294 294
295 /* ------------------------------------------------------------------------- */ 295 /* ------------------------------------------------------------------------- */
296 296
297 void rtc_reset (void) 297 void rtc_reset (void)
298 { 298 {
299 return; /* nothing to do */ 299 return; /* nothing to do */
300 } 300 }
301 301
302 #else /* not CONFIG_SXNI855T */ 302 #else /* not CONFIG_SXNI855T */
303 /* ************************************************************************* */ 303 /* ************************************************************************* */
304 304
305 /* read clock time from DS1306 and return it in *tmp */ 305 /* read clock time from DS1306 and return it in *tmp */
306 void rtc_get (struct rtc_time *tmp) 306 void rtc_get (struct rtc_time *tmp)
307 { 307 {
308 unsigned char sec, min, hour, mday, wday, mon, year; 308 unsigned char sec, min, hour, mday, wday, mon, year;
309 309
310 sec = rtc_read (RTC_SECONDS); 310 sec = rtc_read (RTC_SECONDS);
311 min = rtc_read (RTC_MINUTES); 311 min = rtc_read (RTC_MINUTES);
312 hour = rtc_read (RTC_HOURS); 312 hour = rtc_read (RTC_HOURS);
313 mday = rtc_read (RTC_DATE_OF_MONTH); 313 mday = rtc_read (RTC_DATE_OF_MONTH);
314 wday = rtc_read (RTC_DAY_OF_WEEK); 314 wday = rtc_read (RTC_DAY_OF_WEEK);
315 mon = rtc_read (RTC_MONTH); 315 mon = rtc_read (RTC_MONTH);
316 year = rtc_read (RTC_YEAR); 316 year = rtc_read (RTC_YEAR);
317 317
318 debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x " 318 debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
319 "hr: %02x min: %02x sec: %02x\n", 319 "hr: %02x min: %02x sec: %02x\n",
320 year, mon, mday, wday, hour, min, sec); 320 year, mon, mday, wday, hour, min, sec);
321 debug ("Alarms[0]: wday: %02x hour: %02x min: %02x sec: %02x\n", 321 debug ("Alarms[0]: wday: %02x hour: %02x min: %02x sec: %02x\n",
322 rtc_read (RTC_DAY_OF_WEEK_ALARM0), 322 rtc_read (RTC_DAY_OF_WEEK_ALARM0),
323 rtc_read (RTC_HOURS_ALARM0), 323 rtc_read (RTC_HOURS_ALARM0),
324 rtc_read (RTC_MINUTES_ALARM0), rtc_read (RTC_SECONDS_ALARM0)); 324 rtc_read (RTC_MINUTES_ALARM0), rtc_read (RTC_SECONDS_ALARM0));
325 debug ("Alarms[1]: wday: %02x hour: %02x min: %02x sec: %02x\n", 325 debug ("Alarms[1]: wday: %02x hour: %02x min: %02x sec: %02x\n",
326 rtc_read (RTC_DAY_OF_WEEK_ALARM1), 326 rtc_read (RTC_DAY_OF_WEEK_ALARM1),
327 rtc_read (RTC_HOURS_ALARM1), 327 rtc_read (RTC_HOURS_ALARM1),
328 rtc_read (RTC_MINUTES_ALARM1), rtc_read (RTC_SECONDS_ALARM1)); 328 rtc_read (RTC_MINUTES_ALARM1), rtc_read (RTC_SECONDS_ALARM1));
329 329
330 tmp->tm_sec = bcd2bin (sec & 0x7F); /* convert Seconds */ 330 tmp->tm_sec = bcd2bin (sec & 0x7F); /* convert Seconds */
331 tmp->tm_min = bcd2bin (min & 0x7F); /* convert Minutes */ 331 tmp->tm_min = bcd2bin (min & 0x7F); /* convert Minutes */
332 332
333 /* convert Hours */ 333 /* convert Hours */
334 tmp->tm_hour = (hour & 0x40) 334 tmp->tm_hour = (hour & 0x40)
335 ? ((hour & 0x20) /* 12 hour mode */ 335 ? ((hour & 0x20) /* 12 hour mode */
336 ? bcd2bin (hour & 0x1F) + 11 /* PM */ 336 ? bcd2bin (hour & 0x1F) + 11 /* PM */
337 : bcd2bin (hour & 0x1F) - 1 /* AM */ 337 : bcd2bin (hour & 0x1F) - 1 /* AM */
338 ) 338 )
339 : bcd2bin (hour & 0x3F); /* 24 hour mode */ 339 : bcd2bin (hour & 0x3F); /* 24 hour mode */
340 340
341 tmp->tm_mday = bcd2bin (mday & 0x3F); /* convert Day of the Month */ 341 tmp->tm_mday = bcd2bin (mday & 0x3F); /* convert Day of the Month */
342 tmp->tm_mon = bcd2bin (mon & 0x1F); /* convert Month */ 342 tmp->tm_mon = bcd2bin (mon & 0x1F); /* convert Month */
343 tmp->tm_year = bcd2bin (year) + 2000; /* convert Year */ 343 tmp->tm_year = bcd2bin (year) + 2000; /* convert Year */
344 tmp->tm_wday = bcd2bin (wday & 0x07) - 1; /* convert Day of the Week */ 344 tmp->tm_wday = bcd2bin (wday & 0x07) - 1; /* convert Day of the Week */
345 tmp->tm_yday = 0; 345 tmp->tm_yday = 0;
346 tmp->tm_isdst = 0; 346 tmp->tm_isdst = 0;
347 347
348 debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 348 debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
349 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 349 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
350 tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 350 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
351 } 351 }
352 352
353 /* ------------------------------------------------------------------------- */ 353 /* ------------------------------------------------------------------------- */
354 354
355 /* set clock time from *tmp in DS1306 RTC */ 355 /* set clock time from *tmp in DS1306 RTC */
356 void rtc_set (struct rtc_time *tmp) 356 void rtc_set (struct rtc_time *tmp)
357 { 357 {
358 debug ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 358 debug ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
359 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 359 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
360 tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 360 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
361 361
362 rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000)); 362 rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000));
363 rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon)); 363 rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon));
364 rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday)); 364 rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday));
365 rtc_write (RTC_DAY_OF_WEEK, bin2bcd (tmp->tm_wday + 1)); 365 rtc_write (RTC_DAY_OF_WEEK, bin2bcd (tmp->tm_wday + 1));
366 rtc_write (RTC_HOURS, bin2bcd (tmp->tm_hour)); 366 rtc_write (RTC_HOURS, bin2bcd (tmp->tm_hour));
367 rtc_write (RTC_MINUTES, bin2bcd (tmp->tm_min)); 367 rtc_write (RTC_MINUTES, bin2bcd (tmp->tm_min));
368 rtc_write (RTC_SECONDS, bin2bcd (tmp->tm_sec)); 368 rtc_write (RTC_SECONDS, bin2bcd (tmp->tm_sec));
369 } 369 }
370 370
371 /* ------------------------------------------------------------------------- */ 371 /* ------------------------------------------------------------------------- */
372 372
373 /* reset the DS1306 */ 373 /* reset the DS1306 */
374 void rtc_reset (void) 374 void rtc_reset (void)
375 { 375 {
376 /* clear the control register */ 376 /* clear the control register */
377 rtc_write (RTC_CONTROL, 0x00); /* 1st step: reset WP */ 377 rtc_write (RTC_CONTROL, 0x00); /* 1st step: reset WP */
378 rtc_write (RTC_CONTROL, 0x00); /* 2nd step: reset 1Hz, AIE1, AIE0 */ 378 rtc_write (RTC_CONTROL, 0x00); /* 2nd step: reset 1Hz, AIE1, AIE0 */
379 379
380 /* reset all alarms */ 380 /* reset all alarms */
381 rtc_write (RTC_SECONDS_ALARM0, 0x00); 381 rtc_write (RTC_SECONDS_ALARM0, 0x00);
382 rtc_write (RTC_SECONDS_ALARM1, 0x00); 382 rtc_write (RTC_SECONDS_ALARM1, 0x00);
383 rtc_write (RTC_MINUTES_ALARM0, 0x00); 383 rtc_write (RTC_MINUTES_ALARM0, 0x00);
384 rtc_write (RTC_MINUTES_ALARM1, 0x00); 384 rtc_write (RTC_MINUTES_ALARM1, 0x00);
385 rtc_write (RTC_HOURS_ALARM0, 0x00); 385 rtc_write (RTC_HOURS_ALARM0, 0x00);
386 rtc_write (RTC_HOURS_ALARM1, 0x00); 386 rtc_write (RTC_HOURS_ALARM1, 0x00);
387 rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00); 387 rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00);
388 rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00); 388 rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00);
389 } 389 }
390 390
391 /* ------------------------------------------------------------------------- */ 391 /* ------------------------------------------------------------------------- */
392 392
393 static unsigned char rtc_read (unsigned char reg) 393 static unsigned char rtc_read (unsigned char reg)
394 { 394 {
395 unsigned char dout[2]; /* SPI Output Data Bytes */ 395 unsigned char dout[2]; /* SPI Output Data Bytes */
396 unsigned char din[2]; /* SPI Input Data Bytes */ 396 unsigned char din[2]; /* SPI Input Data Bytes */
397 397
398 dout[0] = reg; 398 dout[0] = reg;
399 399
400 if (spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din) != 0) { 400 if (spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din) != 0) {
401 return 0; 401 return 0;
402 } else { 402 } else {
403 return din[1]; 403 return din[1];
404 } 404 }
405 } 405 }
406 406
407 /* ------------------------------------------------------------------------- */ 407 /* ------------------------------------------------------------------------- */
408 408
409 static void rtc_write (unsigned char reg, unsigned char val) 409 static void rtc_write (unsigned char reg, unsigned char val)
410 { 410 {
411 unsigned char dout[2]; /* SPI Output Data Bytes */ 411 unsigned char dout[2]; /* SPI Output Data Bytes */
412 unsigned char din[2]; /* SPI Input Data Bytes */ 412 unsigned char din[2]; /* SPI Input Data Bytes */
413 413
414 dout[0] = 0x80 | reg; 414 dout[0] = 0x80 | reg;
415 dout[1] = val; 415 dout[1] = val;
416 416
417 spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din); 417 spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din);
418 } 418 }
419 419
420 #endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */ 420 #endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */
421 421
422 /* ------------------------------------------------------------------------- */ 422 /* ------------------------------------------------------------------------- */
423 423
424 static unsigned char bcd2bin (unsigned char n) 424 static unsigned char bcd2bin (unsigned char n)
425 { 425 {
426 return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F)); 426 return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
427 } 427 }
428 428
429 /* ------------------------------------------------------------------------- */ 429 /* ------------------------------------------------------------------------- */
430 430
431 static unsigned int bin2bcd (unsigned int n) 431 static unsigned int bin2bcd (unsigned int n)
432 { 432 {
433 return (((n / 10) << 4) | (n % 10)); 433 return (((n / 10) << 4) | (n % 10));
434 } 434 }
435 /* ------------------------------------------------------------------------- */ 435 /* ------------------------------------------------------------------------- */
436 436