layerscape: add 64b/32b target for ls1012ardb device
[openwrt/openwrt.git] / package / boot / uboot-layerscape / patches / 0043-DNCPE-296-PFE-reset-workaround.patch
1 From b17d75d2c1dc6cd1d55bcddbf7d3d4242e85e88e Mon Sep 17 00:00:00 2001
2 From: Anji J <anji.jagarlmudi@freescale.com>
3 Date: Fri, 20 May 2016 15:25:12 +0530
4 Subject: [PATCH 43/93] DNCPE-296 PFE reset workaround
5
6 LS1012A PFE doesn't have global reset control.
7 Due to this Linux pfe doesn't work when it was started at U-boot
8 This patch provides U-boot command to stop pfe, that should be used before starting Linux.
9
10 Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>>
11 Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
12 ---
13 common/cmd_pfe_commands.c | 83 +++++++++++++++++++++++++++++++++++-
14 drivers/net/pfe_eth/pfe/cbus/hif.h | 3 ++
15 drivers/net/pfe_eth/pfe/pfe.h | 2 +
16 drivers/net/pfe_eth/pfe_driver.c | 58 ++++++++++++++++++++-----
17 drivers/net/pfe_eth/pfe_eth.c | 6 +--
18 5 files changed, 136 insertions(+), 16 deletions(-)
19
20 diff --git a/common/cmd_pfe_commands.c b/common/cmd_pfe_commands.c
21 index f9f92c7..0e22097 100644
22 --- a/common/cmd_pfe_commands.c
23 +++ b/common/cmd_pfe_commands.c
24 @@ -35,6 +35,7 @@
25 #include "../drivers/net/pfe_eth/pfe/cbus/gpi.h"
26 DECLARE_GLOBAL_DATA_PTR;
27
28 +void hif_rx_desc_disable(void);
29 int pfe_load_elf(int pe_mask, const struct firmware *fw);
30 int ls1012a_gemac_initialize(bd_t * bis, int dev_id, char *devname);
31
32 @@ -593,7 +594,9 @@ void bmu(int id, void *base)
33 }
34
35 #define PESTATUS_ADDR_CLASS 0x800
36 +#define PEMBOX_ADDR_CLASS 0x890
37 #define PESTATUS_ADDR_TMU 0x80
38 +#define PEMBOX_ADDR_TMU 0x290
39 #define PESTATUS_ADDR_UTIL 0x0
40
41 static void pfe_pe_status(int argc, char * const argv[])
42 @@ -857,7 +860,6 @@ void hif_rx_enable(void)
43 void hif_rx_disable(void)
44 }
45 #endif
46 -
47 #define ROUTE_TABLE_START (CONFIG_DDR_PHYS_BASEADDR+ROUTE_TABLE_BASEADDR)
48 static void pfe_command_fftest(int argc, char * const argv[])
49 {
50 @@ -865,7 +867,6 @@ static void pfe_command_fftest(int argc, char * const argv[])
51 struct eth_device *edev_eth0;
52 struct eth_device *edev_eth1;
53
54 -
55 // open eth0 and eth1
56 edev_eth0 = eth_get_dev_by_name("pfe_eth0");
57 if (!edev_eth0)
58 @@ -916,6 +917,80 @@ static void pfe_command_start(int argc, char * const argv[])
59 }
60 #endif
61
62 +#ifdef PFE_LS1012A_RESET_WA
63 +/*This function sends a dummy packet to HIF through TMU3 */
64 +static void send_dummy_pkt_to_hif(void)
65 +{
66 + u32 buf;
67 + static u32 dummy_pkt[] = {
68 + 0x4200800a, 0x01000003, 0x00018100, 0x00000000,
69 + 0x33221100, 0x2b785544, 0xd73093cb, 0x01000608,
70 + 0x04060008, 0x2b780200, 0xd73093cb, 0x0a01a8c0,
71 + 0x33221100, 0xa8c05544, 0x00000301, 0x00000000,
72 + 0x00000000, 0x00000000, 0x00000000, 0xbe86c51f };
73 +
74 + /*Allocate BMU2 buffer */
75 + buf = readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL);
76 +
77 + printf("Sending a dummy pkt to HIF %x\n", buf);
78 + buf += 0x80;
79 + memcpy((void *)DDR_PFE_TO_VIRT(buf), dummy_pkt, sizeof(dummy_pkt));
80 + /*Write length and pkt to TMU*/
81 + writel(0x03000042, TMU_PHY_INQ_PKTPTR);
82 + writel(buf, TMU_PHY_INQ_PKTINFO);
83 +
84 +}
85 +
86 +static void pfe_command_stop(int argc, char * const argv[])
87 +{
88 + int id;
89 + u32 rx_status;
90 + printf("Stopping PFE \n");
91 +
92 + /*Mark all descriptors as LAST_BD */
93 + hif_rx_desc_disable();
94 +
95 + /*If HIF Rx BDP is busy send a dummy packet */
96 + rx_status = readl(HIF_RX_STATUS);
97 + printf("rx_status %x %x\n",rx_status, BDP_CSR_RX_DMA_ACTV);
98 + if(rx_status & BDP_CSR_RX_DMA_ACTV)
99 + send_dummy_pkt_to_hif();
100 + udelay(10);
101 +
102 + if(readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV)
103 + printf("Unable to stop HIF\n");
104 +
105 + /*Disable Class PEs */
106 +
107 + for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
108 + {
109 + printf("Stop %d\n", id);
110 + /*Inform PE to stop */
111 + pe_dmem_write(id, cpu_to_be32(1), PEMBOX_ADDR_CLASS, 4);
112 + udelay(10);
113 +
114 + printf("Reading %d\n", id);
115 + /*Read status */
116 + if(!pe_dmem_read(id, PEMBOX_ADDR_CLASS+4, 4))
117 + printf("Failed to stop PE%d\n", id);
118 + }
119 + /*Disable TMU PEs */
120 + for (id = TMU0_ID; id <= TMU_MAX_ID; id++)
121 + {
122 + if(id == TMU2_ID) continue;
123 +
124 + printf("Stop %d\n", id);
125 + /*Inform PE to stop */
126 + pe_dmem_write(id, 1, PEMBOX_ADDR_TMU, 4);
127 + udelay(10);
128 +
129 + printf("Reading %d\n", id);
130 + /*Read status */
131 + if(!pe_dmem_read(id, PEMBOX_ADDR_TMU+4, 4))
132 + printf("Failed to stop PE%d\n", id);
133 + }
134 +}
135 +#endif
136
137 static int pfe_command(cmd_tbl_t *cmdtp, int flag, int argc,
138 char * const argv[])
139 @@ -965,6 +1040,10 @@ static int pfe_command(cmd_tbl_t *cmdtp, int flag, int argc,
140 else if (strcmp(argv[1], "start") == 0)
141 pfe_command_start(argc, argv);
142 #endif
143 +#ifdef PFE_LS1012A_RESET_WA
144 + else if (strcmp(argv[1], "stop") == 0)
145 + pfe_command_stop(argc, argv);
146 +#endif
147 else
148 {
149 printf("Unknown option: %s\n", argv[1]);
150 diff --git a/drivers/net/pfe_eth/pfe/cbus/hif.h b/drivers/net/pfe_eth/pfe/cbus/hif.h
151 index a4dd7c2..2329faa 100644
152 --- a/drivers/net/pfe_eth/pfe/cbus/hif.h
153 +++ b/drivers/net/pfe_eth/pfe/cbus/hif.h
154 @@ -34,6 +34,9 @@
155 #define HIF_CTRL_BDP_POLL_CTRL_EN (1<<1)
156 #define HIF_CTRL_BDP_CH_START_WSTB (1<<2)
157
158 +/*HIF_RX_STATUS bits */
159 +#define BDP_CSR_RX_DMA_ACTV (1<<16)
160 +
161 /*HIF_INT_ENABLE bits */
162 #define HIF_INT_EN (1 << 0)
163 #define HIF_RXBD_INT_EN (1 << 1)
164 diff --git a/drivers/net/pfe_eth/pfe/pfe.h b/drivers/net/pfe_eth/pfe/pfe.h
165 index e8e2221..6994a20 100644
166 --- a/drivers/net/pfe_eth/pfe/pfe.h
167 +++ b/drivers/net/pfe_eth/pfe/pfe.h
168 @@ -1,6 +1,8 @@
169 #ifndef _PFE_H_
170 #define _PFE_H_
171
172 +#define PFE_LS1012A_RESET_WA
173 +
174 #define CLASS_DMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20))
175 #define CLASS_IMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20)) /* Only valid for mem access register interface */
176 #define CLASS_DMEM_SIZE 0x00002000
177 diff --git a/drivers/net/pfe_eth/pfe_driver.c b/drivers/net/pfe_eth/pfe_driver.c
178 index ca00e98..b06a352 100644
179 --- a/drivers/net/pfe_eth/pfe_driver.c
180 +++ b/drivers/net/pfe_eth/pfe_driver.c
181 @@ -51,13 +51,18 @@ int pfe_recv(unsigned int *pkt_ptr, int *phy_port)
182 struct rx_desc_s *rx_desc = g_rx_desc;
183 struct bufDesc *bd;
184 int len = -1;
185 - //volatile u32 ctrl;
186 + volatile u32 ctrl;
187 struct hif_header_s *hif_header;
188
189 bd = rx_desc->rxBase + rx_desc->rxToRead;
190
191 - if (bd->ctrl & BD_CTRL_DESC_EN)
192 + if (bd->ctrl & BD_CTRL_DESC_EN) {
193 + if(!(readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV)){
194 + /*If BDP is not active give write strobe */
195 + writel((readl(HIF_RX_CTRL) | HIF_CTRL_BDP_CH_START_WSTB), HIF_RX_CTRL);
196 + }
197 return len; //No pending Rx packet
198 + }
199
200 /* this len include hif_header(8bytes) */
201 len = bd->ctrl & 0xFFFF;
202 @@ -69,7 +74,7 @@ int pfe_recv(unsigned int *pkt_ptr, int *phy_port)
203 dprint("Pkt recv'd: Pkt ptr(%p), len(%d), gemac_port(%d) status(%08x)\n",
204 hif_header, len, hif_header->port_no, bd->status);
205
206 -#if 0
207 +#if DEBUG
208 {
209 int i;
210 unsigned char *p = (unsigned char *)hif_header;
211 @@ -85,20 +90,26 @@ int pfe_recv(unsigned int *pkt_ptr, int *phy_port)
212 *pkt_ptr = (unsigned int )(hif_header + 1);
213 *phy_port = hif_header->port_no;
214 len -= sizeof(struct hif_header_s);
215 -#if 0
216 +
217 +#if defined(PFE_LS1012A_RESET_WA)
218 /* reset bd control field */
219 - ctrl = (MAX_FRAME_SIZE | BD_CTRL_DESC_EN | BD_CTRL_DIR);
220 + ctrl = (MAX_FRAME_SIZE | BD_CTRL_LAST_BD | BD_CTRL_LIFM | BD_CTRL_DESC_EN | BD_CTRL_DIR);
221 +#else
222 + /* reset bd control field */
223 + ctrl = (MAX_FRAME_SIZE | BD_CTRL_LIFM | BD_CTRL_DESC_EN | BD_CTRL_DIR);
224 + /* If we use BD_CTRL_LAST_BD, rxToRead never changes */
225 + rx_desc->rxToRead = (rx_desc->rxToRead + 1) & (rx_desc->rxRingSize - 1);
226 +#endif
227 bd->ctrl = ctrl;
228 bd->status = 0;
229
230 - rx_desc->rxToRead = (rx_desc->rxToRead + 1) & (rx_desc->rxRingSize - 1);
231
232 /* Give START_STROBE to BDP to fetch the descriptor __NOW__,
233 * BDP need not to wait for rx_poll_cycle time to fetch the descriptor,
234 * In idle state (ie., no rx pkt), BDP will not fetch
235 * the descriptor even if strobe is given(I think) */
236 writel((readl(HIF_RX_CTRL) | HIF_CTRL_BDP_CH_START_WSTB), HIF_RX_CTRL);
237 -#endif
238 +
239 return len;
240 }
241
242 @@ -298,14 +309,37 @@ void hif_rx_desc_dump(void)
243 rx_desc = g_rx_desc;
244 bd_va = rx_desc->rxBase;
245
246 - printf("HIF rx desc: base_va: %p, base_pa: %08x\n", rx_desc->rxBase, rx_desc->rxBase_pa);
247 + dprint("HIF rx desc: base_va: %p, base_pa: %08x\n", rx_desc->rxBase, rx_desc->rxBase_pa);
248 for (i=0; i < rx_desc->rxRingSize; i++) {
249 -// printf("status: %08x, ctrl: %08x, data: %08x, next: %p\n",
250 -// bd_va->status, bd_va->ctrl, bd_va->data, bd_va->next);
251 + dprint("status: %08x, ctrl: %08x, data: %08x, next: %p\n",
252 + bd_va->status, bd_va->ctrl, bd_va->data, bd_va->next);
253 + bd_va++;
254 + }
255 +}
256 +
257 +/** This function mark all Rx descriptors as LAST_BD.
258 + */
259 +void hif_rx_desc_disable(void)
260 +{
261 + int i;
262 + struct rx_desc_s *rx_desc;
263 + struct bufDesc *bd_va;
264 +
265 + if (g_rx_desc == NULL) {
266 + printf("%s: HIF Rx desc not initialized \n", __func__);
267 + return;
268 + }
269 +
270 + rx_desc = g_rx_desc;
271 + bd_va = rx_desc->rxBase;
272 +
273 + for (i=0; i < rx_desc->rxRingSize; i++) {
274 + bd_va->ctrl |= BD_CTRL_LAST_BD;
275 bd_va++;
276 }
277 }
278
279 +
280 /** HIF Rx Desc initialization function.
281 */
282 static int hif_rx_desc_init(struct pfe *pfe)
283 @@ -348,7 +382,11 @@ static int hif_rx_desc_init(struct pfe *pfe)
284
285 memset(bd_va, 0, sizeof(struct bufDesc) * rx_desc->rxRingSize);
286
287 +#if defined(PFE_LS1012A_RESET_WA)
288 + ctrl = (MAX_FRAME_SIZE | BD_CTRL_LAST_BD | BD_CTRL_DESC_EN | BD_CTRL_DIR | BD_CTRL_LIFM);
289 +#else
290 ctrl = (MAX_FRAME_SIZE | BD_CTRL_DESC_EN | BD_CTRL_DIR | BD_CTRL_LIFM);
291 +#endif
292 for (i=0; i < rx_desc->rxRingSize; i++) {
293 bd_va->next = (u32 )(bd_pa + 1);
294 bd_va->ctrl = ctrl;
295 diff --git a/drivers/net/pfe_eth/pfe_eth.c b/drivers/net/pfe_eth/pfe_eth.c
296 index 40ac095..40f2c39 100644
297 --- a/drivers/net/pfe_eth/pfe_eth.c
298 +++ b/drivers/net/pfe_eth/pfe_eth.c
299 @@ -48,7 +48,7 @@ static void ls1012a_gemac_enable(void *gemac_base)
300 writel(readl(gemac_base + EMAC_ECNTRL_REG) | EMAC_ECNTRL_ETHER_EN, gemac_base + EMAC_ECNTRL_REG);
301 }
302
303 -static void ls1012a_gemac_dsable(void *gemac_base)
304 +static void ls1012a_gemac_disable(void *gemac_base)
305 {
306 writel(readl(gemac_base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_ETHER_EN, gemac_base + EMAC_ECNTRL_REG);
307 }
308 @@ -113,7 +113,7 @@ static void ls1012a_eth_halt(struct eth_device *edev)
309 {
310 struct ls1012a_eth_dev *priv = (struct ls1012a_eth_dev *)edev->priv;
311
312 - ls1012a_gemac_enable(priv->gem->gemac_base);
313 + ls1012a_gemac_disable(priv->gem->gemac_base);
314
315 gpi_disable(priv->gem->egpi_base);
316
317 @@ -216,14 +216,12 @@ static int ls1012a_eth_recv(struct eth_device *dev)
318 dprint("Rx pkt: pkt_buf(%08x), phy_port(%d), len(%d)\n", pkt_buf, phy_port, len);
319 if (phy_port != priv->gemac_port) {
320 printf("Rx pkt not on expected port\n");
321 - pfe_recv_ack();
322 return 0;
323 }
324
325 // Pass the packet up to the protocol layers.
326 net_process_received_packet((uchar *)pkt_buf, len);
327
328 - pfe_recv_ack();
329 return 0;
330 }
331
332 --
333 1.7.9.5
334