base-files: define yes/no as valid boolean options
[openwrt.git] / target / linux / mvebu / patches-3.10 / 0047-PCI-mvebu-Adapt-to-the-new-device-tree-layout.patch
1 From 90b1f963b07d05e8243e5053a910e8a47222f7a1 Mon Sep 17 00:00:00 2001
2 From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
3 Date: Fri, 5 Jul 2013 14:54:17 +0200
4 Subject: [PATCH 047/203] PCI: mvebu: Adapt to the new device tree layout
5
6 The new device tree layout encodes the window's target ID and attribute
7 in the PCIe controller node's ranges property. This allows to parse
8 such entries to obtain such information and use the recently introduced
9 MBus API to create the windows, instead of using the current name based
10 scheme.
11
12 Acked-by: Bjorn Helgaas <bhelgaas@google.com>
13 Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
14 Tested-by: Andrew Lunn <andrew@lunn.ch>
15 Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
16 ---
17  drivers/pci/host/pci-mvebu.c | 113 ++++++++++++++++++++++++++++++++-----------
18  1 file changed, 84 insertions(+), 29 deletions(-)
19
20 --- a/drivers/pci/host/pci-mvebu.c
21 +++ b/drivers/pci/host/pci-mvebu.c
22 @@ -119,6 +119,10 @@ struct mvebu_pcie_port {
23         u32 port;
24         u32 lane;
25         int devfn;
26 +       unsigned int mem_target;
27 +       unsigned int mem_attr;
28 +       unsigned int io_target;
29 +       unsigned int io_attr;
30         struct clk *clk;
31         struct mvebu_sw_pci_bridge bridge;
32         struct device_node *dn;
33 @@ -303,10 +307,9 @@ static void mvebu_pcie_handle_iobase_cha
34                             (port->bridge.iolimitupper << 16)) -
35                             iobase);
36  
37 -       mvebu_mbus_add_window_remap_flags(port->name, port->iowin_base,
38 -                                         port->iowin_size,
39 -                                         iobase,
40 -                                         MVEBU_MBUS_PCI_IO);
41 +       mvebu_mbus_add_window_remap_by_id(port->io_target, port->io_attr,
42 +                                         port->iowin_base, port->iowin_size,
43 +                                         iobase);
44  
45         pci_ioremap_io(iobase, port->iowin_base);
46  }
47 @@ -338,10 +341,8 @@ static void mvebu_pcie_handle_membase_ch
48                 (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
49                 port->memwin_base;
50  
51 -       mvebu_mbus_add_window_remap_flags(port->name, port->memwin_base,
52 -                                         port->memwin_size,
53 -                                         MVEBU_MBUS_NO_REMAP,
54 -                                         MVEBU_MBUS_PCI_MEM);
55 +       mvebu_mbus_add_window_by_id(port->mem_target, port->mem_attr,
56 +                                   port->memwin_base, port->memwin_size);
57  }
58  
59  /*
60 @@ -730,12 +731,54 @@ mvebu_pcie_map_registers(struct platform
61         return devm_request_and_ioremap(&pdev->dev, &regs);
62  }
63  
64 +#define DT_FLAGS_TO_TYPE(flags)       (((flags) >> 24) & 0x03)
65 +#define    DT_TYPE_IO                 0x1
66 +#define    DT_TYPE_MEM32              0x2
67 +#define DT_CPUADDR_TO_TARGET(cpuaddr) (((cpuaddr) >> 56) & 0xFF)
68 +#define DT_CPUADDR_TO_ATTR(cpuaddr)   (((cpuaddr) >> 48) & 0xFF)
69 +
70 +static int mvebu_get_tgt_attr(struct device_node *np, int devfn,
71 +                             unsigned long type, int *tgt, int *attr)
72 +{
73 +       const int na = 3, ns = 2;
74 +       const __be32 *range;
75 +       int rlen, nranges, rangesz, pna, i;
76 +
77 +       range = of_get_property(np, "ranges", &rlen);
78 +       if (!range)
79 +               return -EINVAL;
80 +
81 +       pna = of_n_addr_cells(np);
82 +       rangesz = pna + na + ns;
83 +       nranges = rlen / sizeof(__be32) / rangesz;
84 +
85 +       for (i = 0; i < nranges; i++) {
86 +               u32 flags = of_read_number(range, 1);
87 +               u32 slot = of_read_number(range, 2);
88 +               u64 cpuaddr = of_read_number(range + na, pna);
89 +               unsigned long rtype;
90 +
91 +               if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_IO)
92 +                       rtype = IORESOURCE_IO;
93 +               else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32)
94 +                       rtype = IORESOURCE_MEM;
95 +
96 +               if (slot == PCI_SLOT(devfn) && type == rtype) {
97 +                       *tgt = DT_CPUADDR_TO_TARGET(cpuaddr);
98 +                       *attr = DT_CPUADDR_TO_ATTR(cpuaddr);
99 +                       return 0;
100 +               }
101 +
102 +               range += rangesz;
103 +       }
104 +
105 +       return -ENOENT;
106 +}
107 +
108  static int __init mvebu_pcie_probe(struct platform_device *pdev)
109  {
110         struct mvebu_pcie *pcie;
111         struct device_node *np = pdev->dev.of_node;
112 -       struct of_pci_range range;
113 -       struct of_pci_range_parser parser;
114         struct device_node *child;
115         int i, ret;
116  
117 @@ -746,29 +789,25 @@ static int __init mvebu_pcie_probe(struc
118  
119         pcie->pdev = pdev;
120  
121 -       if (of_pci_range_parser_init(&parser, np))
122 +       /* Get the PCIe memory and I/O aperture */
123 +       mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
124 +       if (resource_size(&pcie->mem) == 0) {
125 +               dev_err(&pdev->dev, "invalid memory aperture size\n");
126                 return -EINVAL;
127 +       }
128  
129 -       /* Get the I/O and memory ranges from DT */
130 -       for_each_of_pci_range(&parser, &range) {
131 -               unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
132 -               if (restype == IORESOURCE_IO) {
133 -                       of_pci_range_to_resource(&range, np, &pcie->io);
134 -                       of_pci_range_to_resource(&range, np, &pcie->realio);
135 -                       pcie->io.name = "I/O";
136 -                       pcie->realio.start = max_t(resource_size_t,
137 -                                                  PCIBIOS_MIN_IO,
138 -                                                  range.pci_addr);
139 -                       pcie->realio.end = min_t(resource_size_t,
140 -                                                IO_SPACE_LIMIT,
141 -                                                range.pci_addr + range.size);
142 -               }
143 -               if (restype == IORESOURCE_MEM) {
144 -                       of_pci_range_to_resource(&range, np, &pcie->mem);
145 -                       pcie->mem.name = "MEM";
146 -               }
147 +       mvebu_mbus_get_pcie_io_aperture(&pcie->io);
148 +       if (resource_size(&pcie->io) == 0) {
149 +               dev_err(&pdev->dev, "invalid I/O aperture size\n");
150 +               return -EINVAL;
151         }
152  
153 +       pcie->realio.flags = pcie->io.flags;
154 +       pcie->realio.start = PCIBIOS_MIN_IO;
155 +       pcie->realio.end = min_t(resource_size_t,
156 +                                 IO_SPACE_LIMIT,
157 +                                 resource_size(&pcie->io));
158 +
159         /* Get the bus range */
160         ret = of_pci_parse_bus_range(np, &pcie->busn);
161         if (ret) {
162 @@ -816,6 +855,22 @@ static int __init mvebu_pcie_probe(struc
163                 if (port->devfn < 0)
164                         continue;
165  
166 +               ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_MEM,
167 +                                        &port->mem_target, &port->mem_attr);
168 +               if (ret < 0) {
169 +                       dev_err(&pdev->dev, "PCIe%d.%d: cannot get tgt/attr for mem window\n",
170 +                               port->port, port->lane);
171 +                       continue;
172 +               }
173 +
174 +               ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_IO,
175 +                                        &port->io_target, &port->io_attr);
176 +               if (ret < 0) {
177 +                       dev_err(&pdev->dev, "PCIe%d.%d: cannot get tgt/attr for io window\n",
178 +                               port->port, port->lane);
179 +                       continue;
180 +               }
181 +
182                 port->base = mvebu_pcie_map_registers(pdev, child, port);
183                 if (!port->base) {
184                         dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",