]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/kernel/wandboard/imx/0011-add-pcie-designware.patch
snort: Update urls for rules download (2.9.7.0) in 'ids.cgi'
[ipfire-2.x.git] / src / patches / kernel / wandboard / imx / 0011-add-pcie-designware.patch
1 --- /dev/null 2013-12-09 21:30:35.000000000 +0000
2 +++ drivers/pci/host/pcie-designware.h 2013-09-20 01:59:32.000000000 +0000
3 @@ -0,0 +1,65 @@
4 +/*
5 + * Synopsys Designware PCIe host controller driver
6 + *
7 + * Copyright (C) 2013 Samsung Electronics Co., Ltd.
8 + * http://www.samsung.com
9 + *
10 + * Author: Jingoo Han <jg1.han@samsung.com>
11 + *
12 + * This program is free software; you can redistribute it and/or modify
13 + * it under the terms of the GNU General Public License version 2 as
14 + * published by the Free Software Foundation.
15 + */
16 +
17 +struct pcie_port_info {
18 + u32 cfg0_size;
19 + u32 cfg1_size;
20 + u32 io_size;
21 + u32 mem_size;
22 + phys_addr_t io_bus_addr;
23 + phys_addr_t mem_bus_addr;
24 +};
25 +
26 +struct pcie_port {
27 + struct device *dev;
28 + u8 root_bus_nr;
29 + void __iomem *dbi_base;
30 + u64 cfg0_base;
31 + void __iomem *va_cfg0_base;
32 + u64 cfg1_base;
33 + void __iomem *va_cfg1_base;
34 + u64 io_base;
35 + u64 mem_base;
36 + spinlock_t conf_lock;
37 + struct resource cfg;
38 + struct resource io;
39 + struct resource mem;
40 + struct pcie_port_info config;
41 + int irq;
42 + u32 lanes;
43 + struct pcie_host_ops *ops;
44 +};
45 +
46 +struct pcie_host_ops {
47 + void (*readl_rc)(struct pcie_port *pp,
48 + void __iomem *dbi_base, u32 *val);
49 + void (*writel_rc)(struct pcie_port *pp,
50 + u32 val, void __iomem *dbi_base);
51 + int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val);
52 + int (*wr_own_conf)(struct pcie_port *pp, int where, int size, u32 val);
53 + int (*link_up)(struct pcie_port *pp);
54 + void (*host_init)(struct pcie_port *pp);
55 +};
56 +
57 +extern unsigned long global_io_offset;
58 +
59 +int cfg_read(void __iomem *addr, int where, int size, u32 *val);
60 +int cfg_write(void __iomem *addr, int where, int size, u32 val);
61 +int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size, u32 val);
62 +int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, u32 *val);
63 +int dw_pcie_link_up(struct pcie_port *pp);
64 +void dw_pcie_setup_rc(struct pcie_port *pp);
65 +int dw_pcie_host_init(struct pcie_port *pp);
66 +int dw_pcie_setup(int nr, struct pci_sys_data *sys);
67 +struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys);
68 +int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
69 --- /dev/null 2013-12-09 21:30:35.000000000 +0000
70 +++ drivers/pci/host/pcie-designware.c 2013-09-20 01:59:32.000000000 +0000
71 @@ -0,0 +1,565 @@
72 +/*
73 + * Synopsys Designware PCIe host controller driver
74 + *
75 + * Copyright (C) 2013 Samsung Electronics Co., Ltd.
76 + * http://www.samsung.com
77 + *
78 + * Author: Jingoo Han <jg1.han@samsung.com>
79 + *
80 + * This program is free software; you can redistribute it and/or modify
81 + * it under the terms of the GNU General Public License version 2 as
82 + * published by the Free Software Foundation.
83 + */
84 +
85 +#include <linux/kernel.h>
86 +#include <linux/module.h>
87 +#include <linux/of_address.h>
88 +#include <linux/pci.h>
89 +#include <linux/pci_regs.h>
90 +#include <linux/types.h>
91 +
92 +#include "pcie-designware.h"
93 +
94 +/* Synopsis specific PCIE configuration registers */
95 +#define PCIE_PORT_LINK_CONTROL 0x710
96 +#define PORT_LINK_MODE_MASK (0x3f << 16)
97 +#define PORT_LINK_MODE_1_LANES (0x1 << 16)
98 +#define PORT_LINK_MODE_2_LANES (0x3 << 16)
99 +#define PORT_LINK_MODE_4_LANES (0x7 << 16)
100 +
101 +#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
102 +#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
103 +#define PORT_LOGIC_LINK_WIDTH_MASK (0x1ff << 8)
104 +#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
105 +#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
106 +#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
107 +
108 +#define PCIE_MSI_ADDR_LO 0x820
109 +#define PCIE_MSI_ADDR_HI 0x824
110 +#define PCIE_MSI_INTR0_ENABLE 0x828
111 +#define PCIE_MSI_INTR0_MASK 0x82C
112 +#define PCIE_MSI_INTR0_STATUS 0x830
113 +
114 +#define PCIE_ATU_VIEWPORT 0x900
115 +#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
116 +#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
117 +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
118 +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
119 +#define PCIE_ATU_CR1 0x904
120 +#define PCIE_ATU_TYPE_MEM (0x0 << 0)
121 +#define PCIE_ATU_TYPE_IO (0x2 << 0)
122 +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
123 +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
124 +#define PCIE_ATU_CR2 0x908
125 +#define PCIE_ATU_ENABLE (0x1 << 31)
126 +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
127 +#define PCIE_ATU_LOWER_BASE 0x90C
128 +#define PCIE_ATU_UPPER_BASE 0x910
129 +#define PCIE_ATU_LIMIT 0x914
130 +#define PCIE_ATU_LOWER_TARGET 0x918
131 +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
132 +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
133 +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
134 +#define PCIE_ATU_UPPER_TARGET 0x91C
135 +
136 +static struct hw_pci dw_pci;
137 +
138 +unsigned long global_io_offset;
139 +
140 +static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
141 +{
142 + return sys->private_data;
143 +}
144 +
145 +int cfg_read(void __iomem *addr, int where, int size, u32 *val)
146 +{
147 + *val = readl(addr);
148 +
149 + if (size == 1)
150 + *val = (*val >> (8 * (where & 3))) & 0xff;
151 + else if (size == 2)
152 + *val = (*val >> (8 * (where & 3))) & 0xffff;
153 + else if (size != 4)
154 + return PCIBIOS_BAD_REGISTER_NUMBER;
155 +
156 + return PCIBIOS_SUCCESSFUL;
157 +}
158 +
159 +int cfg_write(void __iomem *addr, int where, int size, u32 val)
160 +{
161 + if (size == 4)
162 + writel(val, addr);
163 + else if (size == 2)
164 + writew(val, addr + (where & 2));
165 + else if (size == 1)
166 + writeb(val, addr + (where & 3));
167 + else
168 + return PCIBIOS_BAD_REGISTER_NUMBER;
169 +
170 + return PCIBIOS_SUCCESSFUL;
171 +}
172 +
173 +static inline void dw_pcie_readl_rc(struct pcie_port *pp, u32 reg, u32 *val)
174 +{
175 + if (pp->ops->readl_rc)
176 + pp->ops->readl_rc(pp, pp->dbi_base + reg, val);
177 + else
178 + *val = readl(pp->dbi_base + reg);
179 +}
180 +
181 +static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
182 +{
183 + if (pp->ops->writel_rc)
184 + pp->ops->writel_rc(pp, val, pp->dbi_base + reg);
185 + else
186 + writel(val, pp->dbi_base + reg);
187 +}
188 +
189 +int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
190 + u32 *val)
191 +{
192 + int ret;
193 +
194 + if (pp->ops->rd_own_conf)
195 + ret = pp->ops->rd_own_conf(pp, where, size, val);
196 + else
197 + ret = cfg_read(pp->dbi_base + (where & ~0x3), where, size, val);
198 +
199 + return ret;
200 +}
201 +
202 +int dw_pcie_wr_own_conf(struct pcie_port *pp, int where, int size,
203 + u32 val)
204 +{
205 + int ret;
206 +
207 + if (pp->ops->wr_own_conf)
208 + ret = pp->ops->wr_own_conf(pp, where, size, val);
209 + else
210 + ret = cfg_write(pp->dbi_base + (where & ~0x3), where, size,
211 + val);
212 +
213 + return ret;
214 +}
215 +
216 +int dw_pcie_link_up(struct pcie_port *pp)
217 +{
218 + if (pp->ops->link_up)
219 + return pp->ops->link_up(pp);
220 + else
221 + return 0;
222 +}
223 +
224 +int __init dw_pcie_host_init(struct pcie_port *pp)
225 +{
226 + struct device_node *np = pp->dev->of_node;
227 + struct of_pci_range range;
228 + struct of_pci_range_parser parser;
229 + u32 val;
230 +
231 + if (of_pci_range_parser_init(&parser, np)) {
232 + dev_err(pp->dev, "missing ranges property\n");
233 + return -EINVAL;
234 + }
235 +
236 + /* Get the I/O and memory ranges from DT */
237 + for_each_of_pci_range(&parser, &range) {
238 + unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
239 + if (restype == IORESOURCE_IO) {
240 + of_pci_range_to_resource(&range, np, &pp->io);
241 + pp->io.name = "I/O";
242 + pp->io.start = max_t(resource_size_t,
243 + PCIBIOS_MIN_IO,
244 + range.pci_addr + global_io_offset);
245 + pp->io.end = min_t(resource_size_t,
246 + IO_SPACE_LIMIT,
247 + range.pci_addr + range.size
248 + + global_io_offset);
249 + pp->config.io_size = resource_size(&pp->io);
250 + pp->config.io_bus_addr = range.pci_addr;
251 + }
252 + if (restype == IORESOURCE_MEM) {
253 + of_pci_range_to_resource(&range, np, &pp->mem);
254 + pp->mem.name = "MEM";
255 + pp->config.mem_size = resource_size(&pp->mem);
256 + pp->config.mem_bus_addr = range.pci_addr;
257 + }
258 + if (restype == 0) {
259 + of_pci_range_to_resource(&range, np, &pp->cfg);
260 + pp->config.cfg0_size = resource_size(&pp->cfg)/2;
261 + pp->config.cfg1_size = resource_size(&pp->cfg)/2;
262 + }
263 + }
264 +
265 + if (!pp->dbi_base) {
266 + pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
267 + resource_size(&pp->cfg));
268 + if (!pp->dbi_base) {
269 + dev_err(pp->dev, "error with ioremap\n");
270 + return -ENOMEM;
271 + }
272 + }
273 +
274 + pp->cfg0_base = pp->cfg.start;
275 + pp->cfg1_base = pp->cfg.start + pp->config.cfg0_size;
276 + pp->io_base = pp->io.start;
277 + pp->mem_base = pp->mem.start;
278 +
279 + pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
280 + pp->config.cfg0_size);
281 + if (!pp->va_cfg0_base) {
282 + dev_err(pp->dev, "error with ioremap in function\n");
283 + return -ENOMEM;
284 + }
285 + pp->va_cfg1_base = devm_ioremap(pp->dev, pp->cfg1_base,
286 + pp->config.cfg1_size);
287 + if (!pp->va_cfg1_base) {
288 + dev_err(pp->dev, "error with ioremap\n");
289 + return -ENOMEM;
290 + }
291 +
292 + if (of_property_read_u32(np, "num-lanes", &pp->lanes)) {
293 + dev_err(pp->dev, "Failed to parse the number of lanes\n");
294 + return -EINVAL;
295 + }
296 +
297 + if (pp->ops->host_init)
298 + pp->ops->host_init(pp);
299 +
300 + dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
301 +
302 + /* program correct class for RC */
303 + dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI);
304 +
305 + dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val);
306 + val |= PORT_LOGIC_SPEED_CHANGE;
307 + dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
308 +
309 + dw_pci.nr_controllers = 1;
310 + dw_pci.private_data = (void **)&pp;
311 +
312 + pci_common_init(&dw_pci);
313 + pci_assign_unassigned_resources();
314 +#ifdef CONFIG_PCI_DOMAINS
315 + dw_pci.domain++;
316 +#endif
317 +
318 + return 0;
319 +}
320 +
321 +static void dw_pcie_prog_viewport_cfg0(struct pcie_port *pp, u32 busdev)
322 +{
323 + /* Program viewport 0 : OUTBOUND : CFG0 */
324 + dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
325 + PCIE_ATU_VIEWPORT);
326 + dw_pcie_writel_rc(pp, pp->cfg0_base, PCIE_ATU_LOWER_BASE);
327 + dw_pcie_writel_rc(pp, (pp->cfg0_base >> 32), PCIE_ATU_UPPER_BASE);
328 + dw_pcie_writel_rc(pp, pp->cfg0_base + pp->config.cfg0_size - 1,
329 + PCIE_ATU_LIMIT);
330 + dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
331 + dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
332 + dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG0, PCIE_ATU_CR1);
333 + dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
334 +}
335 +
336 +static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev)
337 +{
338 + /* Program viewport 1 : OUTBOUND : CFG1 */
339 + dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
340 + PCIE_ATU_VIEWPORT);
341 + dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1);
342 + dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
343 + dw_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE);
344 + dw_pcie_writel_rc(pp, (pp->cfg1_base >> 32), PCIE_ATU_UPPER_BASE);
345 + dw_pcie_writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1,
346 + PCIE_ATU_LIMIT);
347 + dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
348 + dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
349 +}
350 +
351 +static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
352 +{
353 + /* Program viewport 0 : OUTBOUND : MEM */
354 + dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
355 + PCIE_ATU_VIEWPORT);
356 + dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
357 + dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
358 + dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE);
359 + dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE);
360 + dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
361 + PCIE_ATU_LIMIT);
362 + dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET);
363 + dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
364 + PCIE_ATU_UPPER_TARGET);
365 +}
366 +
367 +static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
368 +{
369 + /* Program viewport 1 : OUTBOUND : IO */
370 + dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
371 + PCIE_ATU_VIEWPORT);
372 + dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
373 + dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
374 + dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE);
375 + dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE);
376 + dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1,
377 + PCIE_ATU_LIMIT);
378 + dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET);
379 + dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
380 + PCIE_ATU_UPPER_TARGET);
381 +}
382 +
383 +static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
384 + u32 devfn, int where, int size, u32 *val)
385 +{
386 + int ret = PCIBIOS_SUCCESSFUL;
387 + u32 address, busdev;
388 +
389 + busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
390 + PCIE_ATU_FUNC(PCI_FUNC(devfn));
391 + address = where & ~0x3;
392 +
393 + if (bus->parent->number == pp->root_bus_nr) {
394 + dw_pcie_prog_viewport_cfg0(pp, busdev);
395 + ret = cfg_read(pp->va_cfg0_base + address, where, size, val);
396 + dw_pcie_prog_viewport_mem_outbound(pp);
397 + } else {
398 + dw_pcie_prog_viewport_cfg1(pp, busdev);
399 + ret = cfg_read(pp->va_cfg1_base + address, where, size, val);
400 + dw_pcie_prog_viewport_io_outbound(pp);
401 + }
402 +
403 + return ret;
404 +}
405 +
406 +static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
407 + u32 devfn, int where, int size, u32 val)
408 +{
409 + int ret = PCIBIOS_SUCCESSFUL;
410 + u32 address, busdev;
411 +
412 + busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
413 + PCIE_ATU_FUNC(PCI_FUNC(devfn));
414 + address = where & ~0x3;
415 +
416 + if (bus->parent->number == pp->root_bus_nr) {
417 + dw_pcie_prog_viewport_cfg0(pp, busdev);
418 + ret = cfg_write(pp->va_cfg0_base + address, where, size, val);
419 + dw_pcie_prog_viewport_mem_outbound(pp);
420 + } else {
421 + dw_pcie_prog_viewport_cfg1(pp, busdev);
422 + ret = cfg_write(pp->va_cfg1_base + address, where, size, val);
423 + dw_pcie_prog_viewport_io_outbound(pp);
424 + }
425 +
426 + return ret;
427 +}
428 +
429 +
430 +static int dw_pcie_valid_config(struct pcie_port *pp,
431 + struct pci_bus *bus, int dev)
432 +{
433 + /* If there is no link, then there is no device */
434 + if (bus->number != pp->root_bus_nr) {
435 + if (!dw_pcie_link_up(pp))
436 + return 0;
437 + }
438 +
439 + /* access only one slot on each root port */
440 + if (bus->number == pp->root_bus_nr && dev > 0)
441 + return 0;
442 +
443 + /*
444 + * do not read more than one device on the bus directly attached
445 + * to RC's (Virtual Bridge's) DS side.
446 + */
447 + if (bus->primary == pp->root_bus_nr && dev > 0)
448 + return 0;
449 +
450 + return 1;
451 +}
452 +
453 +static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
454 + int size, u32 *val)
455 +{
456 + struct pcie_port *pp = sys_to_pcie(bus->sysdata);
457 + unsigned long flags;
458 + int ret;
459 +
460 + if (!pp) {
461 + BUG();
462 + return -EINVAL;
463 + }
464 +
465 + if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
466 + *val = 0xffffffff;
467 + return PCIBIOS_DEVICE_NOT_FOUND;
468 + }
469 +
470 + spin_lock_irqsave(&pp->conf_lock, flags);
471 + if (bus->number != pp->root_bus_nr)
472 + ret = dw_pcie_rd_other_conf(pp, bus, devfn,
473 + where, size, val);
474 + else
475 + ret = dw_pcie_rd_own_conf(pp, where, size, val);
476 + spin_unlock_irqrestore(&pp->conf_lock, flags);
477 +
478 + return ret;
479 +}
480 +
481 +static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
482 + int where, int size, u32 val)
483 +{
484 + struct pcie_port *pp = sys_to_pcie(bus->sysdata);
485 + unsigned long flags;
486 + int ret;
487 +
488 + if (!pp) {
489 + BUG();
490 + return -EINVAL;
491 + }
492 +
493 + if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
494 + return PCIBIOS_DEVICE_NOT_FOUND;
495 +
496 + spin_lock_irqsave(&pp->conf_lock, flags);
497 + if (bus->number != pp->root_bus_nr)
498 + ret = dw_pcie_wr_other_conf(pp, bus, devfn,
499 + where, size, val);
500 + else
501 + ret = dw_pcie_wr_own_conf(pp, where, size, val);
502 + spin_unlock_irqrestore(&pp->conf_lock, flags);
503 +
504 + return ret;
505 +}
506 +
507 +static struct pci_ops dw_pcie_ops = {
508 + .read = dw_pcie_rd_conf,
509 + .write = dw_pcie_wr_conf,
510 +};
511 +
512 +int dw_pcie_setup(int nr, struct pci_sys_data *sys)
513 +{
514 + struct pcie_port *pp;
515 +
516 + pp = sys_to_pcie(sys);
517 +
518 + if (!pp)
519 + return 0;
520 +
521 + if (global_io_offset < SZ_1M && pp->config.io_size > 0) {
522 + sys->io_offset = global_io_offset - pp->config.io_bus_addr;
523 + pci_ioremap_io(sys->io_offset, pp->io.start);
524 + global_io_offset += SZ_64K;
525 + pci_add_resource_offset(&sys->resources, &pp->io,
526 + sys->io_offset);
527 + }
528 +
529 + sys->mem_offset = pp->mem.start - pp->config.mem_bus_addr;
530 + pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
531 +
532 + return 1;
533 +}
534 +
535 +struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
536 +{
537 + struct pci_bus *bus;
538 + struct pcie_port *pp = sys_to_pcie(sys);
539 +
540 + if (pp) {
541 + pp->root_bus_nr = sys->busnr;
542 + bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
543 + sys, &sys->resources);
544 + } else {
545 + bus = NULL;
546 + BUG();
547 + }
548 +
549 + return bus;
550 +}
551 +
552 +int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
553 +{
554 + struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
555 +
556 + return pp->irq;
557 +}
558 +
559 +static struct hw_pci dw_pci = {
560 + .setup = dw_pcie_setup,
561 + .scan = dw_pcie_scan_bus,
562 + .map_irq = dw_pcie_map_irq,
563 +};
564 +
565 +void dw_pcie_setup_rc(struct pcie_port *pp)
566 +{
567 + struct pcie_port_info *config = &pp->config;
568 + u32 val;
569 + u32 membase;
570 + u32 memlimit;
571 +
572 + /* set the number of lines as 4 */
573 + dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val);
574 + val &= ~PORT_LINK_MODE_MASK;
575 + switch (pp->lanes) {
576 + case 1:
577 + val |= PORT_LINK_MODE_1_LANES;
578 + break;
579 + case 2:
580 + val |= PORT_LINK_MODE_2_LANES;
581 + break;
582 + case 4:
583 + val |= PORT_LINK_MODE_4_LANES;
584 + break;
585 + }
586 + dw_pcie_writel_rc(pp, val, PCIE_PORT_LINK_CONTROL);
587 +
588 + /* set link width speed control register */
589 + dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, &val);
590 + val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
591 + switch (pp->lanes) {
592 + case 1:
593 + val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
594 + break;
595 + case 2:
596 + val |= PORT_LOGIC_LINK_WIDTH_2_LANES;
597 + break;
598 + case 4:
599 + val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
600 + break;
601 + }
602 + dw_pcie_writel_rc(pp, val, PCIE_LINK_WIDTH_SPEED_CONTROL);
603 +
604 + /* setup RC BARs */
605 + dw_pcie_writel_rc(pp, 0x00000004, PCI_BASE_ADDRESS_0);
606 + dw_pcie_writel_rc(pp, 0x00000004, PCI_BASE_ADDRESS_1);
607 +
608 + /* setup interrupt pins */
609 + dw_pcie_readl_rc(pp, PCI_INTERRUPT_LINE, &val);
610 + val &= 0xffff00ff;
611 + val |= 0x00000100;
612 + dw_pcie_writel_rc(pp, val, PCI_INTERRUPT_LINE);
613 +
614 + /* setup bus numbers */
615 + dw_pcie_readl_rc(pp, PCI_PRIMARY_BUS, &val);
616 + val &= 0xff000000;
617 + val |= 0x00010100;
618 + dw_pcie_writel_rc(pp, val, PCI_PRIMARY_BUS);
619 +
620 + /* setup memory base, memory limit */
621 + membase = ((u32)pp->mem_base & 0xfff00000) >> 16;
622 + memlimit = (config->mem_size + (u32)pp->mem_base) & 0xfff00000;
623 + val = memlimit | membase;
624 + dw_pcie_writel_rc(pp, val, PCI_MEMORY_BASE);
625 +
626 + /* setup command register */
627 + dw_pcie_readl_rc(pp, PCI_COMMAND, &val);
628 + val &= 0xffff0000;
629 + val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
630 + PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
631 + dw_pcie_writel_rc(pp, val, PCI_COMMAND);
632 +}
633 +
634 +MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
635 +MODULE_DESCRIPTION("Designware PCIe host controller driver");
636 +MODULE_LICENSE("GPL v2");