2 * PCIe driver for PLX NAS782X SoCs
4 * Author: Ma Haijun <mahaijuns@gmail.com>
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
11 #include <linux/kernel.h>
12 #include <linux/pci.h>
13 #include <linux/clk.h>
14 #include <linux/module.h>
15 #include <linux/mbus.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/slab.h>
18 #include <linux/platform_device.h>
19 #include <linux/of_address.h>
20 #include <linux/of_device.h>
21 #include <linux/of_gpio.h>
22 #include <linux/of_irq.h>
23 #include <linux/of_pci.h>
24 #include <linux/of_platform.h>
25 #include <linux/gpio.h>
26 #include <linux/delay.h>
27 #include <linux/clk.h>
28 #include <linux/phy.h>
29 #include <linux/phy/phy.h>
30 #include <linux/regmap.h>
31 #include <linux/reset.h>
33 #include <linux/sizes.h>
35 #define SYS_CTRL_HCSL_CTRL_REGOFFSET 0x114
37 static inline void oxnas_register_clear_mask(void __iomem
*p
, unsigned mask
)
39 u32 val
= readl_relaxed(p
);
42 writel_relaxed(val
, p
);
45 static inline void oxnas_register_set_mask(void __iomem
*p
, unsigned mask
)
47 u32 val
= readl_relaxed(p
);
50 writel_relaxed(val
, p
);
53 static inline void oxnas_register_value_mask(void __iomem
*p
,
54 unsigned mask
, unsigned new_value
)
56 /* TODO sanity check mask & new_value = new_value */
57 u32 val
= readl_relaxed(p
);
61 writel_relaxed(val
, p
);
64 #define VERSION_ID_MAGIC 0x082510b5
65 #define LINK_UP_TIMEOUT_SECONDS 1
66 #define NUM_CONTROLLERS 1
69 PCIE_DEVICE_TYPE_MASK
= 0x0F,
70 PCIE_DEVICE_TYPE_ENDPOINT
= 0,
71 PCIE_DEVICE_TYPE_LEGACY_ENDPOINT
= 1,
72 PCIE_DEVICE_TYPE_ROOT
= 4,
75 PCIE_READY_ENTR_L23
= BIT(9),
76 PCIE_LINK_UP
= BIT(11),
77 PCIE_OBTRANS
= BIT(12),
80 /* core config registers */
82 PCI_CONFIG_VERSION_DEVICEID
= 0,
83 PCI_CONFIG_COMMAND_STATUS
= 4,
86 /* inbound config registers */
88 IB_ADDR_XLATE_ENABLE
= 0xFC,
91 ENABLE_IN_ADDR_TRANS
= BIT(0),
94 /* outbound config registers, offset relative to PCIE_POM0_MEM_ADDR */
96 PCIE_POM0_MEM_ADDR
= 0,
97 PCIE_POM1_MEM_ADDR
= 4,
98 PCIE_IN0_MEM_ADDR
= 8,
99 PCIE_IN1_MEM_ADDR
= 12,
100 PCIE_IN_IO_ADDR
= 16,
101 PCIE_IN_CFG0_ADDR
= 20,
102 PCIE_IN_CFG1_ADDR
= 24,
103 PCIE_IN_MSG_ADDR
= 28,
104 PCIE_IN0_MEM_LIMIT
= 32,
105 PCIE_IN1_MEM_LIMIT
= 36,
106 PCIE_IN_IO_LIMIT
= 40,
107 PCIE_IN_CFG0_LIMIT
= 44,
108 PCIE_IN_CFG1_LIMIT
= 48,
109 PCIE_IN_MSG_LIMIT
= 52,
110 PCIE_AHB_SLAVE_CTRL
= 56,
112 PCIE_SLAVE_BE_SHIFT
= 22,
115 #define PCIE_SLAVE_BE(val) ((val) << PCIE_SLAVE_BE_SHIFT)
116 #define PCIE_SLAVE_BE_MASK PCIE_SLAVE_BE(0xF)
118 struct oxnas_pcie_shared
{
119 /* seems all access are serialized, no lock required */
123 /* Structure representing one PCIe interfaces */
125 void __iomem
*cfgbase
;
127 void __iomem
*inbound
;
128 struct regmap
*sys_ctrl
;
129 unsigned int outbound_offset
;
130 unsigned int pcie_ctrl_offset
;
133 struct platform_device
*pdev
;
136 struct resource pre_mem
; /* prefetchable */
137 struct resource non_mem
; /* non-prefetchable */
138 struct resource busn
; /* max available bus numbers */
139 int card_reset
; /* gpio pin, optional */
140 unsigned hcsl_en
; /* hcsl pci enable bit */
142 struct clk
*busclk
; /* for pcie bus, actually the PLLB */
143 void *private_data
[1];
147 static struct oxnas_pcie_shared pcie_shared
= {
151 static inline struct oxnas_pcie
*sys_to_pcie(struct pci_sys_data
*sys
)
153 return sys
->private_data
;
157 static inline void set_out_lanes(struct oxnas_pcie
*pcie
, unsigned lanes
)
159 regmap_update_bits(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_AHB_SLAVE_CTRL
,
160 PCIE_SLAVE_BE_MASK
, PCIE_SLAVE_BE(lanes
));
164 static int oxnas_pcie_link_up(struct oxnas_pcie
*pcie
)
169 /* Poll for PCIE link up */
170 end
= jiffies
+ (LINK_UP_TIMEOUT_SECONDS
* HZ
);
171 while (!time_after(jiffies
, end
)) {
172 regmap_read(pcie
->sys_ctrl
, pcie
->pcie_ctrl_offset
, &val
);
173 if (val
& PCIE_LINK_UP
)
179 static void oxnas_pcie_setup_hw(struct oxnas_pcie
*pcie
)
181 /* We won't have any inbound address translation. This allows PCI
182 * devices to access anywhere in the AHB address map. Might be regarded
183 * as a bit dangerous, but let's get things working before we worry
186 oxnas_register_clear_mask(pcie
->inbound
+ IB_ADDR_XLATE_ENABLE
,
187 ENABLE_IN_ADDR_TRANS
);
191 * Program outbound translation windows
193 * Outbound window is what is referred to as "PCI client" region in HRM
195 * Could use the larger alternative address space to get >>64M regions
196 * for graphics cards etc., but will not bother at this point.
198 * IP bug means that AMBA window size must be a power of 2
200 * Set mem0 window for first 16MB of outbound window non-prefetchable
201 * Set mem1 window for second 16MB of outbound window prefetchable
202 * Set io window for next 16MB of outbound window
203 * Set cfg0 for final 1MB of outbound window
205 * Ignore mem1, cfg1 and msg windows for now as no obvious use cases for
206 * 820 that would need them
208 * Probably ideally want no offset between mem0 window start as seen by
209 * ARM and as seen on PCI bus and get Linux to assign memory regions to
210 * PCI devices using the same "PCI client" region start address as seen
214 /* Set PCIeA mem0 region to be 1st 16MB of the 64MB PCIeA window */
215 regmap_write(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_IN0_MEM_ADDR
, pcie
->non_mem
.start
);
216 regmap_write(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_IN0_MEM_LIMIT
, pcie
->non_mem
.end
);
217 regmap_write(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_POM0_MEM_ADDR
, pcie
->non_mem
.start
);
219 /* Set PCIeA mem1 region to be 2nd 16MB of the 64MB PCIeA window */
220 regmap_write(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_IN1_MEM_ADDR
, pcie
->pre_mem
.start
);
221 regmap_write(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_IN1_MEM_LIMIT
, pcie
->pre_mem
.end
);
222 regmap_write(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_POM1_MEM_ADDR
, pcie
->pre_mem
.start
);
224 /* Set PCIeA io to be third 16M region of the 64MB PCIeA window*/
225 regmap_write(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_IN_IO_ADDR
, pcie
->io
.start
);
226 regmap_write(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_IN_IO_LIMIT
, pcie
->io
.end
);
229 /* Set PCIeA cgf0 to be last 16M region of the 64MB PCIeA window*/
230 regmap_write(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_IN_CFG0_ADDR
, pcie
->cfg
.start
);
231 regmap_write(pcie
->sys_ctrl
, pcie
->outbound_offset
+ PCIE_IN_CFG0_LIMIT
, pcie
->cfg
.end
);
234 /* Enable outbound address translation */
235 regmap_write_bits(pcie
->sys_ctrl
, pcie
->pcie_ctrl_offset
, PCIE_OBTRANS
, PCIE_OBTRANS
);
239 * Program PCIe command register for core to:
240 * enable memory space
244 writel_relaxed(7, pcie
->base
+ PCI_CONFIG_COMMAND_STATUS
);
249 static unsigned oxnas_pcie_cfg_to_offset(
250 struct pci_sys_data
*sys
,
251 unsigned char bus_number
,
255 unsigned int function
= PCI_FUNC(devfn
);
256 unsigned int slot
= PCI_SLOT(devfn
);
257 unsigned char bus_number_offset
;
259 bus_number_offset
= bus_number
- sys
->busnr
;
262 * We'll assume for now that the offset, function, slot, bus encoding
263 * should map onto linear, contiguous addresses in PCIe config space,
264 * albeit that the majority will be unused as only slot 0 is valid for
265 * any PCIe bus and most devices have only function 0
267 * Could be that PCIe in fact works by not encoding the slot number into
268 * the config space address as it's known that only slot 0 is valid.
269 * We'll have to experiment if/when we get a PCIe switch connected to
272 return (bus_number_offset
<< 20) | (slot
<< 15) | (function
<< 12) |
276 /* PCI configuration space write function */
277 static int oxnas_pcie_wr_conf(struct pci_bus
*bus
, u32 devfn
,
278 int where
, int size
, u32 val
)
281 struct oxnas_pcie
*pcie
= sys_to_pcie(bus
->sysdata
);
286 /* Only a single device per bus for PCIe point-to-point links */
287 if (PCI_SLOT(devfn
) > 0)
288 return PCIBIOS_DEVICE_NOT_FOUND
;
291 return PCIBIOS_DEVICE_NOT_FOUND
;
293 offset
= oxnas_pcie_cfg_to_offset(bus
->sysdata
, bus
->number
, devfn
,
296 value
= val
<< (8 * (where
& 3));
297 lanes
= (0xf >> (4-size
)) << (where
& 3);
298 /* it race with mem and io write, but the possibility is low, normally
299 * all config writes happens at driver initialize stage, wont interleave
301 * and many pcie cards use dword (4bytes) access mem/io access only,
302 * so not bother to copy that ugly work-around now. */
303 spin_lock_irqsave(&pcie
->lock
, flags
);
304 set_out_lanes(pcie
, lanes
);
305 writel_relaxed(value
, pcie
->cfgbase
+ offset
);
306 set_out_lanes(pcie
, 0xf);
307 spin_unlock_irqrestore(&pcie
->lock
, flags
);
309 return PCIBIOS_SUCCESSFUL
;
312 /* PCI configuration space read function */
313 static int oxnas_pcie_rd_conf(struct pci_bus
*bus
, u32 devfn
, int where
,
316 struct oxnas_pcie
*pcie
= sys_to_pcie(bus
->sysdata
);
319 u32 left_bytes
, right_bytes
;
321 /* Only a single device per bus for PCIe point-to-point links */
322 if (PCI_SLOT(devfn
) > 0) {
324 return PCIBIOS_DEVICE_NOT_FOUND
;
327 if (!pcie
->haslink
) {
329 return PCIBIOS_DEVICE_NOT_FOUND
;
332 offset
= oxnas_pcie_cfg_to_offset(bus
->sysdata
, bus
->number
, devfn
,
334 value
= readl_relaxed(pcie
->cfgbase
+ offset
);
335 left_bytes
= where
& 3;
336 right_bytes
= 4 - left_bytes
- size
;
337 value
<<= right_bytes
* 8;
338 value
>>= (left_bytes
+ right_bytes
) * 8;
341 return PCIBIOS_SUCCESSFUL
;
344 static struct pci_ops oxnas_pcie_ops
= {
345 .read
= oxnas_pcie_rd_conf
,
346 .write
= oxnas_pcie_wr_conf
,
349 static int oxnas_pcie_setup(int nr
, struct pci_sys_data
*sys
)
351 struct oxnas_pcie
*pcie
= sys_to_pcie(sys
);
353 pci_add_resource_offset(&sys
->resources
, &pcie
->non_mem
, sys
->mem_offset
);
354 pci_add_resource_offset(&sys
->resources
, &pcie
->pre_mem
, sys
->mem_offset
);
355 pci_add_resource_offset(&sys
->resources
, &pcie
->io
, sys
->io_offset
);
356 pci_add_resource(&sys
->resources
, &pcie
->busn
);
357 if (sys
->busnr
== 0) { /* default one */
358 sys
->busnr
= pcie
->busn
.start
;
360 /* do not use devm_ioremap_resource, it does not like cfg resource */
361 pcie
->cfgbase
= devm_ioremap(&pcie
->pdev
->dev
, pcie
->cfg
.start
,
362 resource_size(&pcie
->cfg
));
366 oxnas_pcie_setup_hw(pcie
);
371 static void oxnas_pcie_enable(struct device
*dev
, struct oxnas_pcie
*pcie
)
376 memset(&hw
, 0, sizeof(hw
));
377 for (i
= 0; i
< NUM_CONTROLLERS
; i
++)
378 pcie
->private_data
[i
] = pcie
;
380 hw
.nr_controllers
= NUM_CONTROLLERS
;
381 /* I think use stack pointer is a bad idea though it is valid in this case */
382 hw
.private_data
= pcie
->private_data
;
383 hw
.setup
= oxnas_pcie_setup
;
384 hw
.map_irq
= of_irq_parse_and_map_pci
;
385 hw
.ops
= &oxnas_pcie_ops
;
387 /* pass dev to maintain of tree, interrupt mapping rely on this */
388 pci_common_init_dev(dev
, &hw
);
391 static int oxnas_pcie_shared_init(struct platform_device
*pdev
, struct oxnas_pcie
*pcie
)
393 if (++pcie_shared
.refcount
== 1) {
395 phy_power_on(pcie
->phy
);
403 /* maybe we will call it when enter low power state */
404 static void oxnas_pcie_shared_deinit(struct platform_device
*pdev
)
406 if (--pcie_shared
.refcount
== 0) {
407 /* no cleanup needed */;
413 oxnas_pcie_map_registers(struct platform_device
*pdev
,
414 struct device_node
*np
,
415 struct oxnas_pcie
*pcie
)
417 struct resource regs
;
419 u32 outbound_ctrl_offset
;
420 u32 pcie_ctrl_offset
;
422 ret
= of_address_to_resource(np
, 0, ®s
);
425 pcie
->base
= devm_ioremap_resource(&pdev
->dev
, ®s
);
429 ret
= of_address_to_resource(np
, 1, ®s
);
432 pcie
->inbound
= devm_ioremap_resource(&pdev
->dev
, ®s
);
436 pcie
->phy
= devm_of_phy_get(&pdev
->dev
, np
, NULL
);
437 if (IS_ERR(pcie
->phy
)) {
438 if (PTR_ERR(pcie
->phy
) == -EPROBE_DEFER
)
439 return PTR_ERR(pcie
->phy
);
443 if (of_property_read_u32(np
, "plxtech,pcie-outbound-offset",
444 &outbound_ctrl_offset
))
446 pcie
->outbound_offset
= outbound_ctrl_offset
;
448 if (of_property_read_u32(np
, "plxtech,pcie-ctrl-offset",
451 pcie
->pcie_ctrl_offset
= pcie_ctrl_offset
;
456 static int oxnas_pcie_init_res(struct platform_device
*pdev
,
457 struct oxnas_pcie
*pcie
,
458 struct device_node
*np
)
460 struct of_pci_range range
;
461 struct of_pci_range_parser parser
;
464 if (of_pci_range_parser_init(&parser
, np
))
467 /* Get the I/O and memory ranges from DT */
468 for_each_of_pci_range(&parser
, &range
) {
470 unsigned long restype
= range
.flags
& IORESOURCE_TYPE_BITS
;
471 if (restype
== IORESOURCE_IO
) {
472 of_pci_range_to_resource(&range
, np
, &pcie
->io
);
473 pcie
->io
.name
= "I/O";
475 if (restype
== IORESOURCE_MEM
) {
476 if (range
.flags
& IORESOURCE_PREFETCH
) {
477 of_pci_range_to_resource(&range
, np
, &pcie
->pre_mem
);
478 pcie
->pre_mem
.name
= "PRE MEM";
480 of_pci_range_to_resource(&range
, np
, &pcie
->non_mem
);
481 pcie
->non_mem
.name
= "NON MEM";
486 of_pci_range_to_resource(&range
, np
, &pcie
->cfg
);
489 /* Get the bus range */
490 ret
= of_pci_parse_bus_range(np
, &pcie
->busn
);
493 dev_err(&pdev
->dev
, "failed to parse bus-range property: %d\n",
498 pcie
->card_reset
= of_get_gpio(np
, 0);
499 if (pcie
->card_reset
< 0)
500 dev_info(&pdev
->dev
, "card reset gpio pin not exists\n");
502 if (of_property_read_u32(np
, "plxtech,pcie-hcsl-bit", &pcie
->hcsl_en
))
505 pcie
->clk
= of_clk_get_by_name(np
, "pcie");
506 if (IS_ERR(pcie
->clk
)) {
507 return PTR_ERR(pcie
->clk
);
510 pcie
->busclk
= of_clk_get_by_name(np
, "busclk");
511 if (IS_ERR(pcie
->busclk
)) {
513 return PTR_ERR(pcie
->busclk
);
519 static void oxnas_pcie_init_hw(struct platform_device
*pdev
,
520 struct oxnas_pcie
*pcie
)
525 clk_prepare_enable(pcie
->busclk
);
527 /* reset PCIe cards use hard-wired gpio pin */
528 if (pcie
->card_reset
>= 0 &&
529 !gpio_direction_output(pcie
->card_reset
, 0)) {
532 /* must tri-state the pin to pull it up */
533 gpio_direction_input(pcie
->card_reset
);
538 /* ToDo: use phy power-on port... */
539 regmap_update_bits(pcie
->sys_ctrl
, SYS_CTRL_HCSL_CTRL_REGOFFSET
,
540 BIT(pcie
->hcsl_en
), BIT(pcie
->hcsl_en
));
543 ret
= device_reset(&pdev
->dev
);
545 dev_err(&pdev
->dev
, "core reset failed %d\n", ret
);
549 /* Start PCIe core clocks */
550 clk_prepare_enable(pcie
->clk
);
552 version_id
= readl_relaxed(pcie
->base
+ PCI_CONFIG_VERSION_DEVICEID
);
553 dev_info(&pdev
->dev
, "PCIe version/deviceID 0x%x\n", version_id
);
555 if (version_id
!= VERSION_ID_MAGIC
) {
556 dev_info(&pdev
->dev
, "PCIe controller not found\n");
561 /* allow entry to L23 state */
562 regmap_write_bits(pcie
->sys_ctrl
, pcie
->pcie_ctrl_offset
,
563 PCIE_READY_ENTR_L23
, PCIE_READY_ENTR_L23
);
565 /* Set PCIe core into RootCore mode */
566 regmap_write_bits(pcie
->sys_ctrl
, pcie
->pcie_ctrl_offset
,
567 PCIE_DEVICE_TYPE_MASK
, PCIE_DEVICE_TYPE_ROOT
);
570 /* Bring up the PCI core */
571 regmap_write_bits(pcie
->sys_ctrl
, pcie
->pcie_ctrl_offset
,
572 PCIE_LTSSM
, PCIE_LTSSM
);
576 static int oxnas_pcie_probe(struct platform_device
*pdev
)
578 struct oxnas_pcie
*pcie
;
579 struct device_node
*np
= pdev
->dev
.of_node
;
582 pcie
= devm_kzalloc(&pdev
->dev
, sizeof(struct oxnas_pcie
),
589 spin_lock_init(&pcie
->lock
);
591 pcie
->sys_ctrl
= syscon_regmap_lookup_by_compatible("oxsemi,ox820-sys-ctrl");
592 if (IS_ERR(pcie
->sys_ctrl
))
593 return PTR_ERR(pcie
->sys_ctrl
);
595 ret
= oxnas_pcie_init_res(pdev
, pcie
, np
);
598 if (pcie
->card_reset
>= 0) {
599 ret
= gpio_request_one(pcie
->card_reset
, GPIOF_DIR_IN
,
600 dev_name(&pdev
->dev
));
602 dev_err(&pdev
->dev
, "cannot request gpio pin %d\n",
608 ret
= oxnas_pcie_map_registers(pdev
, np
, pcie
);
610 dev_err(&pdev
->dev
, "cannot map registers\n");
614 ret
= oxnas_pcie_shared_init(pdev
, pcie
);
618 /* if hw not found, haslink cleared */
619 oxnas_pcie_init_hw(pdev
, pcie
);
621 if (pcie
->haslink
&& oxnas_pcie_link_up(pcie
)) {
623 dev_info(&pdev
->dev
, "link up\n");
626 dev_info(&pdev
->dev
, "link down\n");
628 /* should we register our controller even when pcie->haslink is 0 ? */
629 /* register the controller with framework */
630 oxnas_pcie_enable(&pdev
->dev
, pcie
);
635 if (pcie
->card_reset
)
636 gpio_free(pcie
->card_reset
);
641 static const struct of_device_id oxnas_pcie_of_match_table
[] = {
642 { .compatible
= "plxtech,nas782x-pcie", },
646 static struct platform_driver oxnas_pcie_driver
= {
648 .name
= "oxnas-pcie",
649 .suppress_bind_attrs
= true,
650 .of_match_table
= oxnas_pcie_of_match_table
,
652 .probe
= oxnas_pcie_probe
,
655 builtin_platform_driver(oxnas_pcie_driver
);