]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/sunxi_wemac.c
mxc_ipuv3: fix memory alignment of framebuffer
[karo-tx-uboot.git] / drivers / net / sunxi_wemac.c
1 /*
2  * sunxi_wemac.c -- Allwinner A10 ethernet driver
3  *
4  * (C) Copyright 2012, Stefan Roese <sr@denx.de>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16
17 #include <common.h>
18 #include <malloc.h>
19 #include <net.h>
20 #include <miiphy.h>
21 #include <linux/err.h>
22 #include <asm/io.h>
23 #include <asm/arch/clock.h>
24 #include <asm/arch/gpio.h>
25
26 /* EMAC register  */
27 struct wemac_regs {
28         u32 ctl;        /* 0x00 */
29         u32 tx_mode;    /* 0x04 */
30         u32 tx_flow;    /* 0x08 */
31         u32 tx_ctl0;    /* 0x0c */
32         u32 tx_ctl1;    /* 0x10 */
33         u32 tx_ins;     /* 0x14 */
34         u32 tx_pl0;     /* 0x18 */
35         u32 tx_pl1;     /* 0x1c */
36         u32 tx_sta;     /* 0x20 */
37         u32 tx_io_data; /* 0x24 */
38         u32 tx_io_data1; /* 0x28 */
39         u32 tx_tsvl0;   /* 0x2c */
40         u32 tx_tsvh0;   /* 0x30 */
41         u32 tx_tsvl1;   /* 0x34 */
42         u32 tx_tsvh1;   /* 0x38 */
43         u32 rx_ctl;     /* 0x3c */
44         u32 rx_hash0;   /* 0x40 */
45         u32 rx_hash1;   /* 0x44 */
46         u32 rx_sta;     /* 0x48 */
47         u32 rx_io_data; /* 0x4c */
48         u32 rx_fbc;     /* 0x50 */
49         u32 int_ctl;    /* 0x54 */
50         u32 int_sta;    /* 0x58 */
51         u32 mac_ctl0;   /* 0x5c */
52         u32 mac_ctl1;   /* 0x60 */
53         u32 mac_ipgt;   /* 0x64 */
54         u32 mac_ipgr;   /* 0x68 */
55         u32 mac_clrt;   /* 0x6c */
56         u32 mac_maxf;   /* 0x70 */
57         u32 mac_supp;   /* 0x74 */
58         u32 mac_test;   /* 0x78 */
59         u32 mac_mcfg;   /* 0x7c */
60         u32 mac_mcmd;   /* 0x80 */
61         u32 mac_madr;   /* 0x84 */
62         u32 mac_mwtd;   /* 0x88 */
63         u32 mac_mrdd;   /* 0x8c */
64         u32 mac_mind;   /* 0x90 */
65         u32 mac_ssrr;   /* 0x94 */
66         u32 mac_a0;     /* 0x98 */
67         u32 mac_a1;     /* 0x9c */
68 };
69
70 /* SRAMC register  */
71 struct sunxi_sramc_regs {
72         u32 ctrl0;
73         u32 ctrl1;
74 };
75
76 /* 0: Disable       1: Aborted frame enable(default) */
77 #define EMAC_TX_AB_M            (0x1 << 0)
78 /* 0: CPU           1: DMA(default) */
79 #define EMAC_TX_TM              (0x1 << 1)
80
81 #define EMAC_TX_SETUP           (0)
82
83 /* 0: DRQ asserted  1: DRQ automatically(default) */
84 #define EMAC_RX_DRQ_MODE        (0x1 << 1)
85 /* 0: CPU           1: DMA(default) */
86 #define EMAC_RX_TM              (0x1 << 2)
87 /* 0: Normal(default)        1: Pass all Frames */
88 #define EMAC_RX_PA              (0x1 << 4)
89 /* 0: Normal(default)        1: Pass Control Frames */
90 #define EMAC_RX_PCF             (0x1 << 5)
91 /* 0: Normal(default)        1: Pass Frames with CRC Error */
92 #define EMAC_RX_PCRCE           (0x1 << 6)
93 /* 0: Normal(default)        1: Pass Frames with Length Error */
94 #define EMAC_RX_PLE             (0x1 << 7)
95 /* 0: Normal                 1: Pass Frames length out of range(default) */
96 #define EMAC_RX_POR             (0x1 << 8)
97 /* 0: Not accept             1: Accept unicast Packets(default) */
98 #define EMAC_RX_UCAD            (0x1 << 16)
99 /* 0: Normal(default)        1: DA Filtering */
100 #define EMAC_RX_DAF             (0x1 << 17)
101 /* 0: Not accept             1: Accept multicast Packets(default) */
102 #define EMAC_RX_MCO             (0x1 << 20)
103 /* 0: Disable(default)       1: Enable Hash filter */
104 #define EMAC_RX_MHF             (0x1 << 21)
105 /* 0: Not accept             1: Accept Broadcast Packets(default) */
106 #define EMAC_RX_BCO             (0x1 << 22)
107 /* 0: Disable(default)       1: Enable SA Filtering */
108 #define EMAC_RX_SAF             (0x1 << 24)
109 /* 0: Normal(default)        1: Inverse Filtering */
110 #define EMAC_RX_SAIF            (0x1 << 25)
111
112 #define EMAC_RX_SETUP           (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \
113                                  EMAC_RX_MCO | EMAC_RX_BCO)
114
115 /* 0: Disable                1: Enable Receive Flow Control(default) */
116 #define EMAC_MAC_CTL0_RFC       (0x1 << 2)
117 /* 0: Disable                1: Enable Transmit Flow Control(default) */
118 #define EMAC_MAC_CTL0_TFC       (0x1 << 3)
119
120 #define EMAC_MAC_CTL0_SETUP     (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC)
121
122 /* 0: Disable                1: Enable MAC Frame Length Checking(default) */
123 #define EMAC_MAC_CTL1_FLC       (0x1 << 1)
124 /* 0: Disable(default)       1: Enable Huge Frame */
125 #define EMAC_MAC_CTL1_HF        (0x1 << 2)
126 /* 0: Disable(default)       1: Enable MAC Delayed CRC */
127 #define EMAC_MAC_CTL1_DCRC      (0x1 << 3)
128 /* 0: Disable                1: Enable MAC CRC(default) */
129 #define EMAC_MAC_CTL1_CRC       (0x1 << 4)
130 /* 0: Disable                1: Enable MAC PAD Short frames(default) */
131 #define EMAC_MAC_CTL1_PC        (0x1 << 5)
132 /* 0: Disable(default)       1: Enable MAC PAD Short frames and append CRC */
133 #define EMAC_MAC_CTL1_VC        (0x1 << 6)
134 /* 0: Disable(default)       1: Enable MAC auto detect Short frames */
135 #define EMAC_MAC_CTL1_ADP       (0x1 << 7)
136 /* 0: Disable(default)       1: Enable */
137 #define EMAC_MAC_CTL1_PRE       (0x1 << 8)
138 /* 0: Disable(default)       1: Enable */
139 #define EMAC_MAC_CTL1_LPE       (0x1 << 9)
140 /* 0: Disable(default)       1: Enable no back off */
141 #define EMAC_MAC_CTL1_NB        (0x1 << 12)
142 /* 0: Disable(default)       1: Enable */
143 #define EMAC_MAC_CTL1_BNB       (0x1 << 13)
144 /* 0: Disable(default)       1: Enable */
145 #define EMAC_MAC_CTL1_ED        (0x1 << 14)
146
147 #define EMAC_MAC_CTL1_SETUP     (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \
148                                  EMAC_MAC_CTL1_PC)
149
150 #define EMAC_MAC_IPGT           0x15
151
152 #define EMAC_MAC_NBTB_IPG1      0xC
153 #define EMAC_MAC_NBTB_IPG2      0x12
154
155 #define EMAC_MAC_CW             0x37
156 #define EMAC_MAC_RM             0xF
157
158 #define EMAC_MAC_MFL            0x0600
159
160 /* Receive status */
161 #define EMAC_CRCERR             (1 << 4)
162 #define EMAC_LENERR             (3 << 5)
163
164 #define DMA_CPU_TRRESHOLD       2000
165
166 struct wemac_eth_dev {
167         u32 speed;
168         u32 duplex;
169         u32 phy_configured;
170         int link_printed;
171 };
172
173 struct wemac_rxhdr {
174         s16 rx_len;
175         u16 rx_status;
176 };
177
178 static void wemac_inblk_32bit(void *reg, void *data, int count)
179 {
180         int cnt = (count + 3) >> 2;
181
182         if (cnt) {
183                 u32 *buf = data;
184
185                 do {
186                         u32 x = readl(reg);
187                         *buf++ = x;
188                 } while (--cnt);
189         }
190 }
191
192 static void wemac_outblk_32bit(void *reg, void *data, int count)
193 {
194         int cnt = (count + 3) >> 2;
195
196         if (cnt) {
197                 const u32 *buf = data;
198
199                 do {
200                         writel(*buf++, reg);
201                 } while (--cnt);
202         }
203 }
204
205 /*
206  * Read a word from phyxcer
207  */
208 static int wemac_phy_read(const char *devname, unsigned char addr,
209                           unsigned char reg, unsigned short *value)
210 {
211         struct eth_device *dev = eth_get_dev_by_name(devname);
212         struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
213
214         /* issue the phy address and reg */
215         writel(addr << 8 | reg, &regs->mac_madr);
216
217         /* pull up the phy io line */
218         writel(0x1, &regs->mac_mcmd);
219
220         /* Wait read complete */
221         mdelay(1);
222
223         /* push down the phy io line */
224         writel(0x0, &regs->mac_mcmd);
225
226         /* and write data */
227         *value = readl(&regs->mac_mrdd);
228
229         return 0;
230 }
231
232 /*
233  * Write a word to phyxcer
234  */
235 static int wemac_phy_write(const char *devname, unsigned char addr,
236                            unsigned char reg, unsigned short value)
237 {
238         struct eth_device *dev = eth_get_dev_by_name(devname);
239         struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
240
241         /* issue the phy address and reg */
242         writel(addr << 8 | reg, &regs->mac_madr);
243
244         /* pull up the phy io line */
245         writel(0x1, &regs->mac_mcmd);
246
247         /* Wait write complete */
248         mdelay(1);
249
250         /* push down the phy io line */
251         writel(0x0, &regs->mac_mcmd);
252
253         /* and write data */
254         writel(value, &regs->mac_mwtd);
255
256         return 0;
257 }
258
259 static void emac_setup(struct eth_device *dev)
260 {
261         struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
262         u32 reg_val;
263         u16 phy_val;
264         u32 duplex_flag;
265
266         /* Set up TX */
267         writel(EMAC_TX_SETUP, &regs->tx_mode);
268
269         /* Set up RX */
270         writel(EMAC_RX_SETUP, &regs->rx_ctl);
271
272         /* Set MAC */
273         /* Set MAC CTL0 */
274         writel(EMAC_MAC_CTL0_SETUP, &regs->mac_ctl0);
275
276         /* Set MAC CTL1 */
277         wemac_phy_read(dev->name, 1, 0, &phy_val);
278         debug("PHY SETUP, reg 0 value: %x\n", phy_val);
279         duplex_flag = !!(phy_val & (1 << 8));
280
281         reg_val = 0;
282         if (duplex_flag)
283                 reg_val = (0x1 << 0);
284         writel(EMAC_MAC_CTL1_SETUP | reg_val, &regs->mac_ctl1);
285
286         /* Set up IPGT */
287         writel(EMAC_MAC_IPGT, &regs->mac_ipgt);
288
289         /* Set up IPGR */
290         writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), &regs->mac_ipgr);
291
292         /* Set up Collison window */
293         writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), &regs->mac_clrt);
294
295         /* Set up Max Frame Length */
296         writel(EMAC_MAC_MFL, &regs->mac_maxf);
297 }
298
299 static void wemac_reset(struct eth_device *dev)
300 {
301         struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
302
303         debug("resetting device\n");
304
305         /* RESET device */
306         writel(0, &regs->ctl);
307         udelay(200);
308
309         writel(1, &regs->ctl);
310         udelay(200);
311 }
312
313 static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd)
314 {
315         struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
316         struct wemac_eth_dev *priv = dev->priv;
317         u16 phy_reg;
318
319         /* Init EMAC */
320
321         /* Flush RX FIFO */
322         setbits_le32(&regs->rx_ctl, 0x8);
323         udelay(1);
324
325         /* Init MAC */
326
327         /* Soft reset MAC */
328         clrbits_le32(&regs->mac_ctl0, 1 << 15);
329
330         /* Set MII clock */
331         clrsetbits_le32(&regs->mac_mcfg, 0xf << 2, 0xd << 2);
332
333         /* Clear RX counter */
334         writel(0x0, &regs->rx_fbc);
335         udelay(1);
336
337         /* Set up EMAC */
338         emac_setup(dev);
339
340         writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 |
341                dev->enetaddr[2], &regs->mac_a1);
342         writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 |
343                dev->enetaddr[5], &regs->mac_a0);
344
345         mdelay(1);
346
347         wemac_reset(dev);
348
349         /* PHY POWER UP */
350         wemac_phy_read(dev->name, 1, 0, &phy_reg);
351         wemac_phy_write(dev->name, 1, 0, phy_reg & (~(1 << 11)));
352         mdelay(1);
353
354         wemac_phy_read(dev->name, 1, 0, &phy_reg);
355
356         priv->speed = miiphy_speed(dev->name, 0);
357         priv->duplex = miiphy_duplex(dev->name, 0);
358
359         /* Print link status only once */
360         if (!priv->link_printed) {
361                 printf("ENET Speed is %d Mbps - %s duplex connection\n",
362                        priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL");
363                 priv->link_printed = 1;
364         }
365
366         /* Set EMAC SPEED depend on PHY */
367         clrsetbits_le32(&regs->mac_supp, 1 << 8,
368                         ((phy_reg & (1 << 13)) >> 13) << 8);
369
370         /* Set duplex depend on phy */
371         clrsetbits_le32(&regs->mac_ctl1, 1 << 0,
372                         ((phy_reg & (1 << 8)) >> 8) << 0);
373
374         /* Enable RX/TX */
375         setbits_le32(&regs->ctl, 0x7);
376
377         return 0;
378 }
379
380 static void sunxi_wemac_eth_halt(struct eth_device *dev)
381 {
382         /* Nothing to do here */
383 }
384
385 static int sunxi_wemac_eth_recv(struct eth_device *dev)
386 {
387         struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
388         struct wemac_rxhdr rxhdr;
389         u32 rxcount;
390         u32 reg_val;
391         int rx_len;
392         int rx_status;
393         int good_packet;
394
395         /* Check packet ready or not */
396
397         /*
398          * Race warning: The first packet might arrive with
399          * the interrupts disabled, but the second will fix
400          */
401         rxcount = readl(&regs->rx_fbc);
402         if (!rxcount) {
403                 /* Had one stuck? */
404                 rxcount = readl(&regs->rx_fbc);
405                 if (!rxcount)
406                         return 0;
407         }
408
409         reg_val = readl(&regs->rx_io_data);
410         if (reg_val != 0x0143414d) {
411                 /* Disable RX */
412                 clrbits_le32(&regs->ctl, 1 << 2);
413
414                 /* Flush RX FIFO */
415                 setbits_le32(&regs->rx_ctl, 1 << 3);
416                 while (readl(&regs->rx_ctl) & (1 << 3))
417                         ;
418
419                 /* Enable RX */
420                 setbits_le32(&regs->ctl, 1 << 2);
421
422                 return 0;
423         }
424
425         /*
426          * A packet ready now
427          * Get status/length
428          */
429         good_packet = 1;
430
431         wemac_inblk_32bit(&regs->rx_io_data, &rxhdr, sizeof(rxhdr));
432
433         rx_len = rxhdr.rx_len;
434         rx_status = rxhdr.rx_status;
435
436         /* Packet Status check */
437         if (rx_len < 0x40) {
438                 good_packet = 0;
439                 debug("RX: Bad Packet (runt)\n");
440         }
441
442         /* rx_status is identical to RSR register. */
443         if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) {
444                 good_packet = 0;
445                 if (rx_status & EMAC_CRCERR)
446                         printf("crc error\n");
447                 if (rx_status & EMAC_LENERR)
448                         printf("length error\n");
449         }
450
451         /* Move data from WEMAC */
452         if (good_packet) {
453                 if (rx_len > DMA_CPU_TRRESHOLD) {
454                         printf("Received packet is too big (len=%d)\n", rx_len);
455                 } else {
456                         wemac_inblk_32bit((void *)&regs->rx_io_data,
457                                           NetRxPackets[0], rx_len);
458
459                         /* Pass to upper layer */
460                         NetReceive(NetRxPackets[0], rx_len);
461                         return rx_len;
462                 }
463         }
464
465         return 0;
466 }
467
468 static int sunxi_wemac_eth_send(struct eth_device *dev, void *packet, int len)
469 {
470         struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
471
472         /* Select channel 0 */
473         writel(0, &regs->tx_ins);
474
475         /* Write packet */
476         wemac_outblk_32bit((void *)&regs->tx_io_data, packet, len);
477
478         /* Set TX len */
479         writel(len, &regs->tx_pl0);
480
481         /* Start translate from fifo to phy */
482         setbits_le32(&regs->tx_ctl0, 1);
483
484         return 0;
485 }
486
487 int sunxi_wemac_initialize(void)
488 {
489         struct sunxi_ccm_reg *const ccm =
490                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
491         struct sunxi_sramc_regs *sram =
492                 (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE;
493         struct eth_device *dev;
494         struct wemac_eth_dev *priv;
495         int pin;
496
497         dev = malloc(sizeof(*dev));
498         if (dev == NULL)
499                 return -ENOMEM;
500
501         priv = (struct wemac_eth_dev *)malloc(sizeof(struct wemac_eth_dev));
502         if (!priv) {
503                 free(dev);
504                 return -ENOMEM;
505         }
506
507         memset(dev, 0, sizeof(*dev));
508         memset(priv, 0, sizeof(struct wemac_eth_dev));
509
510         /* Map SRAM to EMAC */
511         setbits_le32(&sram->ctrl1, 0x5 << 2);
512
513         /* Configure pin mux settings for MII Ethernet */
514         for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++)
515                 sunxi_gpio_set_cfgpin(pin, 2);
516
517         /* Set up clock gating */
518         setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_EMAC);
519
520         dev->iobase = SUNXI_EMAC_BASE;
521         dev->priv = priv;
522         dev->init = sunxi_wemac_eth_init;
523         dev->halt = sunxi_wemac_eth_halt;
524         dev->send = sunxi_wemac_eth_send;
525         dev->recv = sunxi_wemac_eth_recv;
526         strcpy(dev->name, "wemac");
527
528         eth_register(dev);
529
530         miiphy_register(dev->name, wemac_phy_read, wemac_phy_write);
531
532         return 0;
533 }