1 // SPDX-License-Identifier: GPL-2.0+
2 #include <common.h>
3 #include <dm.h>
4 #include <reset.h>
5 #include <fdtdec.h>
6 #include <pci.h>
7 #include <asm/io.h>
8 #include <asm/arch/ahbc_aspeed.h>
9 #include "pcie_aspeed.h"
10
11 DECLARE_GLOBAL_DATA_PTR;
12
13 /* PCI Host Controller registers */
14 #define ASPEED_PCIE_CLASS_CODE 0x04
15 #define ASPEED_PCIE_GLOBAL 0x30
16 #define ASPEED_PCIE_CFG_DIN 0x50
17 #define ASPEED_PCIE_CFG3 0x58
18 #define ASPEED_PCIE_LOCK 0x7C
19 #define ASPEED_PCIE_LINK 0xC0
20 #define ASPEED_PCIE_INT 0xC4
21 #define ASPEED_PCIE_LINK_STS 0xD0
22
23 /* AST_PCIE_CFG2 0x04 */
24 #define PCIE_CFG_CLASS_CODE(x) ((x) << 8)
25 #define PCIE_CFG_REV_ID(x) (x)
26
27 /* AST_PCIE_GLOBAL 0x30 */
28 #define ROOT_COMPLEX_ID(x) ((x) << 4)
29
30 /* AST_PCIE_LOCK 0x7C */
31 #define PCIE_UNLOCK 0xa8
32
33 /* AST_PCIE_LINK 0xC0 */
34 #define PCIE_LINK_STS BIT(5)
35
36 /* ASPEED_PCIE_LINK_STS 0xD0 */
37 #define PCIE_LINK_5G BIT(17)
38 #define PCIE_LINK_2_5G BIT(16)
39
aspeed_pcie_phy_link_status(struct udevice * dev)40 extern int aspeed_pcie_phy_link_status(struct udevice *dev)
41 {
42 struct aspeed_rc_bridge *rc_bridge = dev_get_priv(dev);
43 u32 pcie_link = readl(rc_bridge->reg + ASPEED_PCIE_LINK);
44 int ret = 0;
45
46 printf("RC Bridge %s : ", dev->name);
47 if (pcie_link & PCIE_LINK_STS) {
48 printf("Link up\n");
49 ret = 1;
50 } else {
51 printf("Link down\n");
52 ret = 0;
53 }
54
55 return ret;
56 }
57
aspeed_pcie_phy_probe(struct udevice * dev)58 static int aspeed_pcie_phy_probe(struct udevice *dev)
59 {
60 struct reset_ctl reset_ctl;
61 int ret = 0;
62 struct aspeed_rc_bridge *rc_bridge = dev_get_priv(dev);
63
64 debug("%s(dev=%p)\n", __func__, dev);
65
66 ret = reset_get_by_index(dev, 0, &reset_ctl);
67
68 if (ret) {
69 printf("%s(): Failed to get reset signal\n", __func__);
70 return ret;
71 }
72
73 //reset rc bridge
74 reset_assert(&reset_ctl);
75
76 rc_bridge->reg = devfdt_get_addr_ptr(dev);
77 if (IS_ERR(rc_bridge->reg))
78 return PTR_ERR(rc_bridge->reg);
79
80 writel(PCIE_UNLOCK, rc_bridge->reg + ASPEED_PCIE_LOCK);
81 writel(ROOT_COMPLEX_ID(0x3), rc_bridge->reg + ASPEED_PCIE_GLOBAL);
82
83 return 0;
84 }
85
86 static const struct udevice_id aspeed_pcie_phy_ids[] = {
87 { .compatible = "aspeed,ast2600-pcie_phy" },
88 { }
89 };
90
91 U_BOOT_DRIVER(aspeed_rc_bridge) = {
92 .name = "aspeed_pcie_phy",
93 .id = UCLASS_MISC,
94 .of_match = aspeed_pcie_phy_ids,
95 .probe = aspeed_pcie_phy_probe,
96 .priv_auto_alloc_size = sizeof(struct aspeed_rc_bridge),
97 };
98
99