Commit | Line | Data |
---|---|---|
f473832f RM |
1 | /* |
2 | * Broadcom specific AMBA | |
3 | * PCIe Gen 2 Core | |
4 | * | |
5 | * Copyright 2014, Broadcom Corporation | |
6 | * Copyright 2014, Rafał Miłecki <zajec5@gmail.com> | |
7 | * | |
8 | * Licensed under the GNU/GPL. See COPYING for details. | |
9 | */ | |
10 | ||
11 | #include "bcma_private.h" | |
12 | #include <linux/bcma/bcma.h> | |
13 | ||
14 | /************************************************** | |
15 | * R/W ops. | |
16 | **************************************************/ | |
17 | ||
18 | #if 0 | |
19 | static u32 bcma_core_pcie2_cfg_read(struct bcma_drv_pcie2 *pcie2, u32 addr) | |
20 | { | |
21 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr); | |
22 | pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR); | |
23 | return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA); | |
24 | } | |
25 | #endif | |
26 | ||
27 | static void bcma_core_pcie2_cfg_write(struct bcma_drv_pcie2 *pcie2, u32 addr, | |
28 | u32 val) | |
29 | { | |
30 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr); | |
31 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, val); | |
32 | } | |
33 | ||
34 | /************************************************** | |
35 | * Init. | |
36 | **************************************************/ | |
37 | ||
38 | static u32 bcma_core_pcie2_war_delay_perst_enab(struct bcma_drv_pcie2 *pcie2, | |
39 | bool enable) | |
40 | { | |
41 | u32 val; | |
42 | ||
43 | /* restore back to default */ | |
44 | val = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL); | |
45 | val |= PCIE2_CLKC_DLYPERST; | |
46 | val &= ~PCIE2_CLKC_DISSPROMLD; | |
47 | if (enable) { | |
48 | val &= ~PCIE2_CLKC_DLYPERST; | |
49 | val |= PCIE2_CLKC_DISSPROMLD; | |
50 | } | |
51 | pcie2_write32(pcie2, (BCMA_CORE_PCIE2_CLK_CONTROL), val); | |
52 | /* flush */ | |
53 | return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL); | |
54 | } | |
55 | ||
56 | static void bcma_core_pcie2_set_ltr_vals(struct bcma_drv_pcie2 *pcie2) | |
57 | { | |
58 | /* LTR0 */ | |
59 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x844); | |
60 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x883c883c); | |
61 | /* LTR1 */ | |
62 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x848); | |
63 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x88648864); | |
64 | /* LTR2 */ | |
65 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x84C); | |
66 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x90039003); | |
67 | } | |
68 | ||
69 | static void bcma_core_pcie2_hw_ltr_war(struct bcma_drv_pcie2 *pcie2) | |
70 | { | |
71 | u8 core_rev = pcie2->core->id.rev; | |
72 | u32 devstsctr2; | |
73 | ||
74 | if (core_rev < 2 || core_rev == 10 || core_rev > 13) | |
75 | return; | |
76 | ||
77 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, | |
78 | PCIE2_CAP_DEVSTSCTRL2_OFFSET); | |
79 | devstsctr2 = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA); | |
80 | if (devstsctr2 & PCIE2_CAP_DEVSTSCTRL2_LTRENAB) { | |
81 | /* force the right LTR values */ | |
82 | bcma_core_pcie2_set_ltr_vals(pcie2); | |
83 | ||
84 | /* TODO: | |
85 | si_core_wrapperreg(pcie2, 3, 0x60, 0x8080, 0); */ | |
86 | ||
87 | /* enable the LTR */ | |
88 | devstsctr2 |= PCIE2_CAP_DEVSTSCTRL2_LTRENAB; | |
89 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, | |
90 | PCIE2_CAP_DEVSTSCTRL2_OFFSET); | |
91 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, devstsctr2); | |
92 | ||
93 | /* set the LTR state to be active */ | |
94 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE, | |
95 | PCIE2_LTR_ACTIVE); | |
96 | usleep_range(1000, 2000); | |
97 | ||
98 | /* set the LTR state to be sleep */ | |
99 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE, | |
100 | PCIE2_LTR_SLEEP); | |
101 | usleep_range(1000, 2000); | |
102 | } | |
103 | } | |
104 | ||
105 | static void pciedev_crwlpciegen2(struct bcma_drv_pcie2 *pcie2) | |
106 | { | |
107 | u8 core_rev = pcie2->core->id.rev; | |
108 | bool pciewar160, pciewar162; | |
109 | ||
110 | pciewar160 = core_rev == 7 || core_rev == 9 || core_rev == 11; | |
111 | pciewar162 = core_rev == 5 || core_rev == 7 || core_rev == 8 || | |
112 | core_rev == 9 || core_rev == 11; | |
113 | ||
114 | if (!pciewar160 && !pciewar162) | |
115 | return; | |
116 | ||
117 | /* TODO */ | |
118 | #if 0 | |
119 | pcie2_set32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL, | |
120 | PCIE_DISABLE_L1CLK_GATING); | |
121 | #if 0 | |
122 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, | |
123 | PCIEGEN2_COE_PVT_TL_CTRL_0); | |
124 | pcie2_mask32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, | |
125 | ~(1 << COE_PVT_TL_CTRL_0_PM_DIS_L1_REENTRY_BIT)); | |
126 | #endif | |
127 | #endif | |
128 | } | |
129 | ||
130 | static void pciedev_crwlpciegen2_180(struct bcma_drv_pcie2 *pcie2) | |
131 | { | |
132 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_PMCR_REFUP); | |
133 | pcie2_set32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x1f); | |
134 | } | |
135 | ||
136 | static void pciedev_crwlpciegen2_182(struct bcma_drv_pcie2 *pcie2) | |
137 | { | |
138 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_SBMBX); | |
139 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 1 << 0); | |
140 | } | |
141 | ||
142 | static void pciedev_reg_pm_clk_period(struct bcma_drv_pcie2 *pcie2) | |
143 | { | |
144 | struct bcma_drv_cc *drv_cc = &pcie2->core->bus->drv_cc; | |
145 | u8 core_rev = pcie2->core->id.rev; | |
146 | u32 alp_khz, pm_value; | |
147 | ||
148 | if (core_rev <= 13) { | |
149 | alp_khz = bcma_pmu_get_alp_clock(drv_cc) / 1000; | |
150 | pm_value = (1000000 * 2) / alp_khz; | |
151 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, | |
152 | PCIE2_PVT_REG_PM_CLK_PERIOD); | |
153 | pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, pm_value); | |
154 | } | |
155 | } | |
156 | ||
157 | void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2) | |
158 | { | |
159 | struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo; | |
160 | u32 tmp; | |
161 | ||
162 | tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54)); | |
163 | if ((tmp & 0xe) >> 1 == 2) | |
164 | bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17); | |
165 | ||
166 | /* TODO: Do we need pcie_reqsize? */ | |
167 | ||
168 | if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3) | |
169 | bcma_core_pcie2_war_delay_perst_enab(pcie2, true); | |
170 | bcma_core_pcie2_hw_ltr_war(pcie2); | |
171 | pciedev_crwlpciegen2(pcie2); | |
172 | pciedev_reg_pm_clk_period(pcie2); | |
173 | pciedev_crwlpciegen2_180(pcie2); | |
174 | pciedev_crwlpciegen2_182(pcie2); | |
175 | } |