1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/pci-ecam.h>
3 #include <linux/delay.h>
6 #define SMP8759_MUX 0x48
7 #define SMP8759_TEST_OUT 0x74
13 static int smp8759_config_read(struct pci_bus
*bus
, unsigned int devfn
,
14 int where
, int size
, u32
*val
)
16 struct pci_config_window
*cfg
= bus
->sysdata
;
17 struct tango_pcie
*pcie
= dev_get_drvdata(cfg
->parent
);
20 /* Reads in configuration space outside devfn 0 return garbage */
22 return PCIBIOS_FUNC_NOT_SUPPORTED
;
25 * PCI config and MMIO accesses are muxed. Linux doesn't have a
26 * mutual exclusion mechanism for config vs. MMIO accesses, so
27 * concurrent accesses may cause corruption.
29 writel_relaxed(1, pcie
->base
+ SMP8759_MUX
);
30 ret
= pci_generic_config_read(bus
, devfn
, where
, size
, val
);
31 writel_relaxed(0, pcie
->base
+ SMP8759_MUX
);
36 static int smp8759_config_write(struct pci_bus
*bus
, unsigned int devfn
,
37 int where
, int size
, u32 val
)
39 struct pci_config_window
*cfg
= bus
->sysdata
;
40 struct tango_pcie
*pcie
= dev_get_drvdata(cfg
->parent
);
43 writel_relaxed(1, pcie
->base
+ SMP8759_MUX
);
44 ret
= pci_generic_config_write(bus
, devfn
, where
, size
, val
);
45 writel_relaxed(0, pcie
->base
+ SMP8759_MUX
);
50 static struct pci_ecam_ops smp8759_ecam_ops
= {
53 .map_bus
= pci_ecam_map_bus
,
54 .read
= smp8759_config_read
,
55 .write
= smp8759_config_write
,
59 static int tango_pcie_link_up(struct tango_pcie
*pcie
)
61 void __iomem
*test_out
= pcie
->base
+ SMP8759_TEST_OUT
;
64 writel_relaxed(16, test_out
);
65 for (i
= 0; i
< 10; ++i
) {
66 u32 ltssm_state
= readl_relaxed(test_out
) >> 8;
67 if ((ltssm_state
& 0x1f) == 0xf) /* L0 */
69 usleep_range(3000, 4000);
75 static int tango_pcie_probe(struct platform_device
*pdev
)
77 struct device
*dev
= &pdev
->dev
;
78 struct tango_pcie
*pcie
;
82 dev_warn(dev
, "simultaneous PCI config and MMIO accesses may cause data corruption\n");
83 add_taint(TAINT_CRAP
, LOCKDEP_STILL_OK
);
85 pcie
= devm_kzalloc(dev
, sizeof(*pcie
), GFP_KERNEL
);
89 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
90 pcie
->base
= devm_ioremap_resource(dev
, res
);
91 if (IS_ERR(pcie
->base
))
92 return PTR_ERR(pcie
->base
);
94 platform_set_drvdata(pdev
, pcie
);
96 if (!tango_pcie_link_up(pcie
))
99 return pci_host_common_probe(pdev
, &smp8759_ecam_ops
);
102 static const struct of_device_id tango_pcie_ids
[] = {
103 { .compatible
= "sigma,smp8759-pcie" },
107 static struct platform_driver tango_pcie_driver
= {
108 .probe
= tango_pcie_probe
,
110 .name
= KBUILD_MODNAME
,
111 .of_match_table
= tango_pcie_ids
,
112 .suppress_bind_attrs
= true,
115 builtin_platform_driver(tango_pcie_driver
);
118 * The root complex advertises the wrong device class.
119 * Header Type 1 is for PCI-to-PCI bridges.
121 static void tango_fixup_class(struct pci_dev
*dev
)
123 dev
->class = PCI_CLASS_BRIDGE_PCI
<< 8;
125 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA
, 0x0024, tango_fixup_class
);
126 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA
, 0x0028, tango_fixup_class
);
129 * The root complex exposes a "fake" BAR, which is used to filter
130 * bus-to-system accesses. Only accesses within the range defined by this
131 * BAR are forwarded to the host, others are ignored.
133 * By default, the DMA framework expects an identity mapping, and DRAM0 is
134 * mapped at 0x80000000.
136 static void tango_fixup_bar(struct pci_dev
*dev
)
138 dev
->non_compliant_bars
= true;
139 pci_write_config_dword(dev
, PCI_BASE_ADDRESS_0
, 0x80000000);
141 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA
, 0x0024, tango_fixup_bar
);
142 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIGMA
, 0x0028, tango_fixup_bar
);