]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_pci.c
* Switch LWMON board default config from FRAM to EEPROM;
[karo-tx-uboot.git] / common / cmd_pci.c
1 /*
2  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
3  * Andreas Heppel <aheppel@sysgo.de>
4  *
5  * (C) Copyright 2002
6  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
7  * Wolfgang Grandegger, DENX Software Engineering, wg@denx.de.
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27
28 /*
29  * PCI routines
30  */
31
32 #include <common.h>
33
34 #ifdef CONFIG_PCI
35
36 #include <command.h>
37 #include <cmd_boot.h>
38 #include <asm/processor.h>
39 #include <asm/io.h>
40 #include <cmd_pci.h>
41 #include <pci.h>
42
43 #if (CONFIG_COMMANDS & CFG_CMD_PCI)
44
45 extern int cmd_get_data_size(char* arg, int default_size);
46
47 unsigned char   ShortPCIListing = 1;
48
49 /*
50  * Follows routines for the output of infos about devices on PCI bus.
51  */
52
53 void pci_header_show(pci_dev_t dev);
54 void pci_header_show_brief(pci_dev_t dev);
55
56 /*
57  * Subroutine:  pciinfo
58  *
59  * Description: Show information about devices on PCI bus.
60  *                              Depending on the define CFG_SHORT_PCI_LISTING
61  *                              the output will be more or less exhaustive.
62  *
63  * Inputs:      bus_no          the number of the bus to be scanned.
64  *
65  * Return:      None
66  *
67  */
68 void pciinfo(int BusNum, int ShortPCIListing)
69 {
70         int Device;
71         int Function;
72         unsigned char HeaderType;
73         unsigned short VendorID;
74         pci_dev_t dev;
75
76         printf("Scanning PCI devices on bus %d\n", BusNum);
77
78         if (ShortPCIListing) {
79                 printf("BusDevFun  VendorId   DeviceId   Device Class       Sub-Class\n");
80                 printf("_____________________________________________________________\n");
81         }
82
83         for (Device = 0; Device < PCI_MAX_PCI_DEVICES; Device++) {
84                 HeaderType = 0;
85                 VendorID = 0;
86                 for (Function = 0; Function < PCI_MAX_PCI_FUNCTIONS; Function++) {
87                         /*
88                          * If this is not a multi-function device, we skip the rest.
89                          */
90                         if (Function && !(HeaderType & 0x80))
91                                 break;
92
93                         dev = PCI_BDF(BusNum, Device, Function);
94
95                         pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID);
96                         if ((VendorID == 0xFFFF) || (VendorID == 0x0000))
97                                 continue;
98
99                         if (!Function) pci_read_config_byte(dev, PCI_HEADER_TYPE, &HeaderType);
100
101                         if (ShortPCIListing)
102                         {
103                                 printf("%02x.%02x.%02x   ", BusNum, Device, Function);
104                                 pci_header_show_brief(dev);
105                         }
106                         else
107                         {
108                                 printf("\nFound PCI device %02x.%02x.%02x:\n",
109                                        BusNum, Device, Function);
110                                 pci_header_show(dev);
111                         }
112             }
113     }
114 }
115
116 char* pci_classes_str(u8 class)
117 {
118         static char *pci_classes[] = {
119                 "Build before PCI Rev2.0",
120                 "Mass storage controller",
121                 "Network controller     ",
122                 "Display controller     ",
123                 "Multimedia device      ",
124                 "Memory controller      ",
125                 "Bridge device          ",
126                 "Simple comm. controller",
127                 "Base system peripheral ",
128                 "Input device           ",
129                 "Docking station        ",
130                 "Processor              ",
131                 "Serial bus controller  ",
132                 "Reserved entry         ",
133                 "Does not fit any class "
134         };
135
136         if (class < (sizeof pci_classes / sizeof *pci_classes))
137                 return pci_classes[(int) class];
138
139         return  "???                    ";
140 }
141
142 /*
143  * Subroutine:  pci_header_show_brief
144  *
145  * Description: Reads and prints the header of the
146  *              specified PCI device in short form.
147  *
148  * Inputs:      dev      Bus+Device+Function number
149  *
150  * Return:      None
151  *
152  */
153 void pci_header_show_brief(pci_dev_t dev)
154 {
155         u16 vendor, device;
156         u8 class, subclass;
157
158         pci_read_config_word(dev, PCI_VENDOR_ID, &vendor);
159         pci_read_config_word(dev, PCI_DEVICE_ID, &device);
160         pci_read_config_byte(dev, PCI_CLASS_CODE, &class);
161         pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &subclass);
162
163         printf("0x%.4x     0x%.4x     %s 0x%.2x\n",
164                vendor, device,
165                pci_classes_str(class), subclass);
166 }
167
168 /*
169  * Subroutine:  PCI_Header_Show
170  *
171  * Description: Reads the header of the specified PCI device.
172  *
173  * Inputs:              BusDevFunc      Bus+Device+Function number
174  *
175  * Return:      None
176  *
177  */
178 void pci_header_show(pci_dev_t dev)
179 {
180         u8 _byte, header_type;
181         u16 _word;
182         u32 _dword;
183
184 #define PRINT(msg, type, reg) \
185         pci_read_config_##type(dev, reg, &_##type); \
186         printf(msg, _##type)
187
188 #define PRINT2(msg, type, reg, func) \
189         pci_read_config_##type(dev, reg, &_##type); \
190         printf(msg, _##type, func(_##type))
191
192         pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
193
194         PRINT ("  vendor ID =                   0x%.4x\n", word, PCI_VENDOR_ID);
195         PRINT ("  device ID =                   0x%.4x\n", word, PCI_DEVICE_ID);
196         PRINT ("  command register =            0x%.4x\n", word, PCI_COMMAND);
197         PRINT ("  status register =             0x%.4x\n", word, PCI_STATUS);
198         PRINT ("  revision ID =                 0x%.2x\n", byte, PCI_REVISION_ID);
199         PRINT2("  class code =                  0x%.2x (%s)\n", byte, PCI_CLASS_CODE,
200                                                                 pci_classes_str);
201         PRINT ("  sub class code =              0x%.2x\n", byte, PCI_CLASS_SUB_CODE);
202         PRINT ("  programming interface =       0x%.2x\n", byte, PCI_CLASS_PROG);
203         PRINT ("  cache line =                  0x%.2x\n", byte, PCI_CACHE_LINE_SIZE);
204         PRINT ("  latency time =                0x%.2x\n", byte, PCI_LATENCY_TIMER);
205         PRINT ("  header type =                 0x%.2x\n", byte, PCI_HEADER_TYPE);
206         PRINT ("  BIST =                        0x%.2x\n", byte, PCI_BIST);
207         PRINT ("  base address 0 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_0);
208
209         switch (header_type & 0x03) {
210         case PCI_HEADER_TYPE_NORMAL:    /* "normal" PCI device */
211                 PRINT ("  base address 1 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_1);
212                 PRINT ("  base address 2 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_2);
213                 PRINT ("  base address 3 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_3);
214                 PRINT ("  base address 4 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_4);
215                 PRINT ("  base address 5 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_5);
216                 PRINT ("  cardBus CIS pointer =         0x%.8x\n", dword, PCI_CARDBUS_CIS);
217                 PRINT ("  sub system vendor ID =        0x%.4x\n", word, PCI_SUBSYSTEM_VENDOR_ID);
218                 PRINT ("  sub system ID =               0x%.4x\n", word, PCI_SUBSYSTEM_ID);
219                 PRINT ("  expansion ROM base address =  0x%.8x\n", dword, PCI_ROM_ADDRESS);
220                 PRINT ("  interrupt line =              0x%.2x\n", byte, PCI_INTERRUPT_LINE);
221                 PRINT ("  interrupt pin =               0x%.2x\n", byte, PCI_INTERRUPT_PIN);
222                 PRINT ("  min Grant =                   0x%.2x\n", byte, PCI_MIN_GNT);
223                 PRINT ("  max Latency =                 0x%.2x\n", byte, PCI_MAX_LAT);
224                 break;
225                 
226         case PCI_HEADER_TYPE_BRIDGE:    /* PCI-to-PCI bridge */
227
228                 PRINT ("  base address 1 =              0x%.8x\n", dword, PCI_BASE_ADDRESS_1);
229                 PRINT ("  primary bus number =          0x%.2x\n", byte, PCI_PRIMARY_BUS);
230                 PRINT ("  secondary bus number =        0x%.2x\n", byte, PCI_SECONDARY_BUS);
231                 PRINT ("  subordinate bus number =      0x%.2x\n", byte, PCI_SUBORDINATE_BUS);
232                 PRINT ("  secondary latency timer =     0x%.2x\n", byte, PCI_SEC_LATENCY_TIMER);
233                 PRINT ("  IO base =                     0x%.2x\n", byte, PCI_IO_BASE);
234                 PRINT ("  IO limit =                    0x%.2x\n", byte, PCI_IO_LIMIT);
235                 PRINT ("  secondary status =            0x%.4x\n", word, PCI_SEC_STATUS);
236                 PRINT ("  memory base =                 0x%.4x\n", word, PCI_MEMORY_BASE);
237                 PRINT ("  memory limit =                0x%.4x\n", word, PCI_MEMORY_LIMIT);
238                 PRINT ("  prefetch memory base =        0x%.4x\n", word, PCI_PREF_MEMORY_BASE);
239                 PRINT ("  prefetch memory limit =       0x%.4x\n", word, PCI_PREF_MEMORY_LIMIT);
240                 PRINT ("  prefetch memory base upper =  0x%.8x\n", dword, PCI_PREF_BASE_UPPER32);
241                 PRINT ("  prefetch memory limit upper = 0x%.8x\n", dword, PCI_PREF_LIMIT_UPPER32);
242                 PRINT ("  IO base upper 16 bits =       0x%.4x\n", word, PCI_IO_BASE_UPPER16);
243                 PRINT ("  IO limit upper 16 bits =      0x%.4x\n", word, PCI_IO_LIMIT_UPPER16);
244                 PRINT ("  expansion ROM base address =  0x%.8x\n", dword, PCI_ROM_ADDRESS1);
245                 PRINT ("  interrupt line =              0x%.2x\n", byte, PCI_INTERRUPT_LINE);
246                 PRINT ("  interrupt pin =               0x%.2x\n", byte, PCI_INTERRUPT_PIN);
247                 PRINT ("  bridge control =              0x%.4x\n", word, PCI_BRIDGE_CONTROL);
248                 break;
249
250         case PCI_HEADER_TYPE_CARDBUS:   /* PCI-to-CardBus bridge */
251
252                 PRINT ("  capabilities =                0x%.2x\n", byte, PCI_CB_CAPABILITY_LIST);
253                 PRINT ("  secondary status =            0x%.4x\n", word, PCI_CB_SEC_STATUS);
254                 PRINT ("  primary bus number =          0x%.2x\n", byte, PCI_CB_PRIMARY_BUS);
255                 PRINT ("  CardBus number =              0x%.2x\n", byte, PCI_CB_CARD_BUS);
256                 PRINT ("  subordinate bus number =      0x%.2x\n", byte, PCI_CB_SUBORDINATE_BUS);
257                 PRINT ("  CardBus latency timer =       0x%.2x\n", byte, PCI_CB_LATENCY_TIMER);         
258                 PRINT ("  CardBus memory base 0 =       0x%.8x\n", dword, PCI_CB_MEMORY_BASE_0);
259                 PRINT ("  CardBus memory limit 0 =      0x%.8x\n", dword, PCI_CB_MEMORY_LIMIT_0);
260                 PRINT ("  CardBus memory base 1 =       0x%.8x\n", dword, PCI_CB_MEMORY_BASE_1);
261                 PRINT ("  CardBus memory limit 1 =      0x%.8x\n", dword, PCI_CB_MEMORY_LIMIT_1);
262                 PRINT ("  CardBus IO base 0 =           0x%.4x\n", word, PCI_CB_IO_BASE_0);
263                 PRINT ("  CardBus IO base high 0 =      0x%.4x\n", word, PCI_CB_IO_BASE_0_HI);
264                 PRINT ("  CardBus IO limit 0 =          0x%.4x\n", word, PCI_CB_IO_LIMIT_0);
265                 PRINT ("  CardBus IO limit high 0 =     0x%.4x\n", word, PCI_CB_IO_LIMIT_0_HI);
266                 PRINT ("  CardBus IO base 1 =           0x%.4x\n", word, PCI_CB_IO_BASE_1);
267                 PRINT ("  CardBus IO base high 1 =      0x%.4x\n", word, PCI_CB_IO_BASE_1_HI);
268                 PRINT ("  CardBus IO limit 1 =          0x%.4x\n", word, PCI_CB_IO_LIMIT_1);
269                 PRINT ("  CardBus IO limit high 1 =     0x%.4x\n", word, PCI_CB_IO_LIMIT_1_HI);
270                 PRINT ("  interrupt line =              0x%.2x\n", byte, PCI_INTERRUPT_LINE);
271                 PRINT ("  interrupt pin =               0x%.2x\n", byte, PCI_INTERRUPT_PIN);
272                 PRINT ("  bridge control =              0x%.4x\n", word, PCI_CB_BRIDGE_CONTROL);
273                 PRINT ("  subvendor ID =                0x%.4x\n", word, PCI_CB_SUBSYSTEM_VENDOR_ID);
274                 PRINT ("  subdevice ID =                0x%.4x\n", word, PCI_CB_SUBSYSTEM_ID);
275                 PRINT ("  PC Card 16bit base address =  0x%.8x\n", dword, PCI_CB_LEGACY_MODE_BASE);
276                 break;
277                 
278         default:
279                 printf("unknown header\n");
280                 break;  
281     }
282
283 #undef PRINT
284 #undef PRINT2
285 }
286
287 /* Convert the "bus.device.function" identifier into a number.
288  */
289 static pci_dev_t get_pci_dev(char* name)
290 {
291         char cnum[12];
292         int len, i, iold, n;
293         int bdfs[3] = {0,0,0};
294
295         len = strlen(name);
296         if (len > 8)
297                 return -1;
298         for (i = 0, iold = 0, n = 0; i < len; i++) {
299                 if (name[i] == '.') {
300                         memcpy(cnum, &name[iold], i - iold);
301                         cnum[i - iold] = '\0';
302                         bdfs[n++] = simple_strtoul(cnum, NULL, 16);
303                         iold = i + 1;
304                 }
305         }
306         strcpy(cnum, &name[iold]);
307         if (n == 0)
308                 n = 1;
309         bdfs[n] = simple_strtoul(cnum, NULL, 16);
310         return PCI_BDF(bdfs[0], bdfs[1], bdfs[2]);
311 }
312
313 static int pci_cfg_display(pci_dev_t bdf, ulong addr, ulong size, ulong length)
314 {
315 #define DISP_LINE_LEN   16
316         ulong i, nbytes, linebytes;
317         int rc = 0;
318
319         if (length == 0)
320                 length = 0x40 / size; /* Standard PCI configuration space */
321
322         /* Print the lines.
323          * once, and all accesses are with the specified bus width.
324          */
325         nbytes = length * size;
326         do {
327                 uint    val4;
328                 ushort  val2;
329                 u_char  val1;
330
331                 printf("%08lx:", addr);
332                 linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
333                 for (i=0; i<linebytes; i+= size) {
334                         if (size == 4) {
335                                 pci_read_config_dword(bdf, addr, &val4);
336                                 printf(" %08x", val4);
337                         } else if (size == 2) {
338                                 pci_read_config_word(bdf, addr, &val2);
339                                 printf(" %04x", val2);
340                         } else {
341                                 pci_read_config_byte(bdf, addr, &val1);
342                                 printf(" %02x", val1);
343                         }
344                         addr += size;
345                 }
346                 printf("\n");
347                 nbytes -= linebytes;
348                 if (ctrlc()) {
349                         rc = 1;
350                         break;
351                 }
352         } while (nbytes > 0);
353
354         return (rc);
355 }
356
357 static int pci_cfg_write (pci_dev_t bdf, ulong addr, ulong size, ulong value)
358 {
359         if (size == 4) {
360                 pci_write_config_dword(bdf, addr, value);
361         }
362         else if (size == 2) {
363                 ushort val = value & 0xffff;
364                 pci_write_config_word(bdf, addr, val);
365         }
366         else {
367                 u_char val = value & 0xff;
368                 pci_write_config_byte(bdf, addr, val);
369         }
370         return 0;
371 }
372
373 static int
374 pci_cfg_modify (pci_dev_t bdf, ulong addr, ulong size, ulong value, int incrflag)
375 {
376         ulong   i;
377         int     nbytes;
378         extern char console_buffer[];
379         uint    val4;
380         ushort  val2;
381         u_char  val1;
382
383         /* Print the address, followed by value.  Then accept input for
384          * the next value.  A non-converted value exits.
385          */
386         do {
387                 printf("%08lx:", addr);
388                 if (size == 4) {
389                         pci_read_config_dword(bdf, addr, &val4);
390                         printf(" %08x", val4);
391                 }
392                 else if (size == 2) {
393                         pci_read_config_word(bdf, addr, &val2);
394                         printf(" %04x", val2);
395                 }
396                 else {
397                         pci_read_config_byte(bdf, addr, &val1);
398                         printf(" %02x", val1);
399                 }
400
401                 nbytes = readline (" ? ");
402                 if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
403                         /* <CR> pressed as only input, don't modify current
404                          * location and move to next. "-" pressed will go back.
405                          */
406                         if (incrflag)
407                                 addr += nbytes ? -size : size;
408                         nbytes = 1;
409 #ifdef CONFIG_BOOT_RETRY_TIME
410                         reset_cmd_timeout(); /* good enough to not time out */
411 #endif
412                 }
413 #ifdef CONFIG_BOOT_RETRY_TIME
414                 else if (nbytes == -2) {
415                         break;  /* timed out, exit the command  */
416                 }
417 #endif
418                 else {
419                         char *endp;
420                         i = simple_strtoul(console_buffer, &endp, 16);
421                         nbytes = endp - console_buffer;
422                         if (nbytes) {
423 #ifdef CONFIG_BOOT_RETRY_TIME
424                                 /* good enough to not time out
425                                  */
426                                 reset_cmd_timeout();
427 #endif
428                                 pci_cfg_write (bdf, addr, size, i);
429                                 if (incrflag)
430                                         addr += size;
431                         }
432                 }
433         } while (nbytes);
434
435         return 0;
436 }
437
438 /* PCI Configuration Space access commands
439  *
440  * Syntax:
441  *      pci display[.b, .w, .l] bus.device.function} [addr] [len]
442  *      pci next[.b, .w, .l] bus.device.function [addr]
443  *      pci modify[.b, .w, .l] bus.device.function [addr]
444  *      pci write[.b, .w, .l] bus.device.function addr value
445  */
446 int do_pci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
447 {
448         ulong addr = 0, value = 0, size = 0;
449         pci_dev_t bdf = 0;
450         char cmd = 's';
451
452         if (argc > 1)
453                 cmd = argv[1][0];
454
455         switch (cmd) {
456         case 'd':               /* display */
457         case 'n':               /* next */
458         case 'm':               /* modify */
459         case 'w':               /* write */
460                 /* Check for a size specification. */
461                 size = cmd_get_data_size(argv[1], 4);
462                 if (argc > 3)
463                         addr = simple_strtoul(argv[3], NULL, 16);
464                 if (argc > 4)
465                         value = simple_strtoul(argv[4], NULL, 16);
466         case 'h':               /* header */
467                 if (argc < 3)
468                         goto usage;
469                 if ((bdf = get_pci_dev(argv[2])) == -1)
470                         return 1;
471                 break;
472         default:                /* scan bus */
473                 value = 1; /* short listing */
474                 bdf = 0;   /* bus number  */
475                 if (argc > 1) {
476                         if (argv[argc-1][0] == 'l') {
477                                 value = 0;
478                                 argc--;
479                         }
480                         if (argc > 1)
481                                 bdf = simple_strtoul(argv[1], NULL, 16);
482                 }
483                 pciinfo(bdf, value);
484                 return 0;
485         }
486
487         switch (argv[1][0]) {
488         case 'h':               /* header */
489                 pci_header_show(bdf);
490                 return 0;
491         case 'd':               /* display */
492                 return pci_cfg_display(bdf, addr, size, value);
493         case 'n':               /* next */
494                 if (argc < 4)
495                         goto usage;
496                 return pci_cfg_modify(bdf, addr, size, value, 0);
497         case 'm':               /* modify */
498                 if (argc < 4)
499                         goto usage;
500                 return pci_cfg_modify(bdf, addr, size, value, 1);
501         case 'w':               /* write */
502                 if (argc < 5)
503                         goto usage;
504                 return pci_cfg_write(bdf, addr, size, value);
505         }
506
507         return 1;
508  usage:
509         printf ("Usage:\n%s\n", cmdtp->usage);
510         return 1;
511 }
512
513 #endif /* (CONFIG_COMMANDS & CFG_CMD_PCI) */
514
515 #endif /* CONFIG_PCI */