blob: bb78e7874b14d1f8f186cd4e6d37623db42c6ea0 [file] [log] [blame]
Neil Armstrong06e006b2021-03-25 15:49:21 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Amlogic DesignWare based PCIe host controller driver
4 *
5 * Copyright (c) 2021 BayLibre, SAS
6 * Author: Neil Armstrong <narmstrong@baylibre.com>
7 *
8 * Based on pcie_dw_rockchip.c
9 * Copyright (c) 2021 Rockchip, Inc.
10 */
11
Neil Armstrong06e006b2021-03-25 15:49:21 +010012#include <clk.h>
13#include <dm.h>
14#include <generic-phy.h>
15#include <pci.h>
16#include <power-domain.h>
17#include <reset.h>
18#include <syscon.h>
19#include <asm/global_data.h>
20#include <asm/io.h>
21#include <asm-generic/gpio.h>
22#include <dm/device_compat.h>
23#include <linux/iopoll.h>
24#include <linux/delay.h>
25#include <linux/log2.h>
26#include <linux/bitfield.h>
27
28#include "pcie_dw_common.h"
29
30DECLARE_GLOBAL_DATA_PTR;
31
32/**
33 * struct meson_pcie - Amlogic Meson DW PCIe controller state
34 *
35 * @pci: The common PCIe DW structure
36 * @meson_cfg_base: The base address of vendor regs
37 * @phy
38 * @clk_port
39 * @clk_general
40 * @clk_pclk
41 * @rsts
42 * @rst_gpio: The #PERST signal for slot
43 */
44struct meson_pcie {
45 /* Must be first member of the struct */
46 struct pcie_dw dw;
47 void *meson_cfg_base;
48 struct phy phy;
49 struct clk clk_port;
50 struct clk clk_general;
51 struct clk clk_pclk;
52 struct reset_ctl_bulk rsts;
53 struct gpio_desc rst_gpio;
54};
55
56#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
57
58#define PCIE_CAP_MAX_PAYLOAD_SIZE(x) ((x) << 5)
59#define PCIE_CAP_MAX_READ_REQ_SIZE(x) ((x) << 12)
60
61/* PCIe specific config registers */
62#define PCIE_CFG0 0x0
63#define APP_LTSSM_ENABLE BIT(7)
64
65#define PCIE_CFG_STATUS12 0x30
66#define IS_SMLH_LINK_UP(x) ((x) & (1 << 6))
67#define IS_RDLH_LINK_UP(x) ((x) & (1 << 16))
68#define IS_LTSSM_UP(x) ((((x) >> 10) & 0x1f) == 0x11)
69
70#define PCIE_CFG_STATUS17 0x44
71#define PM_CURRENT_STATE(x) (((x) >> 7) & 0x1)
72
73#define WAIT_LINKUP_TIMEOUT 4000
74#define PORT_CLK_RATE 100000000UL
75#define MAX_PAYLOAD_SIZE 256
76#define MAX_READ_REQ_SIZE 256
77#define PCIE_RESET_DELAY 500
78#define PCIE_SHARED_RESET 1
79#define PCIE_NORMAL_RESET 0
80
81enum pcie_data_rate {
82 PCIE_GEN1,
83 PCIE_GEN2,
84 PCIE_GEN3,
85 PCIE_GEN4
86};
87
88/* Parameters for the waiting for #perst signal */
89#define PERST_WAIT_US 1000000
90
91static inline u32 meson_cfg_readl(struct meson_pcie *priv, u32 reg)
92{
93 return readl(priv->meson_cfg_base + reg);
94}
95
96static inline void meson_cfg_writel(struct meson_pcie *priv, u32 val, u32 reg)
97{
98 writel(val, priv->meson_cfg_base + reg);
99}
100
101/**
102 * meson_pcie_configure() - Configure link
103 *
104 * @meson_pcie: Pointer to the PCI controller state
105 *
106 * Configure the link mode and width
107 */
108static void meson_pcie_configure(struct meson_pcie *priv)
109{
110 u32 val;
111
112 dw_pcie_dbi_write_enable(&priv->dw, true);
113
114 val = readl(priv->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
115 val &= ~PORT_LINK_FAST_LINK_MODE;
116 val |= PORT_LINK_DLL_LINK_EN;
117 val &= ~PORT_LINK_MODE_MASK;
118 val |= PORT_LINK_MODE_1_LANES;
119 writel(val, priv->dw.dbi_base + PCIE_PORT_LINK_CONTROL);
120
121 val = readl(priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
122 val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
123 val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
124 writel(val, priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
125
126 dw_pcie_dbi_write_enable(&priv->dw, false);
127}
128
129static inline void meson_pcie_enable_ltssm(struct meson_pcie *priv)
130{
131 u32 val;
132
133 val = meson_cfg_readl(priv, PCIE_CFG0);
134 val |= APP_LTSSM_ENABLE;
135 meson_cfg_writel(priv, val, PCIE_CFG0);
136}
137
138static int meson_pcie_wait_link_up(struct meson_pcie *priv)
139{
140 u32 speed_okay = 0;
141 u32 cnt = 0;
142 u32 state12, state17, smlh_up, ltssm_up, rdlh_up;
143
144 do {
145 state12 = meson_cfg_readl(priv, PCIE_CFG_STATUS12);
146 state17 = meson_cfg_readl(priv, PCIE_CFG_STATUS17);
147 smlh_up = IS_SMLH_LINK_UP(state12);
148 rdlh_up = IS_RDLH_LINK_UP(state12);
149 ltssm_up = IS_LTSSM_UP(state12);
150
151 if (PM_CURRENT_STATE(state17) < PCIE_GEN3)
152 speed_okay = 1;
153
154 if (smlh_up)
155 debug("%s: smlh_link_up is on\n", __func__);
156 if (rdlh_up)
157 debug("%s: rdlh_link_up is on\n", __func__);
158 if (ltssm_up)
159 debug("%s: ltssm_up is on\n", __func__);
160 if (speed_okay)
161 debug("%s: speed_okay\n", __func__);
162
163 if (smlh_up && rdlh_up && ltssm_up && speed_okay)
164 return 0;
165
166 cnt++;
167
168 udelay(10);
169 } while (cnt < WAIT_LINKUP_TIMEOUT);
170
171 printf("%s: error: wait linkup timeout\n", __func__);
172 return -EIO;
173}
174
175/**
176 * meson_pcie_link_up() - Wait for the link to come up
177 *
178 * @meson_pcie: Pointer to the PCI controller state
179 * @cap_speed: Desired link speed
180 *
181 * Return: 1 (true) for active line and negative (false) for no link (timeout)
182 */
183static int meson_pcie_link_up(struct meson_pcie *priv, u32 cap_speed)
184{
185 /* DW link configurations */
186 meson_pcie_configure(priv);
187
188 /* Reset the device */
189 if (dm_gpio_is_valid(&priv->rst_gpio)) {
190 dm_gpio_set_value(&priv->rst_gpio, 1);
191 /*
192 * Minimal is 100ms from spec but we see
193 * some wired devices need much more, such as 600ms.
194 * Add a enough delay to cover all cases.
195 */
196 udelay(PERST_WAIT_US);
197 dm_gpio_set_value(&priv->rst_gpio, 0);
198 }
199
200 /* Enable LTSSM */
201 meson_pcie_enable_ltssm(priv);
202
203 return meson_pcie_wait_link_up(priv);
204}
205
206static int meson_size_to_payload(int size)
207{
208 /*
209 * dwc supports 2^(val+7) payload size, which val is 0~5 default to 1.
210 * So if input size is not 2^order alignment or less than 2^7 or bigger
211 * than 2^12, just set to default size 2^(1+7).
212 */
213 if (!is_power_of_2(size) || size < 128 || size > 4096) {
214 debug("%s: payload size %d, set to default 256\n", __func__, size);
215 return 1;
216 }
217
218 return fls(size) - 8;
219}
220
221static void meson_set_max_payload(struct meson_pcie *priv, int size)
222{
223 u32 val;
224 u16 offset = dm_pci_find_capability(priv->dw.dev, PCI_CAP_ID_EXP);
225 int max_payload_size = meson_size_to_payload(size);
226
227 dw_pcie_dbi_write_enable(&priv->dw, true);
228
229 val = readl(priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);
230 val &= ~PCI_EXP_DEVCTL_PAYLOAD;
231 writel(val, priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);
232
233 val = readl(priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);
234 val |= PCIE_CAP_MAX_PAYLOAD_SIZE(max_payload_size);
235 writel(val, priv->dw.dbi_base + PCI_EXP_DEVCTL);
236
237 dw_pcie_dbi_write_enable(&priv->dw, false);
238}
239
240static void meson_set_max_rd_req_size(struct meson_pcie *priv, int size)
241{
242 u32 val;
243 u16 offset = dm_pci_find_capability(priv->dw.dev, PCI_CAP_ID_EXP);
244 int max_rd_req_size = meson_size_to_payload(size);
245
246 dw_pcie_dbi_write_enable(&priv->dw, true);
247
248 val = readl(priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);
249 val &= ~PCI_EXP_DEVCTL_PAYLOAD;
250 writel(val, priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);
251
252 val = readl(priv->dw.dbi_base + offset + PCI_EXP_DEVCTL);
253 val |= PCIE_CAP_MAX_READ_REQ_SIZE(max_rd_req_size);
254 writel(val, priv->dw.dbi_base + PCI_EXP_DEVCTL);
255
256 dw_pcie_dbi_write_enable(&priv->dw, false);
257}
258
259static int meson_pcie_init_port(struct udevice *dev)
260{
261 int ret;
262 struct meson_pcie *priv = dev_get_priv(dev);
263
264 ret = generic_phy_init(&priv->phy);
265 if (ret) {
266 dev_err(dev, "failed to init phy (ret=%d)\n", ret);
267 return ret;
268 }
269
270 ret = generic_phy_power_on(&priv->phy);
271 if (ret) {
272 dev_err(dev, "failed to power on phy (ret=%d)\n", ret);
273 goto err_exit_phy;
274 }
275
276 ret = generic_phy_reset(&priv->phy);
277 if (ret) {
278 dev_err(dev, "failed to reset phy (ret=%d)\n", ret);
279 goto err_exit_phy;
280 }
281
282 ret = reset_assert_bulk(&priv->rsts);
283 if (ret) {
284 dev_err(dev, "failed to assert resets (ret=%d)\n", ret);
285 goto err_power_off_phy;
286 }
287
288 udelay(PCIE_RESET_DELAY);
289
290 ret = reset_deassert_bulk(&priv->rsts);
291 if (ret) {
292 dev_err(dev, "failed to deassert resets (ret=%d)\n", ret);
293 goto err_power_off_phy;
294 }
295
296 udelay(PCIE_RESET_DELAY);
297
298 ret = clk_set_rate(&priv->clk_port, PORT_CLK_RATE);
299 if (ret) {
300 dev_err(dev, "failed to set port clk rate (ret=%d)\n", ret);
301 goto err_deassert_bulk;
302 }
303
304 ret = clk_enable(&priv->clk_general);
305 if (ret) {
306 dev_err(dev, "failed to enable clk general (ret=%d)\n", ret);
307 goto err_deassert_bulk;
308 }
309
310 ret = clk_enable(&priv->clk_pclk);
311 if (ret) {
312 dev_err(dev, "failed to enable pclk (ret=%d)\n", ret);
313 goto err_deassert_bulk;
314 }
315
316 meson_set_max_payload(priv, MAX_PAYLOAD_SIZE);
317 meson_set_max_rd_req_size(priv, MAX_READ_REQ_SIZE);
318
319 pcie_dw_setup_host(&priv->dw);
320
Neil Armstrongc7bfcbe2021-09-08 14:32:12 +0200321 meson_pcie_link_up(priv, LINK_SPEED_GEN_2);
Neil Armstrong06e006b2021-03-25 15:49:21 +0100322
323 return 0;
Neil Armstrong06e006b2021-03-25 15:49:21 +0100324err_deassert_bulk:
325 reset_assert_bulk(&priv->rsts);
326err_power_off_phy:
327 generic_phy_power_off(&priv->phy);
328err_exit_phy:
329 generic_phy_exit(&priv->phy);
330
331 return ret;
332}
333
334static int meson_pcie_parse_dt(struct udevice *dev)
335{
336 struct meson_pcie *priv = dev_get_priv(dev);
337 int ret;
338
Johan Jonker5ff88122023-03-13 01:31:49 +0100339 priv->dw.dbi_base = dev_read_addr_index_ptr(dev, 0);
Neil Armstrong06e006b2021-03-25 15:49:21 +0100340 if (!priv->dw.dbi_base)
Johan Jonker5ff88122023-03-13 01:31:49 +0100341 return -EINVAL;
Neil Armstrong06e006b2021-03-25 15:49:21 +0100342
343 dev_dbg(dev, "ELBI address is 0x%p\n", priv->dw.dbi_base);
344
Johan Jonker5ff88122023-03-13 01:31:49 +0100345 priv->meson_cfg_base = dev_read_addr_index_ptr(dev, 1);
Neil Armstrong06e006b2021-03-25 15:49:21 +0100346 if (!priv->meson_cfg_base)
Johan Jonker5ff88122023-03-13 01:31:49 +0100347 return -EINVAL;
Neil Armstrong06e006b2021-03-25 15:49:21 +0100348
349 dev_dbg(dev, "CFG address is 0x%p\n", priv->meson_cfg_base);
350
351 ret = gpio_request_by_name(dev, "reset-gpios", 0,
352 &priv->rst_gpio, GPIOD_IS_OUT);
353 if (ret) {
354 dev_err(dev, "failed to find reset-gpios property\n");
355 return ret;
356 }
357
358 ret = reset_get_bulk(dev, &priv->rsts);
359 if (ret) {
360 dev_err(dev, "Can't get reset: %d\n", ret);
361 return ret;
362 }
363
364 ret = clk_get_by_name(dev, "port", &priv->clk_port);
365 if (ret) {
366 dev_err(dev, "Can't get port clock: %d\n", ret);
367 return ret;
368 }
369
370 ret = clk_get_by_name(dev, "general", &priv->clk_general);
371 if (ret) {
372 dev_err(dev, "Can't get port clock: %d\n", ret);
373 return ret;
374 }
375
376 ret = clk_get_by_name(dev, "pclk", &priv->clk_pclk);
377 if (ret) {
378 dev_err(dev, "Can't get port clock: %d\n", ret);
379 return ret;
380 }
381
382 ret = generic_phy_get_by_index(dev, 0, &priv->phy);
383 if (ret) {
384 dev_err(dev, "failed to get pcie phy (ret=%d)\n", ret);
385 return ret;
386 }
387
388 return 0;
389}
390
391/**
392 * meson_pcie_probe() - Probe the PCIe bus for active link
393 *
394 * @dev: A pointer to the device being operated on
395 *
396 * Probe for an active link on the PCIe bus and configure the controller
397 * to enable this port.
398 *
399 * Return: 0 on success, else -ENODEV
400 */
401static int meson_pcie_probe(struct udevice *dev)
402{
403 struct meson_pcie *priv = dev_get_priv(dev);
404 struct udevice *ctlr = pci_get_controller(dev);
405 struct pci_controller *hose = dev_get_uclass_priv(ctlr);
406 int ret = 0;
407
408 priv->dw.first_busno = dev_seq(dev);
409 priv->dw.dev = dev;
410
411 ret = meson_pcie_parse_dt(dev);
412 if (ret)
413 return ret;
414
415 ret = meson_pcie_init_port(dev);
416 if (ret) {
417 dm_gpio_free(dev, &priv->rst_gpio);
418 return ret;
419 }
420
421 printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n",
422 dev_seq(dev), pcie_dw_get_link_speed(&priv->dw),
423 pcie_dw_get_link_width(&priv->dw),
424 hose->first_busno);
425
426 return pcie_dw_prog_outbound_atu_unroll(&priv->dw,
427 PCIE_ATU_REGION_INDEX0,
428 PCIE_ATU_TYPE_MEM,
429 priv->dw.mem.phys_start,
430 priv->dw.mem.bus_start,
431 priv->dw.mem.size);
432}
433
434static const struct dm_pci_ops meson_pcie_ops = {
435 .read_config = pcie_dw_read_config,
436 .write_config = pcie_dw_write_config,
437};
438
439static const struct udevice_id meson_pcie_ids[] = {
440 { .compatible = "amlogic,axg-pcie" },
441 { .compatible = "amlogic,g12a-pcie" },
442 { }
443};
444
445U_BOOT_DRIVER(meson_dw_pcie) = {
446 .name = "pcie_dw_meson",
447 .id = UCLASS_PCI,
448 .of_match = meson_pcie_ids,
449 .ops = &meson_pcie_ops,
450 .probe = meson_pcie_probe,
451 .priv_auto = sizeof(struct meson_pcie),
452};