1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2017-2020 NXP
4  * Copyright 2014-2015 Freescale Semiconductor, Inc.
5  * Layerscape PCIe driver
6  */
7 
8 #include <common.h>
9 #include <log.h>
10 #include <asm/global_data.h>
11 #include <asm/io.h>
12 #include <errno.h>
13 #include <malloc.h>
14 #if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
15 	defined(CONFIG_ARM)
16 #include <asm/arch/clock.h>
17 #endif
18 #include "pcie_layerscape.h"
19 
20 DECLARE_GLOBAL_DATA_PTR;
21 
22 LIST_HEAD(ls_pcie_list);
23 
dbi_readl(struct ls_pcie * pcie,unsigned int offset)24 unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset)
25 {
26 	return in_le32(pcie->dbi + offset);
27 }
28 
dbi_writel(struct ls_pcie * pcie,unsigned int value,unsigned int offset)29 void dbi_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset)
30 {
31 	out_le32(pcie->dbi + offset, value);
32 }
33 
ctrl_readl(struct ls_pcie * pcie,unsigned int offset)34 unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset)
35 {
36 	if (pcie->big_endian)
37 		return in_be32(pcie->ctrl + offset);
38 	else
39 		return in_le32(pcie->ctrl + offset);
40 }
41 
ctrl_writel(struct ls_pcie * pcie,unsigned int value,unsigned int offset)42 void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
43 		 unsigned int offset)
44 {
45 	if (pcie->big_endian)
46 		out_be32(pcie->ctrl + offset, value);
47 	else
48 		out_le32(pcie->ctrl + offset, value);
49 }
50 
ls_pcie_dbi_ro_wr_en(struct ls_pcie * pcie)51 void 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 
ls_pcie_dbi_ro_wr_dis(struct ls_pcie * pcie)61 void 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 
ls_pcie_ltssm(struct ls_pcie * pcie)71 static 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 
ls_pcie_link_up(struct ls_pcie * pcie)87 int ls_pcie_link_up(struct ls_pcie *pcie)
88 {
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 
ls_pcie_atu_outbound_set(struct ls_pcie * pcie,int idx,int type,u64 phys,u64 bus_addr,u64 size)98 void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
99 			      u64 phys, u64 bus_addr, u64 size)
100 {
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 */
ls_pcie_atu_inbound_set(struct ls_pcie * pcie,u32 pf,u32 vf_flag,int type,int idx,int bar,u64 phys)112 void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
113 			     int type, int idx, int bar, u64 phys)
114 {
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);
118 	dbi_writel(pcie, type | PCIE_ATU_FUNC_NUM(pf), PCIE_ATU_CR1);
119 	dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
120 		   (vf_flag ? PCIE_ATU_FUNC_NUM_MATCH_EN : 0) |
121 		   (vf_flag ? PCIE_ATU_VFBAR_MATCH_MODE_EN : 0) |
122 		   PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2);
123 }
124 
ls_pcie_dump_atu(struct ls_pcie * pcie,u32 win_num,u32 type)125 void ls_pcie_dump_atu(struct ls_pcie *pcie, u32 win_num, u32 type)
126 {
127 	int win_idx;
128 
129 	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);
132 		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));
136 		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 		}
144 		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 }
150