]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/freescale/common/cds_pci_ft.c
4cd804577b9ed22722f39d0a48f5aaa879bb9fa7
[karo-tx-uboot.git] / board / freescale / common / cds_pci_ft.c
1 /*
2  * Copyright 2004 Freescale Semiconductor.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+ 
5  */
6
7 #include <common.h>
8 #include <libfdt.h>
9 #include <fdt_support.h>
10 #include "cadmus.h"
11
12 #if defined(CONFIG_OF_BOARD_SETUP)
13 static void cds_pci_fixup(void *blob)
14 {
15         int node;
16         const char *path;
17         int len, slot, i;
18         u32 *map = NULL, *piccells = NULL;
19         int off, cells;
20
21         node = fdt_path_offset(blob, "/aliases");
22         if (node >= 0) {
23                 path = fdt_getprop(blob, node, "pci0", NULL);
24                 if (path) {
25                         node = fdt_path_offset(blob, path);
26                         if (node >= 0) {
27                                 map = fdt_getprop_w(blob, node, "interrupt-map", &len);
28                         }
29                         /* Each item in "interrupt-map" property is translated with
30                          * following cells:
31                          * PCI #address-cells, PCI #interrupt-cells,
32                          * PIC address, PIC #address-cells, PIC #interrupt-cells.
33                          */
34                         cells = fdt_getprop_u32_default(blob, path, "#address-cells", 1);
35                         cells += fdt_getprop_u32_default(blob, path, "#interrupt-cells", 1);
36                         off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*(map+cells)));
37                         if (off <= 0)
38                                 return;
39                         cells += 1;
40                         piccells = (u32 *)fdt_getprop(blob, off, "#address-cells", NULL);
41                         if (piccells == NULL)
42                                 return;
43                         cells += *piccells;
44                         piccells = (u32 *)fdt_getprop(blob, off, "#interrupt-cells", NULL);
45                         if (piccells == NULL)
46                                 return;
47                         cells += *piccells;
48                 }
49         }
50
51         if (map) {
52                 len /= sizeof(u32);
53
54                 slot = get_pci_slot();
55
56                 for (i=0;i<len;i+=cells) {
57                         /* We rotate the interrupt pins so that the mapping
58                          * changes depending on the slot the carrier card is in.
59                          */
60                         map[3] = ((map[3] + slot - 2) % 4) + 1;
61                         map+=cells;
62                 }
63         }
64 }
65
66 void
67 ft_board_setup(void *blob, bd_t *bd)
68 {
69         ft_cpu_setup(blob, bd);
70 #ifdef CONFIG_PCI
71         ft_pci_setup(blob, bd);
72         cds_pci_fixup(blob);
73 #endif
74 }
75 #endif