blob: 3c7c4ca18e8b5324bb5bf3e0a1f28fb86774fc09 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Minghuan Liana4d6b612014-10-31 13:43:44 +08002/*
Xiaowei Bao13b277f2020-07-09 23:31:33 +08003 * Copyright 2017-2020 NXP
Minghuan Lianfdab5452015-01-21 17:29:20 +08004 * Copyright 2014-2015 Freescale Semiconductor, Inc.
Minghuan Liana4d6b612014-10-31 13:43:44 +08005 * Layerscape PCIe driver
Minghuan Liana4d6b612014-10-31 13:43:44 +08006 */
7
8#include <common.h>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060010#include <asm/global_data.h>
Minghuan Liana4d6b612014-10-31 13:43:44 +080011#include <asm/io.h>
Minghuan Lianfdab5452015-01-21 17:29:20 +080012#include <errno.h>
13#include <malloc.h>
Simon Glass243182c2017-05-17 08:23:06 -060014#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
15 defined(CONFIG_ARM)
16#include <asm/arch/clock.h>
17#endif
Hou Zhiqiang09716a7b2016-12-13 14:54:16 +080018#include "pcie_layerscape.h"
Minghuan Lianfdab5452015-01-21 17:29:20 +080019
Minghuan Lianc1067842016-12-13 14:54:17 +080020DECLARE_GLOBAL_DATA_PTR;
21
Minghuan Lianc1067842016-12-13 14:54:17 +080022LIST_HEAD(ls_pcie_list);
23
Xiaowei Bao13b277f2020-07-09 23:31:33 +080024unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset)
Minghuan Lianc1067842016-12-13 14:54:17 +080025{
26 return in_le32(pcie->dbi + offset);
27}
28
Xiaowei Bao13b277f2020-07-09 23:31:33 +080029void dbi_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset)
Minghuan Lianc1067842016-12-13 14:54:17 +080030{
31 out_le32(pcie->dbi + offset, value);
32}
33
Xiaowei Bao13b277f2020-07-09 23:31:33 +080034unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset)
Minghuan Lianc1067842016-12-13 14:54:17 +080035{
36 if (pcie->big_endian)
37 return in_be32(pcie->ctrl + offset);
38 else
39 return in_le32(pcie->ctrl + offset);
40}
41
Xiaowei Bao13b277f2020-07-09 23:31:33 +080042void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
43 unsigned int offset)
Minghuan Lianc1067842016-12-13 14:54:17 +080044{
45 if (pcie->big_endian)
46 out_be32(pcie->ctrl + offset, value);
47 else
48 out_le32(pcie->ctrl + offset, value);
49}
50
Xiaowei Bao13b277f2020-07-09 23:31:33 +080051void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie)
52{
53 u32 reg, val;
54
55 reg = PCIE_MISC_CONTROL_1_OFF;
56 val = dbi_readl(pcie, reg);
57 val |= PCIE_DBI_RO_WR_EN;
58 dbi_writel(pcie, val, reg);
59}
60
61void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie)
62{
63 u32 reg, val;
64
65 reg = PCIE_MISC_CONTROL_1_OFF;
66 val = dbi_readl(pcie, reg);
67 val &= ~PCIE_DBI_RO_WR_EN;
68 dbi_writel(pcie, val, reg);
69}
70
Minghuan Lianc1067842016-12-13 14:54:17 +080071static int ls_pcie_ltssm(struct ls_pcie *pcie)
72{
73 u32 state;
74 uint svr;
75
76 svr = get_svr();
77 if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) == SVR_LS102XA) {
78 state = ctrl_readl(pcie, LS1021_PEXMSCPORTSR(pcie->idx));
79 state = (state >> LS1021_LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
80 } else {
81 state = ctrl_readl(pcie, PCIE_PF_DBG) & LTSSM_STATE_MASK;
82 }
83
84 return state;
85}
86
Xiaowei Bao13b277f2020-07-09 23:31:33 +080087int ls_pcie_link_up(struct ls_pcie *pcie)
Minghuan Lianc1067842016-12-13 14:54:17 +080088{
89 int ltssm;
90
91 ltssm = ls_pcie_ltssm(pcie);
92 if (ltssm < LTSSM_PCIE_L0)
93 return 0;
94
95 return 1;
96}
97
Xiaowei Bao13b277f2020-07-09 23:31:33 +080098void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
Xiaowei Baoecb85db2020-07-09 23:31:39 +080099 u64 phys, u64 bus_addr, u64 size)
Minghuan Lianc1067842016-12-13 14:54:17 +0800100{
101 dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | idx, PCIE_ATU_VIEWPORT);
102 dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_BASE);
103 dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_BASE);
104 dbi_writel(pcie, (u32)phys + size - 1, PCIE_ATU_LIMIT);
105 dbi_writel(pcie, (u32)bus_addr, PCIE_ATU_LOWER_TARGET);
106 dbi_writel(pcie, bus_addr >> 32, PCIE_ATU_UPPER_TARGET);
107 dbi_writel(pcie, type, PCIE_ATU_CR1);
108 dbi_writel(pcie, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
109}
110
111/* Use bar match mode and MEM type as default */
Xiaowei Baoecb85db2020-07-09 23:31:39 +0800112void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
113 int type, int idx, int bar, u64 phys)
Minghuan Lianc1067842016-12-13 14:54:17 +0800114{
115 dbi_writel(pcie, PCIE_ATU_REGION_INBOUND | idx, PCIE_ATU_VIEWPORT);
116 dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_TARGET);
117 dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_TARGET);
Xiaowei Baob4d63b02020-07-09 23:31:36 +0800118 dbi_writel(pcie, type | PCIE_ATU_FUNC_NUM(pf), PCIE_ATU_CR1);
Minghuan Lianc1067842016-12-13 14:54:17 +0800119 dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
Xiaowei Baoecb85db2020-07-09 23:31:39 +0800120 (vf_flag ? PCIE_ATU_FUNC_NUM_MATCH_EN : 0) |
121 (vf_flag ? PCIE_ATU_VFBAR_MATCH_MODE_EN : 0) |
Minghuan Lianc1067842016-12-13 14:54:17 +0800122 PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2);
123}
124
Xiaowei Baobb3f7132020-07-09 23:31:40 +0800125void ls_pcie_dump_atu(struct ls_pcie *pcie, u32 win_num, u32 type)
Minghuan Lianc1067842016-12-13 14:54:17 +0800126{
Xiaowei Baobb3f7132020-07-09 23:31:40 +0800127 int win_idx;
Minghuan Lianc1067842016-12-13 14:54:17 +0800128
Xiaowei Baobb3f7132020-07-09 23:31:40 +0800129 for (win_idx = 0; win_idx < win_num; win_idx++) {
130 dbi_writel(pcie, type | win_idx, PCIE_ATU_VIEWPORT);
131 debug("iATU%d:\n", win_idx);
Minghuan Lianc1067842016-12-13 14:54:17 +0800132 debug("\tLOWER PHYS 0x%08x\n",
133 dbi_readl(pcie, PCIE_ATU_LOWER_BASE));
134 debug("\tUPPER PHYS 0x%08x\n",
135 dbi_readl(pcie, PCIE_ATU_UPPER_BASE));
Xiaowei Baobb3f7132020-07-09 23:31:40 +0800136 if (type == PCIE_ATU_REGION_OUTBOUND) {
137 debug("\tLOWER BUS 0x%08x\n",
138 dbi_readl(pcie, PCIE_ATU_LOWER_TARGET));
139 debug("\tUPPER BUS 0x%08x\n",
140 dbi_readl(pcie, PCIE_ATU_UPPER_TARGET));
141 debug("\tLIMIT 0x%08x\n",
142 dbi_readl(pcie, PCIE_ATU_LIMIT));
143 }
Minghuan Lianc1067842016-12-13 14:54:17 +0800144 debug("\tCR1 0x%08x\n",
145 dbi_readl(pcie, PCIE_ATU_CR1));
146 debug("\tCR2 0x%08x\n",
147 dbi_readl(pcie, PCIE_ATU_CR2));
148 }
149}