blob: 8e3b13b49ea0bc1e79f6b526a8e55bb89b4e0e1d [file] [log] [blame]
Wilson Dinge51f2b12018-03-26 15:57:29 +08001/*
2 * ***************************************************************************
3 * Copyright (C) 2015 Marvell International Ltd.
4 * ***************************************************************************
5 * This program is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation, either version 2 of the License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 * ***************************************************************************
17 */
18/* pcie_advk.c
19 *
20 * Ported from Linux driver - driver/pci/host/pci-aardvark.c
21 *
22 * Author: Victor Gu <xigu@marvell.com>
23 * Hezi Shahmoon <hezi.shahmoon@marvell.com>
Pali Rohár22f69fc2021-12-16 12:04:06 +010024 * Pali Rohár <pali@kernel.org>
Wilson Dinge51f2b12018-03-26 15:57:29 +080025 *
26 */
27
28#include <common.h>
29#include <dm.h>
30#include <pci.h>
31#include <asm/io.h>
32#include <asm-generic/gpio.h>
Simon Glass336d4612020-02-03 07:36:16 -070033#include <dm/device_compat.h>
Simon Glasscd93d622020-05-10 11:40:13 -060034#include <linux/bitops.h>
Simon Glassc05ed002020-05-10 11:40:11 -060035#include <linux/delay.h>
Wilson Dinge51f2b12018-03-26 15:57:29 +080036#include <linux/ioport.h>
37
Pali Rohár819a43c2022-02-10 14:53:42 +010038/* PCIe Root Port register offsets */
39#define ADVK_ROOT_PORT_PCI_CFG_OFF 0x0
40#define ADVK_ROOT_PORT_PCI_EXP_OFF 0xc0
41#define ADVK_ROOT_PORT_PCI_ERR_OFF 0x100
Wilson Dinge51f2b12018-03-26 15:57:29 +080042
Pali Rohárcf2a5892022-02-10 14:53:43 +010043/* PIO registers */
44#define ADVK_PIO_BASE_ADDR 0x4000
45#define ADVK_PIO_CTRL (ADVK_PIO_BASE_ADDR + 0x0)
46#define ADVK_PIO_CTRL_TYPE_MASK GENMASK(3, 0)
47#define ADVK_PIO_CTRL_TYPE_SHIFT 0
48#define ADVK_PIO_CTRL_TYPE_RD_TYPE0 0x8
49#define ADVK_PIO_CTRL_TYPE_RD_TYPE1 0x9
50#define ADVK_PIO_CTRL_TYPE_WR_TYPE0 0xa
51#define ADVK_PIO_CTRL_TYPE_WR_TYPE1 0xb
52#define ADVK_PIO_CTRL_ADDR_WIN_DISABLE BIT(24)
53#define ADVK_PIO_STAT (ADVK_PIO_BASE_ADDR + 0x4)
54#define ADVK_PIO_COMPLETION_STATUS_MASK GENMASK(9, 7)
55#define ADVK_PIO_COMPLETION_STATUS_SHIFT 7
56#define ADVK_PIO_COMPLETION_STATUS_OK 0
57#define ADVK_PIO_COMPLETION_STATUS_UR 1
58#define ADVK_PIO_COMPLETION_STATUS_CRS 2
59#define ADVK_PIO_COMPLETION_STATUS_CA 4
60#define ADVK_PIO_NON_POSTED_REQ BIT(10)
61#define ADVK_PIO_ERR_STATUS BIT(11)
62#define ADVK_PIO_ADDR_LS (ADVK_PIO_BASE_ADDR + 0x8)
63#define ADVK_PIO_ADDR_MS (ADVK_PIO_BASE_ADDR + 0xc)
64#define ADVK_PIO_WR_DATA (ADVK_PIO_BASE_ADDR + 0x10)
65#define ADVK_PIO_WR_DATA_STRB (ADVK_PIO_BASE_ADDR + 0x14)
66#define ADVK_PIO_RD_DATA (ADVK_PIO_BASE_ADDR + 0x18)
67#define ADVK_PIO_START (ADVK_PIO_BASE_ADDR + 0x1c)
68#define ADVK_PIO_ISR (ADVK_PIO_BASE_ADDR + 0x20)
Wilson Dinge51f2b12018-03-26 15:57:29 +080069
Pali Rohárcf2a5892022-02-10 14:53:43 +010070/* Global Control registers */
71#define ADVK_GLOBAL_CTRL_BASE_ADDR 0x4800
72#define ADVK_GLOBAL_CTRL0 (ADVK_GLOBAL_CTRL_BASE_ADDR + 0x0)
73#define ADVK_GLOBAL_CTRL0_SPEED_GEN_MASK GENMASK(1, 0)
74#define ADVK_GLOBAL_CTRL0_SPEED_GEN_SHIFT 0
75#define ADVK_GLOBAL_CTRL0_SPEED_GEN_1 0
76#define ADVK_GLOBAL_CTRL0_SPEED_GEN_2 1
77#define ADVK_GLOBAL_CTRL0_SPEED_GEN_3 2
78#define ADVK_GLOBAL_CTRL0_IS_RC BIT(2)
79#define ADVK_GLOBAL_CTRL0_LANE_COUNT_MASK GENMASK(4, 3)
80#define ADVK_GLOBAL_CTRL0_LANE_COUNT_SHIFT 3
81#define ADVK_GLOBAL_CTRL0_LANE_COUNT_1 0
82#define ADVK_GLOBAL_CTRL0_LANE_COUNT_2 1
83#define ADVK_GLOBAL_CTRL0_LANE_COUNT_4 2
84#define ADVK_GLOBAL_CTRL0_LANE_COUNT_8 3
85#define ADVK_GLOBAL_CTRL0_LINK_TRAINING_EN BIT(6)
86#define ADVK_GLOBAL_CTRL2 (ADVK_GLOBAL_CTRL_BASE_ADDR + 0x8)
87#define ADVK_GLOBAL_CTRL2_STRICT_ORDER_EN BIT(5)
88#define ADVK_GLOBAL_CTRL2_ADDRWIN_MAP_EN BIT(6)
Wilson Dinge51f2b12018-03-26 15:57:29 +080089
Pali Rohárcf2a5892022-02-10 14:53:43 +010090/* PCIe window configuration registers */
91#define ADVK_OB_WIN_BASE_ADDR 0x4c00
92#define ADVK_OB_WIN_BLOCK_SIZE 0x20
93#define ADVK_OB_WIN_COUNT 8
94#define ADVK_OB_WIN_REG_ADDR(win, offset) (ADVK_OB_WIN_BASE_ADDR + ADVK_OB_WIN_BLOCK_SIZE * (win) + (offset))
95#define ADVK_OB_WIN_MATCH_LS(win) ADVK_OB_WIN_REG_ADDR(win, 0x00)
96#define ADVK_OB_WIN_ENABLE BIT(0)
97#define ADVK_OB_WIN_MATCH_MS(win) ADVK_OB_WIN_REG_ADDR(win, 0x04)
98#define ADVK_OB_WIN_REMAP_LS(win) ADVK_OB_WIN_REG_ADDR(win, 0x08)
99#define ADVK_OB_WIN_REMAP_MS(win) ADVK_OB_WIN_REG_ADDR(win, 0x0c)
100#define ADVK_OB_WIN_MASK_LS(win) ADVK_OB_WIN_REG_ADDR(win, 0x10)
101#define ADVK_OB_WIN_MASK_MS(win) ADVK_OB_WIN_REG_ADDR(win, 0x14)
102#define ADVK_OB_WIN_ACTIONS(win) ADVK_OB_WIN_REG_ADDR(win, 0x18)
103#define ADVK_OB_WIN_DEFAULT_ACTIONS (ADVK_OB_WIN_ACTIONS(ADVK_OB_WIN_COUNT-1) + 0x4)
104#define ADVK_OB_WIN_FUNC_NUM_MASK GENMASK(31, 24)
105#define ADVK_OB_WIN_FUNC_NUM_SHIFT 24
106#define ADVK_OB_WIN_FUNC_NUM_ENABLE BIT(23)
107#define ADVK_OB_WIN_BUS_NUM_BITS_MASK GENMASK(22, 20)
108#define ADVK_OB_WIN_BUS_NUM_BITS_SHIFT 20
109#define ADVK_OB_WIN_MSG_CODE_ENABLE BIT(22)
110#define ADVK_OB_WIN_MSG_CODE_MASK GENMASK(21, 14)
111#define ADVK_OB_WIN_MSG_CODE_SHIFT 14
112#define ADVK_OB_WIN_MSG_PAYLOAD_LEN BIT(12)
113#define ADVK_OB_WIN_ATTR_ENABLE BIT(11)
114#define ADVK_OB_WIN_ATTR_TC_MASK GENMASK(10, 8)
115#define ADVK_OB_WIN_ATTR_TC_SHIFT 8
116#define ADVK_OB_WIN_ATTR_RELAXED BIT(7)
117#define ADVK_OB_WIN_ATTR_NOSNOOP BIT(6)
118#define ADVK_OB_WIN_ATTR_POISON BIT(5)
119#define ADVK_OB_WIN_ATTR_IDO BIT(4)
120#define ADVK_OB_WIN_TYPE_MASK GENMASK(3, 0)
121#define ADVK_OB_WIN_TYPE_SHIFT 0
122#define ADVK_OB_WIN_TYPE_MEM 0x0
123#define ADVK_OB_WIN_TYPE_IO 0x4
124#define ADVK_OB_WIN_TYPE_CONFIG_TYPE0 0x8
125#define ADVK_OB_WIN_TYPE_CONFIG_TYPE1 0x9
126#define ADVK_OB_WIN_TYPE_MSG 0xc
Pali Rohárb3217222021-05-26 17:59:40 +0200127
Pali Rohárcf2a5892022-02-10 14:53:43 +0100128/* Local Management Interface registers */
129#define ADVK_LMI_BASE_ADDR 0x6000
130#define ADVK_LMI_PHY_CFG0 (ADVK_LMI_BASE_ADDR + 0x0)
131#define ADVK_LMI_PHY_CFG0_LTSSM_MASK GENMASK(29, 24)
132#define ADVK_LMI_PHY_CFG0_LTSSM_SHIFT 24
133#define ADVK_LMI_PHY_CFG0_LTSSM_L0 0x10
134#define ADVK_LMI_PHY_CFG0_LTSSM_DISABLED 0x20
135#define ADVK_LMI_VENDOR_ID (ADVK_LMI_BASE_ADDR + 0x44)
Wilson Dinge51f2b12018-03-26 15:57:29 +0800136
Pali Rohárcf2a5892022-02-10 14:53:43 +0100137/* Core Control registers */
138#define ADVK_CORE_CTRL_BASE_ADDR 0x18000
139#define ADVK_CORE_CTRL_CONFIG (ADVK_CORE_CTRL_BASE_ADDR + 0x0)
140#define ADVK_CORE_CTRL_CONFIG_COMMAND_MODE BIT(0)
Wilson Dinge51f2b12018-03-26 15:57:29 +0800141
Wilson Dinge51f2b12018-03-26 15:57:29 +0800142/* PCIe Retries & Timeout definitions */
Pali Roháreccbd4a2021-04-22 16:23:04 +0200143#define PIO_MAX_RETRIES 1500
144#define PIO_WAIT_TIMEOUT 1000
145#define LINK_MAX_RETRIES 10
Wilson Dinge51f2b12018-03-26 15:57:29 +0800146#define LINK_WAIT_TIMEOUT 100000
147
Pali Rohárcf2a5892022-02-10 14:53:43 +0100148#define CFG_RD_CRS_VAL 0xFFFF0001
Wilson Dinge51f2b12018-03-26 15:57:29 +0800149
Wilson Dinge51f2b12018-03-26 15:57:29 +0800150/**
151 * struct pcie_advk - Advk PCIe controller state
152 *
Marek Behún8247c902021-09-26 00:54:46 +0200153 * @base: The base address of the register space.
154 * @first_busno: Bus number of the PCIe root-port.
155 * This may vary depending on the PCIe setup.
156 * @sec_busno: Bus number for the device behind the PCIe root-port.
157 * @dev: The pointer to PCI uclass device.
158 * @reset_gpio: GPIO descriptor for PERST.
159 * @cfgcache: Buffer for emulation of PCIe Root Port's PCI Bridge registers
160 * that are not available on Aardvark.
161 * @cfgcrssve: For CRSSVE emulation.
Wilson Dinge51f2b12018-03-26 15:57:29 +0800162 */
163struct pcie_advk {
Marek Behún96a3c982021-09-26 00:54:45 +0200164 void *base;
165 int first_busno;
166 int sec_busno;
167 struct udevice *dev;
168 struct gpio_desc reset_gpio;
Pali Rohárfed5bec2021-11-11 16:35:48 +0100169 u32 cfgcache[(0x3c - 0x10) / 4];
Marek Behún96a3c982021-09-26 00:54:45 +0200170 bool cfgcrssve;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800171};
172
173static inline void advk_writel(struct pcie_advk *pcie, uint val, uint reg)
174{
175 writel(val, pcie->base + reg);
176}
177
178static inline uint advk_readl(struct pcie_advk *pcie, uint reg)
179{
180 return readl(pcie->base + reg);
181}
182
183/**
184 * pcie_advk_addr_valid() - Check for valid bus address
185 *
Pali Rohárcb056002021-09-26 00:54:42 +0200186 * @pcie: Pointer to the PCI bus
187 * @busno: Bus number of PCI device
188 * @dev: Device number of PCI device
189 * @func: Function number of PCI device
Wilson Dinge51f2b12018-03-26 15:57:29 +0800190 * @bdf: The PCI device to access
Wilson Dinge51f2b12018-03-26 15:57:29 +0800191 *
Pali Rohárcb056002021-09-26 00:54:42 +0200192 * Return: true on valid, false on invalid
Wilson Dinge51f2b12018-03-26 15:57:29 +0800193 */
Pali Rohárcb056002021-09-26 00:54:42 +0200194static bool pcie_advk_addr_valid(struct pcie_advk *pcie,
195 int busno, u8 dev, u8 func)
Wilson Dinge51f2b12018-03-26 15:57:29 +0800196{
Pali Rohárcb056002021-09-26 00:54:42 +0200197 /* On the primary (local) bus there is only one PCI Bridge */
198 if (busno == pcie->first_busno && (dev != 0 || func != 0))
199 return false;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800200
Pali Rohárcb056002021-09-26 00:54:42 +0200201 /*
202 * In PCI-E only a single device (0) can exist on the secondary bus.
203 * Beyond the secondary bus, there might be a Switch and anything is
204 * possible.
205 */
206 if (busno == pcie->sec_busno && dev != 0)
207 return false;
208
209 return true;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800210}
211
212/**
213 * pcie_advk_wait_pio() - Wait for PIO access to be accomplished
214 *
215 * @pcie: The PCI device to access
216 *
Pali Roháreccbd4a2021-04-22 16:23:04 +0200217 * Wait up to 1.5 seconds for PIO access to be accomplished.
Wilson Dinge51f2b12018-03-26 15:57:29 +0800218 *
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200219 * Return positive - retry count if PIO access is accomplished.
220 * Return negative - error if PIO access is timed out.
Wilson Dinge51f2b12018-03-26 15:57:29 +0800221 */
222static int pcie_advk_wait_pio(struct pcie_advk *pcie)
223{
224 uint start, isr;
225 uint count;
226
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200227 for (count = 1; count <= PIO_MAX_RETRIES; count++) {
Pali Rohárcf2a5892022-02-10 14:53:43 +0100228 start = advk_readl(pcie, ADVK_PIO_START);
229 isr = advk_readl(pcie, ADVK_PIO_ISR);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800230 if (!start && isr)
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200231 return count;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800232 /*
233 * Do not check the PIO state too frequently,
234 * 100us delay is appropriate.
235 */
236 udelay(PIO_WAIT_TIMEOUT);
237 }
238
Pali Roháreccbd4a2021-04-22 16:23:04 +0200239 dev_err(pcie->dev, "PIO read/write transfer time out\n");
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200240 return -ETIMEDOUT;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800241}
242
243/**
244 * pcie_advk_check_pio_status() - Validate PIO status and get the read result
245 *
246 * @pcie: Pointer to the PCI bus
Pali Rohár4cd61c42021-08-09 09:53:13 +0200247 * @allow_crs: Only for read requests, if CRS response is allowed
248 * @read_val: Pointer to the read result
Wilson Dinge51f2b12018-03-26 15:57:29 +0800249 *
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200250 * Return: 0 on success
Wilson Dinge51f2b12018-03-26 15:57:29 +0800251 */
252static int pcie_advk_check_pio_status(struct pcie_advk *pcie,
Pali Rohár4cd61c42021-08-09 09:53:13 +0200253 bool allow_crs,
Wilson Dinge51f2b12018-03-26 15:57:29 +0800254 uint *read_val)
255{
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200256 int ret;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800257 uint reg;
258 unsigned int status;
259 char *strcomp_status, *str_posted;
260
Pali Rohárcf2a5892022-02-10 14:53:43 +0100261 reg = advk_readl(pcie, ADVK_PIO_STAT);
262 status = (reg & ADVK_PIO_COMPLETION_STATUS_MASK) >>
263 ADVK_PIO_COMPLETION_STATUS_SHIFT;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800264
265 switch (status) {
Pali Rohárcf2a5892022-02-10 14:53:43 +0100266 case ADVK_PIO_COMPLETION_STATUS_OK:
267 if (reg & ADVK_PIO_ERR_STATUS) {
Wilson Dinge51f2b12018-03-26 15:57:29 +0800268 strcomp_status = "COMP_ERR";
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200269 ret = -EFAULT;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800270 break;
271 }
272 /* Get the read result */
Pali Rohár4cd61c42021-08-09 09:53:13 +0200273 if (read_val)
Pali Rohárcf2a5892022-02-10 14:53:43 +0100274 *read_val = advk_readl(pcie, ADVK_PIO_RD_DATA);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800275 /* No error */
276 strcomp_status = NULL;
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200277 ret = 0;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800278 break;
Pali Rohárcf2a5892022-02-10 14:53:43 +0100279 case ADVK_PIO_COMPLETION_STATUS_UR:
Pali Rohár4cd61c42021-08-09 09:53:13 +0200280 strcomp_status = "UR";
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200281 ret = -EOPNOTSUPP;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800282 break;
Pali Rohárcf2a5892022-02-10 14:53:43 +0100283 case ADVK_PIO_COMPLETION_STATUS_CRS:
Pali Rohár4cd61c42021-08-09 09:53:13 +0200284 if (allow_crs && read_val) {
Wilson Dinge51f2b12018-03-26 15:57:29 +0800285 /* For reading, CRS is not an error status. */
286 *read_val = CFG_RD_CRS_VAL;
287 strcomp_status = NULL;
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200288 ret = 0;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800289 } else {
290 strcomp_status = "CRS";
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200291 ret = -EAGAIN;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800292 }
293 break;
Pali Rohárcf2a5892022-02-10 14:53:43 +0100294 case ADVK_PIO_COMPLETION_STATUS_CA:
Wilson Dinge51f2b12018-03-26 15:57:29 +0800295 strcomp_status = "CA";
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200296 ret = -ECANCELED;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800297 break;
298 default:
299 strcomp_status = "Unknown";
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200300 ret = -EINVAL;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800301 break;
302 }
303
304 if (!strcomp_status)
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200305 return ret;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800306
Pali Rohárcf2a5892022-02-10 14:53:43 +0100307 if (reg & ADVK_PIO_NON_POSTED_REQ)
Wilson Dinge51f2b12018-03-26 15:57:29 +0800308 str_posted = "Non-posted";
309 else
310 str_posted = "Posted";
311
Marek Behún157bc522021-09-07 17:27:08 +0200312 dev_dbg(pcie->dev, "%s PIO Response Status: %s, %#x @ %#x\n",
Wilson Dinge51f2b12018-03-26 15:57:29 +0800313 str_posted, strcomp_status, reg,
Pali Rohárcf2a5892022-02-10 14:53:43 +0100314 advk_readl(pcie, ADVK_PIO_ADDR_LS));
Wilson Dinge51f2b12018-03-26 15:57:29 +0800315
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200316 return ret;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800317}
318
319/**
320 * pcie_advk_read_config() - Read from configuration space
321 *
322 * @bus: Pointer to the PCI bus
323 * @bdf: Identifies the PCIe device to access
324 * @offset: The offset into the device's configuration space
325 * @valuep: A pointer at which to store the read value
326 * @size: Indicates the size of access to perform
327 *
328 * Read a value of size @size from offset @offset within the configuration
329 * space of the device identified by the bus, device & function numbers in @bdf
330 * on the PCI bus @bus.
331 *
332 * Return: 0 on success
333 */
Simon Glassc4e72c42020-01-27 08:49:37 -0700334static int pcie_advk_read_config(const struct udevice *bus, pci_dev_t bdf,
Wilson Dinge51f2b12018-03-26 15:57:29 +0800335 uint offset, ulong *valuep,
336 enum pci_size_t size)
337{
338 struct pcie_advk *pcie = dev_get_priv(bus);
Pali Rohárcb056002021-09-26 00:54:42 +0200339 int busno = PCI_BUS(bdf) - dev_seq(bus);
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200340 int retry_count;
Pali Rohár4cd61c42021-08-09 09:53:13 +0200341 bool allow_crs;
Pali Rohárcb056002021-09-26 00:54:42 +0200342 ulong data;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800343 uint reg;
344 int ret;
345
346 dev_dbg(pcie->dev, "PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ",
347 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
348
Pali Rohárcb056002021-09-26 00:54:42 +0200349 if (!pcie_advk_addr_valid(pcie, busno, PCI_DEV(bdf), PCI_FUNC(bdf))) {
Wilson Dinge51f2b12018-03-26 15:57:29 +0800350 dev_dbg(pcie->dev, "- out of range\n");
351 *valuep = pci_get_ff(size);
352 return 0;
353 }
354
Pali Rohár758262b2021-08-27 14:14:43 +0200355 /*
Pali Rohárfed5bec2021-11-11 16:35:48 +0100356 * The configuration space of the PCI Bridge on primary (first) bus is
Pali Rohárcb056002021-09-26 00:54:42 +0200357 * not accessible via PIO transfers like all other PCIe devices. PCI
358 * Bridge config registers are available directly in Aardvark memory
Pali Rohárfed5bec2021-11-11 16:35:48 +0100359 * space starting at offset zero. The PCI Bridge config space is of
360 * Type 0, but the BAR registers (including ROM BAR) don't have the same
361 * meaning as in the PCIe specification. Therefore do not access BAR
362 * registers and non-common registers (those which have different
363 * meaning for Type 0 and Type 1 config space) of the primary PCI Bridge
364 * and instead read their content from driver virtual cfgcache[].
Pali Rohárcb056002021-09-26 00:54:42 +0200365 */
366 if (busno == pcie->first_busno) {
Pali Rohárfed5bec2021-11-11 16:35:48 +0100367 if ((offset >= 0x10 && offset < 0x34) || (offset >= 0x38 && offset < 0x3c))
Pali Rohárcb056002021-09-26 00:54:42 +0200368 data = pcie->cfgcache[(offset - 0x10) / 4];
Pali Rohárcb056002021-09-26 00:54:42 +0200369 else
Pali Rohár819a43c2022-02-10 14:53:42 +0100370 data = advk_readl(pcie, ADVK_ROOT_PORT_PCI_CFG_OFF + (offset & ~3));
Pali Rohárcb056002021-09-26 00:54:42 +0200371
372 if ((offset & ~3) == (PCI_HEADER_TYPE & ~3)) {
373 /*
374 * Change Header Type of PCI Bridge device to Type 1
375 * (0x01, used by PCI Bridges) because hardwired value
376 * is Type 0 (0x00, used by Endpoint devices).
377 */
378 data &= ~0x007f0000;
379 data |= PCI_HEADER_TYPE_BRIDGE << 16;
380 }
381
Pali Rohár819a43c2022-02-10 14:53:42 +0100382 if ((offset & ~3) == ADVK_ROOT_PORT_PCI_EXP_OFF + PCI_EXP_RTCTL) {
Pali Rohár1d7ad682021-09-26 00:54:44 +0200383 /* CRSSVE bit is stored only in cache */
384 if (pcie->cfgcrssve)
385 data |= PCI_EXP_RTCTL_CRSSVE;
386 }
387
Pali Rohár819a43c2022-02-10 14:53:42 +0100388 if ((offset & ~3) == ADVK_ROOT_PORT_PCI_EXP_OFF + (PCI_EXP_RTCAP & ~3)) {
Pali Rohár1d7ad682021-09-26 00:54:44 +0200389 /* CRS is emulated below, so set CRSVIS capability */
390 data |= PCI_EXP_RTCAP_CRSVIS << 16;
391 }
392
Pali Rohárcb056002021-09-26 00:54:42 +0200393 *valuep = pci_conv_32_to_size(data, offset, size);
394
395 return 0;
396 }
397
398 /*
Pali Rohár758262b2021-08-27 14:14:43 +0200399 * Returning fabricated CRS value (0xFFFF0001) by PCIe Root Complex to
400 * OS is allowed only for 4-byte PCI_VENDOR_ID config read request and
401 * only when CRSSVE bit in Root Port PCIe device is enabled. In all
402 * other error PCIe Root Complex must return all-ones.
Pali Rohár1d7ad682021-09-26 00:54:44 +0200403 *
Pali Rohár758262b2021-08-27 14:14:43 +0200404 * U-Boot currently does not support handling of CRS return value for
405 * PCI_VENDOR_ID config read request and also does not set CRSSVE bit.
Pali Rohár1d7ad682021-09-26 00:54:44 +0200406 * So it means that pcie->cfgcrssve is false. But the code is prepared
407 * for returning CRS, so that if U-Boot does support CRS in the future,
408 * it will work for Aardvark.
Pali Rohár758262b2021-08-27 14:14:43 +0200409 */
Pali Rohárbd4064f2021-10-19 11:05:01 +0200410 allow_crs = (offset == PCI_VENDOR_ID) && (size == PCI_SIZE_32) && pcie->cfgcrssve;
Pali Rohár4cd61c42021-08-09 09:53:13 +0200411
Pali Rohárcf2a5892022-02-10 14:53:43 +0100412 if (advk_readl(pcie, ADVK_PIO_START)) {
Pali Roháreccbd4a2021-04-22 16:23:04 +0200413 dev_err(pcie->dev,
414 "Previous PIO read/write transfer is still running\n");
Pali Rohár4cd61c42021-08-09 09:53:13 +0200415 if (allow_crs) {
416 *valuep = CFG_RD_CRS_VAL;
417 return 0;
418 }
419 *valuep = pci_get_ff(size);
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200420 return -EAGAIN;
Pali Roháreccbd4a2021-04-22 16:23:04 +0200421 }
Wilson Dinge51f2b12018-03-26 15:57:29 +0800422
423 /* Program the control register */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100424 reg = advk_readl(pcie, ADVK_PIO_CTRL);
425 reg &= ~ADVK_PIO_CTRL_TYPE_MASK;
Pali Rohárcb056002021-09-26 00:54:42 +0200426 if (busno == pcie->sec_busno)
Pali Rohárcf2a5892022-02-10 14:53:43 +0100427 reg |= ADVK_PIO_CTRL_TYPE_RD_TYPE0 << ADVK_PIO_CTRL_TYPE_SHIFT;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800428 else
Pali Rohárcf2a5892022-02-10 14:53:43 +0100429 reg |= ADVK_PIO_CTRL_TYPE_RD_TYPE1 << ADVK_PIO_CTRL_TYPE_SHIFT;
430 advk_writel(pcie, reg, ADVK_PIO_CTRL);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800431
432 /* Program the address registers */
Pali Rohára4bc38d2021-11-03 01:01:05 +0100433 reg = PCIE_ECAM_OFFSET(busno, PCI_DEV(bdf), PCI_FUNC(bdf), (offset & ~0x3));
Pali Rohárcf2a5892022-02-10 14:53:43 +0100434 advk_writel(pcie, reg, ADVK_PIO_ADDR_LS);
435 advk_writel(pcie, 0, ADVK_PIO_ADDR_MS);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800436
Pali Rohár57fa6fb2021-11-01 10:12:51 +0100437 /* Program the data strobe */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100438 advk_writel(pcie, 0xf, ADVK_PIO_WR_DATA_STRB);
Pali Rohár57fa6fb2021-11-01 10:12:51 +0100439
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200440 retry_count = 0;
441
442retry:
Wilson Dinge51f2b12018-03-26 15:57:29 +0800443 /* Start the transfer */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100444 advk_writel(pcie, 1, ADVK_PIO_ISR);
445 advk_writel(pcie, 1, ADVK_PIO_START);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800446
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200447 ret = pcie_advk_wait_pio(pcie);
448 if (ret < 0) {
Pali Rohár4cd61c42021-08-09 09:53:13 +0200449 if (allow_crs) {
450 *valuep = CFG_RD_CRS_VAL;
451 return 0;
452 }
453 *valuep = pci_get_ff(size);
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200454 return ret;
Pali Roháreccbd4a2021-04-22 16:23:04 +0200455 }
Wilson Dinge51f2b12018-03-26 15:57:29 +0800456
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200457 retry_count += ret;
458
Wilson Dinge51f2b12018-03-26 15:57:29 +0800459 /* Check PIO status and get the read result */
Pali Rohár4cd61c42021-08-09 09:53:13 +0200460 ret = pcie_advk_check_pio_status(pcie, allow_crs, &reg);
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200461 if (ret == -EAGAIN && retry_count < PIO_MAX_RETRIES)
462 goto retry;
Pali Rohár4cd61c42021-08-09 09:53:13 +0200463 if (ret) {
464 *valuep = pci_get_ff(size);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800465 return ret;
Pali Rohár4cd61c42021-08-09 09:53:13 +0200466 }
Wilson Dinge51f2b12018-03-26 15:57:29 +0800467
468 dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08x)\n",
469 offset, size, reg);
470 *valuep = pci_conv_32_to_size(reg, offset, size);
471
472 return 0;
473}
474
475/**
476 * pcie_calc_datastrobe() - Calculate data strobe
477 *
478 * @offset: The offset into the device's configuration space
479 * @size: Indicates the size of access to perform
480 *
481 * Calculate data strobe according to offset and size
482 *
483 */
484static uint pcie_calc_datastrobe(uint offset, enum pci_size_t size)
485{
486 uint bytes, data_strobe;
487
488 switch (size) {
489 case PCI_SIZE_8:
490 bytes = 1;
491 break;
492 case PCI_SIZE_16:
493 bytes = 2;
494 break;
495 default:
496 bytes = 4;
497 }
498
499 data_strobe = GENMASK(bytes - 1, 0) << (offset & 0x3);
500
501 return data_strobe;
502}
503
504/**
505 * pcie_advk_write_config() - Write to configuration space
506 *
507 * @bus: Pointer to the PCI bus
508 * @bdf: Identifies the PCIe device to access
509 * @offset: The offset into the device's configuration space
510 * @value: The value to write
511 * @size: Indicates the size of access to perform
512 *
513 * Write the value @value of size @size from offset @offset within the
514 * configuration space of the device identified by the bus, device & function
515 * numbers in @bdf on the PCI bus @bus.
516 *
517 * Return: 0 on success
518 */
519static int pcie_advk_write_config(struct udevice *bus, pci_dev_t bdf,
520 uint offset, ulong value,
521 enum pci_size_t size)
522{
523 struct pcie_advk *pcie = dev_get_priv(bus);
Pali Rohárcb056002021-09-26 00:54:42 +0200524 int busno = PCI_BUS(bdf) - dev_seq(bus);
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200525 int retry_count;
Pali Rohárcb056002021-09-26 00:54:42 +0200526 ulong data;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800527 uint reg;
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200528 int ret;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800529
530 dev_dbg(pcie->dev, "PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
531 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
532 dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08lx)\n",
533 offset, size, value);
534
Pali Rohárcb056002021-09-26 00:54:42 +0200535 if (!pcie_advk_addr_valid(pcie, busno, PCI_DEV(bdf), PCI_FUNC(bdf))) {
Wilson Dinge51f2b12018-03-26 15:57:29 +0800536 dev_dbg(pcie->dev, "- out of range\n");
537 return 0;
538 }
539
Pali Rohárcb056002021-09-26 00:54:42 +0200540 /*
Pali Rohárfed5bec2021-11-11 16:35:48 +0100541 * As explained in pcie_advk_read_config(), PCI Bridge config registers
542 * are available directly in Aardvark memory space starting at offset
543 * zero. Type 1 specific registers are not available, so we write their
544 * content only into driver virtual cfgcache[].
Pali Rohárcb056002021-09-26 00:54:42 +0200545 */
546 if (busno == pcie->first_busno) {
Pali Rohárfed5bec2021-11-11 16:35:48 +0100547 if ((offset >= 0x10 && offset < 0x34) ||
548 (offset >= 0x38 && offset < 0x3c)) {
Pali Rohárcb056002021-09-26 00:54:42 +0200549 data = pcie->cfgcache[(offset - 0x10) / 4];
550 data = pci_conv_size_to_32(data, value, offset, size);
Pali Roháraaddce02021-10-12 13:19:19 +0200551 /* This PCI bridge does not have configurable bars */
552 if ((offset & ~3) == PCI_BASE_ADDRESS_0 ||
Pali Rohárfed5bec2021-11-11 16:35:48 +0100553 (offset & ~3) == PCI_BASE_ADDRESS_1 ||
554 (offset & ~3) == PCI_ROM_ADDRESS1)
Pali Roháraaddce02021-10-12 13:19:19 +0200555 data = 0x0;
Pali Rohárcb056002021-09-26 00:54:42 +0200556 pcie->cfgcache[(offset - 0x10) / 4] = data;
Pali Rohárcb056002021-09-26 00:54:42 +0200557 } else {
Pali Rohár819a43c2022-02-10 14:53:42 +0100558 data = advk_readl(pcie, ADVK_ROOT_PORT_PCI_CFG_OFF + (offset & ~3));
Pali Rohárcb056002021-09-26 00:54:42 +0200559 data = pci_conv_size_to_32(data, value, offset, size);
Pali Rohár819a43c2022-02-10 14:53:42 +0100560 advk_writel(pcie, data, ADVK_ROOT_PORT_PCI_CFG_OFF + (offset & ~3));
Pali Rohárcb056002021-09-26 00:54:42 +0200561 }
562
563 if (offset == PCI_PRIMARY_BUS)
564 pcie->first_busno = data & 0xff;
565
566 if (offset == PCI_SECONDARY_BUS ||
567 (offset == PCI_PRIMARY_BUS && size != PCI_SIZE_8))
568 pcie->sec_busno = (data >> 8) & 0xff;
569
Pali Rohár819a43c2022-02-10 14:53:42 +0100570 if ((offset & ~3) == ADVK_ROOT_PORT_PCI_EXP_OFF + PCI_EXP_RTCTL)
Pali Rohár1d7ad682021-09-26 00:54:44 +0200571 pcie->cfgcrssve = data & PCI_EXP_RTCTL_CRSSVE;
572
Pali Rohárcb056002021-09-26 00:54:42 +0200573 return 0;
574 }
575
Pali Rohárcf2a5892022-02-10 14:53:43 +0100576 if (advk_readl(pcie, ADVK_PIO_START)) {
Pali Roháreccbd4a2021-04-22 16:23:04 +0200577 dev_err(pcie->dev,
578 "Previous PIO read/write transfer is still running\n");
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200579 return -EAGAIN;
Pali Roháreccbd4a2021-04-22 16:23:04 +0200580 }
Wilson Dinge51f2b12018-03-26 15:57:29 +0800581
582 /* Program the control register */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100583 reg = advk_readl(pcie, ADVK_PIO_CTRL);
584 reg &= ~ADVK_PIO_CTRL_TYPE_MASK;
Pali Rohárcb056002021-09-26 00:54:42 +0200585 if (busno == pcie->sec_busno)
Pali Rohárcf2a5892022-02-10 14:53:43 +0100586 reg |= ADVK_PIO_CTRL_TYPE_WR_TYPE0 << ADVK_PIO_CTRL_TYPE_SHIFT;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800587 else
Pali Rohárcf2a5892022-02-10 14:53:43 +0100588 reg |= ADVK_PIO_CTRL_TYPE_WR_TYPE1 << ADVK_PIO_CTRL_TYPE_SHIFT;
589 advk_writel(pcie, reg, ADVK_PIO_CTRL);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800590
591 /* Program the address registers */
Pali Rohára4bc38d2021-11-03 01:01:05 +0100592 reg = PCIE_ECAM_OFFSET(busno, PCI_DEV(bdf), PCI_FUNC(bdf), (offset & ~0x3));
Pali Rohárcf2a5892022-02-10 14:53:43 +0100593 advk_writel(pcie, reg, ADVK_PIO_ADDR_LS);
594 advk_writel(pcie, 0, ADVK_PIO_ADDR_MS);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800595 dev_dbg(pcie->dev, "\tPIO req. - addr = 0x%08x\n", reg);
596
597 /* Program the data register */
598 reg = pci_conv_size_to_32(0, value, offset, size);
Pali Rohárcf2a5892022-02-10 14:53:43 +0100599 advk_writel(pcie, reg, ADVK_PIO_WR_DATA);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800600 dev_dbg(pcie->dev, "\tPIO req. - val = 0x%08x\n", reg);
601
602 /* Program the data strobe */
603 reg = pcie_calc_datastrobe(offset, size);
Pali Rohárcf2a5892022-02-10 14:53:43 +0100604 advk_writel(pcie, reg, ADVK_PIO_WR_DATA_STRB);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800605 dev_dbg(pcie->dev, "\tPIO req. - strb = 0x%02x\n", reg);
606
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200607 retry_count = 0;
608
609retry:
Wilson Dinge51f2b12018-03-26 15:57:29 +0800610 /* Start the transfer */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100611 advk_writel(pcie, 1, ADVK_PIO_ISR);
612 advk_writel(pcie, 1, ADVK_PIO_START);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800613
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200614 ret = pcie_advk_wait_pio(pcie);
615 if (ret < 0)
616 return ret;
617
618 retry_count += ret;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800619
620 /* Check PIO status */
Pali Rohárd9ac6e22021-08-27 14:14:44 +0200621 ret = pcie_advk_check_pio_status(pcie, false, NULL);
622 if (ret == -EAGAIN && retry_count < PIO_MAX_RETRIES)
623 goto retry;
624 return ret;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800625}
626
627/**
628 * pcie_advk_link_up() - Check if PCIe link is up or not
629 *
630 * @pcie: The PCI device to access
631 *
632 * Return 1 (true) on link up.
633 * Return 0 (false) on link down.
634 */
635static int pcie_advk_link_up(struct pcie_advk *pcie)
636{
637 u32 val, ltssm_state;
638
Pali Rohárcf2a5892022-02-10 14:53:43 +0100639 val = advk_readl(pcie, ADVK_LMI_PHY_CFG0);
640 ltssm_state = (val & ADVK_LMI_PHY_CFG0_LTSSM_MASK) >> ADVK_LMI_PHY_CFG0_LTSSM_SHIFT;
641 return ltssm_state >= ADVK_LMI_PHY_CFG0_LTSSM_L0 && ltssm_state < ADVK_LMI_PHY_CFG0_LTSSM_DISABLED;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800642}
643
644/**
645 * pcie_advk_wait_for_link() - Wait for link training to be accomplished
646 *
647 * @pcie: The PCI device to access
648 *
649 * Wait up to 1 second for link training to be accomplished.
650 *
651 * Return 1 (true) if link training ends up with link up success.
652 * Return 0 (false) if link training ends up with link up failure.
653 */
654static int pcie_advk_wait_for_link(struct pcie_advk *pcie)
655{
656 int retries;
657
658 /* check if the link is up or not */
Pali Roháreccbd4a2021-04-22 16:23:04 +0200659 for (retries = 0; retries < LINK_MAX_RETRIES; retries++) {
Wilson Dinge51f2b12018-03-26 15:57:29 +0800660 if (pcie_advk_link_up(pcie)) {
Pali Rohárcb056002021-09-26 00:54:42 +0200661 printf("PCIe: Link up\n");
Wilson Dinge51f2b12018-03-26 15:57:29 +0800662 return 0;
663 }
664
665 udelay(LINK_WAIT_TIMEOUT);
666 }
667
Pali Rohárcb056002021-09-26 00:54:42 +0200668 printf("PCIe: Link down\n");
Wilson Dinge51f2b12018-03-26 15:57:29 +0800669
670 return -ETIMEDOUT;
671}
672
Pali Rohárb3217222021-05-26 17:59:40 +0200673/*
674 * Set PCIe address window register which could be used for memory
675 * mapping.
676 */
677static void pcie_advk_set_ob_win(struct pcie_advk *pcie, u8 win_num,
678 phys_addr_t match, phys_addr_t remap,
679 phys_addr_t mask, u32 actions)
680{
Pali Rohárcf2a5892022-02-10 14:53:43 +0100681 advk_writel(pcie, ADVK_OB_WIN_ENABLE |
682 lower_32_bits(match), ADVK_OB_WIN_MATCH_LS(win_num));
683 advk_writel(pcie, upper_32_bits(match), ADVK_OB_WIN_MATCH_MS(win_num));
684 advk_writel(pcie, lower_32_bits(remap), ADVK_OB_WIN_REMAP_LS(win_num));
685 advk_writel(pcie, upper_32_bits(remap), ADVK_OB_WIN_REMAP_MS(win_num));
686 advk_writel(pcie, lower_32_bits(mask), ADVK_OB_WIN_MASK_LS(win_num));
687 advk_writel(pcie, upper_32_bits(mask), ADVK_OB_WIN_MASK_MS(win_num));
688 advk_writel(pcie, actions, ADVK_OB_WIN_ACTIONS(win_num));
Pali Rohárb3217222021-05-26 17:59:40 +0200689}
690
691static void pcie_advk_disable_ob_win(struct pcie_advk *pcie, u8 win_num)
692{
Pali Rohárcf2a5892022-02-10 14:53:43 +0100693 advk_writel(pcie, 0, ADVK_OB_WIN_MATCH_LS(win_num));
694 advk_writel(pcie, 0, ADVK_OB_WIN_MATCH_MS(win_num));
695 advk_writel(pcie, 0, ADVK_OB_WIN_REMAP_LS(win_num));
696 advk_writel(pcie, 0, ADVK_OB_WIN_REMAP_MS(win_num));
697 advk_writel(pcie, 0, ADVK_OB_WIN_MASK_LS(win_num));
698 advk_writel(pcie, 0, ADVK_OB_WIN_MASK_MS(win_num));
699 advk_writel(pcie, 0, ADVK_OB_WIN_ACTIONS(win_num));
Pali Rohárb3217222021-05-26 17:59:40 +0200700}
701
702static void pcie_advk_set_ob_region(struct pcie_advk *pcie, int *wins,
703 struct pci_region *region, u32 actions)
704{
705 phys_addr_t phys_start = region->phys_start;
706 pci_addr_t bus_start = region->bus_start;
707 pci_size_t size = region->size;
708 phys_addr_t win_mask;
709 u64 win_size;
710
711 if (*wins == -1)
712 return;
713
714 /*
715 * The n-th PCIe window is configured by tuple (match, remap, mask)
Pali Rohár960d4592021-07-08 20:19:00 +0200716 * and an access to address A uses this window if A matches the
Pali Rohárb3217222021-05-26 17:59:40 +0200717 * match with given mask.
718 * So every PCIe window size must be a power of two and every start
719 * address must be aligned to window size. Minimal size is 64 KiB
Pali Rohára8314952021-07-08 20:18:58 +0200720 * because lower 16 bits of mask must be zero. Remapped address
721 * may have set only bits from the mask.
Pali Rohárb3217222021-05-26 17:59:40 +0200722 */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100723 while (*wins < ADVK_OB_WIN_COUNT && size > 0) {
Pali Rohárb3217222021-05-26 17:59:40 +0200724 /* Calculate the largest aligned window size */
725 win_size = (1ULL << (fls64(size) - 1)) |
726 (phys_start ? (1ULL << __ffs64(phys_start)) : 0);
727 win_size = 1ULL << __ffs64(win_size);
Pali Rohára8314952021-07-08 20:18:58 +0200728 win_mask = ~(win_size - 1);
729 if (win_size < 0x10000 || (bus_start & ~win_mask))
Pali Rohárb3217222021-05-26 17:59:40 +0200730 break;
731
732 dev_dbg(pcie->dev,
733 "Configuring PCIe window %d: [0x%llx-0x%llx] as 0x%x\n",
734 *wins, (u64)phys_start, (u64)phys_start + win_size,
735 actions);
Pali Rohárb3217222021-05-26 17:59:40 +0200736 pcie_advk_set_ob_win(pcie, *wins, phys_start, bus_start,
737 win_mask, actions);
738
739 phys_start += win_size;
740 bus_start += win_size;
741 size -= win_size;
742 (*wins)++;
743 }
744
745 if (size > 0) {
746 *wins = -1;
747 dev_err(pcie->dev,
748 "Invalid PCIe region [0x%llx-0x%llx]\n",
749 (u64)region->phys_start,
750 (u64)region->phys_start + region->size);
751 }
752}
753
Wilson Dinge51f2b12018-03-26 15:57:29 +0800754/**
755 * pcie_advk_setup_hw() - PCIe initailzation
756 *
757 * @pcie: The PCI device to access
758 *
759 * Return: 0 on success
760 */
761static int pcie_advk_setup_hw(struct pcie_advk *pcie)
762{
Pali Rohárb3217222021-05-26 17:59:40 +0200763 struct pci_region *io, *mem, *pref;
764 int i, wins;
Wilson Dinge51f2b12018-03-26 15:57:29 +0800765 u32 reg;
766
767 /* Set to Direct mode */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100768 reg = advk_readl(pcie, ADVK_CORE_CTRL_CONFIG);
769 reg &= ~ADVK_CORE_CTRL_CONFIG_COMMAND_MODE;
770 advk_writel(pcie, reg, ADVK_CORE_CTRL_CONFIG);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800771
772 /* Set PCI global control register to RC mode */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100773 reg = advk_readl(pcie, ADVK_GLOBAL_CTRL0);
774 reg |= ADVK_GLOBAL_CTRL0_IS_RC;
775 advk_writel(pcie, reg, ADVK_GLOBAL_CTRL0);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800776
Pali Rohár2fa30d02021-03-03 14:37:59 +0100777 /*
778 * Replace incorrect PCI vendor id value 0x1b4b by correct value 0x11ab.
Pali Rohárcf2a5892022-02-10 14:53:43 +0100779 * ADVK_LMI_VENDOR_ID contains vendor id in low 16 bits and subsystem vendor
Pali Rohár2fa30d02021-03-03 14:37:59 +0100780 * id in high 16 bits. Updating this register changes readback value of
Pali Rohárcf2a5892022-02-10 14:53:43 +0100781 * read-only vendor id bits in Root Port PCI_VENDOR_ID register. Workaround
Pali Rohár2fa30d02021-03-03 14:37:59 +0100782 * for erratum 4.1: "The value of device and vendor ID is incorrect".
783 */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100784 advk_writel(pcie, 0x11ab11ab, ADVK_LMI_VENDOR_ID);
Pali Rohár2fa30d02021-03-03 14:37:59 +0100785
Pali Rohárcb056002021-09-26 00:54:42 +0200786 /*
787 * Change Class Code of PCI Bridge device to PCI Bridge (0x600400),
788 * because default value is Mass Storage Controller (0x010400), causing
789 * U-Boot to fail to recognize it as P2P Bridge.
790 *
791 * Note that this Aardvark PCI Bridge does not have a compliant Type 1
792 * Configuration Space and it even cannot be accessed via Aardvark's
Pali Rohárfed5bec2021-11-11 16:35:48 +0100793 * PCI config space access method. Aardvark PCI Bridge Config space is
Pali Rohárcb056002021-09-26 00:54:42 +0200794 * available in internal Aardvark registers starting at offset 0x0
Pali Rohárfed5bec2021-11-11 16:35:48 +0100795 * and has format of Type 0 config space.
796 *
797 * Moreover Type 0 BAR registers (ranges 0x10 - 0x28 and 0x30 - 0x34)
798 * have the same format in Marvell's specification as in PCIe
799 * specification, but their meaning is totally different (and not even
800 * the same meaning as explained in the corresponding comment in the
801 * pci_mvebu driver; aardvark is still different).
802 *
803 * So our driver converts Type 0 config space to Type 1 and reports
804 * Header Type as Type 1. Access to BAR registers and to non-existent
805 * Type 1 registers is redirected to the virtual cfgcache[] buffer,
806 * which avoids changing unrelated registers.
Pali Rohárcb056002021-09-26 00:54:42 +0200807 */
Pali Rohár819a43c2022-02-10 14:53:42 +0100808 reg = advk_readl(pcie, ADVK_ROOT_PORT_PCI_CFG_OFF + PCI_CLASS_REVISION);
Pali Rohárcb056002021-09-26 00:54:42 +0200809 reg &= ~0xffffff00;
810 reg |= (PCI_CLASS_BRIDGE_PCI << 8) << 8;
Pali Rohár819a43c2022-02-10 14:53:42 +0100811 advk_writel(pcie, reg, ADVK_ROOT_PORT_PCI_CFG_OFF + PCI_CLASS_REVISION);
Pali Rohárcb056002021-09-26 00:54:42 +0200812
Pali Rohár819a43c2022-02-10 14:53:42 +0100813 /* Enable generation and checking of ECRC on PCIe Root Port */
814 reg = advk_readl(pcie, ADVK_ROOT_PORT_PCI_ERR_OFF + PCI_ERR_CAP);
815 reg |= PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE;
816 advk_writel(pcie, reg, ADVK_ROOT_PORT_PCI_ERR_OFF + PCI_ERR_CAP);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800817
Pali Rohár819a43c2022-02-10 14:53:42 +0100818 /* Set PCIe Device Control register on PCIe Root Port */
819 reg = advk_readl(pcie, ADVK_ROOT_PORT_PCI_EXP_OFF + PCI_EXP_DEVCTL);
820 reg &= ~PCI_EXP_DEVCTL_RELAX_EN;
821 reg &= ~PCI_EXP_DEVCTL_NOSNOOP_EN;
822 reg &= ~PCI_EXP_DEVCTL_PAYLOAD;
823 reg &= ~PCI_EXP_DEVCTL_READRQ;
824 reg |= PCI_EXP_DEVCTL_PAYLOAD_512B;
825 reg |= PCI_EXP_DEVCTL_READRQ_512B;
826 advk_writel(pcie, reg, ADVK_ROOT_PORT_PCI_EXP_OFF + PCI_EXP_DEVCTL);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800827
828 /* Program PCIe Control 2 to disable strict ordering */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100829 reg = advk_readl(pcie, ADVK_GLOBAL_CTRL2);
830 reg &= ~ADVK_GLOBAL_CTRL2_STRICT_ORDER_EN;
831 advk_writel(pcie, reg, ADVK_GLOBAL_CTRL2);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800832
833 /* Set GEN2 */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100834 reg = advk_readl(pcie, ADVK_GLOBAL_CTRL0);
835 reg &= ~ADVK_GLOBAL_CTRL0_SPEED_GEN_MASK;
836 reg |= ADVK_GLOBAL_CTRL0_SPEED_GEN_2 << ADVK_GLOBAL_CTRL0_SPEED_GEN_SHIFT;
837 advk_writel(pcie, reg, ADVK_GLOBAL_CTRL0);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800838
839 /* Set lane X1 */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100840 reg = advk_readl(pcie, ADVK_GLOBAL_CTRL0);
841 reg &= ~ADVK_GLOBAL_CTRL0_LANE_COUNT_MASK;
842 reg |= ADVK_GLOBAL_CTRL0_LANE_COUNT_1 << ADVK_GLOBAL_CTRL0_LANE_COUNT_SHIFT;
843 advk_writel(pcie, reg, ADVK_GLOBAL_CTRL0);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800844
845 /* Enable link training */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100846 reg = advk_readl(pcie, ADVK_GLOBAL_CTRL0);
847 reg |= ADVK_GLOBAL_CTRL0_LINK_TRAINING_EN;
848 advk_writel(pcie, reg, ADVK_GLOBAL_CTRL0);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800849
850 /*
851 * Enable AXI address window location generation:
852 * When it is enabled, the default outbound window
853 * configurations (Default User Field: 0xD0074CFC)
854 * are used to transparent address translation for
855 * the outbound transactions. Thus, PCIe address
Pali Rohárb3217222021-05-26 17:59:40 +0200856 * windows are not required for transparent memory
857 * access when default outbound window configuration
858 * is set for memory access.
Wilson Dinge51f2b12018-03-26 15:57:29 +0800859 */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100860 reg = advk_readl(pcie, ADVK_GLOBAL_CTRL2);
861 reg |= ADVK_GLOBAL_CTRL2_ADDRWIN_MAP_EN;
862 advk_writel(pcie, reg, ADVK_GLOBAL_CTRL2);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800863
864 /*
865 * Bypass the address window mapping for PIO:
866 * Since PIO access already contains all required
867 * info over AXI interface by PIO registers, the
868 * address window is not required.
869 */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100870 reg = advk_readl(pcie, ADVK_PIO_CTRL);
871 reg |= ADVK_PIO_CTRL_ADDR_WIN_DISABLE;
872 advk_writel(pcie, reg, ADVK_PIO_CTRL);
Wilson Dinge51f2b12018-03-26 15:57:29 +0800873
Pali Rohárb3217222021-05-26 17:59:40 +0200874 /*
875 * Set memory access in Default User Field so it
876 * is not required to configure PCIe address for
877 * transparent memory access.
878 */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100879 advk_writel(pcie, ADVK_OB_WIN_TYPE_MEM, ADVK_OB_WIN_DEFAULT_ACTIONS);
Pali Rohárb3217222021-05-26 17:59:40 +0200880
881 /*
882 * Configure PCIe address windows for non-memory or
883 * non-transparent access as by default PCIe uses
884 * transparent memory access.
885 */
886 wins = 0;
887 pci_get_regions(pcie->dev, &io, &mem, &pref);
888 if (io)
Pali Rohárcf2a5892022-02-10 14:53:43 +0100889 pcie_advk_set_ob_region(pcie, &wins, io, ADVK_OB_WIN_TYPE_IO);
Pali Rohárb3217222021-05-26 17:59:40 +0200890 if (mem && mem->phys_start != mem->bus_start)
Pali Rohárcf2a5892022-02-10 14:53:43 +0100891 pcie_advk_set_ob_region(pcie, &wins, mem, ADVK_OB_WIN_TYPE_MEM);
Pali Rohárb3217222021-05-26 17:59:40 +0200892 if (pref && pref->phys_start != pref->bus_start)
Pali Rohárcf2a5892022-02-10 14:53:43 +0100893 pcie_advk_set_ob_region(pcie, &wins, pref, ADVK_OB_WIN_TYPE_MEM);
Pali Rohárb3217222021-05-26 17:59:40 +0200894
895 /* Disable remaining PCIe outbound windows */
Pali Rohárcf2a5892022-02-10 14:53:43 +0100896 for (i = ((wins >= 0) ? wins : 0); i < ADVK_OB_WIN_COUNT; i++)
Pali Rohárb3217222021-05-26 17:59:40 +0200897 pcie_advk_disable_ob_win(pcie, i);
898
899 if (wins == -1)
900 return -EINVAL;
901
Wilson Dinge51f2b12018-03-26 15:57:29 +0800902 /* Wait for PCIe link up */
903 if (pcie_advk_wait_for_link(pcie))
904 return -ENXIO;
905
Wilson Dinge51f2b12018-03-26 15:57:29 +0800906 return 0;
907}
908
909/**
910 * pcie_advk_probe() - Probe the PCIe bus for active link
911 *
912 * @dev: A pointer to the device being operated on
913 *
914 * Probe for an active link on the PCIe bus and configure the controller
915 * to enable this port.
916 *
917 * Return: 0 on success, else -ENODEV
918 */
919static int pcie_advk_probe(struct udevice *dev)
920{
921 struct pcie_advk *pcie = dev_get_priv(dev);
922
Pali Rohár828d3262020-08-19 15:57:07 +0200923 gpio_request_by_name(dev, "reset-gpios", 0, &pcie->reset_gpio,
Wilson Dinge51f2b12018-03-26 15:57:29 +0800924 GPIOD_IS_OUT);
925 /*
926 * Issue reset to add-in card through the dedicated GPIO.
927 * Some boards are connecting the card reset pin to common system
928 * reset wire and others are using separate GPIO port.
929 * In the last case we have to release a reset of the addon card
930 * using this GPIO.
931 *
932 * FIX-ME:
933 * The PCIe RESET signal is not supposed to be released along
934 * with the SOC RESET signal. It should be lowered as early as
935 * possible before PCIe PHY initialization. Moreover, the PCIe
936 * clock should be gated as well.
937 */
Pali Rohár828d3262020-08-19 15:57:07 +0200938 if (dm_gpio_is_valid(&pcie->reset_gpio)) {
Pali Rohár279b5732021-01-18 12:09:33 +0100939 dev_dbg(dev, "Toggle PCIE Reset GPIO ...\n");
Pali Rohár828d3262020-08-19 15:57:07 +0200940 dm_gpio_set_value(&pcie->reset_gpio, 1);
Pali Rohár563b85b2020-08-19 15:57:06 +0200941 mdelay(200);
Pali Rohár828d3262020-08-19 15:57:07 +0200942 dm_gpio_set_value(&pcie->reset_gpio, 0);
Pali Rohár835d9692020-08-25 10:45:04 +0200943 } else {
Pali Rohár279b5732021-01-18 12:09:33 +0100944 dev_warn(dev, "PCIE Reset on GPIO support is missing\n");
Wilson Dinge51f2b12018-03-26 15:57:29 +0800945 }
Wilson Dinge51f2b12018-03-26 15:57:29 +0800946
Wilson Dinge51f2b12018-03-26 15:57:29 +0800947 pcie->dev = pci_get_controller(dev);
948
Pali Rohárcb056002021-09-26 00:54:42 +0200949 /* PCI Bridge support 32-bit I/O and 64-bit prefetch mem addressing */
950 pcie->cfgcache[(PCI_IO_BASE - 0x10) / 4] =
951 PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8);
952 pcie->cfgcache[(PCI_PREF_MEMORY_BASE - 0x10) / 4] =
953 PCI_PREF_RANGE_TYPE_64 | (PCI_PREF_RANGE_TYPE_64 << 16);
954
Wilson Dinge51f2b12018-03-26 15:57:29 +0800955 return pcie_advk_setup_hw(pcie);
956}
957
Pali Rohár828d3262020-08-19 15:57:07 +0200958static int pcie_advk_remove(struct udevice *dev)
959{
Pali Rohár828d3262020-08-19 15:57:07 +0200960 struct pcie_advk *pcie = dev_get_priv(dev);
Pali Rohár5f50b882020-09-22 13:21:38 +0200961 u32 reg;
Pali Rohárb3217222021-05-26 17:59:40 +0200962 int i;
963
Pali Rohárcf2a5892022-02-10 14:53:43 +0100964 for (i = 0; i < ADVK_OB_WIN_COUNT; i++)
Pali Rohárb3217222021-05-26 17:59:40 +0200965 pcie_advk_disable_ob_win(pcie, i);
Pali Rohár828d3262020-08-19 15:57:07 +0200966
Pali Rohár819a43c2022-02-10 14:53:42 +0100967 reg = advk_readl(pcie, ADVK_ROOT_PORT_PCI_CFG_OFF + PCI_COMMAND);
968 reg &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
969 advk_writel(pcie, reg, ADVK_ROOT_PORT_PCI_CFG_OFF + PCI_COMMAND);
Pali Rohár7b85aef2021-05-26 17:59:35 +0200970
Pali Rohárcf2a5892022-02-10 14:53:43 +0100971 reg = advk_readl(pcie, ADVK_GLOBAL_CTRL0);
972 reg &= ~ADVK_GLOBAL_CTRL0_LINK_TRAINING_EN;
973 advk_writel(pcie, reg, ADVK_GLOBAL_CTRL0);
Pali Rohár5f50b882020-09-22 13:21:38 +0200974
Pali Rohár828d3262020-08-19 15:57:07 +0200975 return 0;
976}
977
Wilson Dinge51f2b12018-03-26 15:57:29 +0800978/**
Simon Glassd1998a92020-12-03 16:55:21 -0700979 * pcie_advk_of_to_plat() - Translate from DT to device state
Wilson Dinge51f2b12018-03-26 15:57:29 +0800980 *
981 * @dev: A pointer to the device being operated on
982 *
983 * Translate relevant data from the device tree pertaining to device @dev into
984 * state that the driver will later make use of. This state is stored in the
985 * device's private data structure.
986 *
987 * Return: 0 on success, else -EINVAL
988 */
Simon Glassd1998a92020-12-03 16:55:21 -0700989static int pcie_advk_of_to_plat(struct udevice *dev)
Wilson Dinge51f2b12018-03-26 15:57:29 +0800990{
991 struct pcie_advk *pcie = dev_get_priv(dev);
992
993 /* Get the register base address */
994 pcie->base = (void *)dev_read_addr_index(dev, 0);
995 if ((fdt_addr_t)pcie->base == FDT_ADDR_T_NONE)
996 return -EINVAL;
997
998 return 0;
999}
1000
1001static const struct dm_pci_ops pcie_advk_ops = {
1002 .read_config = pcie_advk_read_config,
1003 .write_config = pcie_advk_write_config,
1004};
1005
1006static const struct udevice_id pcie_advk_ids[] = {
Pali Rohára544d652021-05-26 17:59:36 +02001007 { .compatible = "marvell,armada-3700-pcie" },
Wilson Dinge51f2b12018-03-26 15:57:29 +08001008 { }
1009};
1010
1011U_BOOT_DRIVER(pcie_advk) = {
1012 .name = "pcie_advk",
1013 .id = UCLASS_PCI,
1014 .of_match = pcie_advk_ids,
1015 .ops = &pcie_advk_ops,
Simon Glassd1998a92020-12-03 16:55:21 -07001016 .of_to_plat = pcie_advk_of_to_plat,
Wilson Dinge51f2b12018-03-26 15:57:29 +08001017 .probe = pcie_advk_probe,
Pali Rohár828d3262020-08-19 15:57:07 +02001018 .remove = pcie_advk_remove,
1019 .flags = DM_FLAG_OS_PREPARE,
Simon Glass41575d82020-12-03 16:55:17 -07001020 .priv_auto = sizeof(struct pcie_advk),
Wilson Dinge51f2b12018-03-26 15:57:29 +08001021};