Commit 7205e4075d8b50e4dd89fe39ed03860b23cbb704
1 parent
149dded2b1
Exists in
master
and in
54 other branches
* Patches by Denis Peter, 9 Sep 2003:
add FAT support for IDE, SCSI and USB * Patches by Gleb Natapov, 2 Sep 2003: - cleanup of POST code for unsupported architectures - MPC824x locks way0 of data cache for use as initial RAM; this patch unlocks it after relocation to RAM and invalidates the locked entries. * Patch by Gleb Natapov, 30 Aug 2003: new I2C driver for mpc107 bridge. Now works from flash. * Patch by Dave Ellis, 11 Aug 2003: - JFFS2: fix typo in common/cmd_jffs2.c - JFFS2: fix CFG_JFFS2_SORT_FRAGMENTS option - JFFS2: remove node version 0 warning - JFFS2: accept JFFS2 PADDING nodes - SXNI855T: add AM29LV800 support - SXNI855T: move environment from EEPROM to flash - SXNI855T: boot from JFFS2 in NOR or NAND flash * Patch by Bill Hargen, 11 Aug 2003: fixes for I2C on MPC8240 - fix i2c_write routine - fix iprobe command - eliminates use of global variables, plus dead code, cleanup.
Showing 47 changed files with 1270 additions and 2475 deletions Side-by-side Diff
- CHANGELOG
- CREDITS
- MAINTAINERS
- board/mpl/common/common_util.c
- board/mpl/common/common_util.h
- board/mpl/common/flash.c
- board/mpl/common/isa.c
- board/mpl/common/isa.h
- board/mpl/common/pci_parts.h
- board/mpl/common/piix4_pci.h
- board/mpl/mip405/cmd_mip405.c
- board/mpl/mip405/init.S
- board/mpl/mip405/mip405.c
- board/mpl/mip405/mip405.h
- board/mpl/pip405/init.S
- board/mpl/pip405/pip405.c
- board/mpl/pip405/pip405.h
- board/sixnet/flash.c
- board/sixnet/sixnet.c
- common/cmd_doc.c
- common/cmd_fat.c
- common/cmd_jffs2.c
- cpu/mpc824x/Makefile
- cpu/mpc824x/drivers/i2c/Makefile
- cpu/mpc824x/drivers/i2c/Makefile_pc
- cpu/mpc824x/drivers/i2c/README
- cpu/mpc824x/drivers/i2c/i2c.c
- cpu/mpc824x/drivers/i2c/i2c.h
- cpu/mpc824x/drivers/i2c/i2c1.c
- cpu/mpc824x/drivers/i2c/i2c2.S
- cpu/mpc824x/drivers/i2c/i2c_export.h
- cpu/mpc824x/start.S
- cpu/pxa/mmc.c
- disk/part_dos.c
- disk/part_dos.h
- fs/fat/fat.c
- fs/jffs2/jffs2_1pass.c
- include/configs/AdderII.h
- include/configs/MIP405.h
- include/configs/PIP405.h
- include/configs/SXNI855T.h
- include/fat.h
- include/jffs2/jffs2.h
- include/part.h
- post/cache_8xx.S
- post/ether.c
- post/uart.c
CHANGELOG
... | ... | @@ -2,6 +2,33 @@ |
2 | 2 | Changes for U-Boot 0.4.8: |
3 | 3 | ====================================================================== |
4 | 4 | |
5 | +* Patches by Denis Peter, 9 Sep 2003: | |
6 | + add FAT support for IDE, SCSI and USB | |
7 | + | |
8 | +* Patches by Gleb Natapov, 2 Sep 2003: | |
9 | + - cleanup of POST code for unsupported architectures | |
10 | + - MPC824x locks way0 of data cache for use as initial RAM; | |
11 | + this patch unlocks it after relocation to RAM and invalidates | |
12 | + the locked entries. | |
13 | + | |
14 | +* Patch by Gleb Natapov, 30 Aug 2003: | |
15 | + new I2C driver for mpc107 bridge. Now works from flash. | |
16 | + | |
17 | +* Patch by Dave Ellis, 11 Aug 2003: | |
18 | + - JFFS2: fix typo in common/cmd_jffs2.c | |
19 | + - JFFS2: fix CFG_JFFS2_SORT_FRAGMENTS option | |
20 | + - JFFS2: remove node version 0 warning | |
21 | + - JFFS2: accept JFFS2 PADDING nodes | |
22 | + - SXNI855T: add AM29LV800 support | |
23 | + - SXNI855T: move environment from EEPROM to flash | |
24 | + - SXNI855T: boot from JFFS2 in NOR or NAND flash | |
25 | + | |
26 | +* Patch by Bill Hargen, 11 Aug 2003: | |
27 | + fixes for I2C on MPC8240 | |
28 | + - fix i2c_write routine | |
29 | + - fix iprobe command | |
30 | + - eliminates use of global variables, plus dead code, cleanup. | |
31 | + | |
5 | 32 | * Add support for USB Mass Storage Devices (BBB) |
6 | 33 | (tested with USB memory sticks only) |
7 | 34 |
CREDITS
MAINTAINERS
board/mpl/common/common_util.c
... | ... | @@ -375,139 +375,7 @@ |
375 | 375 | } |
376 | 376 | } |
377 | 377 | |
378 | -/* ------------------------------------------------------------------------- */ | |
379 | 378 | |
380 | - /* switches the cs0 and the cs1 to the locations. | |
381 | - When boot is TRUE, the the mapping is switched | |
382 | - to the boot configuration, If it is FALSE, the | |
383 | - flash will be switched in the boot area */ | |
384 | - | |
385 | -#undef SW_CS_DBG | |
386 | -#ifdef SW_CS_DBG | |
387 | -#define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args) | |
388 | -#else | |
389 | -#define SW_CS_PRINTF(fmt,args...) | |
390 | -#endif | |
391 | - | |
392 | -#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) | |
393 | -int switch_cs(unsigned char boot) | |
394 | -{ | |
395 | - unsigned long pbcr; | |
396 | - int mode; | |
397 | - | |
398 | - mode=get_boot_mode(); | |
399 | - mtdcr(ebccfga, pb0cr); | |
400 | - pbcr = mfdcr (ebccfgd); | |
401 | - if (mode & BOOT_MPS) { | |
402 | - /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */ | |
403 | - /* we need only to switch if boot from MPS */ | |
404 | - /* printf(" MPS boot mode detected. ");*/ | |
405 | - /* printf("cs0 cfg: %lx\n",pbcr); */ | |
406 | - if(boot) { | |
407 | - /* switch to boot configuration */ | |
408 | - /* this is a 8bit boot, switch cs0 to flash location */ | |
409 | - SW_CS_PRINTF("switch to boot mode (MPS on High address\n"); | |
410 | - pbcr&=0x000FFFFF; /*mask base address of the cs0 */ | |
411 | - pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000); | |
412 | - mtdcr(ebccfga, pb0cr); | |
413 | - mtdcr(ebccfgd, pbcr); | |
414 | - SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr); | |
415 | - mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */ | |
416 | - pbcr = mfdcr(ebccfgd); | |
417 | - SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr); | |
418 | - pbcr&=0x000FFFFF; /*mask base address of the cs1 */ | |
419 | - pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000); | |
420 | - mtdcr(ebccfga, pb1cr); | |
421 | - mtdcr(ebccfgd, pbcr); | |
422 | - SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr); | |
423 | - } | |
424 | - else { | |
425 | - /* map flash to boot area, */ | |
426 | - SW_CS_PRINTF("map Flash to boot area\n"); | |
427 | - pbcr&=0x000FFFFF; /*mask base address of the cs0 */ | |
428 | - pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000); | |
429 | - mtdcr(ebccfga, pb0cr); | |
430 | - mtdcr(ebccfgd, pbcr); | |
431 | - SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr); | |
432 | - mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */ | |
433 | - pbcr = mfdcr(ebccfgd); | |
434 | - SW_CS_PRINTF(" cs1 cfg: %lx\n",pbcr); | |
435 | - pbcr&=0x000FFFFF; /*mask base address of the cs1 */ | |
436 | - pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000); | |
437 | - mtdcr(ebccfga, pb1cr); | |
438 | - mtdcr(ebccfgd, pbcr); | |
439 | - SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr); | |
440 | - } | |
441 | - return 1; | |
442 | - } | |
443 | - else { | |
444 | - SW_CS_PRINTF("Normal boot, no switching necessary\n"); | |
445 | - return 0; | |
446 | - } | |
447 | - | |
448 | -} | |
449 | - | |
450 | -int get_boot_mode(void) | |
451 | -{ | |
452 | - unsigned long pbcr; | |
453 | - int res = 0; | |
454 | - pbcr = mfdcr (strap); | |
455 | - if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) | |
456 | - /* boot via MPS or MPS mapping */ | |
457 | - res = BOOT_MPS; | |
458 | - if(pbcr & PSR_ROM_LOC) | |
459 | - /* boot via PCI.. */ | |
460 | - res |= BOOT_PCI; | |
461 | - return res; | |
462 | -} | |
463 | - | |
464 | -/* Setup cs0 parameter finally. | |
465 | - Map the flash high (in boot area) | |
466 | - This code can only be executed from SDRAM (after relocation). | |
467 | -*/ | |
468 | -void setup_cs_reloc(void) | |
469 | -{ | |
470 | - unsigned long pbcr; | |
471 | - /* Since we are relocated, we can set-up the CS finaly | |
472 | - * but first of all, switch off PCI mapping (in case it was a PCI boot) */ | |
473 | - out32r(PMM0MA,0L); | |
474 | - icache_enable (); /* we are relocated */ | |
475 | - /* for PCI Boot, we have to set-up the remaining CS correctly */ | |
476 | - pbcr = mfdcr (strap); | |
477 | - if(pbcr & PSR_ROM_LOC) { | |
478 | - /* boot via PCI.. */ | |
479 | - if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) { | |
480 | - /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */ | |
481 | - #ifdef DEBUG | |
482 | - printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000)); | |
483 | - #endif | |
484 | - mtdcr (ebccfga, pb0ap); | |
485 | - mtdcr (ebccfgd, MPS_AP); | |
486 | - mtdcr (ebccfga, pb0cr); | |
487 | - mtdcr (ebccfgd, MPS_CR_B); | |
488 | - } | |
489 | - else { | |
490 | - /* Flash boot, set up the Flash on CS0 */ | |
491 | - #ifdef DEBUG | |
492 | - printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000)); | |
493 | - #endif | |
494 | - mtdcr (ebccfga, pb0ap); | |
495 | - mtdcr (ebccfgd, FLASH_AP); | |
496 | - mtdcr (ebccfga, pb0cr); | |
497 | - mtdcr (ebccfgd, FLASH_CR_B); | |
498 | - } | |
499 | - } | |
500 | - switch_cs(0); /* map Flash High */ | |
501 | -} | |
502 | - | |
503 | - | |
504 | -#elif defined(CONFIG_VCMA9) | |
505 | -int switch_cs(unsigned char boot) | |
506 | -{ | |
507 | - return 0; | |
508 | -} | |
509 | -#endif /* CONFIG_VCMA9 */ | |
510 | - | |
511 | 379 | int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
512 | 380 | { |
513 | 381 | ulong size,src,ld_addr; |
... | ... | @@ -625,6 +493,7 @@ |
625 | 493 | |
626 | 494 | #ifdef CONFIG_CONSOLE_EXTRA_INFO |
627 | 495 | extern GraphicDevice ctfb; |
496 | +extern int get_boot_mode(void); | |
628 | 497 | |
629 | 498 | void video_get_info_str (int line_number, char *info) |
630 | 499 | { |
board/mpl/common/common_util.h
... | ... | @@ -31,10 +31,8 @@ |
31 | 31 | } backup_t; |
32 | 32 | |
33 | 33 | void get_backup_values(backup_t *buf); |
34 | -int switch_cs(unsigned char boot); | |
34 | + | |
35 | 35 | #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) |
36 | -int get_boot_mode(void); | |
37 | -void setup_cs_reloc(void); | |
38 | 36 | #define BOOT_MPS 0x01 |
39 | 37 | #define BOOT_PCI 0x02 |
40 | 38 | #endif |
board/mpl/common/flash.c
... | ... | @@ -39,6 +39,13 @@ |
39 | 39 | #include <ppc4xx.h> |
40 | 40 | #include <asm/processor.h> |
41 | 41 | #include "common_util.h" |
42 | +#if defined(CONFIG_MIP405) | |
43 | +#include "../mip405/mip405.h" | |
44 | +#endif | |
45 | +#if defined(CONFIG_PIP405) | |
46 | +#include "../pip405/pip405.h" | |
47 | +#endif | |
48 | +#include <405gp_pci.h> | |
42 | 49 | |
43 | 50 | flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ |
44 | 51 | /*----------------------------------------------------------------------- |
45 | 52 | |
46 | 53 | |
47 | 54 | |
48 | 55 | |
49 | 56 | |
50 | 57 | |
... | ... | @@ -66,23 +73,102 @@ |
66 | 73 | #define TRUE 1 |
67 | 74 | |
68 | 75 | /*----------------------------------------------------------------------- |
76 | + * Some CS switching routines: | |
77 | + * | |
78 | + * On PIP/MIP405 we have 3 (4) possible boot mode | |
79 | + * | |
80 | + * - Boot from Flash (Flash CS = CS0, MPS CS = CS1) | |
81 | + * - Boot from MPS (Flash CS = CS1, MPS CS = CS0) | |
82 | + * - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1) | |
83 | + * - Boot from PCI with MPS map (Flash CS = CS1, MPS CS = CS0) | |
84 | + * The flash init is the first board specific routine which is called | |
85 | + * after code relocation (running from SDRAM) | |
86 | + * The first thing we do is to map the Flash CS to the Flash area and | |
87 | + * the MPS CS to the MPS area. Since the flash size is unknown at this | |
88 | + * point, we use the max flash size and the lowest flash address as base. | |
89 | + * | |
90 | + * After flash detection we adjust the size of the CS area accordingly. | |
91 | + * The board_init_r will fill in wrong values in the board init structure, | |
92 | + * but this will be fixed in the misc_init_r routine: | |
93 | + * bd->bi_flashstart=0-flash_info[0].size | |
94 | + * bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN | |
95 | + * bd->bi_flashoffset=0 | |
96 | + * | |
69 | 97 | */ |
98 | +int get_boot_mode(void) | |
99 | +{ | |
100 | + unsigned long pbcr; | |
101 | + int res = 0; | |
102 | + pbcr = mfdcr (strap); | |
103 | + if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) | |
104 | + /* boot via MPS or MPS mapping */ | |
105 | + res = BOOT_MPS; | |
106 | + if(pbcr & PSR_ROM_LOC) | |
107 | + /* boot via PCI.. */ | |
108 | + res |= BOOT_PCI; | |
109 | + return res; | |
110 | +} | |
70 | 111 | |
112 | +/* Map the flash high (in boot area) | |
113 | + This code can only be executed from SDRAM (after relocation). | |
114 | +*/ | |
115 | +void setup_cs_reloc(void) | |
116 | +{ | |
117 | + int mode; | |
118 | + /* Since we are relocated, we can set-up the CS finaly | |
119 | + * but first of all, switch off PCI mapping (in case it was a PCI boot) */ | |
120 | + out32r(PMM0MA,0L); | |
121 | + icache_enable (); /* we are relocated */ | |
122 | + /* get boot mode */ | |
123 | + mode=get_boot_mode(); | |
124 | + /* we map the flash high in every case */ | |
125 | + /* first findout on which cs the flash is */ | |
126 | + if(mode & BOOT_MPS) { | |
127 | + /* map flash high on CS1 and MPS on CS0 */ | |
128 | + mtdcr (ebccfga, pb0ap); | |
129 | + mtdcr (ebccfgd, MPS_AP); | |
130 | + mtdcr (ebccfga, pb0cr); | |
131 | + mtdcr (ebccfgd, MPS_CR); | |
132 | + /* we use the default values (max values) for the flash | |
133 | + * because its real size is not yet known */ | |
134 | + mtdcr (ebccfga, pb1ap); | |
135 | + mtdcr (ebccfgd, FLASH_AP); | |
136 | + mtdcr (ebccfga, pb1cr); | |
137 | + mtdcr (ebccfgd, FLASH_CR_B); | |
138 | + } | |
139 | + else { | |
140 | + /* map flash high on CS0 and MPS on CS1 */ | |
141 | + mtdcr (ebccfga, pb1ap); | |
142 | + mtdcr (ebccfgd, MPS_AP); | |
143 | + mtdcr (ebccfga, pb1cr); | |
144 | + mtdcr (ebccfgd, MPS_CR); | |
145 | + /* we use the default values (max values) for the flash | |
146 | + * because its real size is not yet known */ | |
147 | + mtdcr (ebccfga, pb0ap); | |
148 | + mtdcr (ebccfgd, FLASH_AP); | |
149 | + mtdcr (ebccfga, pb0cr); | |
150 | + mtdcr (ebccfgd, FLASH_CR_B); | |
151 | + } | |
152 | +} | |
71 | 153 | |
154 | + | |
155 | + | |
72 | 156 | unsigned long flash_init (void) |
73 | 157 | { |
74 | - unsigned long size_b0, size_b1; | |
75 | - int i; | |
158 | + unsigned long size_b0, size_b1,flashcr; | |
159 | + int mode, i; | |
160 | + extern char version_string; | |
161 | + char *p=&version_string; | |
76 | 162 | |
77 | 163 | /* Since we are relocated, we can set-up the CS finally */ |
78 | 164 | setup_cs_reloc(); |
79 | 165 | /* get and display boot mode */ |
80 | - i=get_boot_mode(); | |
81 | - if(i & BOOT_PCI) | |
82 | - printf("(PCI Boot %s Map) ",(i & BOOT_MPS) ? | |
166 | + mode=get_boot_mode(); | |
167 | + if(mode & BOOT_PCI) | |
168 | + printf("(PCI Boot %s Map) ",(mode & BOOT_MPS) ? | |
83 | 169 | "MPS" : "Flash"); |
84 | 170 | else |
85 | - printf("(%s Boot) ",(i & BOOT_MPS) ? | |
171 | + printf("(%s Boot) ",(mode & BOOT_MPS) ? | |
86 | 172 | "MPS" : "Flash"); |
87 | 173 | /* Init: no FLASHes known */ |
88 | 174 | for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { |
... | ... | @@ -91,7 +177,7 @@ |
91 | 177 | |
92 | 178 | /* Static FLASH Bank configuration here - FIXME XXX */ |
93 | 179 | |
94 | - size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]); | |
180 | + size_b0 = flash_get_size((vu_long *)CFG_MONITOR_BASE, &flash_info[0]); | |
95 | 181 | |
96 | 182 | if (flash_info[0].flash_id == FLASH_UNKNOWN) { |
97 | 183 | printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", |
98 | 184 | |
... | ... | @@ -109,8 +195,31 @@ |
109 | 195 | flash_info[0].protect[flash_info[0].sector_count-1] = 1; |
110 | 196 | size_b1 = 0 ; |
111 | 197 | flash_info[0].size = size_b0; |
198 | + /* set up flash cs according to the size */ | |
199 | + if(mode & BOOT_MPS) { | |
200 | + /* flash is on CS1 */ | |
201 | + mtdcr(ebccfga, pb1cr); | |
202 | + flashcr = mfdcr (ebccfgd); | |
203 | + /* we map the flash high in every case */ | |
204 | + flashcr&=0x0001FFFF; /* mask out address bits */ | |
205 | + flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */ | |
206 | + flashcr|= (((flash_info[0].size >>21) & 0x07) << 17); /* size addr */ | |
207 | + mtdcr(ebccfga, pb1cr); | |
208 | + mtdcr(ebccfgd, flashcr); | |
209 | + } | |
210 | + else { | |
211 | + /* flash is on CS0 */ | |
212 | + mtdcr(ebccfga, pb0cr); | |
213 | + flashcr = mfdcr (ebccfgd); | |
214 | + /* we map the flash high in every case */ | |
215 | + flashcr&=0x0001FFFF; /* mask out address bits */ | |
216 | + flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */ | |
217 | + flashcr|= (((flash_info[0].size >>21) & 0x07) << 17); /* size addr */ | |
218 | + mtdcr(ebccfga, pb0cr); | |
219 | + mtdcr(ebccfgd, flashcr); | |
220 | + } | |
112 | 221 | #if 0 |
113 | - /* include this if you want to test if | |
222 | + /* enable this if you want to test if | |
114 | 223 | the relocation has be done ok. |
115 | 224 | This will disable both Chipselects */ |
116 | 225 | mtdcr (ebccfga, pb0cr); |
... | ... | @@ -119,6 +228,14 @@ |
119 | 228 | mtdcr (ebccfgd, 0L); |
120 | 229 | printf("CS0 & CS1 switched off for test\n"); |
121 | 230 | #endif |
231 | + /* patch version_string */ | |
232 | + for(i=0;i<0x100;i++) { | |
233 | + if(*p=='\n') { | |
234 | + *p=0; | |
235 | + break; | |
236 | + } | |
237 | + p++; | |
238 | + } | |
122 | 239 | return (size_b0); |
123 | 240 | } |
124 | 241 | |
... | ... | @@ -171,6 +288,8 @@ |
171 | 288 | break; |
172 | 289 | case FLASH_INTEL320T: printf ("TE28F320C3 (32 Mbit, top sector size)\n"); |
173 | 290 | break; |
291 | + case FLASH_AM640U: printf ("AM29LV640U (64 Mbit, uniform sector size)\n"); | |
292 | + break; | |
174 | 293 | default: printf ("Unknown Chip Type\n"); |
175 | 294 | break; |
176 | 295 | } |
... | ... | @@ -211,7 +330,8 @@ |
211 | 330 | |
212 | 331 | |
213 | 332 | /*----------------------------------------------------------------------- |
214 | - */ | |
333 | + | |
334 | +*/ | |
215 | 335 | |
216 | 336 | /* |
217 | 337 | * The following code cannot be run from FLASH! |
... | ... | @@ -220,7 +340,7 @@ |
220 | 340 | { |
221 | 341 | short i; |
222 | 342 | FLASH_WORD_SIZE value; |
223 | - ulong base = (ulong)addr; | |
343 | + ulong base; | |
224 | 344 | volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr; |
225 | 345 | |
226 | 346 | /* Write auto select command: read Manufacturer ID */ |
... | ... | @@ -250,7 +370,7 @@ |
250 | 370 | return (0); /* no or unknown flash */ |
251 | 371 | } |
252 | 372 | value = addr2[1]; /* device ID */ |
253 | - /* printf("Device value %x\n",value); */ | |
373 | + /* printf("Device value %x\n",value); */ | |
254 | 374 | switch (value) { |
255 | 375 | case (FLASH_WORD_SIZE)AMD_ID_F040B: |
256 | 376 | info->flash_id += FLASH_AM040; |
257 | 377 | |
... | ... | @@ -292,12 +412,17 @@ |
292 | 412 | info->sector_count = 35; |
293 | 413 | info->size = 0x00200000; |
294 | 414 | break; /* => 2 MB */ |
295 | -#if 0 /* enable when device IDs are available */ | |
296 | 415 | case (FLASH_WORD_SIZE)AMD_ID_LV320T: |
297 | 416 | info->flash_id += FLASH_AM320T; |
298 | 417 | info->sector_count = 67; |
299 | 418 | info->size = 0x00400000; |
300 | 419 | break; /* => 4 MB */ |
420 | + case (FLASH_WORD_SIZE)AMD_ID_LV640U: | |
421 | + info->flash_id += FLASH_AM640U; | |
422 | + info->sector_count = 128; | |
423 | + info->size = 0x00800000; | |
424 | + break; /* => 8 MB */ | |
425 | +#if 0 /* enable when device IDs are available */ | |
301 | 426 | |
302 | 427 | case (FLASH_WORD_SIZE)AMD_ID_LV320B: |
303 | 428 | info->flash_id += FLASH_AM320B; |
304 | 429 | |
... | ... | @@ -328,10 +453,12 @@ |
328 | 453 | return (0); /* => no or unknown flash */ |
329 | 454 | |
330 | 455 | } |
331 | - | |
456 | + /* base address calculation */ | |
457 | + base=0-info->size; | |
332 | 458 | /* set up sector start address table */ |
333 | 459 | if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || |
334 | - (info->flash_id == FLASH_AM040)){ | |
460 | + (info->flash_id == FLASH_AM040) || | |
461 | + (info->flash_id == FLASH_AM640U)){ | |
335 | 462 | for (i = 0; i < info->sector_count; i++) |
336 | 463 | info->start[i] = base + (i * 0x00010000); |
337 | 464 | } |
board/mpl/common/isa.c
... | ... | @@ -32,7 +32,6 @@ |
32 | 32 | #include "kbd.h" |
33 | 33 | #include "video.h" |
34 | 34 | |
35 | -extern int drv_isa_kbd_init (void); | |
36 | 35 | |
37 | 36 | #undef ISA_DEBUG |
38 | 37 | |
39 | 38 | |
... | ... | @@ -49,7 +48,10 @@ |
49 | 48 | #define FALSE 0 |
50 | 49 | #endif |
51 | 50 | |
51 | +#if defined(CONFIG_PIP405) | |
52 | 52 | |
53 | +extern int drv_isa_kbd_init (void); | |
54 | + | |
53 | 55 | /* fdc (logical device 0) */ |
54 | 56 | const SIO_LOGDEV_TABLE sio_fdc[] = { |
55 | 57 | {0x60, 3}, /* set IO to FDPort (3F0) */ |
56 | 58 | |
... | ... | @@ -183,8 +185,8 @@ |
183 | 185 | close_cfg_super_IO(0x3F0); |
184 | 186 | } |
185 | 187 | } |
188 | +#endif | |
186 | 189 | |
187 | - | |
188 | 190 | /****************************************************************************** |
189 | 191 | * IRQ Controller |
190 | 192 | * we use the Vector mode |
... | ... | @@ -202,7 +204,7 @@ |
202 | 204 | /* |
203 | 205 | * This contains the irq mask for both 8259A irq controllers, |
204 | 206 | */ |
205 | -static unsigned int cached_irq_mask = 0xffff; | |
207 | +static unsigned int cached_irq_mask = 0xfff9; | |
206 | 208 | |
207 | 209 | #define cached_imr1 (unsigned char)cached_irq_mask |
208 | 210 | #define cached_imr2 (unsigned char)(cached_irq_mask>>8) |
209 | 211 | |
210 | 212 | |
211 | 213 | |
... | ... | @@ -387,20 +389,23 @@ |
387 | 389 | isr2=in8(ISR_2); |
388 | 390 | isr1=in8(ISR_1); |
389 | 391 | irq=(unsigned char)irqack; |
390 | - if((irq==7)&&((isr1&0x80)==0)) { | |
392 | + irq-=32; | |
393 | +/* if((irq==7)&&((isr1&0x80)==0)) { | |
391 | 394 | PRINTF("IRQ7 detected but not in ISR\n"); |
392 | 395 | } |
393 | 396 | else { |
394 | - /* we should handle cascaded interrupts here also */ | |
395 | - /* printf("ISA Irq %d\n",irq); */ | |
396 | - isa_irqs[irq].count++; | |
397 | - if (isa_irqs[irq].handler != NULL) | |
398 | - (*isa_irqs[irq].handler)(isa_irqs[irq].arg); /* call isr */ | |
399 | - else | |
397 | +*/ /* we should handle cascaded interrupts here also */ | |
400 | 398 | { |
401 | - PRINTF ("bogus interrupt vector 0x%x\n", irq); | |
399 | +/* printf("ISA Irq %d\n",irq); */ | |
400 | + isa_irqs[irq].count++; | |
401 | + if(irq!=2) { /* just swallow the cascade irq 2 */ | |
402 | + if (isa_irqs[irq].handler != NULL) | |
403 | + (*isa_irqs[irq].handler)(isa_irqs[irq].arg); /* call isr */ | |
404 | + else { | |
405 | + PRINTF ("bogus interrupt vector 0x%x\n", irq); | |
406 | + } | |
407 | + } | |
402 | 408 | } |
403 | - } | |
404 | 409 | /* issue EOI instruction to clear the IRQ */ |
405 | 410 | mask_and_ack_8259A(irq); |
406 | 411 | return 0; |
... | ... | @@ -413,13 +418,13 @@ |
413 | 418 | |
414 | 419 | void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg) |
415 | 420 | { |
416 | - if (isa_irqs[vec].handler != NULL) { | |
417 | - printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n", | |
418 | - vec, (uint)handler, (uint)isa_irqs[vec].handler); | |
419 | - } | |
420 | - isa_irqs[vec].handler = handler; | |
421 | - isa_irqs[vec].arg = arg; | |
422 | - enable_8259A_irq(vec); | |
421 | + if (isa_irqs[vec].handler != NULL) { | |
422 | + printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n", | |
423 | + vec, (uint)handler, (uint)isa_irqs[vec].handler); | |
424 | + } | |
425 | + isa_irqs[vec].handler = handler; | |
426 | + isa_irqs[vec].arg = arg; | |
427 | + enable_8259A_irq(vec); | |
423 | 428 | PRINTF ("Install ISA IRQ %d ==> %p, @ %p mask=%04x\n", vec, handler, &isa_irqs[vec].handler,cached_irq_mask); |
424 | 429 | |
425 | 430 | } |
... | ... | @@ -427,9 +432,9 @@ |
427 | 432 | void isa_irq_free_handler(int vec) |
428 | 433 | { |
429 | 434 | disable_8259A_irq(vec); |
430 | - isa_irqs[vec].handler = NULL; | |
431 | - isa_irqs[vec].arg = NULL; | |
432 | - printf ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask); | |
435 | + isa_irqs[vec].handler = NULL; | |
436 | + isa_irqs[vec].arg = NULL; | |
437 | + PRINTF ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask); | |
433 | 438 | |
434 | 439 | } |
435 | 440 | |
436 | 441 | |
437 | 442 | |
438 | 443 | |
439 | 444 | |
440 | 445 | |
... | ... | @@ -448,17 +453,43 @@ |
448 | 453 | init_8259A(); |
449 | 454 | out8(IMR_2,0xFF); |
450 | 455 | } |
456 | +/*************************************************************************/ | |
451 | 457 | |
458 | +void isa_show_irq(void) | |
459 | +{ | |
460 | + int vec; | |
452 | 461 | |
462 | + printf ("\nISA Interrupt-Information:\n"); | |
463 | + printf ("Nr Routine Arg Count\n"); | |
464 | + | |
465 | + for (vec=0; vec<16; vec++) { | |
466 | + if (isa_irqs[vec].handler != NULL) { | |
467 | + printf ("%02d %08lx %08lx %d\n", | |
468 | + vec, | |
469 | + (ulong)isa_irqs[vec].handler, | |
470 | + (ulong)isa_irqs[vec].arg, | |
471 | + isa_irqs[vec].count); | |
472 | + } | |
473 | + } | |
474 | +} | |
475 | + | |
476 | +int isa_irq_get_count(int vec) | |
477 | +{ | |
478 | + return(isa_irqs[vec].count); | |
479 | +} | |
480 | + | |
453 | 481 | /****************************************************************** |
454 | 482 | * Init the ISA bus and devices. |
455 | 483 | */ |
456 | 484 | |
485 | +#if defined(CONFIG_PIP405) | |
457 | 486 | |
458 | 487 | int isa_init(void) |
459 | 488 | { |
460 | 489 | isa_sio_setup(); |
490 | + isa_init_irq_contr(); | |
461 | 491 | drv_isa_kbd_init(); |
462 | 492 | return 0; |
463 | 493 | } |
494 | +#endif |
board/mpl/common/isa.h
... | ... | @@ -21,12 +21,12 @@ |
21 | 21 | * MA 02111-1307 USA |
22 | 22 | */ |
23 | 23 | |
24 | -#ifndef _PIP405_ISA_H_ | |
25 | -#define _PIP405_ISA_H_ | |
24 | +#ifndef _ISA_H_ | |
25 | +#define _ISA_H_ | |
26 | 26 | /* Super IO */ |
27 | 27 | #define SIO_CFG_PORT 0x3F0 /* Config Port Address */ |
28 | 28 | |
29 | - | |
29 | +#if defined(CONFIG_PIP405) | |
30 | 30 | /* table fore SIO initialization */ |
31 | 31 | typedef struct { |
32 | 32 | const uchar index; |
33 | 33 | |
... | ... | @@ -44,10 +44,14 @@ |
44 | 44 | void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data); |
45 | 45 | void close_cfg_super_IO(int address); |
46 | 46 | void isa_sio_setup(void); |
47 | -void isa_sio_setup(void); | |
47 | +#endif | |
48 | + | |
48 | 49 | void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg); |
49 | 50 | void isa_irq_free_handler(int vec); |
50 | 51 | int handle_isa_int(void); |
52 | +void isa_init_irq_contr(void); | |
53 | +void isa_show_irq(void); | |
54 | +int isa_irq_get_count(int vec); | |
51 | 55 | |
52 | 56 | |
53 | 57 | #endif |
board/mpl/common/pci_parts.h
... | ... | @@ -92,7 +92,7 @@ |
92 | 92 | /* PIIX4 ISA Bridge Function 0 */ |
93 | 93 | static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = { |
94 | 94 | {PCI_CFG_PIIX4_SERIRQ, 0xD0, 1}, /* enable Continous SERIRQ Pin */ |
95 | - {PCI_CFG_PIIX4_GENCFG, 0x00010041, 4}, /* enable SERIRQs, ISA, PNP */ | |
95 | + {PCI_CFG_PIIX4_GENCFG, 0x00018041, 4}, /* enable SERIRQs, ISA, PNP, GPI11 */ | |
96 | 96 | {PCI_CFG_PIIX4_TOM, 0xFE, 1}, /* Top of Memory */ |
97 | 97 | {PCI_CFG_PIIX4_XBCS, 0x02C4, 2}, /* disable all peri CS */ |
98 | 98 | {PCI_CFG_PIIX4_RTCCFG, 0x21, 1}, /* enable RTC */ |
... | ... | @@ -106,6 +106,7 @@ |
106 | 106 | |
107 | 107 | /* PIIX4 IDE Controller Function 1 */ |
108 | 108 | static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = { |
109 | + {PCI_CFG_PIIX4_BMIBA, 0x0001000, 4}, /* set BMI to a valid address */ | |
109 | 110 | {PCI_COMMAND, 0x0001, 2}, /* enable IO access */ |
110 | 111 | #if !defined(CONFIG_MIP405T) |
111 | 112 | {PCI_CFG_PIIX4_IDETIM, 0x80008000, 4}, /* enable Both IDE channels */ |
112 | 113 | |
... | ... | @@ -129,10 +130,10 @@ |
129 | 130 | |
130 | 131 | /* PIIX4 Power Management Function 3 */ |
131 | 132 | static struct pci_pip405_config_entry piix4_pmm_cntrl_f3[] = { |
132 | - {PCI_COMMAND, 0x0001, 2}, /* enable IO access */ | |
133 | - {PCI_CFG_PIIX4_PMAB, 0x00004000, 4}, /* set PMBA to "valid" value */ | |
134 | - {PCI_CFG_PIIX4_PMMISC, 0x01, 1}, /* enable PMBA IO access */ | |
133 | + {PCI_CFG_PIIX4_PMBA, 0x00004000, 4}, /* set PMBA to "valid" value */ | |
135 | 134 | {PCI_CFG_PIIX4_SMBBA, 0x00005000, 4}, /* set SMBBA to "valid" value */ |
135 | + {PCI_CFG_PIIX4_PMMISC, 0x01, 1}, /* enable PMBA IO access */ | |
136 | + {PCI_COMMAND, 0x0001, 2}, /* enable IO access */ | |
136 | 137 | { } /* end of device table */ |
137 | 138 | }; |
138 | 139 | /* PPC405 Dummy only used to prevent autosetup on this host bridge */ |
board/mpl/common/piix4_pci.h
... | ... | @@ -143,7 +143,7 @@ |
143 | 143 | #define PCI_CFG_PIIX4_LEGSUP 0xC0 |
144 | 144 | |
145 | 145 | /* Function 3 Power Management */ |
146 | -#define PCI_CFG_PIIX4_PMAB 0x40 | |
146 | +#define PCI_CFG_PIIX4_PMBA 0x40 | |
147 | 147 | #define PCI_CFG_PIIX4_CNTA 0x44 |
148 | 148 | #define PCI_CFG_PIIX4_CNTB 0x48 |
149 | 149 | #define PCI_CFG_PIIX4_GPICTL 0x4C |
board/mpl/mip405/cmd_mip405.c
... | ... | @@ -54,10 +54,13 @@ |
54 | 54 | return (do_mplcommon(cmdtp, flag, argc, argv)); |
55 | 55 | } |
56 | 56 | U_BOOT_CMD( |
57 | - mip405, 6, 1, do_mip405, | |
57 | + mip405, 8, 1, do_mip405, | |
58 | 58 | "mip405 - MIP405 specific Cmds\n", |
59 | 59 | "flash mem [SrcAddr] - updates U-Boot with image in memory\n" |
60 | 60 | "mip405 flash mps - updates U-Boot with image from MPS\n" |
61 | + "mip405 info - displays board information\n" | |
62 | + "mip405 led <on> - switches LED on (on=1) or off (on=0)\n" | |
63 | + "mip405 mem [cnt] - Memory Test <cnt>-times, <cnt> = -1 loop forever\n" | |
61 | 64 | ); |
62 | 65 | |
63 | 66 | /* ------------------------------------------------------------------------- */ |
board/mpl/mip405/init.S
... | ... | @@ -87,19 +87,15 @@ |
87 | 87 | mfdcr r4,ebccfgd |
88 | 88 | |
89 | 89 | andi. r0, r4, 0x2000 /* mask out irrelevant bits */ |
90 | - beq 0f /* jump if 8 bit bus width */ | |
90 | + beq 0f /* jump if 8 bit bus width */ | |
91 | 91 | |
92 | - /* setup 16 bit things (Flash Boot) | |
92 | + /* setup 16 bit things | |
93 | 93 | *----------------------------------------------------------------------- |
94 | 94 | * Memory Bank 0 (16 Bit Flash) initialization |
95 | 95 | *---------------------------------------------------------------------- */ |
96 | 96 | |
97 | 97 | addi r4,0,pb0ap |
98 | 98 | mtdcr ebccfga,r4 |
99 | -/* addis r4,0,0xFF8F */ | |
100 | -/* ori r4,r4,0xFE80 */ | |
101 | -/* addis r4,0,0x9B01 */ | |
102 | -/* ori r4,r4,0x5480 */ | |
103 | 99 | addis r4,0,(FLASH_AP_B)@h |
104 | 100 | ori r4,r4,(FLASH_AP_B)@l |
105 | 101 | mtdcr ebccfgd,r4 |
... | ... | @@ -107,8 +103,6 @@ |
107 | 103 | addi r4,0,pb0cr |
108 | 104 | mtdcr ebccfga,r4 |
109 | 105 | /* BS=0x010(4MB),BU=0x3(R/W), */ |
110 | -/* addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h */ | |
111 | -/* ori r4,r4,0xA000 / * BW=0x01(16 bits) */ | |
112 | 106 | addis r4,0,(FLASH_CR_B)@h |
113 | 107 | ori r4,r4,(FLASH_CR_B)@l |
114 | 108 | mtdcr ebccfgd,r4 |
115 | 109 | |
116 | 110 | |
... | ... | @@ -123,21 +117,13 @@ |
123 | 117 | /* 0x7F8FFE80 slowest boot */ |
124 | 118 | addi r4,0,pb0ap |
125 | 119 | mtdcr ebccfga,r4 |
126 | -#if 0 | |
127 | - addis r4,0,0x9B01 | |
128 | - ori r4,r4,0x5480 | |
129 | -#else | |
130 | 120 | addis r4,0,(MPS_AP_B)@h |
131 | 121 | ori r4,r4,(MPS_AP_B)@l |
132 | -#endif | |
133 | 122 | mtdcr ebccfgd,r4 |
134 | 123 | |
135 | 124 | addi r4,0,pb0cr |
136 | 125 | mtdcr ebccfga,r4 |
137 | 126 | /* BS=0x010(4MB),BU=0x3(R/W), */ |
138 | -/* addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h */ | |
139 | -/* ori r4,r4,0x8000 / * BW=0x0( 8 bits) */ | |
140 | - | |
141 | 127 | addis r4,0,(MPS_CR_B)@h |
142 | 128 | ori r4,r4,(MPS_CR_B)@l |
143 | 129 | |
144 | 130 | |
145 | 131 | |
... | ... | @@ -178,18 +164,18 @@ |
178 | 164 | ori r4,r4,0x0000 |
179 | 165 | mtdcr ebccfgd,r4 |
180 | 166 | |
181 | - addi r4,0,pb6cr | |
167 | + addi r4,0,pb6cr | |
182 | 168 | mtdcr ebccfga,r4 |
183 | 169 | addis r4,0,0x0000 |
184 | 170 | ori r4,r4,0x0000 |
185 | 171 | mtdcr ebccfgd,r4 |
186 | 172 | |
187 | - addi r4,0,pb7cr | |
173 | + addi r4,0,pb7cr | |
188 | 174 | mtdcr ebccfga,r4 |
189 | 175 | addis r4,0,0x0000 |
190 | 176 | ori r4,r4,0x0000 |
191 | 177 | mtdcr ebccfgd,r4 |
192 | - nop /* pass2 DCR errata #8 */ | |
178 | + nop /* pass2 DCR errata #8 */ | |
193 | 179 | blr |
194 | 180 | |
195 | 181 | /*----------------------------------------------------------------------------- |
board/mpl/mip405/mip405.c
... | ... | @@ -667,9 +667,16 @@ |
667 | 667 | /* used to check if the time in RTC is valid */ |
668 | 668 | static unsigned long start; |
669 | 669 | static struct rtc_time tm; |
670 | +extern flash_info_t flash_info[]; /* info for FLASH chips */ | |
670 | 671 | |
671 | 672 | int misc_init_r (void) |
672 | 673 | { |
674 | + DECLARE_GLOBAL_DATA_PTR; | |
675 | + /* adjust flash start and size as well as the offset */ | |
676 | + gd->bd->bi_flashstart=0-flash_info[0].size; | |
677 | + gd->bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN; | |
678 | + gd->bd->bi_flashoffset=0; | |
679 | + | |
673 | 680 | /* check, if RTC is running */ |
674 | 681 | rtc_get (&tm); |
675 | 682 | start=get_timer(0); |
board/mpl/mip405/mip405.h
... | ... | @@ -137,13 +137,13 @@ |
137 | 137 | (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5)) |
138 | 138 | |
139 | 139 | /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ |
140 | -#define FLASH_BS 2 /* 4 MByte */ | |
140 | +#define FLASH_BS FLASH_SIZE_PRELIM /* 4 MByte */ | |
141 | 141 | /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */ |
142 | 142 | #define FLASH_BU 3 /* R/W */ |
143 | 143 | /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */ |
144 | 144 | #define FLASH_BW 1 /* 16Bit */ |
145 | 145 | /* CR register for Boot */ |
146 | -#define FLASH_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13)) | |
146 | +#define FLASH_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13)) | |
147 | 147 | /* CR register for non Boot */ |
148 | 148 | #define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13)) |
149 | 149 | |
150 | 150 | |
... | ... | @@ -172,12 +172,13 @@ |
172 | 172 | |
173 | 173 | /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ |
174 | 174 | #define MPS_BS 2 /* 4 MByte */ |
175 | +#define MPS_BS_B FLASH_SIZE_PRELIM /* 1 MByte */ | |
175 | 176 | /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */ |
176 | 177 | #define MPS_BU 3 /* R/W */ |
177 | 178 | /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */ |
178 | 179 | #define MPS_BW 0 /* 8Bit */ |
179 | 180 | /* CR register for Boot */ |
180 | -#define MPS_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13)) | |
181 | +#define MPS_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS_B << 17) + (MPS_BU << 15) + (MPS_BW << 13)) | |
181 | 182 | /* CR register for non Boot */ |
182 | 183 | #define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13)) |
board/mpl/pip405/init.S
... | ... | @@ -41,17 +41,21 @@ |
41 | 41 | |
42 | 42 | #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ |
43 | 43 | |
44 | -#include "configs/PIP405.h" | |
44 | +#include <configs/PIP405.h> | |
45 | 45 | #include <ppc_asm.tmpl> |
46 | 46 | #include <ppc_defs.h> |
47 | 47 | |
48 | 48 | #include <asm/cache.h> |
49 | 49 | #include <asm/mmu.h> |
50 | +#include "pip405.h" | |
50 | 51 | |
52 | + .globl ext_bus_cntlr_init | |
53 | + ext_bus_cntlr_init: | |
54 | + mflr r4 /* save link register */ | |
55 | + mfdcr r3,strap /* get strapping reg */ | |
56 | + andi. r0, r3, PSR_ROM_LOC /* mask out irrelevant bits */ | |
57 | + bnelr /* jump back if PCI boot */ | |
51 | 58 | |
52 | - .globl ext_bus_cntlr_init | |
53 | -ext_bus_cntlr_init: | |
54 | - mflr r4 /* save link register */ | |
55 | 59 | bl ..getAddr |
56 | 60 | ..getAddr: |
57 | 61 | mflr r3 /* get address of ..getAddr */ |
... | ... | @@ -82,7 +86,7 @@ |
82 | 86 | mfdcr r4,ebccfgd |
83 | 87 | |
84 | 88 | andi. r0, r4, 0x2000 /* mask out irrelevant bits */ |
85 | - beq 0f /* jump if 8 bit bus width */ | |
89 | + beq 0f /* jump if 8 bit bus width */ | |
86 | 90 | |
87 | 91 | /* setup 16 bit things |
88 | 92 | *----------------------------------------------------------------------- |
89 | 93 | |
90 | 94 | |
91 | 95 | |
92 | 96 | |
93 | 97 | |
94 | 98 | |
95 | 99 | |
96 | 100 | |
97 | 101 | |
98 | 102 | |
... | ... | @@ -90,74 +94,49 @@ |
90 | 94 | *---------------------------------------------------------------------- */ |
91 | 95 | |
92 | 96 | addi r4,0,pb0ap |
93 | - mtdcr ebccfga,r4 | |
94 | - addis r4,0,0x9B01 | |
95 | - ori r4,r4,0x5480 | |
96 | - mtdcr ebccfgd,r4 | |
97 | + mtdcr ebccfga,r4 | |
98 | + addis r4,0,(FLASH_AP_B)@h | |
99 | + ori r4,r4,(FLASH_AP_B)@l | |
100 | + mtdcr ebccfgd,r4 | |
97 | 101 | |
98 | - addi r4,0,pb0cr | |
99 | - mtdcr ebccfga,r4 | |
100 | - /* BS=0x011(8MB),BU=0x3(R/W), */ | |
101 | - addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h | |
102 | - ori r4,r4,0xA000 /* BW=0x01(16 bits) */ | |
103 | - mtdcr ebccfgd,r4 | |
104 | - | |
105 | - /*----------------------------------------------------------------------- | |
106 | - * Memory Bank 1 (Multi Purpose Socket) initialization | |
107 | - *----------------------------------------------------------------------*/ | |
108 | - addi r4,0,pb1ap | |
109 | - mtdcr ebccfga,r4 | |
110 | - addis r4,0,0x0281 | |
111 | - ori r4,r4,0x5480 | |
112 | - mtdcr ebccfgd,r4 | |
113 | - | |
114 | - addi r4,0,pb1cr | |
115 | - mtdcr ebccfga,r4 | |
116 | - /* BS=0x011(8MB),BU=0x3(R/W), */ | |
117 | - addis r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h | |
118 | - ori r4,r4,0x8000 /* BW=0x0( 8 bits) */ | |
119 | - mtdcr ebccfgd,r4 | |
102 | + addi r4,0,pb0cr | |
103 | + mtdcr ebccfga,r4 | |
104 | + /* BS=0x010(4MB),BU=0x3(R/W), */ | |
105 | + addis r4,0,(FLASH_CR_B)@h | |
106 | + ori r4,r4,(FLASH_CR_B)@l | |
107 | + mtdcr ebccfgd,r4 | |
120 | 108 | b 1f |
121 | 109 | |
122 | 110 | 0: |
123 | - /* 8Bit boot mode: */ | |
111 | + /* 8Bit boot mode: */ | |
124 | 112 | /*----------------------------------------------------------------------- |
125 | - * Memory Bank 0 Multi Purpose Socket initialization | |
126 | - *----------------------------------------------------------------------- */ | |
127 | - | |
113 | + * Memory Bank 0 Multi Purpose Socket initialization | |
114 | + *----------------------------------------------------------------------- */ | |
115 | + /* 0x7F8FFE80 slowest boot */ | |
128 | 116 | addi r4,0,pb0ap |
129 | - mtdcr ebccfga,r4 | |
130 | - addis r4,0,0x9B01 | |
131 | - ori r4,r4,0x5480 | |
132 | - mtdcr ebccfgd,r4 | |
117 | + mtdcr ebccfga,r4 | |
118 | + addis r4,0,(MPS_AP_B)@h | |
119 | + ori r4,r4,(MPS_AP_B)@l | |
120 | + mtdcr ebccfgd,r4 | |
133 | 121 | |
134 | - addi r4,0,pb0cr | |
135 | - mtdcr ebccfga,r4 | |
136 | - /* BS=0x011(4MB),BU=0x3(R/W), */ | |
137 | - addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h | |
138 | - ori r4,r4,0x8000 /* BW=0x0( 8 bits) */ | |
139 | - mtdcr ebccfgd,r4 | |
122 | + addi r4,0,pb0cr | |
123 | + mtdcr ebccfga,r4 | |
124 | + /* BS=0x010(4MB),BU=0x3(R/W), */ | |
125 | + addis r4,0,(MPS_CR_B)@h | |
126 | + ori r4,r4,(MPS_CR_B)@l | |
127 | + mtdcr ebccfgd,r4 | |
140 | 128 | |
129 | + | |
130 | +1: | |
141 | 131 | /*----------------------------------------------------------------------- |
142 | - * Memory Bank 1 (Flash) initialization | |
132 | + * Memory Bank 2-3-4-5-6 (not used) initialization | |
143 | 133 | *-----------------------------------------------------------------------*/ |
144 | - addi r4,0,pb1ap | |
145 | - mtdcr ebccfga,r4 | |
146 | - addis r4,0,0x0281 | |
147 | - ori r4,r4,0x5480 | |
148 | - mtdcr ebccfgd,r4 | |
149 | - | |
150 | 134 | addi r4,0,pb1cr |
151 | 135 | mtdcr ebccfga,r4 |
152 | - /* BS=0x011(8MB),BU=0x3(R/W), */ | |
153 | - addis r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h | |
154 | - ori r4,r4,0xA000 /* BW=0x0( 8 bits) */ | |
136 | + addis r4,0,0x0000 | |
137 | + ori r4,r4,0x0000 | |
155 | 138 | mtdcr ebccfgd,r4 |
156 | 139 | |
157 | -1: | |
158 | - /*----------------------------------------------------------------------- | |
159 | - * Memory Bank 2-3-4-5-6 (not used) initialization | |
160 | - *-----------------------------------------------------------------------*/ | |
161 | 140 | addi r4,0,pb2cr |
162 | 141 | mtdcr ebccfga,r4 |
163 | 142 | addis r4,0,0x0000 |
164 | 143 | |
165 | 144 | |
166 | 145 | |
... | ... | @@ -182,28 +161,18 @@ |
182 | 161 | ori r4,r4,0x0000 |
183 | 162 | mtdcr ebccfgd,r4 |
184 | 163 | |
185 | - addi r4,0,pb6cr | |
164 | + addi r4,0,pb6cr | |
186 | 165 | mtdcr ebccfga,r4 |
187 | 166 | addis r4,0,0x0000 |
188 | 167 | ori r4,r4,0x0000 |
189 | 168 | mtdcr ebccfgd,r4 |
190 | 169 | |
191 | - /*----------------------------------------------------------------------- | |
192 | - * Memory Bank 7 (Config Register) initialization | |
193 | - *----------------------------------------------------------------------- */ | |
194 | - addi r4,0,pb7ap | |
195 | - mtdcr ebccfga,r4 | |
196 | - addis r4,0,0x0181 /* Doc says TWT=3 and Openios TWT=3!! */ | |
197 | - ori r4,r4,0x5280 /* disable Ready, BEM=0 */ | |
198 | - mtdcr ebccfgd,r4 | |
199 | - | |
200 | 170 | addi r4,0,pb7cr |
201 | 171 | mtdcr ebccfga,r4 |
202 | - /* BS=0x0(1MB),BU=0x3(R/W), */ | |
203 | - addis r4,0,((CONFIG_PORT_ADDR & 0xFFF00000) | 0x00010000)@h | |
204 | - ori r4,r4,0x8000 /* BW=0x0(8 bits) */ | |
172 | + addis r4,0,0x0000 | |
173 | + ori r4,r4,0x0000 | |
205 | 174 | mtdcr ebccfgd,r4 |
206 | - nop /* pass2 DCR errata #8 */ | |
175 | + nop /* pass2 DCR errata #8 */ | |
207 | 176 | blr |
208 | 177 | |
209 | 178 | /*----------------------------------------------------------------------------- |
... | ... | @@ -217,4 +186,46 @@ |
217 | 186 | |
218 | 187 | |
219 | 188 | blr |
189 | + | |
190 | + | |
191 | +#if defined(CONFIG_BOOT_PCI) | |
192 | + .section .bootpg,"ax" | |
193 | + .globl _start_pci | |
194 | +/******************************************* | |
195 | + */ | |
196 | + | |
197 | +_start_pci: | |
198 | + /* first handle errata #68 / PCI_18 */ | |
199 | + iccci r0, r0 /* invalidate I-cache */ | |
200 | + lis r31, 0 | |
201 | + mticcr r31 /* ICCR = 0 (all uncachable) */ | |
202 | + isync | |
203 | + | |
204 | + mfccr0 r28 /* set CCR0[24] = 1 */ | |
205 | + ori r28, r28, 0x0080 | |
206 | + mtccr0 r28 | |
207 | + | |
208 | + /* setup PMM0MA (0xEF400004) and PMM0PCIHA (0xEF40000C) */ | |
209 | + lis r28, 0xEF40 | |
210 | + addi r28, r28, 0x0004 | |
211 | + stw r31, 0x0C(r28) /* clear PMM0PCIHA */ | |
212 | + lis r29, 0xFFF8 /* open 512 kByte */ | |
213 | + addi r29, r29, 0x0001/* and enable this region */ | |
214 | + stwbrx r29, r0, r28 /* write PMM0MA */ | |
215 | + | |
216 | + lis r28, 0xEEC0 /* address of PCIC0_CFGADDR */ | |
217 | + addi r29, r28, 4 /* add 4 to r29 -> PCIC0_CFGDATA */ | |
218 | + | |
219 | + lis r31, 0x8000 /* set en bit bus 0 */ | |
220 | + ori r31, r31, 0x304C/* device 6 func 0 reg 4C (XBCS register) */ | |
221 | + stwbrx r31, r0, r28 /* write it */ | |
222 | + | |
223 | + lwbrx r31, r0, r29 /* load XBCS register */ | |
224 | + oris r31, r31, 0x02C4/* clear BIOSCS WPE, set lower, extended and 1M extended BIOS enable */ | |
225 | + stwbrx r31, r0, r29 /* write back XBCS register */ | |
226 | + | |
227 | + nop | |
228 | + nop | |
229 | + b _start /* normal start */ | |
230 | +#endif |
board/mpl/pip405/pip405.c
... | ... | @@ -194,6 +194,11 @@ |
194 | 194 | #ifdef SDRAM_DEBUG |
195 | 195 | DECLARE_GLOBAL_DATA_PTR; |
196 | 196 | #endif |
197 | + /* set up the config port */ | |
198 | + mtdcr (ebccfga, pb7ap); | |
199 | + mtdcr (ebccfgd, CONFIG_PORT_AP); | |
200 | + mtdcr (ebccfga, pb7cr); | |
201 | + mtdcr (ebccfgd, CONFIG_PORT_CR); | |
197 | 202 | |
198 | 203 | memclk = get_bus_freq (tmemclk); |
199 | 204 | tmemclk = 1000000000 / (memclk / 100); /* in 10 ps units */ |
200 | 205 | |
... | ... | @@ -657,8 +662,20 @@ |
657 | 662 | } |
658 | 663 | |
659 | 664 | |
665 | +extern flash_info_t flash_info[]; /* info for FLASH chips */ | |
666 | + | |
660 | 667 | int misc_init_r (void) |
661 | 668 | { |
669 | + DECLARE_GLOBAL_DATA_PTR; | |
670 | + /* adjust flash start and size as well as the offset */ | |
671 | + gd->bd->bi_flashstart=0-flash_info[0].size; | |
672 | + gd->bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN; | |
673 | + gd->bd->bi_flashoffset=0; | |
674 | + | |
675 | + /* if PIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */ | |
676 | + if (mfdcr(strap) & PSR_ROM_LOC) | |
677 | + mtspr(ccr0, (mfspr(ccr0) & ~0x80)); | |
678 | + | |
662 | 679 | return (0); |
663 | 680 | } |
664 | 681 |
board/mpl/pip405/pip405.h
... | ... | @@ -25,6 +25,7 @@ |
25 | 25 | * Global routines used for PIP405 |
26 | 26 | *****************************************************************************/ |
27 | 27 | |
28 | +#ifndef __ASSEMBLY__ | |
28 | 29 | |
29 | 30 | extern int mem_test(unsigned long start, unsigned long ramsize,int mode); |
30 | 31 | |
31 | 32 | |
... | ... | @@ -35,13 +36,13 @@ |
35 | 36 | |
36 | 37 | |
37 | 38 | #define PLD_BASE_ADDRESS CFG_ISA_IO_BASE_ADDRESS + 0x800 |
38 | -#define PLD_PART_REG PLD_BASE_ADDRESS + 0 | |
39 | -#define PLD_VERS_REG PLD_BASE_ADDRESS + 1 | |
39 | +#define PLD_PART_REG PLD_BASE_ADDRESS + 0 | |
40 | +#define PLD_VERS_REG PLD_BASE_ADDRESS + 1 | |
40 | 41 | #define PLD_BOARD_CFG_REG PLD_BASE_ADDRESS + 2 |
41 | 42 | #define PLD_LED_USER_REG PLD_BASE_ADDRESS + 3 |
42 | 43 | #define PLD_SYS_MAN_REG PLD_BASE_ADDRESS + 4 |
43 | 44 | #define PLD_FLASH_COM_REG PLD_BASE_ADDRESS + 5 |
44 | -#define PLD_CAN_REG PLD_BASE_ADDRESS + 6 | |
45 | +#define PLD_CAN_REG PLD_BASE_ADDRESS + 6 | |
45 | 46 | #define PLD_SER_PWR_REG PLD_BASE_ADDRESS + 7 |
46 | 47 | #define PLD_COM_PWR_REG PLD_BASE_ADDRESS + 8 |
47 | 48 | #define PLD_NIC_VGA_REG PLD_BASE_ADDRESS + 9 |
48 | 49 | |
49 | 50 | |
50 | 51 | |
51 | 52 | |
52 | 53 | |
53 | 54 | |
54 | 55 | |
... | ... | @@ -50,87 +51,33 @@ |
50 | 51 | #define PIIX4_VENDOR_ID 0x8086 |
51 | 52 | #define PIIX4_IDE_DEV_ID 0x7111 |
52 | 53 | |
54 | +#endif | |
53 | 55 | |
54 | 56 | /* timings */ |
55 | -/* PLD (CS7) */ | |
56 | -#define PLD_BME 0 /* Burst disable */ | |
57 | -#define PLD_TWE 5 /* 5 * 30ns 120ns Waitstates (access=TWT+1+TH) */ | |
58 | -#define PLD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */ | |
59 | -#define PLD_OEN 1 /* Cycles from CS low to OE low */ | |
60 | -#define PLD_WBN 1 /* Cycles from CS low to WE low */ | |
61 | -#define PLD_WBF 1 /* Cycles from WE high to CS high */ | |
62 | -#define PLD_TH 2 /* Number of hold cycles after transfer */ | |
63 | -#define PLD_RE 0 /* Ready disabled */ | |
64 | -#define PLD_SOR 1 /* Sample on Ready disabled */ | |
65 | -#define PLD_BEM 0 /* Byte Write only active on Write cycles */ | |
66 | -#define PLD_PEN 0 /* Parity disable */ | |
67 | -#define PLD_AP ((PLD_BME << 31) + (PLD_TWE << 23) + (PLD_CSN << 18) + (PLD_OEN << 16) + (PLD_WBN << 14) + \ | |
68 | - (PLD_WBF << 12) + (PLD_TH << 9) + (PLD_RE << 8) + (PLD_SOR << 7) + (PLD_BEM << 6) + (PLD_PEN << 5)) | |
69 | 57 | |
70 | -/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ | |
71 | -#define PLD_BS 0 /* 1 MByte */ | |
72 | -/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */ | |
73 | -#define PLD_BU 3 /* R/W */ | |
74 | -/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */ | |
75 | -#define PLD_BW 0 /* 16Bit */ | |
76 | -#define PLD_CR ((PER_PLD_ADDR & 0xfff00000) + (PLD_BS << 17) + (PLD_BU << 15) + (PLD_BW << 13)) | |
58 | +/* CS Config register (CS7) */ | |
59 | +#define CONFIG_PORT_BME 0 /* Burst disable */ | |
60 | +#define CONFIG_PORT_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */ | |
61 | +#define CONFIG_PORT_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */ | |
62 | +#define CONFIG_PORT_OEN 1 /* Cycles from CS low to OE low */ | |
63 | +#define CONFIG_PORT_WBN 1 /* Cycles from CS low to WE low */ | |
64 | +#define CONFIG_PORT_WBF 1 /* Cycles from WE high to CS high */ | |
65 | +#define CONFIG_PORT_TH 2 /* Number of hold cycles after transfer */ | |
66 | +#define CONFIG_PORT_RE 0 /* Ready disabled */ | |
67 | +#define CONFIG_PORT_SOR 1 /* Sample on Ready disabled */ | |
68 | +#define CONFIG_PORT_BEM 0 /* Byte Write only active on Write cycles */ | |
69 | +#define CONFIG_PORT_PEN 0 /* Parity disable */ | |
70 | +#define CONFIG_PORT_AP ((CONFIG_PORT_BME << 31) + (CONFIG_PORT_TWE << 23) + (CONFIG_PORT_CSN << 18) + (CONFIG_PORT_OEN << 16) + (CONFIG_PORT_WBN << 14) + \ | |
71 | + (CONFIG_PORT_WBF << 12) + (CONFIG_PORT_TH << 9) + (CONFIG_PORT_RE << 8) + (CONFIG_PORT_SOR << 7) + (CONFIG_PORT_BEM << 6) + (CONFIG_PORT_PEN << 5)) | |
77 | 72 | |
78 | - | |
79 | -/* timings */ | |
80 | - | |
81 | -#define PER_BOARD_ADDR (PER_UART1_ADDR+(1024*1024)) | |
82 | -/* Dummy CS to get the board revision */ | |
83 | -#define BOARD_BME 0 /* Burst disable */ | |
84 | -#define BOARD_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */ | |
85 | -#define BOARD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */ | |
86 | -#define BOARD_OEN 1 /* Cycles from CS low to OE low */ | |
87 | -#define BOARD_WBN 1 /* Cycles from CS low to WE low */ | |
88 | -#define BOARD_WBF 1 /* Cycles from WE high to CS high */ | |
89 | -#define BOARD_TH 2 /* Number of hold cycles after transfer */ | |
90 | -#define BOARD_RE 0 /* Ready disabled */ | |
91 | -#define BOARD_SOR 1 /* Sample on Ready disabled */ | |
92 | -#define BOARD_BEM 0 /* Byte Write only active on Write cycles */ | |
93 | -#define BOARD_PEN 0 /* Parity disable */ | |
94 | -#define BOARD_AP ((BOARD_BME << 31) + (BOARD_TWE << 23) + (BOARD_CSN << 18) + (BOARD_OEN << 16) + (BOARD_WBN << 14) + \ | |
95 | - (BOARD_WBF << 12) + (BOARD_TH << 9) + (BOARD_RE << 8) + (BOARD_SOR << 7) + (BOARD_BEM << 6) + (BOARD_PEN << 5)) | |
96 | - | |
97 | 73 | /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ |
98 | -#define BOARD_BS 0 /* 1 MByte */ | |
74 | +#define CONFIG_PORT_BS 0 /* 1 MByte */ | |
99 | 75 | /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */ |
100 | -#define BOARD_BU 3 /* R/W */ | |
76 | +#define CONFIG_PORT_BU 3 /* R/W */ | |
101 | 77 | /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */ |
102 | -#define BOARD_BW 0 /* 16Bit */ | |
103 | -#define BOARD_CR ((PER_BOARD_ADDR & 0xfff00000) + (BOARD_BS << 17) + (BOARD_BU << 15) + (BOARD_BW << 13)) | |
78 | +#define CONFIG_PORT_BW 0 /* 16Bit */ | |
79 | +#define CONFIG_PORT_CR ((CONFIG_PORT_ADDR & 0xfff00000) + (CONFIG_PORT_BS << 17) + (CONFIG_PORT_BU << 15) + (CONFIG_PORT_BW << 13)) | |
104 | 80 | |
105 | - | |
106 | -/* UART0 CS2 */ | |
107 | -#define UART0_BME 0 /* Burst disable */ | |
108 | -#define UART0_TWE 7 /* 7 * 30ns 210ns Waitstates (access=TWT+1+TH) */ | |
109 | -#define UART0_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */ | |
110 | -#define UART0_OEN 1 /* Cycles from CS low to OE low */ | |
111 | -#define UART0_WBN 1 /* Cycles from CS low to WE low */ | |
112 | -#define UART0_WBF 1 /* Cycles from WE high to CS high */ | |
113 | -#define UART0_TH 2 /* Number of hold cycles after transfer */ | |
114 | -#define UART0_RE 0 /* Ready disabled */ | |
115 | -#define UART0_SOR 1 /* Sample on Ready disabled */ | |
116 | -#define UART0_BEM 0 /* Byte Write only active on Write cycles */ | |
117 | -#define UART0_PEN 0 /* Parity disable */ | |
118 | -#define UART0_AP ((UART0_BME << 31) + (UART0_TWE << 23) + (UART0_CSN << 18) + (UART0_OEN << 16) + (UART0_WBN << 14) + \ | |
119 | - (UART0_WBF << 12) + (UART0_TH << 9) + (UART0_RE << 8) + (UART0_SOR << 7) + (UART0_BEM << 6) + (UART0_PEN << 5)) | |
120 | - | |
121 | -/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ | |
122 | -#define UART0_BS 0 /* 1 MByte */ | |
123 | -/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */ | |
124 | -#define UART0_BU 3 /* R/W */ | |
125 | -/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */ | |
126 | -#define UART0_BW 0 /* 8Bit */ | |
127 | -#define UART0_CR ((PER_UART0_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13)) | |
128 | - | |
129 | -/* UART1 CS3 */ | |
130 | -#define UART1_AP UART0_AP /* same timing as UART0 */ | |
131 | -#define UART1_CR ((PER_UART1_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13)) | |
132 | - | |
133 | - | |
134 | 81 | /* Flash CS0 or CS 1 */ |
135 | 82 | /* 0x7F8FFE80 slowest timing at all... */ |
136 | 83 | #define FLASH_BME_B 1 /* Burst enable */ |
137 | 84 | |
138 | 85 | |
139 | 86 | |
... | ... | @@ -149,19 +96,19 @@ |
149 | 96 | #define FLASH_PEN 0 /* Parity disable */ |
150 | 97 | /* Access Parameter Register for non Boot */ |
151 | 98 | #define FLASH_AP ((FLASH_BME << 31) + (FLASH_TWE << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \ |
152 | - (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5)) | |
99 | + (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5)) | |
153 | 100 | /* Access Parameter Register for Boot */ |
154 | 101 | #define FLASH_AP_B ((FLASH_BME_B << 31) + (FLASH_FWT_B << 26) + (FLASH_BWT_B << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \ |
155 | - (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5)) | |
102 | + (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5)) | |
156 | 103 | |
157 | 104 | /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ |
158 | -#define FLASH_BS 2 /* 4 MByte */ | |
105 | +#define FLASH_BS FLASH_SIZE_PRELIM /* 4 MByte */ | |
159 | 106 | /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */ |
160 | 107 | #define FLASH_BU 3 /* R/W */ |
161 | 108 | /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */ |
162 | 109 | #define FLASH_BW 1 /* 16Bit */ |
163 | 110 | /* CR register for Boot */ |
164 | -#define FLASH_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13)) | |
111 | +#define FLASH_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13)) | |
165 | 112 | /* CR register for non Boot */ |
166 | 113 | #define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13)) |
167 | 114 | |
168 | 115 | |
169 | 116 | |
170 | 117 | |
... | ... | @@ -183,19 +130,20 @@ |
183 | 130 | #define MPS_PEN 0 /* Parity disable */ |
184 | 131 | /* Access Parameter Register for non Boot */ |
185 | 132 | #define MPS_AP ((MPS_BME << 31) + (MPS_TWE << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \ |
186 | - (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5)) | |
133 | + (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5)) | |
187 | 134 | /* Access Parameter Register for Boot */ |
188 | -#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \ | |
189 | - (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5)) | |
135 | +#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \ | |
136 | + (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5)) | |
190 | 137 | |
191 | 138 | /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ |
192 | 139 | #define MPS_BS 2 /* 4 MByte */ |
140 | +#define MPS_BS_B FLASH_SIZE_PRELIM /* 1 MByte */ | |
193 | 141 | /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */ |
194 | 142 | #define MPS_BU 3 /* R/W */ |
195 | 143 | /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */ |
196 | 144 | #define MPS_BW 0 /* 8Bit */ |
197 | 145 | /* CR register for Boot */ |
198 | -#define MPS_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13)) | |
146 | +#define MPS_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13)) | |
199 | 147 | /* CR register for non Boot */ |
200 | 148 | #define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13)) |
board/sixnet/flash.c
... | ... | @@ -23,6 +23,10 @@ |
23 | 23 | |
24 | 24 | #include <common.h> |
25 | 25 | #include <mpc8xx.h> |
26 | +/* environment.h defines the various CFG_ENV_... values in terms | |
27 | + * of whichever ones are given in the configuration file. | |
28 | + */ | |
29 | +#include <environment.h> | |
26 | 30 | |
27 | 31 | flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ |
28 | 32 | |
... | ... | @@ -104,6 +108,19 @@ |
104 | 108 | &flash_info[0]); |
105 | 109 | #endif |
106 | 110 | |
111 | +#ifdef CFG_ENV_ADDR | |
112 | + flash_protect ( FLAG_PROTECT_SET, | |
113 | + CFG_ENV_ADDR, | |
114 | + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]); | |
115 | +#endif | |
116 | + | |
117 | +#ifdef CFG_ENV_ADDR_REDUND | |
118 | + flash_protect ( FLAG_PROTECT_SET, | |
119 | + CFG_ENV_ADDR_REDUND, | |
120 | + CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1, | |
121 | + &flash_info[0]); | |
122 | +#endif | |
123 | + | |
107 | 124 | return (size_b); |
108 | 125 | } |
109 | 126 | |
... | ... | @@ -154,6 +171,21 @@ |
154 | 171 | for( i = 0; i < info->sector_count; i++ ) |
155 | 172 | info->start[i] = base + (i * sect_size); |
156 | 173 | } |
174 | + else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD | |
175 | + && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM800T) { | |
176 | + | |
177 | + int sect_size; /* number of bytes/sector */ | |
178 | + | |
179 | + sect_size = 0x00010000 * (sizeof(FPW)/2); | |
180 | + | |
181 | + /* set up sector start address table (top boot sector type) */ | |
182 | + for (i = 0; i < info->sector_count - 3; i++) | |
183 | + info->start[i] = base + (i * sect_size); | |
184 | + i = info->sector_count - 1; | |
185 | + info->start[i--] = base + (info->size - 0x00004000) * (sizeof(FPW)/2); | |
186 | + info->start[i--] = base + (info->size - 0x00006000) * (sizeof(FPW)/2); | |
187 | + info->start[i--] = base + (info->size - 0x00008000) * (sizeof(FPW)/2); | |
188 | + } | |
157 | 189 | } |
158 | 190 | |
159 | 191 | /*----------------------------------------------------------------------- |
... | ... | @@ -196,6 +228,9 @@ |
196 | 228 | } |
197 | 229 | |
198 | 230 | switch (info->flash_id & FLASH_TYPEMASK) { |
231 | + case FLASH_AM800T: | |
232 | + fmt = "29LV800B%s (8 Mbit, %s)\n"; | |
233 | + break; | |
199 | 234 | case FLASH_AM640U: |
200 | 235 | fmt = "29LV641D (64 Mbit, uniform sectors)\n"; |
201 | 236 | break; |
... | ... | @@ -295,6 +330,12 @@ |
295 | 330 | /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */ |
296 | 331 | if (info->flash_id != FLASH_UNKNOWN) switch (addr[1]) { |
297 | 332 | |
333 | + case (FPW)AMD_ID_LV800T: | |
334 | + info->flash_id += FLASH_AM800T; | |
335 | + info->sector_count = 19; | |
336 | + info->size = 0x00100000 * (sizeof(FPW)/2); | |
337 | + break; /* => 1 or 2 MiB */ | |
338 | + | |
298 | 339 | case (FPW)AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */ |
299 | 340 | info->flash_id += FLASH_AM640U; |
300 | 341 | info->sector_count = 128; |
... | ... | @@ -401,6 +442,7 @@ |
401 | 442 | break; |
402 | 443 | |
403 | 444 | case FLASH_AM640U: |
445 | + case FLASH_AM800T: | |
404 | 446 | default: |
405 | 447 | /* no hardware protect that we support */ |
406 | 448 | break; |
... | ... | @@ -438,6 +480,7 @@ |
438 | 480 | case FLASH_28F320C3B: |
439 | 481 | case FLASH_28F640C3B: |
440 | 482 | case FLASH_AM640U: |
483 | + case FLASH_AM800T: | |
441 | 484 | break; |
442 | 485 | case FLASH_UNKNOWN: |
443 | 486 | default: |
... | ... | @@ -735,6 +778,7 @@ |
735 | 778 | break; |
736 | 779 | |
737 | 780 | case FLASH_AM640U: |
781 | + case FLASH_AM800T: | |
738 | 782 | default: |
739 | 783 | /* no hardware protect that we support */ |
740 | 784 | info->protect[sector] = prot; |
board/sixnet/sixnet.c
... | ... | @@ -24,6 +24,7 @@ |
24 | 24 | |
25 | 25 | #include <common.h> |
26 | 26 | #include <config.h> |
27 | +#include <jffs2/jffs2.h> | |
27 | 28 | #include <mpc8xx.h> |
28 | 29 | #include <net.h> /* for eth_init() */ |
29 | 30 | #include <rtc.h> |
... | ... | @@ -602,4 +603,71 @@ |
602 | 603 | |
603 | 604 | return (size_sdram); |
604 | 605 | } |
606 | + | |
607 | +#ifdef CFG_JFFS_CUSTOM_PART | |
608 | + | |
609 | +static struct part_info part; | |
610 | + | |
611 | +#define jffs2_block(i) \ | |
612 | + ((struct jffs2_unknown_node*)(CFG_JFFS2_BASE + (i) * 65536)) | |
613 | + | |
614 | +struct part_info* jffs2_part_info(int part_num) | |
615 | +{ | |
616 | + DECLARE_GLOBAL_DATA_PTR; | |
617 | + bd_t *bd = gd->bd; | |
618 | + char* s; | |
619 | + int i; | |
620 | + int bootnor = 0; /* assume booting from NAND flash */ | |
621 | + | |
622 | + if (part_num != 0) | |
623 | + return 0; /* only support one partition */ | |
624 | + | |
625 | + if (part.usr_priv == (void*)1) | |
626 | + return ∂ /* already have part info */ | |
627 | + | |
628 | + memset(&part, 0, sizeof(part)); | |
629 | + | |
630 | + if (nand_dev_desc[0].ChipID == NAND_ChipID_UNKNOWN) | |
631 | + bootnor = 1; | |
632 | + else if (bd->bi_flashsize < 0x800000) | |
633 | + bootnor = 0; | |
634 | + else for (i = 0; !bootnor && i < 4; ++i) { | |
635 | + /* boot from NOR if JFFS2 info in any of | |
636 | + * first 4 erase blocks | |
637 | + */ | |
638 | + | |
639 | + if (jffs2_block(i)->magic == JFFS2_MAGIC_BITMASK) | |
640 | + bootnor = 1; | |
641 | + } | |
642 | + | |
643 | + if (bootnor) { | |
644 | + /* no NAND flash or boot in NOR, use NOR flash */ | |
645 | + part.offset = (unsigned char *)CFG_JFFS2_BASE; | |
646 | + part.size = CFG_JFFS2_SIZE; | |
647 | + } | |
648 | + else { | |
649 | + char readcmd[60]; | |
650 | + | |
651 | + /* boot info in NAND flash, get and use copy in RAM */ | |
652 | + | |
653 | + /* override info from environment if present */ | |
654 | + s = getenv("fsaddr"); | |
655 | + part.offset = s ? (void *)simple_strtoul(s, NULL, 16) | |
656 | + : (void *)CFG_JFFS2_RAMBASE; | |
657 | + s = getenv("fssize"); | |
658 | + part.size = s ? simple_strtoul(s, NULL, 16) | |
659 | + : CFG_JFFS2_RAMSIZE; | |
660 | + | |
661 | + /* read from nand flash */ | |
662 | + sprintf(readcmd, "nand read.jffs2 %x 0 %x", | |
663 | + (uint32_t)part.offset, part.size); | |
664 | + run_command(readcmd, 0); | |
665 | + } | |
666 | + | |
667 | + part.erasesize = 0; /* unused */ | |
668 | + part.usr_priv=(void*)1; /* ready */ | |
669 | + | |
670 | + return ∂ | |
671 | +} | |
672 | +#endif /* ifdef CFG_JFFS_CUSTOM_PART */ |
common/cmd_doc.c
... | ... | @@ -861,8 +861,13 @@ |
861 | 861 | memcpy(mh, buf, sizeof(struct NFTLMediaHeader)); |
862 | 862 | |
863 | 863 | /* Do some sanity checks on it */ |
864 | - if (mh->UnitSizeFactor != 0xff) { | |
865 | - puts ("Sorry, we don't support UnitSizeFactor " | |
864 | + if (mh->UnitSizeFactor == 0) { | |
865 | +#ifdef NFTL_DEBUG | |
866 | + puts ("UnitSizeFactor 0x00 detected.\n" | |
867 | + "This violates the spec but we think we know what it means...\n"); | |
868 | +#endif | |
869 | + } else if (mh->UnitSizeFactor != 0xff) { | |
870 | + printf ("Sorry, we don't support UnitSizeFactor " | |
866 | 871 | "of != 1 yet.\n"); |
867 | 872 | return -1; |
868 | 873 | } |
... | ... | @@ -950,6 +955,8 @@ |
950 | 955 | |
951 | 956 | /* Ident all the chips present. */ |
952 | 957 | DoC_ScanChips(this); |
958 | + if ((!this->numchips) || (!this->chips)) | |
959 | + return; | |
953 | 960 | |
954 | 961 | nftl = &this->nftl; |
955 | 962 |
common/cmd_fat.c
... | ... | @@ -36,76 +36,179 @@ |
36 | 36 | |
37 | 37 | #include <fat.h> |
38 | 38 | |
39 | -extern block_dev_desc_t *ide_get_dev (int dev); | |
40 | 39 | |
40 | + | |
41 | + | |
42 | +block_dev_desc_t *get_dev (char* ifname, int dev) | |
43 | +{ | |
44 | +#if (CONFIG_COMMANDS & CFG_CMD_IDE) | |
45 | + if (strncmp(ifname,"ide",3)==0) { | |
46 | + extern block_dev_desc_t * ide_get_dev(int dev); | |
47 | + return(ide_get_dev(dev)); | |
48 | + } | |
49 | +#endif | |
50 | +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) | |
51 | + if (strncmp(ifname,"scsi",4)==0) { | |
52 | + extern block_dev_desc_t * scsi_get_dev(int dev); | |
53 | + return(scsi_get_dev(dev)); | |
54 | + } | |
55 | +#endif | |
56 | +#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE)) | |
57 | + if (strncmp(ifname,"usb",3)==0) { | |
58 | + extern block_dev_desc_t * usb_stor_get_dev(int dev); | |
59 | + return(usb_stor_get_dev(dev)); | |
60 | + } | |
61 | +#endif | |
62 | +#if defined(CONFIG_MMC) | |
63 | + if (strncmp(ifname,"mmc",3)==0) { | |
64 | + extern block_dev_desc_t * mmc_get_dev(int dev); | |
65 | + return(mmc_get_dev(dev)); | |
66 | + } | |
67 | +#endif | |
68 | + return NULL; | |
69 | +} | |
70 | + | |
71 | + | |
41 | 72 | int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
42 | 73 | { |
43 | 74 | long size; |
44 | 75 | unsigned long offset; |
45 | 76 | unsigned long count; |
77 | + block_dev_desc_t *dev_desc=NULL; | |
78 | + int dev=0; | |
79 | + int part=1; | |
80 | + char *ep; | |
46 | 81 | |
47 | - if (argc < 3) { | |
48 | - printf ("usage:fatload <filename> <addr> [bytes]\n"); | |
82 | + if (argc < 5) { | |
83 | + printf ("usage: fatload <interface> <dev[:part]> <addr> <filename> [bytes]\n"); | |
49 | 84 | return (0); |
50 | 85 | } |
51 | - | |
52 | - offset = simple_strtoul (argv[2], NULL, 16); | |
53 | - if (argc == 4) | |
54 | - count = simple_strtoul (argv[3], NULL, 16); | |
86 | + dev = (int)simple_strtoul (argv[2], &ep, 16); | |
87 | + dev_desc=get_dev(argv[1],dev); | |
88 | + if (dev_desc==NULL) { | |
89 | + puts ("\n** Invalid boot device **\n"); | |
90 | + return 1; | |
91 | + } | |
92 | + if (*ep) { | |
93 | + if (*ep != ':') { | |
94 | + puts ("\n** Invalid boot device, use `dev[:part]' **\n"); | |
95 | + return 1; | |
96 | + } | |
97 | + part = (int)simple_strtoul(++ep, NULL, 16); | |
98 | + } | |
99 | + if (fat_register_device(dev_desc,part)!=0) { | |
100 | + printf ("\n** Unable to use %s %d:%d for fatload **\n",argv[1],dev,part); | |
101 | + return 1; | |
102 | + } | |
103 | + offset = simple_strtoul (argv[3], NULL, 16); | |
104 | + if (argc == 6) | |
105 | + count = simple_strtoul (argv[5], NULL, 16); | |
55 | 106 | else |
56 | 107 | count = 0; |
108 | + size = file_fat_read (argv[4], (unsigned char *) offset, count); | |
57 | 109 | |
58 | - size = file_fat_read (argv[1], (unsigned char *) offset, count); | |
110 | + if(size==-1) | |
111 | + printf("\n** Unable to read \"%s\" from %s %d:%d **\n",argv[4],argv[1],dev,part); | |
112 | + else | |
113 | + printf ("\n%ld bytes read\n", size); | |
59 | 114 | |
60 | - printf ("%ld bytes read\n", size); | |
61 | - | |
62 | 115 | return size; |
63 | 116 | } |
64 | 117 | |
118 | + | |
119 | + | |
120 | + | |
65 | 121 | U_BOOT_CMD( |
66 | - fatload, 4, 0, do_fat_fsload, | |
122 | + fatload, 6, 0, do_fat_fsload, | |
67 | 123 | "fatload - load binary file from a dos filesystem\n", |
68 | - "[ off ] [ filename ]\n" | |
69 | - " - load binary file from dos filesystem\n" | |
70 | - " with offset 'off'\n" | |
124 | + "<interface> <dev[:part]> <addr> <filename> [bytes]\n" | |
125 | + " - load binary file 'filename' from 'dev' on 'interface'\n" | |
126 | + " to address 'addr' from dos filesystem\n" | |
71 | 127 | ); |
72 | 128 | |
73 | 129 | int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
74 | 130 | { |
75 | 131 | char *filename = "/"; |
76 | 132 | int ret; |
133 | + int dev=0; | |
134 | + int part=1; | |
135 | + char *ep; | |
136 | + block_dev_desc_t *dev_desc=NULL; | |
77 | 137 | |
78 | - if (argc == 2) | |
79 | - ret = file_fat_ls (argv[1]); | |
138 | + if (argc < 3) { | |
139 | + printf ("usage: fatls <interface> <dev[:part]> [directory]\n"); | |
140 | + return (0); | |
141 | + } | |
142 | + dev = (int)simple_strtoul (argv[2], &ep, 16); | |
143 | + dev_desc=get_dev(argv[1],dev); | |
144 | + if (dev_desc==NULL) { | |
145 | + puts ("\n** Invalid boot device **\n"); | |
146 | + return 1; | |
147 | + } | |
148 | + if (*ep) { | |
149 | + if (*ep != ':') { | |
150 | + puts ("\n** Invalid boot device, use `dev[:part]' **\n"); | |
151 | + return 1; | |
152 | + } | |
153 | + part = (int)simple_strtoul(++ep, NULL, 16); | |
154 | + } | |
155 | + if (fat_register_device(dev_desc,part)!=0) { | |
156 | + printf ("\n** Unable to use %s %d:%d for fatls **\n",argv[1],dev,part); | |
157 | + return 1; | |
158 | + } | |
159 | + if (argc == 4) | |
160 | + ret = file_fat_ls (argv[3]); | |
80 | 161 | else |
81 | 162 | ret = file_fat_ls (filename); |
82 | 163 | |
164 | + if(ret!=0) | |
165 | + printf("No Fat FS detected\n"); | |
83 | 166 | return (ret); |
84 | 167 | } |
85 | 168 | |
86 | 169 | U_BOOT_CMD( |
87 | - fatls, 2, 1, do_fat_ls, | |
170 | + fatls, 4, 1, do_fat_ls, | |
88 | 171 | "fatls - list files in a directory (default /)\n", |
89 | - "[ directory ]\n" | |
90 | - " - list files in a directory\n" | |
172 | + "<interface> <dev[:part]> [directory]\n" | |
173 | + " - list files from 'dev' on 'interface' in a 'directory'\n" | |
91 | 174 | ); |
92 | 175 | |
93 | 176 | int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
94 | 177 | { |
95 | - int ret; | |
178 | + int dev=0; | |
179 | + int part=1; | |
180 | + char *ep; | |
181 | + block_dev_desc_t *dev_desc=NULL; | |
96 | 182 | |
97 | - ret = 0; | |
98 | - | |
99 | - printf ("FAT info: %d\n", file_fat_detectfs ()); | |
100 | - | |
101 | - return (ret); | |
183 | + if (argc < 2) { | |
184 | + printf ("usage: fatinfo <interface> <dev[:part]>\n"); | |
185 | + return (0); | |
186 | + } | |
187 | + dev = (int)simple_strtoul (argv[2], &ep, 16); | |
188 | + dev_desc=get_dev(argv[1],dev); | |
189 | + if (dev_desc==NULL) { | |
190 | + puts ("\n** Invalid boot device **\n"); | |
191 | + return 1; | |
192 | + } | |
193 | + if (*ep) { | |
194 | + if (*ep != ':') { | |
195 | + puts ("\n** Invalid boot device, use `dev[:part]' **\n"); | |
196 | + return 1; | |
197 | + } | |
198 | + part = (int)simple_strtoul(++ep, NULL, 16); | |
199 | + } | |
200 | + if (fat_register_device(dev_desc,part)!=0) { | |
201 | + printf ("\n** Unable to use %s %d:%d for fatinfo **\n",argv[1],dev,part); | |
202 | + return 1; | |
203 | + } | |
204 | + return (file_fat_detectfs ()); | |
102 | 205 | } |
103 | 206 | |
104 | 207 | U_BOOT_CMD( |
105 | - fatinfo, 1, 1, do_fat_fsinfo, | |
208 | + fatinfo, 3, 1, do_fat_fsinfo, | |
106 | 209 | "fatinfo - print information about filesystem\n", |
107 | - "\n" | |
108 | - " - print information about filesystem\n" | |
210 | + "<interface> <dev[:part]>\n" | |
211 | + " - print information about filesystem from 'dev' on 'interface'\n" | |
109 | 212 | ); |
110 | 213 | |
111 | 214 | #ifdef NOT_IMPLEMENTED_YET |
common/cmd_jffs2.c
cpu/mpc824x/Makefile
... | ... | @@ -25,14 +25,14 @@ |
25 | 25 | |
26 | 26 | LIB = lib$(CPU).a |
27 | 27 | |
28 | -START = start.S drivers/i2c/i2c2.o | |
28 | +START = start.S | |
29 | 29 | OBJS = traps.o cpu.o cpu_init.o interrupts.o speed.o \ |
30 | - drivers/epic/epic1.o drivers/i2c/i2c1.o pci.o bedbug_603e.o | |
30 | + drivers/epic/epic1.o drivers/i2c/i2c.o pci.o bedbug_603e.o | |
31 | 31 | |
32 | 32 | all: .depend $(START) $(LIB) |
33 | 33 | |
34 | 34 | $(LIB): $(OBJS) |
35 | - $(AR) crv $@ $(OBJS) drivers/i2c/i2c2.o | |
35 | + $(AR) crv $@ $(OBJS) | |
36 | 36 | |
37 | 37 | bedbug_603e.c: |
38 | 38 | ln -s ../mpc8260/bedbug_603e.c bedbug_603e.c |
cpu/mpc824x/drivers/i2c/Makefile
1 | -########################################################################## | |
2 | -# | |
3 | -# Copyright Motorola, Inc. 1997 | |
4 | -# ALL RIGHTS RESERVED | |
5 | -# | |
6 | -# You are hereby granted a copyright license to use, modify, and | |
7 | -# distribute the SOFTWARE so long as this entire notice is retained | |
8 | -# without alteration in any modified and/or redistributed versions, | |
9 | -# and that such modified versions are clearly identified as such. | |
10 | -# No licenses are granted by implication, estoppel or otherwise under | |
11 | -# any patents or trademarks of Motorola, Inc. | |
12 | -# | |
13 | -# The SOFTWARE is provided on an "AS IS" basis and without warranty. | |
14 | -# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS | |
15 | -# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED | |
16 | -# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR | |
17 | -# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH | |
18 | -# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS | |
19 | -# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS. | |
20 | -# | |
21 | -# To the maximum extent permitted by applicable law, IN NO EVENT SHALL | |
22 | -# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER | |
23 | -# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF | |
24 | -# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS | |
25 | -# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR | |
26 | -# INABILITY TO USE THE SOFTWARE. | |
27 | -# | |
28 | -############################################################################ | |
29 | -TARGET = libi2c.a | |
30 | - | |
31 | -#DEBUG = -g | |
32 | -DEBUG = -DI2CDBG | |
33 | -LST = -Hanno -S | |
34 | -OPTIM = | |
35 | -CC = /risc/tools/pkgs/metaware/bin/hcppc | |
36 | -CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc | |
37 | -CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM) | |
38 | -PREP = $(CC) $(CFLAGS) -P | |
39 | - | |
40 | -# Assembler used to build the .s files (for the board version) | |
41 | - | |
42 | -ASOPT = -big_si -c | |
43 | -ASDEBUG = -l -fm | |
44 | -AS = /risc/tools/pkgs/metaware/bin/asppc | |
45 | - | |
46 | -# Linker to bring .o files together into an executable. | |
47 | - | |
48 | -LKOPT = -Bbase=0 -q -Qn -r | |
49 | -LKCMD = | |
50 | -LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT) | |
51 | - | |
52 | -# DOS Utilities | |
53 | - | |
54 | -DEL = rm | |
55 | -COPY = cp | |
56 | -LIST = ls | |
57 | - | |
58 | -OBJECTS = i2c1.o i2c2.o | |
59 | - | |
60 | -all: $(TARGET) | |
61 | - | |
62 | -objects: $(OBJECTS) | |
63 | - | |
64 | -$(TARGET): $(OBJECTS) | |
65 | - $(LINK) $(OBJECTS) -o $@ | |
66 | - | |
67 | -clean: | |
68 | - $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS) | |
69 | - | |
70 | -.s.o: | |
71 | - $(DEL) -f $*.i | |
72 | - $(PREP) -Hasmcpp $< | |
73 | - $(AS) $(ASOPT) $*.i | |
74 | -# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst | |
75 | - | |
76 | -.c.o: | |
77 | - $(CCobj) $< | |
78 | - | |
79 | -.c.s: | |
80 | - $(CCobj) $(LST) $< | |
81 | - | |
82 | -i2c1.o: i2c_export.h i2c.h i2c1.c | |
83 | - | |
84 | -i2c2.o: i2c.h i2c2.s |
cpu/mpc824x/drivers/i2c/Makefile_pc
1 | -########################################################################## | |
2 | -# | |
3 | -# makefile_pc for use with PC mksnt tools dink32/drivers/i2c | |
4 | -# | |
5 | -# Copyright Motorola, Inc. 1997 | |
6 | -# ALL RIGHTS RESERVED | |
7 | -# | |
8 | -# You are hereby granted a copyright license to use, modify, and | |
9 | -# distribute the SOFTWARE so long as this entire notice is retained | |
10 | -# without alteration in any modified and/or redistributed versions, | |
11 | -# and that such modified versions are clearly identified as such. | |
12 | -# No licenses are granted by implication, estoppel or otherwise under | |
13 | -# any patents or trademarks of Motorola, Inc. | |
14 | -# | |
15 | -# The SOFTWARE is provided on an "AS IS" basis and without warranty. | |
16 | -# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS | |
17 | -# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED | |
18 | -# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR | |
19 | -# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH | |
20 | -# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS | |
21 | -# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS. | |
22 | -# | |
23 | -# To the maximum extent permitted by applicable law, IN NO EVENT SHALL | |
24 | -# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER | |
25 | -# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF | |
26 | -# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS | |
27 | -# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR | |
28 | -# INABILITY TO USE THE SOFTWARE. | |
29 | -# | |
30 | -############################################################################ | |
31 | -TARGET = libi2c.a | |
32 | - | |
33 | -#DEBUG = -g | |
34 | -DEBUG = -DI2CDBG | |
35 | -LST = -Hanno -S | |
36 | -OPTIM = | |
37 | -CC = m:/old_tools/tools/hcppc/bin/hcppc | |
38 | -CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc | |
39 | -CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM) | |
40 | -PREP = $(CC) $(CFLAGS) -P | |
41 | - | |
42 | -# Assembler used to build the .s files (for the board version) | |
43 | - | |
44 | -ASOPT = -big_si -c | |
45 | -ASDEBUG = -l -fm | |
46 | -AS = m:/old_tools/tools/hcppc/bin/asppc | |
47 | - | |
48 | -# Linker to bring .o files together into an executable. | |
49 | - | |
50 | -LKOPT = -Bbase=0 -q -Qn -r | |
51 | -LKCMD = | |
52 | -LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT) | |
53 | - | |
54 | -# DOS Utilities | |
55 | - | |
56 | -DEL = rm | |
57 | -COPY = cp | |
58 | -LIST = ls | |
59 | - | |
60 | -OBJECTS = i2c1.o i2c2.o | |
61 | - | |
62 | -all: $(TARGET) | |
63 | - | |
64 | -objects: $(OBJECTS) | |
65 | - | |
66 | -$(TARGET): $(OBJECTS) | |
67 | - $(LINK) $(OBJECTS) -o $@ | |
68 | - | |
69 | -clean: | |
70 | - $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS) | |
71 | - | |
72 | -.s.o: | |
73 | - $(DEL) -f $*.i | |
74 | - $(PREP) -Hasmcpp $< | |
75 | - $(AS) $(ASOPT) $*.i | |
76 | -# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst | |
77 | - | |
78 | -.c.o: | |
79 | - $(CCobj) $< | |
80 | - | |
81 | -.c.s: | |
82 | - $(CCobj) $(LST) $< | |
83 | - | |
84 | -i2c1.o: i2c_export.h i2c.h i2c1.c | |
85 | - $(CCobj) $< | |
86 | - | |
87 | - | |
88 | -i2c2.o: i2c.h i2c2.s | |
89 | - $(DEL) -f $*.i | |
90 | - $(PREP) -Hasmcpp $< | |
91 | - $(AS) $(ASOPT) $*.i |
cpu/mpc824x/drivers/i2c/README
1 | -CONTENT: | |
2 | - | |
3 | - i2c.h | |
4 | - i2c1.c | |
5 | - i2c2.s | |
6 | - | |
7 | -WHAT ARE THESE FILES: | |
8 | - | |
9 | -These files contain MPC8240 (Kahlua) I2C | |
10 | -driver routines. The driver routines are not | |
11 | -written for any specific operating system. | |
12 | -They serves the purpose of code sample, and | |
13 | -jump-start for using the MPC8240 I2C unit. | |
14 | - | |
15 | -For the reason of correctness of C language | |
16 | -syntax, these files are compiled by Metaware | |
17 | -C compiler and assembler. | |
18 | - | |
19 | -ENDIAN NOTATION: | |
20 | - | |
21 | -The algorithm is designed for big-endian mode, | |
22 | -software is responsible for byte swapping. | |
23 | - | |
24 | -USAGE: | |
25 | - | |
26 | -1. The host system that is running on MPC8240 | |
27 | - shall link the files listed here. The memory | |
28 | - location of driver routines shall take into | |
29 | - account of that driver routines need to run | |
30 | - in supervisor mode and they process I2C | |
31 | - interrupt. | |
32 | - | |
33 | -2. The host system is responsible for configuring | |
34 | - the MPC8240 including Embedded Utilities Memory | |
35 | - Block. All I2C driver functions require the | |
36 | - content of Embedded Utilities Memory Block | |
37 | - Base Address Register, EUMBBAR, as the first | |
38 | - parameter. | |
39 | - | |
40 | -3. Before I2C unit of MPC8240 can be used, | |
41 | - initialize I2C unit by calling I2C_Init | |
42 | - with the corresponding parameters. | |
43 | - | |
44 | - Note that the I2CFDR register shall be written | |
45 | - once during the initialization. If it is written | |
46 | - in the midst of transers, or after I2C STOPs or | |
47 | - REPEAT STATRs, depending on the data written, | |
48 | - a long reset time may be encountered. | |
49 | - | |
50 | -4. After I2C unit has been successfully initialized, | |
51 | - use the Application level API to send data or | |
52 | - receive data upon the desired mode, Master or | |
53 | - Slave. | |
54 | - | |
55 | -5. If the host system is also using the EPIC unit | |
56 | - on MPC8240, the system can register the | |
57 | - I2C_ISR with the EPIC including other | |
58 | - desired resources. | |
59 | - | |
60 | - If the host system does not using the EPIC unit | |
61 | - on MPC8240, I2C_Timer_Event function can | |
62 | - be called for each desired time interval. | |
63 | - | |
64 | - In both cases, the host system is free to provide | |
65 | - its own timer event handler and interrupt service | |
66 | - routine. | |
67 | - | |
68 | -6. The I2C driver routines contains a set | |
69 | - of utilities, Set and Get, for host system | |
70 | - to query and modify the desired I2C registers. | |
71 | - | |
72 | -7. It is the host system's responsibility of | |
73 | - queueing the I2C I/O request. The host | |
74 | - system shall check the I2C_ISR return code | |
75 | - for I2C I/O status. If I2C_ISR returns | |
76 | - I2CBUFFEMPTY or I2CBUFFFULL, it means | |
77 | - I2C unit has completed a I/O request | |
78 | - stated by the Application API. | |
79 | - | |
80 | -8. If the host system has more than one master | |
81 | - mode I2C unit I/O requests but doesn't want | |
82 | - to be intervented by being addressed as slave, | |
83 | - the host system can use the master mode | |
84 | - Application API with stop_flag set to 0 in | |
85 | - conjunction with is_cnt flag set to 1. | |
86 | - The first API call sets both stop_flag and | |
87 | - is_cnt to 0, indicating a START condition | |
88 | - shall be generated but when the end of | |
89 | - transaction is reached, do not generate a | |
90 | - STOP condition. Once the host system is | |
91 | - informed that the transaction has been | |
92 | - completed, the next Application API call | |
93 | - shall set is_cnt flag to 1, indicating a | |
94 | - repeated START condition shall be generated. | |
95 | - The last Application API call shall set | |
96 | - stop_flag | |
97 | - to 1. | |
98 | - | |
99 | -9. The I2C_Timer_Event function containes | |
100 | - a user defined function pointer. It | |
101 | - serves the purpose of providing the | |
102 | - host system a way to use its own event | |
103 | - handler instead of the I2C_ISR provided | |
104 | - here. |
cpu/mpc824x/drivers/i2c/i2c.c
1 | +/* | |
2 | + * (C) Copyright 2003 | |
3 | + * Gleb Natapov <gnatapov@mrv.com> | |
4 | + * Some bits are taken from linux driver writen by adrian@humboldt.co.uk | |
5 | + * | |
6 | + * Hardware I2C driver for MPC107 PCI bridge. | |
7 | + * | |
8 | + * See file CREDITS for list of people who contributed to this | |
9 | + * project. | |
10 | + * | |
11 | + * This program is free software; you can redistribute it and/or | |
12 | + * modify it under the terms of the GNU General Public License as | |
13 | + * published by the Free Software Foundation; either version 2 of | |
14 | + * the License, or (at your option) any later version. | |
15 | + * | |
16 | + * This program is distributed in the hope that it will be useful, | |
17 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | + * GNU General Public License for more details. | |
20 | + * | |
21 | + * You should have received a copy of the GNU General Public License | |
22 | + * along with this program; if not, write to the Free Software | |
23 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
24 | + * MA 02111-1307 USA | |
25 | + */ | |
26 | + | |
27 | +#include <common.h> | |
28 | + | |
29 | +#undef I2CDBG | |
30 | + | |
31 | +#ifdef CONFIG_HARD_I2C | |
32 | +#include <i2c.h> | |
33 | + | |
34 | +#define TIMEOUT (CFG_HZ/4) | |
35 | + | |
36 | +#define I2C_Addr ((unsigned *)(CFG_EUMB_ADDR + 0x3000)) | |
37 | + | |
38 | +#define I2CADR &I2C_Addr[0] | |
39 | +#define I2CFDR &I2C_Addr[1] | |
40 | +#define I2CCCR &I2C_Addr[2] | |
41 | +#define I2CCSR &I2C_Addr[3] | |
42 | +#define I2CCDR &I2C_Addr[4] | |
43 | + | |
44 | +#define MPC107_CCR_MEN 0x80 | |
45 | +#define MPC107_CCR_MIEN 0x40 | |
46 | +#define MPC107_CCR_MSTA 0x20 | |
47 | +#define MPC107_CCR_MTX 0x10 | |
48 | +#define MPC107_CCR_TXAK 0x08 | |
49 | +#define MPC107_CCR_RSTA 0x04 | |
50 | + | |
51 | +#define MPC107_CSR_MCF 0x80 | |
52 | +#define MPC107_CSR_MAAS 0x40 | |
53 | +#define MPC107_CSR_MBB 0x20 | |
54 | +#define MPC107_CSR_MAL 0x10 | |
55 | +#define MPC107_CSR_SRW 0x04 | |
56 | +#define MPC107_CSR_MIF 0x02 | |
57 | +#define MPC107_CSR_RXAK 0x01 | |
58 | + | |
59 | +#define I2C_READ 1 | |
60 | +#define I2C_WRITE 0 | |
61 | + | |
62 | +/* taken from linux include/asm-ppc/io.h */ | |
63 | +inline unsigned in_le32 (volatile unsigned *addr) | |
64 | +{ | |
65 | + unsigned ret; | |
66 | + | |
67 | + __asm__ __volatile__ ("lwbrx %0,0,%1;\n" | |
68 | + "twi 0,%0,0;\n" | |
69 | + "isync":"=r" (ret): "r" (addr), "m" (*addr)); | |
70 | + return ret; | |
71 | +} | |
72 | + | |
73 | +inline void out_le32 (volatile unsigned *addr, int val) | |
74 | +{ | |
75 | + __asm__ __volatile__ ("stwbrx %1,0,%2; eieio":"=m" (*addr):"r" (val), | |
76 | + "r" (addr)); | |
77 | +} | |
78 | + | |
79 | +#define writel(val, addr) out_le32(addr, val) | |
80 | +#define readl(addr) in_le32(addr) | |
81 | + | |
82 | +void i2c_init (int speed, int slaveadd) | |
83 | +{ | |
84 | + /* stop I2C controller */ | |
85 | + writel (0x0, I2CCCR); | |
86 | + /* set clock */ | |
87 | + writel (0x1020, I2CFDR); | |
88 | + /* write slave address */ | |
89 | + writel (slaveadd, I2CADR); | |
90 | + /* clear status register */ | |
91 | + writel (0x0, I2CCSR); | |
92 | + /* start I2C controller */ | |
93 | + writel (MPC107_CCR_MEN, I2CCCR); | |
94 | + | |
95 | + return; | |
96 | +} | |
97 | + | |
98 | +static __inline__ int i2c_wait4bus (void) | |
99 | +{ | |
100 | + ulong timeval = get_timer (0); | |
101 | + | |
102 | + while (readl (I2CCSR) & MPC107_CSR_MBB) | |
103 | + if (get_timer (timeval) > TIMEOUT) | |
104 | + return -1; | |
105 | + | |
106 | + return 0; | |
107 | +} | |
108 | + | |
109 | +static __inline__ int i2c_wait (int write) | |
110 | +{ | |
111 | + u32 csr; | |
112 | + ulong timeval = get_timer (0); | |
113 | + | |
114 | + do { | |
115 | + csr = readl (I2CCSR); | |
116 | + | |
117 | + if (!(csr & MPC107_CSR_MIF)) | |
118 | + continue; | |
119 | + | |
120 | + writel (0x0, I2CCSR); | |
121 | + | |
122 | + if (csr & MPC107_CSR_MAL) { | |
123 | +#ifdef I2CDBG | |
124 | + printf ("i2c_wait: MAL\n"); | |
125 | +#endif | |
126 | + return -1; | |
127 | + } | |
128 | + | |
129 | + if (!(csr & MPC107_CSR_MCF)) { | |
130 | +#ifdef I2CDBG | |
131 | + printf ("i2c_wait: unfinished\n"); | |
132 | +#endif | |
133 | + return -1; | |
134 | + } | |
135 | + | |
136 | + if (write == I2C_WRITE && (csr & MPC107_CSR_RXAK)) { | |
137 | +#ifdef I2CDBG | |
138 | + printf ("i2c_wait: No RXACK\n"); | |
139 | +#endif | |
140 | + return -1; | |
141 | + } | |
142 | + | |
143 | + return 0; | |
144 | + } while (get_timer (timeval) < TIMEOUT); | |
145 | + | |
146 | +#ifdef I2CDBG | |
147 | + printf ("i2c_wait: timed out\n"); | |
148 | +#endif | |
149 | + return -1; | |
150 | +} | |
151 | + | |
152 | +static __inline__ int i2c_write_addr (u8 dev, u8 dir, int rsta) | |
153 | +{ | |
154 | + writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX | | |
155 | + (rsta ? MPC107_CCR_RSTA : 0), I2CCCR); | |
156 | + | |
157 | + writel ((dev << 1) | dir, I2CCDR); | |
158 | + | |
159 | + if (i2c_wait (I2C_WRITE) < 0) | |
160 | + return 0; | |
161 | + | |
162 | + return 1; | |
163 | +} | |
164 | + | |
165 | +static __inline__ int __i2c_write (u8 * data, int length) | |
166 | +{ | |
167 | + int i; | |
168 | + | |
169 | + writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX, I2CCCR); | |
170 | + | |
171 | + for (i = 0; i < length; i++) { | |
172 | + writel (data[i], I2CCDR); | |
173 | + | |
174 | + if (i2c_wait (I2C_WRITE) < 0) | |
175 | + break; | |
176 | + } | |
177 | + | |
178 | + return i; | |
179 | +} | |
180 | + | |
181 | +static __inline__ int __i2c_read (u8 * data, int length) | |
182 | +{ | |
183 | + int i; | |
184 | + | |
185 | + writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | | |
186 | + ((length == 1) ? MPC107_CCR_TXAK : 0), I2CCCR); | |
187 | + | |
188 | + /* dummy read */ | |
189 | + readl (I2CCDR); | |
190 | + | |
191 | + for (i = 0; i < length; i++) { | |
192 | + if (i2c_wait (I2C_READ) < 0) | |
193 | + break; | |
194 | + | |
195 | + /* Generate ack on last next to last byte */ | |
196 | + if (i == length - 2) | |
197 | + writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | | |
198 | + MPC107_CCR_TXAK, I2CCCR); | |
199 | + | |
200 | + /* Generate stop on last byte */ | |
201 | + if (i == length - 1) | |
202 | + writel (MPC107_CCR_MEN | MPC107_CCR_TXAK, I2CCCR); | |
203 | + | |
204 | + data[i] = readl (I2CCDR); | |
205 | + } | |
206 | + | |
207 | + return i; | |
208 | +} | |
209 | + | |
210 | +int i2c_read (u8 dev, uint addr, int alen, u8 * data, int length) | |
211 | +{ | |
212 | + int i = 0; | |
213 | + u8 *a = (u8 *) & addr; | |
214 | + | |
215 | + if (i2c_wait4bus () < 0) | |
216 | + goto exit; | |
217 | + | |
218 | + if (i2c_write_addr (dev, I2C_WRITE, 0) == 0) | |
219 | + goto exit; | |
220 | + | |
221 | + if (__i2c_write (&a[4 - alen], alen) != alen) | |
222 | + goto exit; | |
223 | + | |
224 | + if (i2c_write_addr (dev, I2C_READ, 1) == 0) | |
225 | + goto exit; | |
226 | + | |
227 | + i = __i2c_read (data, length); | |
228 | + | |
229 | +exit: | |
230 | + writel (MPC107_CCR_MEN, I2CCCR); | |
231 | + | |
232 | + return !(i == length); | |
233 | +} | |
234 | + | |
235 | +int i2c_write (u8 dev, uint addr, int alen, u8 * data, int length) | |
236 | +{ | |
237 | + int i = 0; | |
238 | + u8 *a = (u8 *) & addr; | |
239 | + | |
240 | + if (i2c_wait4bus () < 0) | |
241 | + goto exit; | |
242 | + | |
243 | + if (i2c_write_addr (dev, I2C_WRITE, 0) == 0) | |
244 | + goto exit; | |
245 | + | |
246 | + if (__i2c_write (&a[4 - alen], alen) != alen) | |
247 | + goto exit; | |
248 | + | |
249 | + i = __i2c_write (data, length); | |
250 | + | |
251 | +exit: | |
252 | + writel (MPC107_CCR_MEN, I2CCCR); | |
253 | + | |
254 | + return !(i == length); | |
255 | +} | |
256 | + | |
257 | +int i2c_probe (uchar chip) | |
258 | +{ | |
259 | + int tmp; | |
260 | + | |
261 | + /* | |
262 | + * Try to read the first location of the chip. The underlying | |
263 | + * driver doesn't appear to support sending just the chip address | |
264 | + * and looking for an <ACK> back. | |
265 | + */ | |
266 | + udelay (10000); | |
267 | + return i2c_read (chip, 0, 1, (char *) &tmp, 1); | |
268 | +} | |
269 | + | |
270 | +uchar i2c_reg_read (uchar i2c_addr, uchar reg) | |
271 | +{ | |
272 | + char buf[1]; | |
273 | + | |
274 | + i2c_read (i2c_addr, reg, 1, buf, 1); | |
275 | + | |
276 | + return (buf[0]); | |
277 | +} | |
278 | + | |
279 | +void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val) | |
280 | +{ | |
281 | + i2c_write (i2c_addr, reg, 1, &val, 1); | |
282 | +} | |
283 | + | |
284 | +#endif /* CONFIG_HARD_I2C */ |
cpu/mpc824x/drivers/i2c/i2c.h
1 | -#ifndef I2C_H | |
2 | -#define I2C_H | |
3 | - | |
4 | -/**************************************************** | |
5 | - * | |
6 | - * Copyright Motrola 1999 | |
7 | - * | |
8 | - ****************************************************/ | |
9 | -#define get_eumbbar() CFG_EUMB_ADDR | |
10 | - | |
11 | -#define I2CADR 0x00003000 | |
12 | -#define I2CFDR 0x00003004 | |
13 | -#define I2CCR 0x00003008 | |
14 | -#define I2CSR 0x0000300C | |
15 | -#define I2CDR 0x00003010 | |
16 | - | |
17 | -typedef enum _i2cstatus | |
18 | -{ | |
19 | - I2CSUCCESS = 0x3000, | |
20 | - I2CADDRESS, | |
21 | - I2CERROR, | |
22 | - I2CBUFFFULL, | |
23 | - I2CBUFFEMPTY, | |
24 | - I2CXMITERROR, | |
25 | - I2CRCVERROR, | |
26 | - I2CBUSBUSY, | |
27 | - I2CALOSS, | |
28 | - I2CNOEVENT, | |
29 | -} I2CStatus; | |
30 | - | |
31 | -typedef enum i2c_control | |
32 | -{ | |
33 | - MEN = 0x00000080, | |
34 | - MIEN = 0x00000040, | |
35 | - MSTA = 0x00000020, | |
36 | - MTX = 0x00000010, | |
37 | - TXAK = 0x00000008, | |
38 | - RSTA = 0x00000004, | |
39 | -} I2C_CONTROL; | |
40 | - | |
41 | -typedef enum i2c_status | |
42 | -{ | |
43 | - MCF = 0x00000080, | |
44 | - MAAS = 0x00000040, | |
45 | - MBB = 0x00000020, | |
46 | - MAL = 0x00000010, | |
47 | - SRW = 0x00000004, | |
48 | - MIF = 0x00000002, | |
49 | - RXAK = 0x00000001, | |
50 | -} I2C_STATUS; | |
51 | - | |
52 | -typedef struct _i2c_ctrl | |
53 | -{ | |
54 | - unsigned int reserved0 : 24; | |
55 | - unsigned int men : 1; | |
56 | - unsigned int mien : 1; | |
57 | - unsigned int msta : 1; | |
58 | - unsigned int mtx : 1; | |
59 | - unsigned int txak : 1; | |
60 | - unsigned int rsta : 1; | |
61 | - unsigned int reserved1 : 2; | |
62 | -} I2C_CTRL; | |
63 | - | |
64 | -typedef struct _i2c_stat | |
65 | -{ | |
66 | - unsigned int rsrv0 : 24; | |
67 | - unsigned int mcf : 1; | |
68 | - unsigned int maas : 1; | |
69 | - unsigned int mbb : 1; | |
70 | - unsigned int mal : 1; | |
71 | - unsigned int rsrv1 : 1; | |
72 | - unsigned int srw : 1; | |
73 | - unsigned int mif : 1; | |
74 | - unsigned int rxak : 1; | |
75 | -} I2C_STAT; | |
76 | - | |
77 | -typedef enum _i2c_mode | |
78 | -{ | |
79 | - RCV = 0, | |
80 | - XMIT = 1, | |
81 | -} I2C_MODE; | |
82 | - | |
83 | -/******************** App. API ******************** | |
84 | - * The application API is for user level application | |
85 | - * to use the funcitonality provided by I2C driver | |
86 | - * | |
87 | - * Note: Its App.s responsibility to swap the data | |
88 | - * byte. In our API, we just transfer whatever | |
89 | - * we are given | |
90 | - **************************************************/ | |
91 | -/** | |
92 | - * Note: | |
93 | - * | |
94 | - * In all following functions, | |
95 | - * the caller shall pass the configured embedded utility memory | |
96 | - * block base, EUMBBAR. | |
97 | - **/ | |
98 | - | |
99 | -/* Send a buffer of data to the intended rcv_addr. | |
100 | - * If stop_flag is set, after the whole buffer | |
101 | - * is sent, generate a STOP signal provided that the | |
102 | - * receiver doesn't signal the STOP in the middle. | |
103 | - * I2C is the master performing transmitting. If | |
104 | - * no STOP signal is generated at the end of current | |
105 | - * transaction, the master can generate a START signal | |
106 | - * to another slave addr. | |
107 | - * | |
108 | - * return I2CSUCCESS if no error. | |
109 | - */ | |
110 | -static I2CStatus I2C_put( unsigned int eumbbar, | |
111 | - unsigned char rcv_addr, /* receiver's address */ | |
112 | - unsigned char *buffer_ptr, /* pointer of data to be sent */ | |
113 | - unsigned int length, /* number of byte of in the buffer */ | |
114 | - unsigned int stop_flag, /* 1 - signal STOP when buffer is empty | |
115 | - * 0 - no STOP signal when buffer is empty | |
116 | - */ | |
117 | - unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB | |
118 | - * 0 - this is a new start, check MBB | |
119 | - */ | |
120 | - | |
121 | -/* Receive a buffer of data from the desired sender_addr | |
122 | - * If stop_flag is set, when the buffer is full and the | |
123 | - * sender does not signal STOP, generate a STOP signal. | |
124 | - * I2C is the master performing receiving. If no STOP signal | |
125 | - * is generated, the master can generate a START signal | |
126 | - * to another slave addr. | |
127 | - * | |
128 | - * return I2CSUCCESS if no error. | |
129 | - */ | |
130 | -static I2CStatus I2C_get( unsigned int eumbbar, | |
131 | - unsigned char sender_addr, /* sender's address */ | |
132 | - unsigned char *buffer_ptr, /* pointer of receiving buffer */ | |
133 | - unsigned int length, /* length of the receiving buffer */ | |
134 | - unsigned int stop_flag, /* 1 - signal STOP when buffer is full | |
135 | - * 0 - no STOP signal when buffer is full | |
136 | - */ | |
137 | - unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB | |
138 | - * 0 - this is a new start, check MBB | |
139 | - */ | |
140 | - | |
141 | -#if 0 /* the I2C_write and I2C_read functions are not active */ | |
142 | -/* Send a buffer of data to the requiring master. | |
143 | - * If stop_flag is set, after the whole buffer is sent, | |
144 | - * generate a STOP signal provided that the requiring | |
145 | - * receiver doesn't signal the STOP in the middle. | |
146 | - * I2C is the slave performing transmitting. | |
147 | - * | |
148 | - * return I2CSUCCESS if no error. | |
149 | - * | |
150 | - * Note: due to the Kahlua design, slave transmitter | |
151 | - * shall not signal STOP since there is no way | |
152 | - * for master to detect it, causing I2C bus hung. | |
153 | - * | |
154 | - * For the above reason, the stop_flag is always | |
155 | - * set, i.e., 1. | |
156 | - * | |
157 | - * programmer shall use the timer on Kahlua to | |
158 | - * control the interval of data byte at the | |
159 | - * master side. | |
160 | - */ | |
161 | -static I2CStatus I2C_write( unsigned int eumbbar, | |
162 | - unsigned char *buffer_ptr, /* pointer of data to be sent */ | |
163 | - unsigned int length, /* number of byte of in the buffer */ | |
164 | - unsigned int stop_flag ); /* 1 - signal STOP when buffer is empty | |
165 | - * 0 - no STOP signal when buffer is empty | |
166 | - */ | |
167 | - | |
168 | - /* Receive a buffer of data from the sending master. | |
169 | - * If stop_flag is set, when the buffer is full and the | |
170 | - * sender does not signal STOP, generate a STOP signal. | |
171 | - * I2C is the slave performing receiving. | |
172 | - * | |
173 | - * return I2CSUCCESS if no error. | |
174 | - */ | |
175 | -static I2CStatus I2C_read(unsigned int eumbbar, | |
176 | - unsigned char *buffer_ptr, /* pointer of receiving buffer */ | |
177 | - unsigned int length, /* length of the receiving buffer */ | |
178 | - unsigned int stop_flag ); /* 1 - signal STOP when buffer is full | |
179 | - * 0 - no STOP signal when buffer is full | |
180 | - */ | |
181 | -#endif /* of if0 for turning off I2C_read & I2C_write */ | |
182 | - | |
183 | -/* if interrupt is not used, this is the timer event handler. | |
184 | - * After each fixed time interval, this function can be called | |
185 | - * to check the I2C status and call appropriate function to | |
186 | - * handle the status event. | |
187 | - */ | |
188 | -static I2CStatus I2C_Timer_Event( unsigned int eumbbar, I2CStatus (*handler)( unsigned int ) ); | |
189 | - | |
190 | -/********************* Kernel API ************************ | |
191 | - * Kernel APIs are functions I2C driver provides to the | |
192 | - * O.S. | |
193 | - *********************************************************/ | |
194 | - | |
195 | -/******************* device I/O function ***************/ | |
196 | - | |
197 | -/* Generate a START signal in the desired mode. | |
198 | - * I2C is the master. | |
199 | - * | |
200 | - * return I2CSUCCESS if no error. | |
201 | - * I2CERROR if i2c unit is not enabled. | |
202 | - * I2CBUSBUSY if bus cannot be granted | |
203 | - */ | |
204 | -static I2CStatus I2C_Start( unsigned int eumbbar, | |
205 | - unsigned char slave_addr, /* address of the receiver */ | |
206 | - I2C_MODE mode, /* XMIT(1) - put (write) | |
207 | - * RCV(0) - get (read) | |
208 | - */ | |
209 | - unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB | |
210 | - * 0 - this is a new start, check MBB | |
211 | - */ | |
212 | - | |
213 | -/* Generate a STOP signal to terminate the transaction. */ | |
214 | -static I2CStatus I2C_Stop( unsigned int eumbbar ); | |
215 | - | |
216 | -/* Do a one-byte master transmit. | |
217 | - * | |
218 | - * return I2CBUFFEMPTY if this is the last byte. | |
219 | - * Otherwise return I2CSUCCESS | |
220 | - */ | |
221 | -static I2CStatus I2C_Master_Xmit( unsigned int eumbbar ); | |
222 | - | |
223 | -/* Do a one-byte master receive. | |
224 | - * | |
225 | - * return I2CBUFFFULL if this is the last byte. | |
226 | - * Otherwise return I2CSUCCESS | |
227 | - */ | |
228 | -static I2CStatus I2C_Master_Rcv( unsigned int eumbbar ); | |
229 | - | |
230 | -/* Do a one-byte slave transmit. | |
231 | - * | |
232 | - * return I2CBUFFEMPTY if this is the last byte. | |
233 | - * Otherwise return I2CSUCCESS | |
234 | - * | |
235 | - */ | |
236 | -static I2CStatus I2C_Slave_Xmit( unsigned int eumbbar ); | |
237 | - | |
238 | -/* Do a one-byte slave receive. | |
239 | - * | |
240 | - * return I2CBUFFFULL if this is the last byte. | |
241 | - * Otherwise return I2CSUCCESS | |
242 | - */ | |
243 | -static I2CStatus I2C_Slave_Rcv( unsigned int eumbbar ); | |
244 | - | |
245 | -/* Process slave address phase. | |
246 | - * | |
247 | - * return I2CADDRESS if this is slave receiver's address phase | |
248 | - * Otherwise return the result of slave xmit one byte. | |
249 | - */ | |
250 | -static I2CStatus I2C_Slave_Addr( unsigned int eumbbar ); | |
251 | - | |
252 | -/******************* Device Control Fucntion ****************/ | |
253 | -/* Initialize I2C unit with desired frequency divider, | |
254 | - * driver's slave address w/o interrupt enabled. | |
255 | - * | |
256 | - * This function must be called before I2C unit can | |
257 | - * be used. | |
258 | - */ | |
259 | -static I2CStatus I2C_Init( unsigned int eumbbar, | |
260 | - unsigned char fdr, /* frequency divider */ | |
261 | - unsigned char addr, /* driver's address used for receiving */ | |
262 | - unsigned int en_int); /* 1 - enable I2C interrupt | |
263 | - * 0 - disable I2C interrup | |
264 | - */ | |
265 | - | |
266 | -/* I2C interrupt service routine. | |
267 | - * | |
268 | - * return I2CADDRESS if it is receiver's (either master or slave) address phase. | |
269 | - * return the result of xmit or receive one byte | |
270 | - */ | |
271 | -static I2CStatus I2C_ISR(unsigned int eumbbar ); | |
272 | - | |
273 | -/* Set I2C Status, i.e., write to I2CSR */ | |
274 | -static void I2C_Set_Stat( unsigned int eumbbar, I2C_STAT stat ); | |
275 | - | |
276 | -/* Query I2C Status, i.e., read I2CSR */ | |
277 | -static I2C_STAT I2C_Get_Stat( unsigned int eumbbar ); | |
278 | - | |
279 | -/* Change I2C Control bits, i.e., write to I2CCR */ | |
280 | -static void I2C_Set_Ctrl( unsigned int eumbbar, I2C_CTRL ); /* new control value */ | |
281 | - | |
282 | -/* Query I2C Control bits, i.e., read I2CCR */ | |
283 | -static I2C_CTRL I2C_Get_Ctrl( unsigned int eumbbar ); | |
284 | - | |
285 | -/* This function performs the work for I2C_do_transaction. The work is | |
286 | - * split into this function to enable I2C_do_transaction to first transmit | |
287 | - * the data address to the I2C slave device without putting the data address | |
288 | - * into the first byte of the buffer. | |
289 | - * | |
290 | - * en_int controls interrupt/polling mode | |
291 | - * act is the type of transaction | |
292 | - * i2c_addr is the I2C address of the slave device | |
293 | - * len is the length of data to send or receive | |
294 | - * buffer is the address of the data buffer | |
295 | - * stop = I2C_NO_STOP, don't signal STOP at end of transaction | |
296 | - * I2C_STOP, signal STOP at end of transaction | |
297 | - * retry is the timeout retry value, currently ignored | |
298 | - * rsta = I2C_NO_RESTART, this is not continuation of existing transaction | |
299 | - * I2C_RESTART, this is a continuation of existing transaction | |
300 | - */ | |
301 | -static I2C_Status I2C_do_buffer( I2C_INTERRUPT_MODE en_int, | |
302 | - I2C_TRANSACTION_MODE act, | |
303 | - unsigned char i2c_addr, | |
304 | - int len, | |
305 | - unsigned char *buffer, | |
306 | - I2C_STOP_MODE stop, | |
307 | - int retry, | |
308 | - I2C_RESTART_MODE rsta); | |
309 | -#endif |
cpu/mpc824x/drivers/i2c/i2c1.c
Changes suppressed. Click to show
1 | -/************************************************************* | |
2 | - * | |
3 | - * Copyright @ Motorola, 1999 | |
4 | - * | |
5 | - ************************************************************/ | |
6 | -#include <common.h> | |
7 | - | |
8 | -#ifdef CONFIG_HARD_I2C | |
9 | -#include <i2c.h> | |
10 | -#include "i2c_export.h" | |
11 | -#include "i2c.h" | |
12 | - | |
13 | -#undef I2CDBG0 | |
14 | -#undef DEBUG | |
15 | - | |
16 | -/* Define a macro to use an optional application-layer print function, if | |
17 | - * one was passed to the I2C library during initialization. If there was | |
18 | - * no function pointer passed, this protects against calling it. Also define | |
19 | - * the global variable that holds the passed pointer. | |
20 | - */ | |
21 | -#define TIMEOUT (CFG_HZ/4) | |
22 | -#define PRINT if ( app_print ) app_print | |
23 | -static int (*app_print) (char *, ...); | |
24 | - | |
25 | -/******************* Internal to I2C Driver *****************/ | |
26 | -static unsigned int ByteToXmit = 0; | |
27 | -static unsigned int XmitByte = 0; | |
28 | -static unsigned char *XmitBuf = 0; | |
29 | -static unsigned int XmitBufEmptyStop = 0; | |
30 | -static unsigned int ByteToRcv = 0; | |
31 | -static unsigned int RcvByte = 0; | |
32 | -static unsigned char *RcvBuf = 0; | |
33 | -static unsigned int RcvBufFulStop = 0; | |
34 | -static unsigned int MasterRcvAddress = 0; | |
35 | - | |
36 | -/* Set by call to get_eumbbar during I2C_Initialize. | |
37 | - * This could be globally available to the I2C library, but there is | |
38 | - * an advantage to passing it as a parameter: it is already in a register | |
39 | - * and doesn't have to be loaded from memory. Also, that is the way the | |
40 | - * I2C library was already implemented and I don't want to change it without | |
41 | - * a more detailed analysis. | |
42 | - * It is being set as a global variable in I2C_Initialize to hide it from | |
43 | - * the DINK application layer, because it is Kahlua-specific. I think that | |
44 | - * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in | |
45 | - * a Kahlua-specific library dealing with the embedded utilities memory block. | |
46 | - * Right now, get_eumbbar is defined in dink32/kahlua.s. The other two are | |
47 | - * defined in dink32/drivers/i2c/i2c2.s. | |
48 | - */ | |
49 | -static unsigned int Global_eumbbar = 0; | |
50 | - | |
51 | -extern unsigned int load_runtime_reg (unsigned int eumbbar, | |
52 | - unsigned int reg); | |
53 | - | |
54 | -extern unsigned int store_runtime_reg (unsigned int eumbbar, | |
55 | - unsigned int reg, unsigned int val); | |
56 | - | |
57 | -/************************** API *****************/ | |
58 | - | |
59 | -/* Application Program Interface (API) are the calls provided by the I2C | |
60 | - * library to upper layer applications (i.e., DINK) to access the Kahlua | |
61 | - * I2C bus interface. The functions and values that are part of this API | |
62 | - * are declared in i2c_export.h. | |
63 | - */ | |
64 | - | |
65 | -/* Initialize I2C unit with the following: | |
66 | - * driver's slave address | |
67 | - * interrupt enabled | |
68 | - * optional pointer to application layer print function | |
69 | - * | |
70 | - * These parameters may be added: | |
71 | - * desired clock rate | |
72 | - * digital filter frequency sampling rate | |
73 | - * | |
74 | - * This function must be called before I2C unit can be used. | |
75 | - */ | |
76 | -I2C_Status I2C_Initialize (unsigned char addr, | |
77 | - I2C_INTERRUPT_MODE en_int, | |
78 | - int (*p) (char *, ...)) | |
79 | -{ | |
80 | - I2CStatus status; | |
81 | - | |
82 | - /* establish the pointer, if there is one, to the application's "printf" */ | |
83 | - app_print = p; | |
84 | - | |
85 | - /* If this is the first call, get the embedded utilities memory block | |
86 | - * base address. I'm not sure what to do about error handling here: | |
87 | - * if a non-zero value is returned, accept it. | |
88 | - */ | |
89 | - if (Global_eumbbar == 0) | |
90 | - Global_eumbbar = get_eumbbar (); | |
91 | - if (Global_eumbbar == 0) { | |
92 | - PRINT ("I2C_Initialize: can't find EUMBBAR\n"); | |
93 | - return I2C_ERROR; | |
94 | - } | |
95 | - | |
96 | - /* validate the I2C address */ | |
97 | - if (addr & 0x80) { | |
98 | - PRINT ("I2C_Initialize, I2C address invalid: %d 0x%x\n", | |
99 | - (unsigned int) addr, (unsigned int) addr); | |
100 | - return I2C_ERROR; | |
101 | - } | |
102 | - | |
103 | - /* Call the internal I2C library function to perform work. | |
104 | - * Accept the default frequency sampling rate (no way to set it currently, | |
105 | - * via I2C_Init) and set the clock frequency to something reasonable. | |
106 | - */ | |
107 | - status = I2C_Init (Global_eumbbar, (unsigned char) 0x31, addr, en_int); | |
108 | - if (status != I2CSUCCESS) { | |
109 | - PRINT ("I2C_Initialize: error in initiation\n"); | |
110 | - return I2C_ERROR; | |
111 | - } | |
112 | - | |
113 | - /* all is well */ | |
114 | - return I2C_SUCCESS; | |
115 | -} | |
116 | - | |
117 | - | |
118 | -/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV | |
119 | - * are implemented. Both are only in polling mode. | |
120 | - * | |
121 | - * en_int controls interrupt/polling mode | |
122 | - * act is the type of transaction | |
123 | - * i2c_addr is the I2C address of the slave device | |
124 | - * data_addr is the address of the data on the slave device | |
125 | - * len is the length of data to send or receive | |
126 | - * buffer is the address of the data buffer | |
127 | - * stop = I2C_NO_STOP, don't signal STOP at end of transaction | |
128 | - * I2C_STOP, signal STOP at end of transaction | |
129 | - * retry is the timeout retry value, currently ignored | |
130 | - * rsta = I2C_NO_RESTART, this is not continuation of existing transaction | |
131 | - * I2C_RESTART, this is a continuation of existing transaction | |
132 | - */ | |
133 | -I2C_Status I2C_do_transaction ( I2C_INTERRUPT_MODE en_int, | |
134 | - I2C_TRANSACTION_MODE act, | |
135 | - unsigned char i2c_addr, | |
136 | - unsigned char data_addr, | |
137 | - int len, | |
138 | - char *buffer, | |
139 | - I2C_STOP_MODE stop, | |
140 | - int retry, I2C_RESTART_MODE rsta) | |
141 | -{ | |
142 | - I2C_Status status; | |
143 | - unsigned char data_addr_buffer[1]; | |
144 | - | |
145 | -#if 1 | |
146 | -/* This is a temporary work-around. The I2C library breaks the protocol | |
147 | - * if it attempts to handle a data transmission in more than one | |
148 | - * transaction, so the data address and the actual data bytes are put | |
149 | - * into a single buffer before sending it to the library internal functions. | |
150 | - * The problem is related to being able to restart a transaction without | |
151 | - * sending the I2C device address or repeating the data address. It may take | |
152 | - * a day or two to sort it all out, so I'll have to get back to it later. | |
153 | - * Look at I2C_Start to see about using some status flags (I'm not sure that | |
154 | - * "stop" and "rsta" are enough to reflect the states, maybe so; but the logic | |
155 | - * in the library is insufficient) to control correct handling of the protocol. | |
156 | - */ | |
157 | - unsigned char dummy_buffer[257]; | |
158 | - | |
159 | - if (act == I2C_MASTER_XMIT) { | |
160 | - int i; | |
161 | - | |
162 | - if (len > 256) | |
163 | - return I2C_ERROR; | |
164 | - for (i = 1; i <= len; i++) | |
165 | - dummy_buffer[i] = buffer[i - 1]; | |
166 | - dummy_buffer[0] = data_addr; | |
167 | - status = I2C_do_buffer (en_int, act, i2c_addr, 1 + len, | |
168 | - dummy_buffer, stop, retry, rsta); | |
169 | - if (status != I2C_SUCCESS) { | |
170 | - PRINT ("I2C_do_transaction: can't perform data transfer\n"); | |
171 | - return I2C_ERROR; | |
172 | - } | |
173 | - return I2C_SUCCESS; | |
174 | - } | |
175 | -#endif /* end of temp work-around */ | |
176 | - | |
177 | - /* validate requested transaction type */ | |
178 | - if ((act != I2C_MASTER_XMIT) && (act != I2C_MASTER_RCV)) { | |
179 | - PRINT ("I2C_do_transaction, invalid transaction request: %d\n", | |
180 | - act); | |
181 | - return I2C_ERROR; | |
182 | - } | |
183 | - | |
184 | - /* range check the I2C address */ | |
185 | - if (i2c_addr & 0x80) { | |
186 | - PRINT ("I2C_do_transaction, I2C address out of range: %d 0x%x\n", | |
187 | - (unsigned int) i2c_addr, (unsigned int) i2c_addr); | |
188 | - return I2C_ERROR; | |
189 | - } else { | |
190 | - data_addr_buffer[0] = data_addr; | |
191 | - } | |
192 | - | |
193 | - /* | |
194 | - * We first have to contact the slave device and transmit the | |
195 | - * data address. Be careful about the STOP and restart stuff. | |
196 | - * We don't want to signal STOP after sending the data | |
197 | - * address, but this could be a continuation if the | |
198 | - * application didn't release the bus after the previous | |
199 | - * transaction, by not sending a STOP after it. | |
200 | - */ | |
201 | - status = I2C_do_buffer (en_int, I2C_MASTER_XMIT, i2c_addr, 1, | |
202 | - data_addr_buffer, I2C_NO_STOP, retry, rsta); | |
203 | - if (status != I2C_SUCCESS) { | |
204 | - PRINT ("I2C_do_transaction: can't send data address for read\n"); | |
205 | - return I2C_ERROR; | |
206 | - } | |
207 | - | |
208 | - /* The data transfer will be a continuation. */ | |
209 | - rsta = I2C_RESTART; | |
210 | - | |
211 | - /* now handle the user data */ | |
212 | - status = I2C_do_buffer (en_int, act, i2c_addr, len, | |
213 | - buffer, stop, retry, rsta); | |
214 | - if (status != I2C_SUCCESS) { | |
215 | - PRINT ("I2C_do_transaction: can't perform data transfer\n"); | |
216 | - return I2C_ERROR; | |
217 | - } | |
218 | - | |
219 | - /* all is well */ | |
220 | - return I2C_SUCCESS; | |
221 | -} | |
222 | - | |
223 | -/* This function performs the work for I2C_do_transaction. The work is | |
224 | - * split into this function to enable I2C_do_transaction to first transmit | |
225 | - * the data address to the I2C slave device without putting the data address | |
226 | - * into the first byte of the buffer. | |
227 | - * | |
228 | - * en_int controls interrupt/polling mode | |
229 | - * act is the type of transaction | |
230 | - * i2c_addr is the I2C address of the slave device | |
231 | - * len is the length of data to send or receive | |
232 | - * buffer is the address of the data buffer | |
233 | - * stop = I2C_NO_STOP, don't signal STOP at end of transaction | |
234 | - * I2C_STOP, signal STOP at end of transaction | |
235 | - * retry is the timeout retry value, currently ignored | |
236 | - * rsta = I2C_NO_RESTART, this is not continuation of existing transaction | |
237 | - * I2C_RESTART, this is a continuation of existing transaction | |
238 | - */ | |
239 | -static I2C_Status I2C_do_buffer (I2C_INTERRUPT_MODE en_int, | |
240 | - I2C_TRANSACTION_MODE act, | |
241 | - unsigned char i2c_addr, | |
242 | - int len, | |
243 | - unsigned char *buffer, | |
244 | - I2C_STOP_MODE stop, | |
245 | - int retry, I2C_RESTART_MODE rsta) | |
246 | -{ | |
247 | - I2CStatus rval; | |
248 | - unsigned int dev_stat; | |
249 | - | |
250 | - if (act == I2C_MASTER_RCV) { | |
251 | - /* set up for master-receive transaction */ | |
252 | - rval = I2C_get (Global_eumbbar, i2c_addr, buffer, len, stop, rsta); | |
253 | - } else { | |
254 | - /* set up for master-transmit transaction */ | |
255 | - rval = I2C_put (Global_eumbbar, i2c_addr, buffer, len, stop, rsta); | |
256 | - } | |
257 | - | |
258 | - /* validate the setup */ | |
259 | - if (rval != I2CSUCCESS) { | |
260 | - dev_stat = load_runtime_reg (Global_eumbbar, I2CSR); | |
261 | - PRINT ("Error(I2C_do_buffer): control phase, code(0x%08x), status(0x%08x)\n", rval, dev_stat); | |
262 | - I2C_Stop (Global_eumbbar); | |
263 | - return I2C_ERROR; | |
264 | - } | |
265 | - | |
266 | - if (en_int == 1) { | |
267 | - /* this should not happen, no interrupt handling yet */ | |
268 | - return I2C_SUCCESS; | |
269 | - } | |
270 | - | |
271 | - /* this performs the polling action, when the transfer is completed, | |
272 | - * the status returned from I2C_Timer_Event will be I2CBUFFFULL or | |
273 | - * I2CBUFFEMPTY (rcv or xmit), I2CSUCCESS or I2CADDRESS indicates the | |
274 | - * transaction is not yet complete, anything else is an error. | |
275 | - */ | |
276 | - while (rval == I2CSUCCESS || rval == I2CADDRESS) { | |
277 | - int timeval = get_timer (0); | |
278 | - | |
279 | - /* poll the device until something happens */ | |
280 | - do { | |
281 | - rval = I2C_Timer_Event (Global_eumbbar, 0); | |
282 | - } | |
283 | - while (rval == I2CNOEVENT && get_timer (timeval) < TIMEOUT); | |
284 | - | |
285 | - /* check for error condition */ | |
286 | - if (rval == I2CSUCCESS || | |
287 | - rval == I2CBUFFFULL || | |
288 | - rval == I2CBUFFEMPTY || | |
289 | - rval == I2CADDRESS) { | |
290 | - ; /* do nothing */ | |
291 | - } else { | |
292 | - /* report the error condition */ | |
293 | - dev_stat = load_runtime_reg (Global_eumbbar, I2CSR); | |
294 | - PRINT ("Error(I2C_do_buffer): code(0x%08x), status(0x%08x)\n", | |
295 | - rval, dev_stat); | |
296 | - return I2C_ERROR; | |
297 | - } | |
298 | - } | |
299 | - | |
300 | - /* all is well */ | |
301 | - return I2C_SUCCESS; | |
302 | -} | |
303 | - | |
304 | -/** | |
305 | - * Note: | |
306 | - * | |
307 | - * In all following functions, | |
308 | - * the caller shall pass the configured embedded utility memory | |
309 | - * block base, EUMBBAR. | |
310 | - **/ | |
311 | - | |
312 | -/*********************************************************** | |
313 | - * function: I2C_put | |
314 | - * | |
315 | - * description: | |
316 | - Send a buffer of data to the intended rcv_addr. | |
317 | - * If stop_flag is set, after the whole buffer | |
318 | - * is sent, generate a STOP signal provided that the | |
319 | - * receiver doesn't signal the STOP in the middle. | |
320 | - * I2C is the master performing transmitting. If | |
321 | - * no STOP signal is generated at the end of current | |
322 | - * transaction, the master can generate a START signal | |
323 | - * to another slave addr. | |
324 | - * | |
325 | - * note: this is master xmit API | |
326 | - *********************************************************/ | |
327 | -static I2CStatus I2C_put (unsigned int eumbbar, unsigned char rcv_addr, /* receiver's address */ | |
328 | - unsigned char *buffer_ptr, /* pointer of data to be sent */ | |
329 | - unsigned int length, /* number of byte of in the buffer */ | |
330 | - unsigned int stop_flag, /* 1 - signal STOP when buffer is empty | |
331 | - * 0 - no STOP signal when buffer is empty | |
332 | - */ | |
333 | - unsigned int is_cnt) | |
334 | -{ /* 1 - this is a restart, don't check MBB | |
335 | - * 0 - this is a new start, check MBB | |
336 | - */ | |
337 | - if (buffer_ptr == 0 || length == 0) { | |
338 | - return I2CERROR; | |
339 | - } | |
340 | -#ifdef I2CDBG0 | |
341 | - PRINT ("%s(%d): I2C_put\n", __FILE__, __LINE__); | |
342 | -#endif | |
343 | - | |
344 | - XmitByte = 0; | |
345 | - ByteToXmit = length; | |
346 | - XmitBuf = buffer_ptr; | |
347 | - XmitBufEmptyStop = stop_flag; | |
348 | - | |
349 | - RcvByte = 0; | |
350 | - ByteToRcv = 0; | |
351 | - RcvBuf = 0; | |
352 | - | |
353 | - /* we are the master, start transaction */ | |
354 | - return I2C_Start (eumbbar, rcv_addr, XMIT, is_cnt); | |
355 | -} | |
356 | - | |
357 | -/*********************************************************** | |
358 | - * function: I2C_get | |
359 | - * | |
360 | - * description: | |
361 | - * Receive a buffer of data from the desired sender_addr | |
362 | - * If stop_flag is set, when the buffer is full and the | |
363 | - * sender does not signal STOP, generate a STOP signal. | |
364 | - * I2C is the master performing receiving. If no STOP signal | |
365 | - * is generated, the master can generate a START signal | |
366 | - * to another slave addr. | |
367 | - * | |
368 | - * note: this is master receive API | |
369 | - **********************************************************/ | |
370 | -static I2CStatus I2C_get (unsigned int eumbbar, unsigned char rcv_from, /* sender's address */ | |
371 | - unsigned char *buffer_ptr, /* pointer of receiving buffer */ | |
372 | - unsigned int length, /* length of the receiving buffer */ | |
373 | - unsigned int stop_flag, /* 1 - signal STOP when buffer is full | |
374 | - * 0 - no STOP signal when buffer is full | |
375 | - */ | |
376 | - unsigned int is_cnt) | |
377 | -{ /* 1 - this is a restart, don't check MBB | |
378 | - * 0 - this is a new start, check MBB | |
379 | - */ | |
380 | - if (buffer_ptr == 0 || length == 0) { | |
381 | - return I2CERROR; | |
382 | - } | |
383 | -#ifdef I2CDBG0 | |
384 | - PRINT ("%s(%d): I2C_get\n", __FILE__, __LINE__); | |
385 | -#endif | |
386 | - | |
387 | - RcvByte = 0; | |
388 | - ByteToRcv = length; | |
389 | - RcvBuf = buffer_ptr; | |
390 | - RcvBufFulStop = stop_flag; | |
391 | - | |
392 | - XmitByte = 0; | |
393 | - ByteToXmit = 0; | |
394 | - XmitBuf = 0; | |
395 | - | |
396 | - /* we are the master, start the transaction */ | |
397 | - return I2C_Start (eumbbar, rcv_from, RCV, is_cnt); | |
398 | - | |
399 | -} | |
400 | - | |
401 | -#if 0 /* turn off dead code */ | |
402 | -/********************************************************* | |
403 | - * function: I2C_write | |
404 | - * | |
405 | - * description: | |
406 | - * Send a buffer of data to the requiring master. | |
407 | - * If stop_flag is set, after the whole buffer is sent, | |
408 | - * generate a STOP signal provided that the requiring | |
409 | - * receiver doesn't signal the STOP in the middle. | |
410 | - * I2C is the slave performing transmitting. | |
411 | - * | |
412 | - * Note: this is slave xmit API. | |
413 | - * | |
414 | - * due to the current Kahlua design, slave transmitter | |
415 | - * shall not signal STOP since there is no way | |
416 | - * for master to detect it, causing I2C bus hung. | |
417 | - * | |
418 | - * For the above reason, the stop_flag is always | |
419 | - * set, i.e., 0. | |
420 | - * | |
421 | - * programmer shall use the timer on Kahlua to | |
422 | - * control the interval of data byte at the | |
423 | - * master side. | |
424 | - *******************************************************/ | |
425 | -static I2CStatus I2C_write (unsigned int eumbbar, unsigned char *buffer_ptr, /* pointer of data to be sent */ | |
426 | - unsigned int length, /* number of byte of in the buffer */ | |
427 | - unsigned int stop_flag) | |
428 | -{ /* 1 - signal STOP when buffer is empty | |
429 | - * 0 - no STOP signal when buffer is empty | |
430 | - */ | |
431 | - if (buffer_ptr == 0 || length == 0) { | |
432 | - return I2CERROR; | |
433 | - } | |
434 | - | |
435 | - XmitByte = 0; | |
436 | - ByteToXmit = length; | |
437 | - XmitBuf = buffer_ptr; | |
438 | - XmitBufEmptyStop = 0; /* in order to avoid bus hung, ignored the user's stop_flag */ | |
439 | - | |
440 | - RcvByte = 0; | |
441 | - ByteToRcv = 0; | |
442 | - RcvBuf = 0; | |
443 | - | |
444 | - /* we are the slave, just wait for being called, or pull */ | |
445 | - /* I2C_Timer_Event( eumbbar ); */ | |
446 | -} | |
447 | - | |
448 | -/****************************************************** | |
449 | - * function: I2C_read | |
450 | - * | |
451 | - * description: | |
452 | - * Receive a buffer of data from the sending master. | |
453 | - * If stop_flag is set, when the buffer is full and the | |
454 | - * sender does not signal STOP, generate a STOP signal. | |
455 | - * I2C is the slave performing receiving. | |
456 | - * | |
457 | - * note: this is slave receive API | |
458 | - ****************************************************/ | |
459 | -static I2CStatus I2C_read (unsigned int eumbbar, unsigned char *buffer_ptr, /* pointer of receiving buffer */ | |
460 | - unsigned int length, /* length of the receiving buffer */ | |
461 | - unsigned int stop_flag) | |
462 | -{ /* 1 - signal STOP when buffer is full | |
463 | - * 0 - no STOP signal when buffer is full | |
464 | - */ | |
465 | - if (buffer_ptr == 0 || length == 0) { | |
466 | - return I2CERROR; | |
467 | - } | |
468 | - | |
469 | - RcvByte = 0; | |
470 | - ByteToRcv = length; | |
471 | - RcvBuf = buffer_ptr; | |
472 | - RcvBufFulStop = stop_flag; | |
473 | - | |
474 | - XmitByte = 0; | |
475 | - ByteToXmit = 0; | |
476 | - XmitBuf = 0; | |
477 | - | |
478 | - /* wait for master to call us, or poll */ | |
479 | - /* I2C_Timer_Event( eumbbar ); */ | |
480 | -} | |
481 | -#endif /* turn off dead code */ | |
482 | - | |
483 | -/********************************************************* | |
484 | - * function: I2c_Timer_Event | |
485 | - * | |
486 | - * description: | |
487 | - * if interrupt is not used, this is the timer event handler. | |
488 | - * After each fixed time interval, this function can be called | |
489 | - * to check the I2C status and call appropriate function to | |
490 | - * handle the status event. | |
491 | - ********************************************************/ | |
492 | -static I2CStatus I2C_Timer_Event (unsigned int eumbbar, | |
493 | - I2CStatus (*handler) (unsigned int)) | |
494 | -{ | |
495 | - I2C_STAT stat; | |
496 | - | |
497 | -#ifdef I2CDBG0 | |
498 | - PRINT ("%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__); | |
499 | -#endif | |
500 | - | |
501 | - stat = I2C_Get_Stat (eumbbar); | |
502 | - | |
503 | - if (stat.mif == 1) { | |
504 | - if (handler == 0) { | |
505 | - return I2C_ISR (eumbbar); | |
506 | - } else { | |
507 | - return (*handler) (eumbbar); | |
508 | - } | |
509 | - } | |
510 | - | |
511 | - return I2CNOEVENT; | |
512 | -} | |
513 | - | |
514 | - | |
515 | -/****************** Device I/O function *****************/ | |
516 | - | |
517 | -/****************************************************** | |
518 | - * function: I2C_Start | |
519 | - * | |
520 | - * description: Generate a START signal in the desired mode. | |
521 | - * I2C is the master. | |
522 | - * | |
523 | - * Return I2CSUCCESS if no error. | |
524 | - * | |
525 | - * note: | |
526 | - ****************************************************/ | |
527 | -static I2CStatus I2C_Start (unsigned int eumbbar, unsigned char slave_addr, /* address of the receiver */ | |
528 | - I2C_MODE mode, /* XMIT(1) - put (write) | |
529 | - * RCV(0) - get (read) | |
530 | - */ | |
531 | - unsigned int is_cnt) | |
532 | -{ /* 1 - this is a restart, don't check MBB | |
533 | - * 0 - this is a new start | |
534 | - */ | |
535 | - unsigned int tmp = 0; | |
536 | - I2C_STAT stat; | |
537 | - I2C_CTRL ctrl; | |
538 | - | |
539 | -#ifdef I2CDBG0 | |
540 | - PRINT ("%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__, | |
541 | - __LINE__, slave_addr, mode, is_cnt); | |
542 | -#endif | |
543 | - | |
544 | - ctrl = I2C_Get_Ctrl (eumbbar); | |
545 | - | |
546 | - /* first make sure I2C has been initialized */ | |
547 | - if (ctrl.men == 0) { | |
548 | - return I2CERROR; | |
549 | - } | |
550 | - | |
551 | - /* next make sure bus is idle */ | |
552 | - stat = I2C_Get_Stat (eumbbar); | |
553 | - | |
554 | - if (is_cnt == 0 && stat.mbb == 1) { | |
555 | - /* sorry, we lost */ | |
556 | - return I2CBUSBUSY; | |
557 | - } else if (is_cnt == 1 && stat.mif == 1 && stat.mal == 0) { | |
558 | - /* sorry, we lost the bus */ | |
559 | - return I2CALOSS; | |
560 | - } | |
561 | - | |
562 | - | |
563 | - /* OK, I2C is enabled and we have the bus */ | |
564 | - | |
565 | - /* prepare to write the slave address */ | |
566 | - ctrl.msta = 1; | |
567 | - ctrl.mtx = 1; | |
568 | - ctrl.txak = 0; | |
569 | - ctrl.rsta = is_cnt; /* set the repeat start bit */ | |
570 | - I2C_Set_Ctrl (eumbbar, ctrl); | |
571 | - | |
572 | - /* write the slave address and xmit/rcv mode bit */ | |
573 | - tmp = load_runtime_reg (eumbbar, I2CDR); | |
574 | - tmp = (tmp & 0xffffff00) | | |
575 | - ((slave_addr & 0x007f) << 1) | | |
576 | - (mode == XMIT ? 0x0 : 0x1); | |
577 | - store_runtime_reg (eumbbar, I2CDR, tmp); | |
578 | - | |
579 | - if (mode == RCV) { | |
580 | - MasterRcvAddress = 1; | |
581 | - } else { | |
582 | - MasterRcvAddress = 0; | |
583 | - } | |
584 | - | |
585 | -#ifdef I2CDBG0 | |
586 | - PRINT ("%s(%d): I2C_Start exit\n", __FILE__, __LINE__); | |
587 | -#endif | |
588 | - | |
589 | - /* wait for the interrupt or poll */ | |
590 | - return I2CSUCCESS; | |
591 | -} | |
592 | - | |
593 | -/*********************************************************** | |
594 | - * function: I2c_Stop | |
595 | - * | |
596 | - * description: Generate a STOP signal to terminate the master | |
597 | - * transaction. | |
598 | - * return I2CSUCCESS | |
599 | - * | |
600 | - **********************************************************/ | |
601 | -static I2CStatus I2C_Stop (unsigned int eumbbar) | |
602 | -{ | |
603 | - I2C_CTRL ctrl; | |
604 | - | |
605 | -#ifdef I2CDBG0 | |
606 | - PRINT ("%s(%d): I2C_Stop enter\n", __FILE__, __LINE__); | |
607 | -#endif | |
608 | - | |
609 | - ctrl = I2C_Get_Ctrl (eumbbar); | |
610 | - ctrl.msta = 0; | |
611 | - I2C_Set_Ctrl (eumbbar, ctrl); | |
612 | - | |
613 | -#ifdef I2CDBG0 | |
614 | - PRINT ("%s(%d): I2C_Stop exit\n", __FILE__, __LINE__); | |
615 | -#endif | |
616 | - | |
617 | - return I2CSUCCESS; | |
618 | -} | |
619 | - | |
620 | -/**************************************************** | |
621 | - * function: I2C_Master_Xmit | |
622 | - * | |
623 | - * description: Master sends one byte of data to | |
624 | - * slave target | |
625 | - * | |
626 | - * return I2CSUCCESS if the byte transmitted. | |
627 | - * Otherwise no-zero | |
628 | - * | |
629 | - * Note: condition must meet when this function is called: | |
630 | - * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && I2CSR(RXAK) == 0 | |
631 | - * I2CCR(MSTA) == 1 && I2CCR(MTX) == 1 | |
632 | - * | |
633 | - ***************************************************/ | |
634 | -static I2CStatus I2C_Master_Xmit (unsigned int eumbbar) | |
635 | -{ | |
636 | - unsigned int val; | |
637 | - | |
638 | - if (ByteToXmit > 0) { | |
639 | - | |
640 | - if (ByteToXmit == XmitByte) { | |
641 | - /* all xmitted */ | |
642 | - ByteToXmit = 0; | |
643 | - | |
644 | - if (XmitBufEmptyStop == 1) { | |
645 | - I2C_Stop (eumbbar); | |
646 | - } | |
647 | - | |
648 | - return I2CBUFFEMPTY; | |
649 | - | |
650 | - } | |
651 | -#ifdef I2CDBG0 | |
652 | - PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__, | |
653 | - *(XmitBuf + XmitByte)); | |
654 | -#endif | |
655 | - | |
656 | - val = *(XmitBuf + XmitByte); | |
657 | - val &= 0x000000ff; | |
658 | - store_runtime_reg (eumbbar, I2CDR, val); | |
659 | - XmitByte++; | |
660 | - | |
661 | - return I2CSUCCESS; | |
662 | - | |
663 | - } | |
664 | - | |
665 | - return I2CBUFFEMPTY; | |
666 | -} | |
667 | - | |
668 | -/*********************************************** | |
669 | - * function: I2C_Master_Rcv | |
670 | - * | |
671 | - * description: master reads one byte data | |
672 | - * from slave source | |
673 | - * | |
674 | - * return I2CSUCCESS if no error | |
675 | - * | |
676 | - * Note: condition must meet when this function is called: | |
677 | - * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && | |
678 | - * I2CCR(MSTA) == 1 && I2CCR(MTX) == 0 | |
679 | - * | |
680 | - ***********************************************/ | |
681 | -static I2CStatus I2C_Master_Rcv (unsigned int eumbbar) | |
682 | -{ | |
683 | - I2C_CTRL ctrl; | |
684 | - unsigned int val; | |
685 | - | |
686 | - if (ByteToRcv > 0) { | |
687 | - | |
688 | - if (ByteToRcv - RcvByte == 2 && RcvBufFulStop == 1) { | |
689 | - /* master requests more than or equal to 2 bytes | |
690 | - * we are reading 2nd to last byte | |
691 | - */ | |
692 | - | |
693 | - /* we need to set I2CCR(TXAK) to generate a STOP */ | |
694 | - ctrl = I2C_Get_Ctrl (eumbbar); | |
695 | - ctrl.txak = 1; | |
696 | - I2C_Set_Ctrl (eumbbar, ctrl); | |
697 | - | |
698 | - /* Kahlua will automatically generate a STOP | |
699 | - * next time a transaction happens | |
700 | - */ | |
701 | - | |
702 | - /* note: the case of master requesting one byte is | |
703 | - * handled in I2C_ISR | |
704 | - */ | |
705 | - } | |
706 | - | |
707 | - /* generat a STOP before reading the last byte */ | |
708 | - if (RcvByte + 1 == ByteToRcv && RcvBufFulStop == 1) { | |
709 | - I2C_Stop (eumbbar); | |
710 | - } | |
711 | - | |
712 | - val = load_runtime_reg (eumbbar, I2CDR); | |
713 | - *(RcvBuf + RcvByte) = val & 0xFF; | |
714 | - | |
715 | -#ifdef I2CDBG0 | |
716 | - PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__, | |
717 | - *(RcvBuf + RcvByte)); | |
718 | -#endif | |
719 | - | |
720 | - RcvByte++; | |
721 | - | |
722 | - if (ByteToRcv == RcvByte) { | |
723 | - ByteToRcv = 0; | |
724 | - | |
725 | - return I2CBUFFFULL; | |
726 | - } | |
727 | - | |
728 | - return I2CSUCCESS; | |
729 | - } | |
730 | - | |
731 | - return I2CBUFFFULL; | |
732 | - | |
733 | -} | |
734 | - | |
735 | -/**************************************************** | |
736 | - * function: I2C_Slave_Xmit | |
737 | - * | |
738 | - * description: Slave sends one byte of data to | |
739 | - * requesting destination | |
740 | - * | |
741 | - * return SUCCESS if the byte transmitted. Otherwise | |
742 | - * No-zero | |
743 | - * | |
744 | - * Note: condition must meet when this function is called: | |
745 | - * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && I2CSR(RXAK) = 0 | |
746 | - * I2CCR(MSTA) == 0 && I2CCR(MTX) == 1 | |
747 | - * | |
748 | - ***************************************************/ | |
749 | -static I2CStatus I2C_Slave_Xmit (unsigned int eumbbar) | |
750 | -{ | |
751 | - unsigned int val; | |
752 | - | |
753 | - if (ByteToXmit > 0) { | |
754 | - | |
755 | - if (ByteToXmit == XmitByte) { | |
756 | - /* no more data to send */ | |
757 | - ByteToXmit = 0; | |
758 | - | |
759 | - /* | |
760 | - * do not toggle I2CCR(MTX). Doing so will | |
761 | - * cause bus-hung since current Kahlua design | |
762 | - * does not give master a way to detect slave | |
763 | - * stop. It is always a good idea for master | |
764 | - * to use timer to prevent the long long | |
765 | - * delays | |
766 | - */ | |
767 | - | |
768 | - return I2CBUFFEMPTY; | |
769 | - } | |
770 | -#ifdef I2CDBG | |
771 | - PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__, | |
772 | - *(XmitBuf + XmitByte)); | |
773 | -#endif | |
774 | - | |
775 | - val = *(XmitBuf + XmitByte); | |
776 | - val &= 0x000000ff; | |
777 | - store_runtime_reg (eumbbar, I2CDR, val); | |
778 | - XmitByte++; | |
779 | - | |
780 | - return I2CSUCCESS; | |
781 | - } | |
782 | - | |
783 | - return I2CBUFFEMPTY; | |
784 | -} | |
785 | - | |
786 | -/*********************************************** | |
787 | - * function: I2C_Slave_Rcv | |
788 | - * | |
789 | - * description: slave reads one byte data | |
790 | - * from master source | |
791 | - * | |
792 | - * return I2CSUCCESS if no error otherwise non-zero | |
793 | - * | |
794 | - * Note: condition must meet when this function is called: | |
795 | - * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && | |
796 | - * I2CCR(MSTA) == 0 && I2CCR(MTX) = 0 | |
797 | - * | |
798 | - ***********************************************/ | |
799 | -static I2CStatus I2C_Slave_Rcv (unsigned int eumbbar) | |
800 | -{ | |
801 | - unsigned int val; | |
802 | - I2C_CTRL ctrl; | |
803 | - | |
804 | - if (ByteToRcv > 0) { | |
805 | - val = load_runtime_reg (eumbbar, I2CDR); | |
806 | - *(RcvBuf + RcvByte) = val & 0xff; | |
807 | -#ifdef I2CDBG | |
808 | - PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__, | |
809 | - *(RcvBuf + RcvByte)); | |
810 | -#endif | |
811 | - RcvByte++; | |
812 | - | |
813 | - if (ByteToRcv == RcvByte) { | |
814 | - if (RcvBufFulStop == 1) { | |
815 | - /* all done */ | |
816 | - ctrl = I2C_Get_Ctrl (eumbbar); | |
817 | - ctrl.txak = 1; | |
818 | - I2C_Set_Ctrl (eumbbar, ctrl); | |
819 | - } | |
820 | - | |
821 | - ByteToRcv = 0; | |
822 | - return I2CBUFFFULL; | |
823 | - } | |
824 | - | |
825 | - return I2CSUCCESS; | |
826 | - } | |
827 | - | |
828 | - return I2CBUFFFULL; | |
829 | -} | |
830 | - | |
831 | -/****************** Device Control Function *************/ | |
832 | - | |
833 | -/********************************************************* | |
834 | - * function: I2C_Init | |
835 | - * | |
836 | - * description: Initialize I2C unit with desired frequency divider, | |
837 | - * master's listening address, with interrupt enabled | |
838 | - * or disabled. | |
839 | - * | |
840 | - * note: | |
841 | - ********************************************************/ | |
842 | -static I2CStatus I2C_Init (unsigned int eumbbar, unsigned char fdr, /* frequency divider */ | |
843 | - unsigned char slave_addr, /* driver's address used for receiving */ | |
844 | - unsigned int en_int) | |
845 | -{ /* 1 - enable I2C interrupt | |
846 | - * 0 - disable I2C interrup | |
847 | - */ | |
848 | - I2C_CTRL ctrl; | |
849 | - unsigned int tmp; | |
850 | - | |
851 | -#ifdef I2CDBG0 | |
852 | - PRINT ("%s(%d): I2C_Init enter\n", __FILE__, __LINE__); | |
853 | -#endif | |
854 | - | |
855 | - ctrl = I2C_Get_Ctrl (eumbbar); | |
856 | - /* disable the I2C module before we change everything */ | |
857 | - ctrl.men = 0; | |
858 | - I2C_Set_Ctrl (eumbbar, ctrl); | |
859 | - | |
860 | - /* set the frequency diver */ | |
861 | - tmp = load_runtime_reg (eumbbar, I2CFDR); | |
862 | - tmp = (tmp & 0xffffffc0) | (fdr & 0x3f); | |
863 | - store_runtime_reg (eumbbar, I2CFDR, tmp); | |
864 | - | |
865 | - /* Set our listening (slave) address */ | |
866 | - tmp = load_runtime_reg (eumbbar, I2CADR); | |
867 | - tmp = (tmp & 0xffffff01) | ((slave_addr & 0x7f) << 1); | |
868 | - store_runtime_reg (eumbbar, I2CADR, tmp); | |
869 | - | |
870 | - /* enable I2C with desired interrupt setting */ | |
871 | - ctrl.men = 1; | |
872 | - ctrl.mien = en_int & 0x1; | |
873 | - I2C_Set_Ctrl (eumbbar, ctrl); | |
874 | -#ifdef I2CDBG0 | |
875 | - PRINT ("%s(%d): I2C_Init exit\n", __FILE__, __LINE__); | |
876 | -#endif | |
877 | - | |
878 | - return I2CSUCCESS; | |
879 | - | |
880 | -} | |
881 | - | |
882 | -/***************************************** | |
883 | - * function I2c_Get_Stat | |
884 | - * | |
885 | - * description: Query I2C Status, i.e., read I2CSR | |
886 | - * | |
887 | - ****************************************/ | |
888 | -static I2C_STAT I2C_Get_Stat (unsigned int eumbbar) | |
889 | -{ | |
890 | - unsigned int temp; | |
891 | - I2C_STAT stat; | |
892 | - | |
893 | - temp = load_runtime_reg (eumbbar, I2CSR); | |
894 | - | |
895 | -#ifdef I2CDBG0 | |
896 | - PRINT ("%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp); | |
897 | -#endif | |
898 | - | |
899 | - stat.rsrv0 = (temp & 0xffffff00) >> 8; | |
900 | - stat.mcf = (temp & 0x00000080) >> 7; | |
901 | - stat.maas = (temp & 0x00000040) >> 6; | |
902 | - stat.mbb = (temp & 0x00000020) >> 5; | |
903 | - stat.mal = (temp & 0x00000010) >> 4; | |
904 | - stat.rsrv1 = (temp & 0x00000008) >> 3; | |
905 | - stat.srw = (temp & 0x00000004) >> 2; | |
906 | - stat.mif = (temp & 0x00000002) >> 1; | |
907 | - stat.rxak = (temp & 0x00000001); | |
908 | - return stat; | |
909 | -} | |
910 | - | |
911 | -/********************************************* | |
912 | - * function: I2c_Set_Ctrl | |
913 | - * | |
914 | - * description: Change I2C Control bits, | |
915 | - * i.e., write to I2CCR | |
916 | - * | |
917 | - ********************************************/ | |
918 | -static void I2C_Set_Ctrl (unsigned int eumbbar, I2C_CTRL ctrl) | |
919 | -{ /* new control value */ | |
920 | - unsigned int temp = load_runtime_reg (eumbbar, I2CCR); | |
921 | - | |
922 | - temp &= 0xffffff03; | |
923 | - temp |= ((ctrl.men & 0x1) << 7); | |
924 | - temp |= ((ctrl.mien & 0x1) << 6); | |
925 | - temp |= ((ctrl.msta & 0x1) << 5); | |
926 | - temp |= ((ctrl.mtx & 0x1) << 4); | |
927 | - temp |= ((ctrl.txak & 0x1) << 3); | |
928 | - temp |= ((ctrl.rsta & 0x1) << 2); | |
929 | -#ifdef I2CDBG0 | |
930 | - PRINT ("%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp); | |
931 | -#endif | |
932 | - store_runtime_reg (eumbbar, I2CCR, temp); | |
933 | - | |
934 | -} | |
935 | - | |
936 | -/***************************************** | |
937 | - * function: I2C_Get_Ctrl | |
938 | - * | |
939 | - * description: Query I2C Control bits, | |
940 | - * i.e., read I2CCR | |
941 | - *****************************************/ | |
942 | -static I2C_CTRL I2C_Get_Ctrl (unsigned int eumbbar) | |
943 | -{ | |
944 | - union { | |
945 | - I2C_CTRL ctrl; | |
946 | - unsigned int temp; | |
947 | - } s; | |
948 | - | |
949 | - s.temp = load_runtime_reg (eumbbar, I2CCR); | |
950 | -#ifdef I2CDBG0 | |
951 | - PRINT ("%s(%d): get ctrl = 0x%08x\n", __FILE__, __LINE__, s.temp); | |
952 | -#endif | |
953 | - | |
954 | - return s.ctrl; | |
955 | -} | |
956 | - | |
957 | - | |
958 | -/**************************************** | |
959 | - * function: I2C_Slave_Addr | |
960 | - * | |
961 | - * description: Process slave address phase. | |
962 | - * return I2CSUCCESS if no error | |
963 | - * | |
964 | - * note: Precondition for calling this function: | |
965 | - * I2CSR(MIF) == 1 && | |
966 | - * I2CSR(MAAS) == 1 | |
967 | - ****************************************/ | |
968 | -static I2CStatus I2C_Slave_Addr (unsigned int eumbbar) | |
969 | -{ | |
970 | - I2C_STAT stat = I2C_Get_Stat (eumbbar); | |
971 | - I2C_CTRL ctrl = I2C_Get_Ctrl (eumbbar); | |
972 | - | |
973 | - if (stat.srw == 1) { | |
974 | - /* we are asked to xmit */ | |
975 | - ctrl.mtx = 1; | |
976 | - I2C_Set_Ctrl (eumbbar, ctrl); /* set MTX */ | |
977 | - return I2C_Slave_Xmit (eumbbar); | |
978 | - } | |
979 | - | |
980 | - /* we are asked to receive data */ | |
981 | - ctrl.mtx = 0; | |
982 | - I2C_Set_Ctrl (eumbbar, ctrl); | |
983 | - (void) load_runtime_reg (eumbbar, I2CDR); /* do a fake read to start */ | |
984 | - | |
985 | - return I2CADDRESS; | |
986 | -} | |
987 | - | |
988 | -/*********************************************** | |
989 | - * function: I2C_ISR | |
990 | - * | |
991 | - * description: I2C Interrupt service routine | |
992 | - * | |
993 | - * note: Precondition: | |
994 | - * I2CSR(MIF) == 1 | |
995 | - **********************************************/ | |
996 | -static I2CStatus I2C_ISR (unsigned int eumbbar) | |
997 | -{ | |
998 | - I2C_STAT stat; | |
999 | - I2C_CTRL ctrl; | |
1000 | - | |
1001 | -#ifdef I2CDBG0 | |
1002 | - PRINT ("%s(%d): I2C_ISR\n", __FILE__, __LINE__); | |
1003 | -#endif | |
1004 | - | |
1005 | - stat = I2C_Get_Stat (eumbbar); | |
1006 | - ctrl = I2C_Get_Ctrl (eumbbar); | |
1007 | - | |
1008 | - /* clear MIF */ | |
1009 | - stat.mif = 0; | |
1010 | - | |
1011 | - /* Now let see what kind of event this is */ | |
1012 | - if (stat.mcf == 1) { | |
1013 | - /* transfer compete */ | |
1014 | - | |
1015 | - /* clear the MIF bit */ | |
1016 | - I2C_Set_Stat (eumbbar, stat); | |
1017 | - | |
1018 | - if (ctrl.msta == 1) { | |
1019 | - /* master */ | |
1020 | - if (ctrl.mtx == 1) { | |
1021 | - /* check if this is the address phase for master receive */ | |
1022 | - if (MasterRcvAddress == 1) { | |
1023 | - /* Yes, it is the address phase of master receive */ | |
1024 | - ctrl.mtx = 0; | |
1025 | - /* now check how much we want to receive */ | |
1026 | - if (ByteToRcv == 1 && RcvBufFulStop == 1) { | |
1027 | - ctrl.txak = 1; | |
1028 | - } | |
1029 | - | |
1030 | - I2C_Set_Ctrl (eumbbar, ctrl); | |
1031 | - (void) load_runtime_reg (eumbbar, I2CDR); /* fake read first */ | |
1032 | - | |
1033 | - MasterRcvAddress = 0; | |
1034 | - return I2CADDRESS; | |
1035 | - | |
1036 | - } | |
1037 | - | |
1038 | - /* master xmit */ | |
1039 | - if (stat.rxak == 0) { | |
1040 | - /* slave has acknowledged */ | |
1041 | - return I2C_Master_Xmit (eumbbar); | |
1042 | - } | |
1043 | - | |
1044 | - /* slave has not acknowledged yet, generate a STOP */ | |
1045 | - if (XmitBufEmptyStop == 1) { | |
1046 | - ctrl.msta = 0; | |
1047 | - I2C_Set_Ctrl (eumbbar, ctrl); | |
1048 | - } | |
1049 | - | |
1050 | - return I2CSUCCESS; | |
1051 | - } | |
1052 | - | |
1053 | - /* master receive */ | |
1054 | - return I2C_Master_Rcv (eumbbar); | |
1055 | - } | |
1056 | - | |
1057 | - /* slave */ | |
1058 | - if (ctrl.mtx == 1) { | |
1059 | - /* slave xmit */ | |
1060 | - if (stat.rxak == 0) { | |
1061 | - /* master has acknowledged */ | |
1062 | - return I2C_Slave_Xmit (eumbbar); | |
1063 | - } | |
1064 | - | |
1065 | - /* master has not acknowledged, wait for STOP */ | |
1066 | - /* do nothing for preventing bus from hung */ | |
1067 | - return I2CSUCCESS; | |
1068 | - } | |
1069 | - | |
1070 | - /* slave rcv */ | |
1071 | - return I2C_Slave_Rcv (eumbbar); | |
1072 | - | |
1073 | - } else if (stat.maas == 1) { | |
1074 | - /* received a call from master */ | |
1075 | - | |
1076 | - /* clear the MIF bit */ | |
1077 | - I2C_Set_Stat (eumbbar, stat); | |
1078 | - | |
1079 | - /* master is calling us, process the address phase */ | |
1080 | - return I2C_Slave_Addr (eumbbar); | |
1081 | - } else { | |
1082 | - /* has to be arbitration lost */ | |
1083 | - stat.mal = 0; | |
1084 | - I2C_Set_Stat (eumbbar, stat); | |
1085 | - | |
1086 | - ctrl.msta = 0; /* return to receive mode */ | |
1087 | - I2C_Set_Ctrl (eumbbar, ctrl); | |
1088 | - } | |
1089 | - | |
1090 | - return I2CSUCCESS; | |
1091 | - | |
1092 | -} | |
1093 | - | |
1094 | -/****************************************************** | |
1095 | - * function: I2C_Set_Stat | |
1096 | - * | |
1097 | - * description: modify the I2CSR | |
1098 | - * | |
1099 | - *****************************************************/ | |
1100 | -static void I2C_Set_Stat (unsigned int eumbbar, I2C_STAT stat) | |
1101 | -{ | |
1102 | - union { | |
1103 | - unsigned int val; | |
1104 | - I2C_STAT stat; | |
1105 | - } s_tmp; | |
1106 | - union { | |
1107 | - unsigned int val; | |
1108 | - I2C_STAT stat; | |
1109 | - } s; | |
1110 | - | |
1111 | - s.val = load_runtime_reg (eumbbar, I2CSR); | |
1112 | - s.val &= 0xffffff08; | |
1113 | - s_tmp.stat = stat; | |
1114 | - s.val |= (s_tmp.val & 0xf7); | |
1115 | - | |
1116 | -#ifdef I2CDBG0 | |
1117 | - PRINT ("%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val); | |
1118 | -#endif | |
1119 | - | |
1120 | - store_runtime_reg (eumbbar, I2CSR, s.val); | |
1121 | - | |
1122 | -} | |
1123 | - | |
1124 | -/****************************************************** | |
1125 | - * The following are routines to glue the rest of | |
1126 | - * U-Boot to the Sandpoint I2C driver. | |
1127 | - *****************************************************/ | |
1128 | - | |
1129 | -void i2c_init (int speed, int slaveadd) | |
1130 | -{ | |
1131 | -#ifdef CFG_I2C_INIT_BOARD | |
1132 | - /* | |
1133 | - * call board specific i2c bus reset routine before accessing the | |
1134 | - * environment, which might be in a chip on that bus. For details | |
1135 | - * about this problem see doc/I2C_Edge_Conditions. | |
1136 | - */ | |
1137 | - i2c_init_board(); | |
1138 | -#endif | |
1139 | - | |
1140 | -#ifdef DEBUG | |
1141 | - I2C_Initialize (0x7f, 0, (void *) printf); | |
1142 | -#else | |
1143 | - I2C_Initialize (0x7f, 0, 0); | |
1144 | -#endif | |
1145 | -} | |
1146 | - | |
1147 | -int i2c_probe (uchar chip) | |
1148 | -{ | |
1149 | - int tmp; | |
1150 | - | |
1151 | - /* | |
1152 | - * Try to read the first location of the chip. The underlying | |
1153 | - * driver doesn't appear to support sending just the chip address | |
1154 | - * and looking for an <ACK> back. | |
1155 | - */ | |
1156 | - udelay(10000); | |
1157 | - return i2c_read (chip, 0, 1, (char *)&tmp, 1); | |
1158 | -} | |
1159 | - | |
1160 | -int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) | |
1161 | -{ | |
1162 | - I2CStatus status; | |
1163 | - uchar xaddr[4]; | |
1164 | - | |
1165 | - if (alen > 0) { | |
1166 | - xaddr[0] = (addr >> 24) & 0xFF; | |
1167 | - xaddr[1] = (addr >> 16) & 0xFF; | |
1168 | - xaddr[2] = (addr >> 8) & 0xFF; | |
1169 | - xaddr[3] = addr & 0xFF; | |
1170 | - | |
1171 | - status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen, | |
1172 | - &xaddr[4 - alen], I2C_NO_STOP, 1, | |
1173 | - I2C_NO_RESTART); | |
1174 | - if (status != I2C_SUCCESS) { | |
1175 | - PRINT ("i2c_read: can't send data address for read\n"); | |
1176 | - return 1; | |
1177 | - } | |
1178 | - } | |
1179 | - | |
1180 | - /* The data transfer will be a continuation. */ | |
1181 | - status = I2C_do_buffer (0, I2C_MASTER_RCV, chip, len, | |
1182 | - buffer, I2C_STOP, 1, (alen > 0 ? I2C_RESTART : | |
1183 | - I2C_NO_RESTART)); | |
1184 | - | |
1185 | - if (status != I2C_SUCCESS) { | |
1186 | - PRINT ("i2c_read: can't perform data transfer\n"); | |
1187 | - return 1; | |
1188 | - } | |
1189 | - | |
1190 | - return 0; | |
1191 | -} | |
1192 | - | |
1193 | -int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) | |
1194 | -{ | |
1195 | - I2CStatus status; | |
1196 | - uchar dummy_buffer[I2C_RXTX_LEN + 2]; | |
1197 | - uchar *p; | |
1198 | - int i; | |
1199 | - | |
1200 | - /* fill in address in big endian order */ | |
1201 | - for (i=alen-1; i>=0; --i) { | |
1202 | - buffer[i] = addr & 0xFF; | |
1203 | - addr >>= 8; | |
1204 | - } | |
1205 | - /* fill in data */ | |
1206 | - p = dummy_buffer + alen; | |
1207 | - | |
1208 | - for (i=0; i<len; ++i) | |
1209 | - *p++ = *buffer++; | |
1210 | - | |
1211 | - status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen + len, | |
1212 | - dummy_buffer, I2C_STOP, 1, I2C_NO_RESTART); | |
1213 | - | |
1214 | -#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS | |
1215 | - udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000); | |
1216 | -#endif | |
1217 | - if (status != I2C_SUCCESS) { | |
1218 | - PRINT ("i2c_write: can't perform data transfer\n"); | |
1219 | - return 1; | |
1220 | - } | |
1221 | - | |
1222 | - return 0; | |
1223 | -} | |
1224 | - | |
1225 | -uchar i2c_reg_read (uchar i2c_addr, uchar reg) | |
1226 | -{ | |
1227 | - char buf[1]; | |
1228 | - | |
1229 | - i2c_init (0, 0); | |
1230 | - | |
1231 | - i2c_read (i2c_addr, reg, 1, buf, 1); | |
1232 | - | |
1233 | - return (buf[0]); | |
1234 | -} | |
1235 | - | |
1236 | -void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val) | |
1237 | -{ | |
1238 | - i2c_init (0, 0); | |
1239 | - | |
1240 | - i2c_write (i2c_addr, reg, 1, &val, 1); | |
1241 | -} | |
1242 | - | |
1243 | -#endif /* CONFIG_HARD_I2C */ |
cpu/mpc824x/drivers/i2c/i2c2.S
1 | -/************************************** | |
2 | - * | |
3 | - * copyright @ Motorola, 1999 | |
4 | - * | |
5 | - **************************************/ | |
6 | - | |
7 | -#include <config.h> | |
8 | -#ifdef CONFIG_HARD_I2C | |
9 | -#include <ppc_asm.tmpl> | |
10 | -#include <asm/mmu.h> | |
11 | -/********************************************************** | |
12 | - * function: load_runtime_reg | |
13 | - * | |
14 | - * input: r3 - value of eumbbar | |
15 | - * r4 - register offset in embedded utility space | |
16 | - * | |
17 | - * output: r3 - register content | |
18 | - **********************************************************/ | |
19 | - .text | |
20 | - .align 2 | |
21 | - .global load_runtime_reg | |
22 | -load_runtime_reg: | |
23 | - | |
24 | -/* xor r5,r5,r5 | |
25 | - * or r5,r5,r3 | |
26 | - * | |
27 | - * lwbrx r3,r4,r5 | |
28 | - */ | |
29 | - lwbrx r3,r4,r3 | |
30 | - sync | |
31 | - | |
32 | - bclr 20, 0 | |
33 | - | |
34 | -/**************************************************************** | |
35 | - * function: store_runtime_reg | |
36 | - * | |
37 | - * input: r3 - value of eumbbar | |
38 | - * r4 - register offset in embedded utility space | |
39 | - * r5 - new value to be stored | |
40 | - * | |
41 | - ****************************************************************/ | |
42 | - .text | |
43 | - .align 2 | |
44 | - .global store_runtime_reg | |
45 | -store_runtime_reg: | |
46 | - | |
47 | - stwbrx r5, r4, r3 | |
48 | - sync | |
49 | - | |
50 | - bclr 20,0 | |
51 | - | |
52 | -#endif /* CONFIG_HARD_I2C */ |
cpu/mpc824x/drivers/i2c/i2c_export.h
1 | -#ifndef I2C_EXPORT_H | |
2 | -#define I2C_EXPORT_H | |
3 | - | |
4 | -/**************************************************** | |
5 | - * | |
6 | - * Copyright Motrola 1999 | |
7 | - * | |
8 | - ****************************************************/ | |
9 | - | |
10 | -/* These are the defined return values for the I2C_do_transaction function. | |
11 | - * Any non-zero value indicates failure. Failure modes can be added for | |
12 | - * more detailed error reporting. | |
13 | - */ | |
14 | -typedef enum _i2c_status | |
15 | -{ | |
16 | - I2C_SUCCESS = 0, | |
17 | - I2C_ERROR, | |
18 | -} I2C_Status; | |
19 | - | |
20 | -/* These are the defined tasks for I2C_do_transaction. | |
21 | - * Modes for SLAVE_RCV and SLAVE_XMIT will be added. | |
22 | - */ | |
23 | -typedef enum _i2c_transaction_mode | |
24 | -{ | |
25 | - I2C_MASTER_RCV = 0, | |
26 | - I2C_MASTER_XMIT = 1, | |
27 | -} I2C_TRANSACTION_MODE; | |
28 | - | |
29 | -typedef enum _i2c_interrupt_mode | |
30 | -{ | |
31 | - I2C_INT_DISABLE = 0, | |
32 | - I2C_INT_ENABLE = 1, | |
33 | -} I2C_INTERRUPT_MODE; | |
34 | - | |
35 | -typedef enum _i2c_stop | |
36 | -{ | |
37 | - I2C_NO_STOP = 0, | |
38 | - I2C_STOP = 1, | |
39 | -} I2C_STOP_MODE; | |
40 | - | |
41 | -typedef enum _i2c_restart | |
42 | -{ | |
43 | - I2C_NO_RESTART = 0, | |
44 | - I2C_RESTART = 1, | |
45 | -} I2C_RESTART_MODE; | |
46 | - | |
47 | -/******************** App. API ******************** | |
48 | - * The application API is for user level application | |
49 | - * to use the functionality provided by I2C driver. | |
50 | - * This is a "generic" I2C interface, it should contain | |
51 | - * nothing specific to the Kahlua implementation. | |
52 | - * Only the generic functions are exported by the library. | |
53 | - * | |
54 | - * Note: Its App.s responsibility to swap the data | |
55 | - * byte. In our API, we just transfer whatever | |
56 | - * we are given | |
57 | - **************************************************/ | |
58 | - | |
59 | - | |
60 | -/* Initialize I2C unit with the following: | |
61 | - * driver's slave address | |
62 | - * interrupt enabled | |
63 | - * optional pointer to application layer print function | |
64 | - * | |
65 | - * These parameters may be added: | |
66 | - * desired clock rate | |
67 | - * digital filter frequency sampling rate | |
68 | - * | |
69 | - * This function must be called before I2C unit can be used. | |
70 | - */ | |
71 | -extern I2C_Status I2C_Initialize( | |
72 | - unsigned char addr, /* driver's I2C slave address */ | |
73 | - I2C_INTERRUPT_MODE en_int, /* 1 - enable I2C interrupt | |
74 | - * 0 - disable I2C interrupt | |
75 | - */ | |
76 | - int (*app_print_function)(char *,...)); /* pointer to optional "printf" | |
77 | - * provided by application | |
78 | - */ | |
79 | - | |
80 | -/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV | |
81 | - * are implemented. Both are only in polling mode. | |
82 | - * | |
83 | - * en_int controls interrupt/polling mode | |
84 | - * act is the type of transaction | |
85 | - * addr is the I2C address of the slave device | |
86 | - * len is the length of data to send or receive | |
87 | - * buffer is the address of the data buffer | |
88 | - * stop = I2C_NO_STOP, don't signal STOP at end of transaction | |
89 | - * I2C_STOP, signal STOP at end of transaction | |
90 | - * retry is the timeout retry value, currently ignored | |
91 | - * rsta = I2C_NO_RESTART, this is not continuation of existing transaction | |
92 | - * I2C_RESTART, this is a continuation of existing transaction | |
93 | - */ | |
94 | -extern I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int, | |
95 | - I2C_TRANSACTION_MODE act, | |
96 | - unsigned char i2c_addr, | |
97 | - unsigned char data_addr, | |
98 | - int len, | |
99 | - char *buffer, | |
100 | - I2C_STOP_MODE stop, | |
101 | - int retry, | |
102 | - I2C_RESTART_MODE rsta); | |
103 | -#endif |
cpu/mpc824x/start.S
... | ... | @@ -526,11 +526,26 @@ |
526 | 526 | stwu r0,-4(r7) |
527 | 527 | bdnz 3b |
528 | 528 | |
529 | +4: | |
530 | +#if !defined(CONFIG_BMW) | |
531 | +/* Unlock the data cache and invalidate locked area */ | |
532 | + xor r0, r0, r0 | |
533 | + mtspr 1011, r0 | |
534 | + lis r4, CFG_INIT_RAM_ADDR@h | |
535 | + ori r4, r4, CFG_INIT_RAM_ADDR@l | |
536 | + li r0, 128 | |
537 | + mtctr r0 | |
538 | +41: | |
539 | + dcbi r0, r4 | |
540 | + addi r4, r4, 32 | |
541 | + bdnz 41b | |
542 | +#endif | |
543 | + | |
529 | 544 | /* |
530 | 545 | * Now flush the cache: note that we must start from a cache aligned |
531 | 546 | * address. Otherwise we might miss one cache line. |
532 | 547 | */ |
533 | -4: cmpwi r6,0 | |
548 | + cmpwi r6,0 | |
534 | 549 | add r5,r3,r5 |
535 | 550 | beq 7f /* Always flush prefetch queue in any case */ |
536 | 551 | subi r0,r6,1 |
cpu/pxa/mmc.c
... | ... | @@ -26,12 +26,20 @@ |
26 | 26 | #include <mmc.h> |
27 | 27 | #include <asm/errno.h> |
28 | 28 | #include <asm/arch/hardware.h> |
29 | +#include <part.h> | |
29 | 30 | |
30 | 31 | #ifdef CONFIG_MMC |
31 | 32 | |
32 | 33 | extern int |
33 | -fat_register_read(int(*block_read)(int device, ulong blknr, ulong blkcnt, uchar *buffer)); | |
34 | +fat_register_device(block_dev_desc_t *dev_desc, int part_no); | |
34 | 35 | |
36 | +static block_dev_desc_t mmc_dev; | |
37 | + | |
38 | +block_dev_desc_t * mmc_get_dev(int dev) | |
39 | +{ | |
40 | + return ((block_dev_desc_t *)&mmc_dev); | |
41 | +} | |
42 | + | |
35 | 43 | /* |
36 | 44 | * FIXME needs to read cid and csd info to determine block size |
37 | 45 | * and other parameters |
38 | 46 | |
... | ... | @@ -379,9 +387,9 @@ |
379 | 387 | return 0; |
380 | 388 | } |
381 | 389 | |
382 | -int | |
390 | +ulong | |
383 | 391 | /****************************************************/ |
384 | -mmc_bread(int dev_num, ulong blknr, ulong blkcnt, uchar *dst) | |
392 | +mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst) | |
385 | 393 | /****************************************************/ |
386 | 394 | { |
387 | 395 | int mmc_block_size = MMC_BLOCK_SIZE; |
... | ... | @@ -441,6 +449,21 @@ |
441 | 449 | printf("Month = %d\n",cid->month); |
442 | 450 | printf("Year = %d\n",1997 + cid->year); |
443 | 451 | } |
452 | + /* fill in device description */ | |
453 | + mmc_dev.if_type = IF_TYPE_MMC; | |
454 | + mmc_dev.dev = 0; | |
455 | + mmc_dev.lun = 0; | |
456 | + mmc_dev.type = 0; | |
457 | + /* FIXME fill in the correct size (is set to 32MByte) */ | |
458 | + mmc_dev.blksz = 512; | |
459 | + mmc_dev.lba = 0x10000; | |
460 | + sprintf(mmc_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x", | |
461 | + cid->id[0], cid->id[1], cid->id[2], | |
462 | + cid->sn[0], cid->sn[1], cid->sn[2]); | |
463 | + sprintf(mmc_dev.product,"%s",cid->name); | |
464 | + sprintf(mmc_dev.revision,"%x %x",cid->hwrev, cid->fwrev); | |
465 | + mmc_dev.removable = 0; | |
466 | + mmc_dev.block_read = mmc_bread; | |
444 | 467 | |
445 | 468 | /* MMC exists, get CSD too */ |
446 | 469 | resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1); |
... | ... | @@ -458,7 +481,7 @@ |
458 | 481 | MMC_CLKRT = 0; /* 20 MHz */ |
459 | 482 | resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1); |
460 | 483 | |
461 | - fat_register_read(mmc_bread); | |
484 | + fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */ | |
462 | 485 | |
463 | 486 | return rc; |
464 | 487 | } |
disk/part_dos.c
... | ... | @@ -67,7 +67,18 @@ |
67 | 67 | (is_extended (p->sys_ind) ? " Extd" : "")); |
68 | 68 | } |
69 | 69 | |
70 | +static int test_block_type(unsigned char *buffer) | |
71 | +{ | |
72 | + if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) || | |
73 | + (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) { | |
74 | + return (-1); | |
75 | + } /* no DOS Signature at all */ | |
76 | + if(strncmp(&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0) | |
77 | + return DOS_PBR; /* is PBR */ | |
78 | + return DOS_MBR; /* Is MBR */ | |
79 | +} | |
70 | 80 | |
81 | + | |
71 | 82 | int test_part_dos (block_dev_desc_t *dev_desc) |
72 | 83 | { |
73 | 84 | unsigned char buffer[DEFAULT_SECTOR_SIZE]; |
74 | 85 | |
... | ... | @@ -94,14 +105,18 @@ |
94 | 105 | dev_desc->dev, ext_part_sector); |
95 | 106 | return; |
96 | 107 | } |
97 | - if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || | |
98 | - buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { | |
108 | + i=test_block_type(buffer); | |
109 | + if(i==-1) { | |
99 | 110 | printf ("bad MBR sector signature 0x%02x%02x\n", |
100 | 111 | buffer[DOS_PART_MAGIC_OFFSET], |
101 | 112 | buffer[DOS_PART_MAGIC_OFFSET + 1]); |
102 | 113 | return; |
103 | 114 | } |
104 | - | |
115 | + if(i==DOS_PBR) { | |
116 | + printf (" 1\t\t 0\t%10ld\t%2x\n", | |
117 | + dev_desc->lba, buffer[DOS_PBR_MEDIA_TYPE_OFFSET]); | |
118 | + return; | |
119 | + } | |
105 | 120 | /* Print all primary/logical partitions */ |
106 | 121 | pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); |
107 | 122 | for (i = 0; i < 4; i++, pt++) { |
disk/part_dos.h
... | ... | @@ -34,6 +34,10 @@ |
34 | 34 | #endif |
35 | 35 | #define DOS_PART_TBL_OFFSET 0x1be |
36 | 36 | #define DOS_PART_MAGIC_OFFSET 0x1fe |
37 | +#define DOS_PBR_FSTYPE_OFFSET 0x36 | |
38 | +#define DOS_PBR_MEDIA_TYPE_OFFSET 0x15 | |
39 | +#define DOS_MBR 0 | |
40 | +#define DOS_PBR 1 | |
37 | 41 | |
38 | 42 | typedef struct dos_partition { |
39 | 43 | unsigned char boot_ind; /* 0x80 - active */ |
fs/fat/fat.c
... | ... | @@ -29,6 +29,7 @@ |
29 | 29 | #include <config.h> |
30 | 30 | #include <fat.h> |
31 | 31 | #include <asm/byteorder.h> |
32 | +#include <part.h> | |
32 | 33 | |
33 | 34 | #if (CONFIG_COMMANDS & CFG_CMD_FAT) |
34 | 35 | |
35 | 36 | |
36 | 37 | |
37 | 38 | |
38 | 39 | |
... | ... | @@ -44,26 +45,70 @@ |
44 | 45 | } |
45 | 46 | } |
46 | 47 | |
47 | -int (*dev_block_read)(int device, __u32 blknr, __u32 blkcnt, __u8 *buffer) = 0; | |
48 | +static block_dev_desc_t *cur_dev = NULL; | |
49 | +static unsigned long part_offset = 0; | |
50 | +static int cur_part = 1; | |
48 | 51 | |
52 | +#define DOS_PART_TBL_OFFSET 0x1be | |
53 | +#define DOS_PART_MAGIC_OFFSET 0x1fe | |
54 | +#define DOS_FS_TYPE_OFFSET 0x36 | |
55 | + | |
49 | 56 | int disk_read (__u32 startblock, __u32 getsize, __u8 * bufptr) |
50 | 57 | { |
51 | - /* FIXME we need to determine the start block of the | |
52 | - * partition where the DOS FS resides | |
53 | - */ | |
54 | - startblock += 32; | |
55 | - | |
56 | - if (dev_block_read) { | |
57 | - return dev_block_read (0, startblock, getsize, bufptr); | |
58 | + startblock += part_offset; | |
59 | + if (cur_dev == NULL) | |
60 | + return -1; | |
61 | + if (cur_dev->block_read) { | |
62 | + return cur_dev->block_read (cur_dev->dev, startblock, getsize, (unsigned long *)bufptr); | |
58 | 63 | } |
59 | 64 | return -1; |
60 | 65 | } |
61 | 66 | |
62 | 67 | |
63 | 68 | int |
64 | -fat_register_read (int (*block_read)(int, __u32, __u32, __u8 *)) | |
69 | +fat_register_device(block_dev_desc_t *dev_desc, int part_no) | |
65 | 70 | { |
66 | - dev_block_read = block_read; | |
71 | + unsigned char buffer[SECTOR_SIZE]; | |
72 | + | |
73 | + if (!dev_desc->block_read) | |
74 | + return -1; | |
75 | + cur_dev=dev_desc; | |
76 | + /* check if we have a MBR (on floppies we have only a PBR) */ | |
77 | + if (dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { | |
78 | + printf ("** Can't read from device %d **\n", dev_desc->dev); | |
79 | + return -1; | |
80 | + } | |
81 | + if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || | |
82 | + buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { | |
83 | + /* no signature found */ | |
84 | + return -1; | |
85 | + } | |
86 | + if(!strncmp(&buffer[DOS_FS_TYPE_OFFSET],"FAT",3)) { | |
87 | + /* ok, we assume we are on a PBR only */ | |
88 | + cur_part = 1; | |
89 | + part_offset=0; | |
90 | + } | |
91 | + else { | |
92 | +#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) | |
93 | + disk_partition_t info; | |
94 | + if(!get_partition_info(dev_desc, part_no, &info)) { | |
95 | + part_offset = info.start; | |
96 | + cur_part = part_no; | |
97 | + } | |
98 | + else { | |
99 | + printf ("** Partition %d not valid on device %d **\n",part_no,dev_desc->dev); | |
100 | + return -1; | |
101 | + } | |
102 | +#else | |
103 | + /* FIXME we need to determine the start block of the | |
104 | + * partition where the DOS FS resides. This can be done | |
105 | + * by using the get_partition_info routine. For this | |
106 | + * purpose the libpart must be included. | |
107 | + */ | |
108 | + part_offset=32; | |
109 | + cur_part = 1; | |
110 | +#endif | |
111 | + } | |
67 | 112 | return 0; |
68 | 113 | } |
69 | 114 | |
70 | 115 | |
... | ... | @@ -246,25 +291,21 @@ |
246 | 291 | } |
247 | 292 | |
248 | 293 | FAT_DPRINT("gc - clustnum: %d, startsect: %d\n", clustnum, startsect); |
249 | - while (size > 0) { | |
250 | - if (size >= FS_BLOCK_SIZE) { | |
251 | - if (disk_read(startsect + idx, 1, buffer) < 0) { | |
252 | - FAT_DPRINT("Error reading data\n"); | |
253 | - return -1; | |
254 | - } | |
255 | - } else { | |
256 | - __u8 tmpbuf[FS_BLOCK_SIZE]; | |
257 | - if (disk_read(startsect + idx, 1, tmpbuf) < 0) { | |
258 | - FAT_DPRINT("Error reading data\n"); | |
259 | - return -1; | |
260 | - } | |
261 | - memcpy(buffer, tmpbuf, size); | |
262 | - | |
263 | - return 0; | |
294 | + if (disk_read(startsect, size/FS_BLOCK_SIZE , buffer) < 0) { | |
295 | + FAT_DPRINT("Error reading data\n"); | |
296 | + return -1; | |
297 | + } | |
298 | + if(size % FS_BLOCK_SIZE) { | |
299 | + __u8 tmpbuf[FS_BLOCK_SIZE]; | |
300 | + idx= size/FS_BLOCK_SIZE; | |
301 | + if (disk_read(startsect + idx, 1, tmpbuf) < 0) { | |
302 | + FAT_DPRINT("Error reading data\n"); | |
303 | + return -1; | |
264 | 304 | } |
265 | - buffer += FS_BLOCK_SIZE; | |
266 | - size -= FS_BLOCK_SIZE; | |
267 | - idx++; | |
305 | + buffer += idx*FS_BLOCK_SIZE; | |
306 | + | |
307 | + memcpy(buffer, tmpbuf, size % FS_BLOCK_SIZE); | |
308 | + return 0; | |
268 | 309 | } |
269 | 310 | |
270 | 311 | return 0; |
... | ... | @@ -283,6 +324,8 @@ |
283 | 324 | unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0; |
284 | 325 | unsigned int bytesperclust = mydata->clust_size * SECTOR_SIZE; |
285 | 326 | __u32 curclust = START(dentptr); |
327 | + __u32 endclust, newclust; | |
328 | + unsigned long actsize; | |
286 | 329 | |
287 | 330 | FAT_DPRINT("Filesize: %ld bytes\n", filesize); |
288 | 331 | |
289 | 332 | |
290 | 333 | |
291 | 334 | |
... | ... | @@ -290,25 +333,56 @@ |
290 | 333 | |
291 | 334 | FAT_DPRINT("Reading: %ld bytes\n", filesize); |
292 | 335 | |
336 | + actsize=bytesperclust; | |
337 | + endclust=curclust; | |
293 | 338 | do { |
294 | - int getsize = (filesize > bytesperclust) ? bytesperclust : | |
295 | - filesize; | |
296 | - | |
297 | - if (get_cluster(mydata, curclust, buffer, getsize) != 0) { | |
339 | + /* search for consecutive clusters */ | |
340 | + while(actsize < filesize) { | |
341 | + newclust = get_fatent(mydata, endclust); | |
342 | + if((newclust -1)!=endclust) | |
343 | + goto getit; | |
344 | + if (newclust <= 0x0001 || newclust >= 0xfff0) { | |
345 | + FAT_DPRINT("curclust: 0x%x\n", newclust); | |
346 | + FAT_DPRINT("Invalid FAT entry\n"); | |
347 | + return gotsize; | |
348 | + } | |
349 | + endclust=newclust; | |
350 | + actsize+= bytesperclust; | |
351 | + } | |
352 | + /* actsize >= file size */ | |
353 | + actsize -= bytesperclust; | |
354 | + /* get remaining clusters */ | |
355 | + if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { | |
298 | 356 | FAT_ERROR("Error reading cluster\n"); |
299 | 357 | return -1; |
300 | 358 | } |
301 | - gotsize += getsize; | |
302 | - filesize -= getsize; | |
303 | - if (filesize <= 0) return gotsize; | |
304 | - buffer += getsize; | |
305 | - | |
306 | - curclust = get_fatent(mydata, curclust); | |
359 | + /* get remaining bytes */ | |
360 | + gotsize += (int)actsize; | |
361 | + filesize -= actsize; | |
362 | + buffer += actsize; | |
363 | + actsize= filesize; | |
364 | + if (get_cluster(mydata, endclust, buffer, (int)actsize) != 0) { | |
365 | + FAT_ERROR("Error reading cluster\n"); | |
366 | + return -1; | |
367 | + } | |
368 | + gotsize+=actsize; | |
369 | + return gotsize; | |
370 | +getit: | |
371 | + if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { | |
372 | + FAT_ERROR("Error reading cluster\n"); | |
373 | + return -1; | |
374 | + } | |
375 | + gotsize += (int)actsize; | |
376 | + filesize -= actsize; | |
377 | + buffer += actsize; | |
378 | + curclust = get_fatent(mydata, endclust); | |
307 | 379 | if (curclust <= 0x0001 || curclust >= 0xfff0) { |
308 | 380 | FAT_DPRINT("curclust: 0x%x\n", curclust); |
309 | 381 | FAT_ERROR("Invalid FAT entry\n"); |
310 | 382 | return gotsize; |
311 | 383 | } |
384 | + actsize=bytesperclust; | |
385 | + endclust=curclust; | |
312 | 386 | } while (1); |
313 | 387 | } |
314 | 388 | |
... | ... | @@ -641,7 +715,7 @@ |
641 | 715 | do_fat_read (const char *filename, void *buffer, unsigned long maxsize, |
642 | 716 | int dols) |
643 | 717 | { |
644 | - __u8 block[FS_BLOCK_SIZE]; /* Block buffer */ | |
718 | + __u8 block[MAX_CLUSTSIZE]; /* Block buffer */ | |
645 | 719 | char fnamecopy[2048]; |
646 | 720 | boot_sector bs; |
647 | 721 | volume_info volinfo; |
... | ... | @@ -713,7 +787,7 @@ |
713 | 787 | while (1) { |
714 | 788 | int i; |
715 | 789 | |
716 | - if (disk_read (cursect, 1, block) < 0) { | |
790 | + if (disk_read (cursect, mydata->clust_size, block) < 0) { | |
717 | 791 | FAT_DPRINT ("Error: reading rootdir block\n"); |
718 | 792 | return -1; |
719 | 793 | } |
720 | 794 | |
... | ... | @@ -880,8 +954,35 @@ |
880 | 954 | boot_sector bs; |
881 | 955 | volume_info volinfo; |
882 | 956 | int fatsize; |
957 | + char vol_label[12]; | |
883 | 958 | |
884 | - return read_bootsectandvi(&bs, &volinfo, &fatsize); | |
959 | + if(cur_dev==NULL) { | |
960 | + printf("No current device\n"); | |
961 | + return 1; | |
962 | + } | |
963 | +#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) | |
964 | + printf("Interface: "); | |
965 | + switch(cur_dev->if_type) { | |
966 | + case IF_TYPE_IDE : printf("IDE"); break; | |
967 | + case IF_TYPE_SCSI : printf("SCSI"); break; | |
968 | + case IF_TYPE_ATAPI : printf("ATAPI"); break; | |
969 | + case IF_TYPE_USB : printf("USB"); break; | |
970 | + case IF_TYPE_DOC : printf("DOC"); break; | |
971 | + case IF_TYPE_MMC : printf("MMC"); break; | |
972 | + default : printf("Unknown"); | |
973 | + } | |
974 | + printf("\n Device %d: ",cur_dev->dev); | |
975 | + dev_print(cur_dev); | |
976 | +#endif | |
977 | + if(read_bootsectandvi(&bs, &volinfo, &fatsize)) { | |
978 | + printf("\nNo valid FAT fs found\n"); | |
979 | + return 1; | |
980 | + } | |
981 | + memcpy (vol_label, volinfo.volume_label, 11); | |
982 | + vol_label[11] = '\0'; | |
983 | + volinfo.fs_type[5]='\0'; | |
984 | + printf("Partition %d: Filesystem: %s \"%s\"\n",cur_part,volinfo.fs_type,vol_label); | |
985 | + return 0; | |
885 | 986 | } |
886 | 987 | |
887 | 988 | |
... | ... | @@ -895,6 +996,7 @@ |
895 | 996 | long |
896 | 997 | file_fat_read(const char *filename, void *buffer, unsigned long maxsize) |
897 | 998 | { |
999 | + printf("reading %s\n",filename); | |
898 | 1000 | return do_fat_read(filename, buffer, maxsize, LS_NO); |
899 | 1001 | } |
900 | 1002 |
fs/jffs2/jffs2_1pass.c
1 | -/* vi: set sw=4 ts=4: */ | |
2 | 1 | /* |
3 | 2 | ------------------------------------------------------------------------- |
4 | 3 | * Filename: jffs2.c |
5 | 4 | |
6 | 5 | |
7 | 6 | |
8 | 7 | |
... | ... | @@ -265,20 +264,56 @@ |
265 | 264 | } |
266 | 265 | |
267 | 266 | #ifdef CFG_JFFS2_SORT_FRAGMENTS |
267 | +/* Sort data entries with the latest version last, so that if there | |
268 | + * is overlapping data the latest version will be used. | |
269 | + */ | |
268 | 270 | static int compare_inodes(struct b_node *new, struct b_node *old) |
269 | 271 | { |
270 | 272 | struct jffs2_raw_inode *jNew = (struct jffs2_raw_inode *)new->offset; |
271 | 273 | struct jffs2_raw_inode *jOld = (struct jffs2_raw_inode *)old->offset; |
272 | 274 | |
273 | - return jNew->version < jOld->version; | |
275 | + return jNew->version > jOld->version; | |
274 | 276 | } |
275 | 277 | |
278 | +/* Sort directory entries so all entries in the same directory | |
279 | + * with the same name are grouped together, with the latest version | |
280 | + * last. This makes it easy to eliminate all but the latest version | |
281 | + * by marking the previous version dead by setting the inode to 0. | |
282 | + */ | |
276 | 283 | static int compare_dirents(struct b_node *new, struct b_node *old) |
277 | 284 | { |
278 | 285 | struct jffs2_raw_dirent *jNew = (struct jffs2_raw_dirent *)new->offset; |
279 | 286 | struct jffs2_raw_dirent *jOld = (struct jffs2_raw_dirent *)old->offset; |
287 | + int cmp; | |
280 | 288 | |
281 | - return jNew->version > jOld->version; | |
289 | + /* ascending sort by pino */ | |
290 | + if (jNew->pino != jOld->pino) | |
291 | + return jNew->pino > jOld->pino; | |
292 | + | |
293 | + /* pino is the same, so use ascending sort by nsize, so | |
294 | + * we don't do strncmp unless we really must. | |
295 | + */ | |
296 | + if (jNew->nsize != jOld->nsize) | |
297 | + return jNew->nsize > jOld->nsize; | |
298 | + | |
299 | + /* length is also the same, so use ascending sort by name | |
300 | + */ | |
301 | + cmp = strncmp(jNew->name, jOld->name, jNew->nsize); | |
302 | + if (cmp != 0) | |
303 | + return cmp > 0; | |
304 | + | |
305 | + /* we have duplicate names in this directory, so use ascending | |
306 | + * sort by version | |
307 | + */ | |
308 | + if (jNew->version > jOld->version) { | |
309 | + /* since jNew is newer, we know jOld is not valid, so | |
310 | + * mark it with inode 0 and it will not be used | |
311 | + */ | |
312 | + jOld->ino = 0; | |
313 | + return 1; | |
314 | + } | |
315 | + | |
316 | + return 0; | |
282 | 317 | } |
283 | 318 | #endif |
284 | 319 | |
285 | 320 | |
... | ... | @@ -327,12 +362,31 @@ |
327 | 362 | struct b_node *b; |
328 | 363 | struct jffs2_raw_inode *jNode; |
329 | 364 | u32 totalSize = 0; |
330 | - u16 latestVersion = 0; | |
365 | + u32 latestVersion = 0; | |
331 | 366 | char *lDest; |
332 | 367 | char *src; |
333 | 368 | long ret; |
334 | 369 | int i; |
335 | 370 | u32 counter = 0; |
371 | +#ifdef CFG_JFFS2_SORT_FRAGMENTS | |
372 | + /* Find file size before loading any data, so fragments that | |
373 | + * start past the end of file can be ignored. A fragment | |
374 | + * that is partially in the file is loaded, so extra data may | |
375 | + * be loaded up to the next 4K boundary above the file size. | |
376 | + * This shouldn't cause trouble when loading kernel images, so | |
377 | + * we will live with it. | |
378 | + */ | |
379 | + for (b = pL->frag.listHead; b != NULL; b = b->next) { | |
380 | + jNode = (struct jffs2_raw_inode *) (b->offset); | |
381 | + if ((inode == jNode->ino)) { | |
382 | + /* get actual file length from the newest node */ | |
383 | + if (jNode->version >= latestVersion) { | |
384 | + totalSize = jNode->isize; | |
385 | + latestVersion = jNode->version; | |
386 | + } | |
387 | + } | |
388 | + } | |
389 | +#endif | |
336 | 390 | |
337 | 391 | for (b = pL->frag.listHead; b != NULL; b = b->next) { |
338 | 392 | jNode = (struct jffs2_raw_inode *) (b->offset); |
339 | 393 | |
... | ... | @@ -349,11 +403,14 @@ |
349 | 403 | putLabeledWord("read_inode: usercompr = ", jNode->usercompr); |
350 | 404 | putLabeledWord("read_inode: flags = ", jNode->flags); |
351 | 405 | #endif |
406 | + | |
407 | +#ifndef CFG_JFFS2_SORT_FRAGMENTS | |
352 | 408 | /* get actual file length from the newest node */ |
353 | 409 | if (jNode->version >= latestVersion) { |
354 | 410 | totalSize = jNode->isize; |
355 | 411 | latestVersion = jNode->version; |
356 | 412 | } |
413 | +#endif | |
357 | 414 | |
358 | 415 | if(dest) { |
359 | 416 | src = ((char *) jNode) + sizeof(struct jffs2_raw_inode); |
360 | 417 | |
... | ... | @@ -430,15 +487,11 @@ |
430 | 487 | if ((pino == jDir->pino) && (len == jDir->nsize) && |
431 | 488 | (jDir->ino) && /* 0 for unlink */ |
432 | 489 | (!strncmp(jDir->name, name, len))) { /* a match */ |
433 | - if (jDir->version < version) continue; | |
490 | + if (jDir->version < version) | |
491 | + continue; | |
434 | 492 | |
435 | - if(jDir->version == 0) { | |
436 | - /* Is this legal? */ | |
437 | - putstr(" ** WARNING ** "); | |
438 | - putnstr(jDir->name, jDir->nsize); | |
439 | - putstr(" is version 0 (in find, ignoring)\r\n"); | |
440 | - } else if(jDir->version == version) { | |
441 | - /* Im pretty sure this isn't ... */ | |
493 | + if (jDir->version == version && inode != 0) { | |
494 | + /* I'm pretty sure this isn't legal */ | |
442 | 495 | putstr(" ** ERROR ** "); |
443 | 496 | putnstr(jDir->name, jDir->nsize); |
444 | 497 | putLabeledWord(" has dup version =", version); |
445 | 498 | |
... | ... | @@ -643,15 +696,11 @@ |
643 | 696 | for(b = pL->dir.listHead; b; b = b->next) { |
644 | 697 | jDir = (struct jffs2_raw_dirent *) (b->offset); |
645 | 698 | if (ino == jDir->ino) { |
646 | - if(jDir->version < version) continue; | |
699 | + if (jDir->version < version) | |
700 | + continue; | |
647 | 701 | |
648 | - if(jDir->version == 0) { | |
649 | - /* Is this legal? */ | |
650 | - putstr(" ** WARNING ** "); | |
651 | - putnstr(jDir->name, jDir->nsize); | |
652 | - putstr(" is version 0 (in resolve, ignoring)\r\n"); | |
653 | - } else if(jDir->version == version) { | |
654 | - /* Im pretty sure this isn't ... */ | |
702 | + if (jDir->version == version && jDirFound) { | |
703 | + /* I'm pretty sure this isn't legal */ | |
655 | 704 | putstr(" ** ERROR ** "); |
656 | 705 | putnstr(jDir->name, jDir->nsize); |
657 | 706 | putLabeledWord(" has dup version (resolve) = ", |
... | ... | @@ -890,6 +939,11 @@ |
890 | 939 | if (node->totlen != sizeof(struct jffs2_unknown_node)) |
891 | 940 | printf("OOPS Cleanmarker has bad size " |
892 | 941 | "%d != %d\n", node->totlen, |
942 | + sizeof(struct jffs2_unknown_node)); | |
943 | + } else if (node->nodetype == JFFS2_NODETYPE_PADDING) { | |
944 | + if (node->totlen < sizeof(struct jffs2_unknown_node)) | |
945 | + printf("OOPS Padding has bad size " | |
946 | + "%d < %d\n", node->totlen, | |
893 | 947 | sizeof(struct jffs2_unknown_node)); |
894 | 948 | } else { |
895 | 949 | printf("Unknown node type: %x len %d " |
include/configs/AdderII.h
... | ... | @@ -48,10 +48,10 @@ |
48 | 48 | #define CONFIG_CLOCKS_IN_MHZ 1 |
49 | 49 | |
50 | 50 | /* Monitor Functions */ |
51 | -#define CONFIG_COMMANDS ( CFG_CMD_FLASH | \ | |
51 | +#define CONFIG_COMMANDS ( CFG_CMD_ENV | \ | |
52 | + CFG_CMD_FLASH | \ | |
52 | 53 | CFG_CMD_MEMORY| \ |
53 | 54 | CFG_CMD_NET | \ |
54 | - CFG_CMD_ENV | \ | |
55 | 55 | CFG_CMD_PING | \ |
56 | 56 | CFG_CMD_SDRAM ) |
57 | 57 |
include/configs/MIP405.h
... | ... | @@ -67,6 +67,7 @@ |
67 | 67 | CFG_CMD_DATE | \ |
68 | 68 | CFG_CMD_ELF | \ |
69 | 69 | CFG_CMD_MII | \ |
70 | + CFG_CMD_FAT | \ | |
70 | 71 | CFG_CMD_PING | \ |
71 | 72 | CFG_CMD_SAVES | \ |
72 | 73 | CFG_CMD_BSP ) |
73 | 74 | |
... | ... | @@ -246,10 +247,11 @@ |
246 | 247 | /* |
247 | 248 | * Init Memory Controller: |
248 | 249 | */ |
250 | +#define FLASH_MAX_SIZE 0x00800000 /* 8MByte max */ | |
251 | +#define FLASH_BASE_PRELIM 0xFF800000 /* open the flash CS */ | |
252 | +/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ | |
253 | +#define FLASH_SIZE_PRELIM 3 /* maximal flash FLASH size bank #0 */ | |
249 | 254 | |
250 | -#define FLASH_BASE0_PRELIM 0xFFC00000 /* FLASH bank #0 */ | |
251 | -#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */ | |
252 | - | |
253 | 255 | #define CONFIG_BOARD_PRE_INIT |
254 | 256 | |
255 | 257 | /* Peripheral Bus Mapping */ |
... | ... | @@ -325,7 +327,7 @@ |
325 | 327 | #undef CONFIG_IDE_LED /* no led for ide supported */ |
326 | 328 | #define CONFIG_IDE_RESET /* reset for ide supported... */ |
327 | 329 | #define CONFIG_IDE_RESET_ROUTINE /* with a special reset function */ |
328 | - | |
330 | +#define CONFIG_SUPPORT_VFAT | |
329 | 331 | /************************************************************ |
330 | 332 | * ATAPI support (experimental) |
331 | 333 | ************************************************************/ |
include/configs/PIP405.h
... | ... | @@ -50,11 +50,13 @@ |
50 | 50 | CFG_CMD_PCI | \ |
51 | 51 | CFG_CMD_CACHE | \ |
52 | 52 | CFG_CMD_IRQ | \ |
53 | + CFG_CMD_ECHO | \ | |
53 | 54 | CFG_CMD_EEPROM | \ |
54 | 55 | CFG_CMD_I2C | \ |
55 | 56 | CFG_CMD_REGINFO | \ |
56 | 57 | CFG_CMD_FDC | \ |
57 | 58 | CFG_CMD_SCSI | \ |
59 | + CFG_CMD_FAT | \ | |
58 | 60 | CFG_CMD_DATE | \ |
59 | 61 | CFG_CMD_ELF | \ |
60 | 62 | CFG_CMD_USB | \ |
... | ... | @@ -141,7 +143,7 @@ |
141 | 143 | #define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ |
142 | 144 | #define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ |
143 | 145 | |
144 | - | |
146 | +#define CONFIG_MISC_INIT_R | |
145 | 147 | /*********************************************************** |
146 | 148 | * Miscellaneous configurable options |
147 | 149 | **********************************************************/ |
148 | 150 | |
... | ... | @@ -231,9 +233,12 @@ |
231 | 233 | /* |
232 | 234 | * Init Memory Controller: |
233 | 235 | */ |
236 | +#define FLASH_MAX_SIZE 0x00800000 /* 8MByte max */ | |
237 | +#define FLASH_BASE_PRELIM 0xFF800000 /* open the flash CS */ | |
238 | +/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ | |
239 | +#define FLASH_SIZE_PRELIM 3 /* maximal flash FLASH size bank #0 */ | |
234 | 240 | |
235 | -#define FLASH_BASE0_PRELIM 0xFFC00000 /* FLASH bank #0 */ | |
236 | -#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */ | |
241 | +#define CONFIG_BOARD_PRE_INIT | |
237 | 242 | |
238 | 243 | /* Configuration Port location */ |
239 | 244 | #define CONFIG_PORT_ADDR 0xF4000000 |
... | ... | @@ -299,6 +304,7 @@ |
299 | 304 | #undef CONFIG_IDE_LED /* no led for ide supported */ |
300 | 305 | #define CONFIG_IDE_RESET /* reset for ide supported... */ |
301 | 306 | #define CONFIG_IDE_RESET_ROUTINE /* with a special reset function */ |
307 | +#define CONFIG_SUPPORT_VFAT | |
302 | 308 | |
303 | 309 | /************************************************************ |
304 | 310 | * ATAPI support (experimental) |
include/configs/SXNI855T.h
... | ... | @@ -145,12 +145,22 @@ |
145 | 145 | |
146 | 146 | #define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ |
147 | 147 | CFG_CMD_EEPROM | \ |
148 | + CFG_CMD_JFFS2 | \ | |
148 | 149 | CFG_CMD_NAND | \ |
149 | 150 | CFG_CMD_DATE) |
150 | 151 | |
151 | 152 | /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ |
152 | 153 | #include <cmd_confdefs.h> |
153 | 154 | |
155 | +#define CFG_JFFS_CUSTOM_PART | |
156 | +#define CFG_JFFS2_SORT_FRAGMENTS | |
157 | +/* JFFS2 location when using NOR flash */ | |
158 | +#define CFG_JFFS2_BASE (CFG_FLASH_BASE + 0x80000) | |
159 | +#define CFG_JFFS2_SIZE (0x780000) | |
160 | +/* JFFS2 location (in RAM) when using NAND flash */ | |
161 | +#define CFG_JFFS2_RAMBASE 0x400000 | |
162 | +#define CFG_JFFS2_RAMSIZE 0x200000 /* NAND boot partition is 2MiB */ | |
163 | + | |
154 | 164 | /* NAND flash support */ |
155 | 165 | #define CONFIG_MTD_NAND_ECC_JFFS2 |
156 | 166 | #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ |
... | ... | @@ -405,13 +415,18 @@ |
405 | 415 | |
406 | 416 | #define CONFIG_RESET_ON_PANIC /* reset if system panic() */ |
407 | 417 | |
408 | -/* to put environment in EEROM */ | |
409 | -#define CFG_ENV_IS_IN_EEPROM 1 | |
410 | -#define CFG_ENV_OFFSET 0 /* Start right at beginning of NVRAM */ | |
411 | -#define CFG_ENV_SIZE 1024 /* Use only a part of it*/ | |
412 | - | |
413 | -#if 1 | |
414 | -#define CONFIG_BOOT_RETRY_TIME 60 /* boot if no command in 60 seconds */ | |
418 | +#define CFG_ENV_IS_IN_FLASH | |
419 | +#ifdef CFG_ENV_IS_IN_FLASH | |
420 | + /* environment is in FLASH */ | |
421 | + #define CFG_ENV_ADDR 0xF8040000 /* AM29LV641 or AM29LV800BT */ | |
422 | + #define CFG_ENV_ADDR_REDUND 0xF8050000 /* AM29LV641 or AM29LV800BT */ | |
423 | + #define CFG_ENV_SECT_SIZE 0x00010000 | |
424 | + #define CFG_ENV_SIZE 0x00002000 | |
425 | +#else | |
426 | + /* environment is in EEPROM */ | |
427 | + #define CFG_ENV_IS_IN_EEPROM 1 | |
428 | + #define CFG_ENV_OFFSET 0 /* at beginning of EEPROM */ | |
429 | + #define CFG_ENV_SIZE 1024 /* Use only a part of it*/ | |
415 | 430 | #endif |
416 | 431 | |
417 | 432 | #if 1 |
include/fat.h
... | ... | @@ -204,6 +204,7 @@ |
204 | 204 | int file_fat_ls(const char *dir); |
205 | 205 | long file_fat_read(const char *filename, void *buffer, unsigned long maxsize); |
206 | 206 | const char *file_getfsname(int idx); |
207 | +int fat_register_device(block_dev_desc_t *dev_desc, int part_no); | |
207 | 208 | |
208 | 209 | #endif /* _FAT_H_ */ |
include/jffs2/jffs2.h
... | ... | @@ -82,6 +82,7 @@ |
82 | 82 | #define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1) |
83 | 83 | #define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2) |
84 | 84 | #define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) |
85 | +#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4) | |
85 | 86 | |
86 | 87 | /* Maybe later... */ |
87 | 88 | /*#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) */ |
include/part.h
post/cache_8xx.S
... | ... | @@ -27,8 +27,7 @@ |
27 | 27 | defined(CONFIG_MPC850) || \ |
28 | 28 | defined(CONFIG_MPC855) || \ |
29 | 29 | defined(CONFIG_MPC860) || \ |
30 | - defined(CONFIG_MPC862) || \ | |
31 | - defined(CONFIG_MPC824X) | |
30 | + defined(CONFIG_MPC862) | |
32 | 31 | |
33 | 32 | #include <post.h> |
34 | 33 | #include <ppc_asm.tmpl> |
... | ... | @@ -491,7 +490,7 @@ |
491 | 490 | mtlr r0 |
492 | 491 | blr |
493 | 492 | |
494 | -#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 || MPC824X */ | |
493 | +#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 */ | |
495 | 494 | #endif /* CONFIG_POST & CFG_POST_CACHE */ |
496 | 495 | #endif /* CONFIG_POST */ |
post/ether.c
... | ... | @@ -38,7 +38,7 @@ |
38 | 38 | #ifdef CONFIG_POST |
39 | 39 | |
40 | 40 | #include <post.h> |
41 | - | |
41 | +#if CONFIG_POST & CFG_POST_ETHER | |
42 | 42 | #if defined(CONFIG_8xx) |
43 | 43 | #include <commproc.h> |
44 | 44 | #elif defined(CONFIG_MPC8260) |
... | ... | @@ -49,8 +49,6 @@ |
49 | 49 | |
50 | 50 | #include <command.h> |
51 | 51 | #include <net.h> |
52 | - | |
53 | -#if CONFIG_POST & CFG_POST_ETHER | |
54 | 52 | |
55 | 53 | #define MIN_PACKET_LENGTH 64 |
56 | 54 | #define MAX_PACKET_LENGTH 256 |
post/uart.c
... | ... | @@ -39,6 +39,7 @@ |
39 | 39 | #ifdef CONFIG_POST |
40 | 40 | |
41 | 41 | #include <post.h> |
42 | +#if CONFIG_POST & CFG_POST_UART | |
42 | 43 | #if defined(CONFIG_8xx) |
43 | 44 | #include <commproc.h> |
44 | 45 | #elif defined(CONFIG_MPC8260) |
... | ... | @@ -48,8 +49,6 @@ |
48 | 49 | #endif |
49 | 50 | #include <command.h> |
50 | 51 | #include <net.h> |
51 | - | |
52 | -#if CONFIG_POST & CFG_POST_UART | |
53 | 52 | |
54 | 53 | #define CTLR_SMC 0 |
55 | 54 | #define CTLR_SCC 1 |