source: branches/backfire/target/linux/ar71xx/files/arch/mips/ar71xx/devices.c @ 28215

Last change on this file since 28215 was 28215, checked in by nbd, 5 years ago

ar71xx: add missing ethernet driver fix backport (fixes #10089)

  • Property svn:eol-style set to native
File size: 14.1 KB
Line 
1/*
2 *  Atheros AR71xx SoC platform devices
3 *
4 *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
5 *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
7 *  Parts of this file are based on Atheros' 2.6.15 BSP
8 *
9 *  This program is free software; you can redistribute it and/or modify it
10 *  under the terms of the GNU General Public License version 2 as published
11 *  by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/etherdevice.h>
18#include <linux/platform_device.h>
19#include <linux/serial_8250.h>
20
21#include <asm/mach-ar71xx/ar71xx.h>
22
23#include "devices.h"
24
25static u8 ar71xx_mac_base[ETH_ALEN] __initdata;
26
27static struct resource ar71xx_uart_resources[] = {
28        {
29                .start  = AR71XX_UART_BASE,
30                .end    = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
31                .flags  = IORESOURCE_MEM,
32        },
33};
34
35#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
36static struct plat_serial8250_port ar71xx_uart_data[] = {
37        {
38                .mapbase        = AR71XX_UART_BASE,
39                .irq            = AR71XX_MISC_IRQ_UART,
40                .flags          = AR71XX_UART_FLAGS,
41                .iotype         = UPIO_MEM32,
42                .regshift       = 2,
43        }, {
44                /* terminating entry */
45        }
46};
47
48static struct platform_device ar71xx_uart_device = {
49        .name           = "serial8250",
50        .id             = PLAT8250_DEV_PLATFORM,
51        .resource       = ar71xx_uart_resources,
52        .num_resources  = ARRAY_SIZE(ar71xx_uart_resources),
53        .dev = {
54                .platform_data  = ar71xx_uart_data
55        },
56};
57
58void __init ar71xx_add_device_uart(void)
59{
60        ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq;
61        platform_device_register(&ar71xx_uart_device);
62}
63
64static struct resource ar71xx_mdio_resources[] = {
65        {
66                .name   = "mdio_base",
67                .flags  = IORESOURCE_MEM,
68                .start  = AR71XX_GE0_BASE,
69                .end    = AR71XX_GE0_BASE + 0x200 - 1,
70        }
71};
72
73static struct ag71xx_mdio_platform_data ar71xx_mdio_data;
74
75struct platform_device ar71xx_mdio_device = {
76        .name           = "ag71xx-mdio",
77        .id             = -1,
78        .resource       = ar71xx_mdio_resources,
79        .num_resources  = ARRAY_SIZE(ar71xx_mdio_resources),
80        .dev = {
81                .platform_data = &ar71xx_mdio_data,
82        },
83};
84
85static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
86{
87        void __iomem *base;
88        u32 t;
89
90        base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE);
91
92        t = __raw_readl(base + cfg_reg);
93        t &= ~(3 << shift);
94        t |=  (2 << shift);
95        __raw_writel(t, base + cfg_reg);
96        udelay(100);
97
98        __raw_writel(pll_val, base + pll_reg);
99
100        t |= (3 << shift);
101        __raw_writel(t, base + cfg_reg);
102        udelay(100);
103
104        t &= ~(3 << shift);
105        __raw_writel(t, base + cfg_reg);
106        udelay(100);
107
108        printk(KERN_DEBUG "ar71xx: pll_reg %#x: %#x\n",
109                (unsigned int)(base + pll_reg), __raw_readl(base + pll_reg));
110
111        iounmap(base);
112}
113
114void __init ar71xx_add_device_mdio(u32 phy_mask)
115{
116        switch (ar71xx_soc) {
117        case AR71XX_SOC_AR7240:
118                ar71xx_mdio_data.is_ar7240 = 1;
119                break;
120        case AR71XX_SOC_AR7241:
121                ar71xx_mdio_data.is_ar7240 = 1;
122                ar71xx_mdio_resources[0].start = AR71XX_GE1_BASE;
123                ar71xx_mdio_resources[0].end = AR71XX_GE1_BASE + 0x200 - 1;
124                break;
125        case AR71XX_SOC_AR7242:
126                ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG,
127                               AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000,
128                               AR71XX_ETH0_PLL_SHIFT);
129                break;
130        default:
131                break;
132        }
133
134        ar71xx_mdio_data.phy_mask = phy_mask;
135
136        platform_device_register(&ar71xx_mdio_device);
137}
138
139struct ar71xx_eth_pll_data ar71xx_eth0_pll_data;
140struct ar71xx_eth_pll_data ar71xx_eth1_pll_data;
141
142static u32 ar71xx_get_eth_pll(unsigned int mac, int speed)
143{
144        struct ar71xx_eth_pll_data *pll_data;
145        u32 pll_val;
146
147        switch (mac) {
148        case 0:
149                pll_data = &ar71xx_eth0_pll_data;
150                break;
151        case 1:
152                pll_data = &ar71xx_eth1_pll_data;
153                break;
154        default:
155                BUG();
156        }
157
158        switch (speed) {
159        case SPEED_10:
160                pll_val = pll_data->pll_10;
161                break;
162        case SPEED_100:
163                pll_val = pll_data->pll_100;
164                break;
165        case SPEED_1000:
166                pll_val = pll_data->pll_1000;
167                break;
168        default:
169                BUG();
170        }
171
172        return pll_val;
173}
174
175static void ar71xx_set_pll_ge0(int speed)
176{
177        u32 val = ar71xx_get_eth_pll(0, speed);
178
179        ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH0_INT_CLOCK,
180                        val, AR71XX_ETH0_PLL_SHIFT);
181}
182
183static void ar71xx_set_pll_ge1(int speed)
184{
185        u32 val = ar71xx_get_eth_pll(1, speed);
186
187        ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR71XX_PLL_REG_ETH1_INT_CLOCK,
188                         val, AR71XX_ETH1_PLL_SHIFT);
189}
190
191static void ar724x_set_pll_ge0(int speed)
192{
193        /* TODO */
194}
195
196static void ar724x_set_pll_ge1(int speed)
197{
198        /* TODO */
199}
200
201static void ar7242_set_pll_ge0(int speed)
202{
203        u32 val = ar71xx_get_eth_pll(0, speed);
204
205        ar71xx_set_pll(AR71XX_PLL_REG_SEC_CONFIG, AR7242_PLL_REG_ETH0_INT_CLOCK,
206                       val, AR71XX_ETH0_PLL_SHIFT);
207}
208
209static void ar91xx_set_pll_ge0(int speed)
210{
211        u32 val = ar71xx_get_eth_pll(0, speed);
212
213        ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
214                         val, AR91XX_ETH0_PLL_SHIFT);
215}
216
217static void ar91xx_set_pll_ge1(int speed)
218{
219        u32 val = ar71xx_get_eth_pll(1, speed);
220
221        ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
222                         val, AR91XX_ETH1_PLL_SHIFT);
223}
224
225static void ar71xx_ddr_flush_ge0(void)
226{
227        ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE0);
228}
229
230static void ar71xx_ddr_flush_ge1(void)
231{
232        ar71xx_ddr_flush(AR71XX_DDR_REG_FLUSH_GE1);
233}
234
235static void ar724x_ddr_flush_ge0(void)
236{
237        ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE0);
238}
239
240static void ar724x_ddr_flush_ge1(void)
241{
242        ar71xx_ddr_flush(AR724X_DDR_REG_FLUSH_GE1);
243}
244
245static void ar91xx_ddr_flush_ge0(void)
246{
247        ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE0);
248}
249
250static void ar91xx_ddr_flush_ge1(void)
251{
252        ar71xx_ddr_flush(AR91XX_DDR_REG_FLUSH_GE1);
253}
254
255static struct resource ar71xx_eth0_resources[] = {
256        {
257                .name   = "mac_base",
258                .flags  = IORESOURCE_MEM,
259                .start  = AR71XX_GE0_BASE,
260                .end    = AR71XX_GE0_BASE + 0x200 - 1,
261        }, {
262                .name   = "mii_ctrl",
263                .flags  = IORESOURCE_MEM,
264                .start  = AR71XX_MII_BASE + MII_REG_MII0_CTRL,
265                .end    = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3,
266        }, {
267                .name   = "mac_irq",
268                .flags  = IORESOURCE_IRQ,
269                .start  = AR71XX_CPU_IRQ_GE0,
270                .end    = AR71XX_CPU_IRQ_GE0,
271        },
272};
273
274struct ag71xx_platform_data ar71xx_eth0_data = {
275        .reset_bit      = RESET_MODULE_GE0_MAC,
276};
277
278struct platform_device ar71xx_eth0_device = {
279        .name           = "ag71xx",
280        .id             = 0,
281        .resource       = ar71xx_eth0_resources,
282        .num_resources  = ARRAY_SIZE(ar71xx_eth0_resources),
283        .dev = {
284                .platform_data = &ar71xx_eth0_data,
285        },
286};
287
288static struct resource ar71xx_eth1_resources[] = {
289        {
290                .name   = "mac_base",
291                .flags  = IORESOURCE_MEM,
292                .start  = AR71XX_GE1_BASE,
293                .end    = AR71XX_GE1_BASE + 0x200 - 1,
294        }, {
295                .name   = "mii_ctrl",
296                .flags  = IORESOURCE_MEM,
297                .start  = AR71XX_MII_BASE + MII_REG_MII1_CTRL,
298                .end    = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3,
299        }, {
300                .name   = "mac_irq",
301                .flags  = IORESOURCE_IRQ,
302                .start  = AR71XX_CPU_IRQ_GE1,
303                .end    = AR71XX_CPU_IRQ_GE1,
304        },
305};
306
307struct ag71xx_platform_data ar71xx_eth1_data = {
308        .reset_bit      = RESET_MODULE_GE1_MAC,
309};
310
311struct platform_device ar71xx_eth1_device = {
312        .name           = "ag71xx",
313        .id             = 1,
314        .resource       = ar71xx_eth1_resources,
315        .num_resources  = ARRAY_SIZE(ar71xx_eth1_resources),
316        .dev = {
317                .platform_data = &ar71xx_eth1_data,
318        },
319};
320
321#define AR71XX_PLL_VAL_1000     0x00110000
322#define AR71XX_PLL_VAL_100      0x00001099
323#define AR71XX_PLL_VAL_10       0x00991099
324
325#define AR724X_PLL_VAL_1000     0x00110000
326#define AR724X_PLL_VAL_100      0x00001099
327#define AR724X_PLL_VAL_10       0x00991099
328
329#define AR7242_PLL_VAL_1000     0x1c000000
330#define AR7242_PLL_VAL_100      0x00000101
331#define AR7242_PLL_VAL_10       0x00001616
332
333#define AR91XX_PLL_VAL_1000     0x1a000000
334#define AR91XX_PLL_VAL_100      0x13000a44
335#define AR91XX_PLL_VAL_10       0x00441099
336
337static void __init ar71xx_init_eth_pll_data(unsigned int id)
338{
339        struct ar71xx_eth_pll_data *pll_data;
340        u32 pll_10, pll_100, pll_1000;
341
342        switch (id) {
343        case 0:
344                pll_data = &ar71xx_eth0_pll_data;
345                break;
346        case 1:
347                pll_data = &ar71xx_eth1_pll_data;
348                break;
349        default:
350                BUG();
351        }
352
353        switch (ar71xx_soc) {
354        case AR71XX_SOC_AR7130:
355        case AR71XX_SOC_AR7141:
356        case AR71XX_SOC_AR7161:
357                pll_10 = AR71XX_PLL_VAL_10;
358                pll_100 = AR71XX_PLL_VAL_100;
359                pll_1000 = AR71XX_PLL_VAL_1000;
360                break;
361
362        case AR71XX_SOC_AR7240:
363        case AR71XX_SOC_AR7241:
364                pll_10 = AR724X_PLL_VAL_10;
365                pll_100 = AR724X_PLL_VAL_100;
366                pll_1000 = AR724X_PLL_VAL_1000;
367                break;
368
369        case AR71XX_SOC_AR7242:
370                pll_10 = AR7242_PLL_VAL_10;
371                pll_100 = AR7242_PLL_VAL_100;
372                pll_1000 = AR7242_PLL_VAL_1000;
373                break;
374
375        case AR71XX_SOC_AR9130:
376        case AR71XX_SOC_AR9132:
377                pll_10 = AR91XX_PLL_VAL_10;
378                pll_100 = AR91XX_PLL_VAL_100;
379                pll_1000 = AR91XX_PLL_VAL_1000;
380                break;
381        default:
382                BUG();
383        }
384
385        if (!pll_data->pll_10)
386                pll_data->pll_10 = pll_10;
387
388        if (!pll_data->pll_100)
389                pll_data->pll_100 = pll_100;
390
391        if (!pll_data->pll_1000)
392                pll_data->pll_1000 = pll_1000;
393}
394
395static int ar71xx_eth_instance __initdata;
396void __init ar71xx_add_device_eth(unsigned int id)
397{
398        struct platform_device *pdev;
399        struct ag71xx_platform_data *pdata;
400
401        ar71xx_init_eth_pll_data(id);
402
403        switch (id) {
404        case 0:
405                switch (ar71xx_eth0_data.phy_if_mode) {
406                case PHY_INTERFACE_MODE_MII:
407                        ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII;
408                        break;
409                case PHY_INTERFACE_MODE_GMII:
410                        ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII;
411                        break;
412                case PHY_INTERFACE_MODE_RGMII:
413                        ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII;
414                        break;
415                case PHY_INTERFACE_MODE_RMII:
416                        ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII;
417                        break;
418                default:
419                        printk(KERN_ERR "ar71xx: invalid PHY interface mode "
420                                        "for eth0\n");
421                        return;
422                }
423                pdev = &ar71xx_eth0_device;
424                break;
425        case 1:
426                switch (ar71xx_eth1_data.phy_if_mode) {
427                case PHY_INTERFACE_MODE_RMII:
428                        ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII;
429                        break;
430                case PHY_INTERFACE_MODE_RGMII:
431                        ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII;
432                        break;
433                default:
434                        printk(KERN_ERR "ar71xx: invalid PHY interface mode "
435                                        "for eth1\n");
436                        return;
437                }
438                pdev = &ar71xx_eth1_device;
439                break;
440        default:
441                printk(KERN_ERR "ar71xx: invalid ethernet id %d\n", id);
442                return;
443        }
444
445        pdata = pdev->dev.platform_data;
446
447        switch (ar71xx_soc) {
448        case AR71XX_SOC_AR7130:
449                pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
450                                      : ar71xx_ddr_flush_ge0;
451                pdata->set_pll =  id ? ar71xx_set_pll_ge1
452                                     : ar71xx_set_pll_ge0;
453                break;
454
455        case AR71XX_SOC_AR7141:
456        case AR71XX_SOC_AR7161:
457                pdata->ddr_flush = id ? ar71xx_ddr_flush_ge1
458                                      : ar71xx_ddr_flush_ge0;
459                pdata->set_pll =  id ? ar71xx_set_pll_ge1
460                                     : ar71xx_set_pll_ge0;
461                pdata->has_gbit = 1;
462                break;
463
464        case AR71XX_SOC_AR7242:
465                ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO |
466                                              RESET_MODULE_GE0_PHY;
467                ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO |
468                                              RESET_MODULE_GE1_PHY;
469                pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
470                                      : ar724x_ddr_flush_ge0;
471                pdata->set_pll =  id ? ar724x_set_pll_ge1
472                                     : ar7242_set_pll_ge0;
473                pdata->has_gbit = 1;
474                pdata->is_ar724x = 1;
475
476                if (!pdata->fifo_cfg1)
477                        pdata->fifo_cfg1 = 0x0010ffff;
478                if (!pdata->fifo_cfg2)
479                        pdata->fifo_cfg2 = 0x015500aa;
480                if (!pdata->fifo_cfg3)
481                        pdata->fifo_cfg3 = 0x01f00140;
482                break;
483
484        case AR71XX_SOC_AR7241:
485                ar71xx_eth0_data.reset_bit |= AR724X_RESET_GE0_MDIO;
486                ar71xx_eth1_data.reset_bit |= AR724X_RESET_GE1_MDIO;
487                /* fall through */
488        case AR71XX_SOC_AR7240:
489                ar71xx_eth0_data.reset_bit |= RESET_MODULE_GE0_PHY;
490                ar71xx_eth1_data.reset_bit |= RESET_MODULE_GE1_PHY;
491                pdata->ddr_flush = id ? ar724x_ddr_flush_ge1
492                                      : ar724x_ddr_flush_ge0;
493                pdata->set_pll =  id ? ar724x_set_pll_ge1
494                                     : ar724x_set_pll_ge0;
495                pdata->is_ar724x = 1;
496                if (ar71xx_soc == AR71XX_SOC_AR7240)
497                        pdata->is_ar7240 = 1;
498
499                if (!pdata->fifo_cfg1)
500                        pdata->fifo_cfg1 = 0x0010ffff;
501                if (!pdata->fifo_cfg2)
502                        pdata->fifo_cfg2 = 0x015500aa;
503                if (!pdata->fifo_cfg3)
504                        pdata->fifo_cfg3 = 0x01f00140;
505                break;
506
507        case AR71XX_SOC_AR9130:
508                pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
509                                      : ar91xx_ddr_flush_ge0;
510                pdata->set_pll =  id ? ar91xx_set_pll_ge1
511                                     : ar91xx_set_pll_ge0;
512                pdata->is_ar91xx = 1;
513                break;
514
515        case AR71XX_SOC_AR9132:
516                pdata->ddr_flush = id ? ar91xx_ddr_flush_ge1
517                                      : ar91xx_ddr_flush_ge0;
518                pdata->set_pll =  id ? ar91xx_set_pll_ge1
519                                      : ar91xx_set_pll_ge0;
520                pdata->is_ar91xx = 1;
521                pdata->has_gbit = 1;
522                break;
523
524        default:
525                BUG();
526        }
527
528        switch (pdata->phy_if_mode) {
529        case PHY_INTERFACE_MODE_GMII:
530        case PHY_INTERFACE_MODE_RGMII:
531                if (!pdata->has_gbit) {
532                        printk(KERN_ERR "ar71xx: no gbit available on eth%d\n",
533                                        id);
534                        return;
535                }
536                /* fallthrough */
537        default:
538                break;
539        }
540
541        if (is_valid_ether_addr(ar71xx_mac_base)) {
542                memcpy(pdata->mac_addr, ar71xx_mac_base, ETH_ALEN);
543                pdata->mac_addr[5] += ar71xx_eth_instance;
544        } else {
545                random_ether_addr(pdata->mac_addr);
546                printk(KERN_DEBUG
547                        "ar71xx: using random MAC address for eth%d\n",
548                        ar71xx_eth_instance);
549        }
550
551        if (pdata->mii_bus_dev == NULL)
552                pdata->mii_bus_dev = &ar71xx_mdio_device.dev;
553
554        /* Reset the device */
555        ar71xx_device_stop(pdata->reset_bit);
556        mdelay(100);
557
558        ar71xx_device_start(pdata->reset_bit);
559        mdelay(100);
560
561        platform_device_register(pdev);
562        ar71xx_eth_instance++;
563}
564
565static struct resource ar71xx_spi_resources[] = {
566        [0] = {
567                .start  = AR71XX_SPI_BASE,
568                .end    = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
569                .flags  = IORESOURCE_MEM,
570        },
571};
572
573static struct platform_device ar71xx_spi_device = {
574        .name           = "ar71xx-spi",
575        .id             = -1,
576        .resource       = ar71xx_spi_resources,
577        .num_resources  = ARRAY_SIZE(ar71xx_spi_resources),
578};
579
580void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
581                                struct spi_board_info const *info,
582                                unsigned n)
583{
584        spi_register_board_info(info, n);
585        ar71xx_spi_device.dev.platform_data = pdata;
586        platform_device_register(&ar71xx_spi_device);
587}
588
589void __init ar71xx_add_device_wdt(void)
590{
591        platform_device_register_simple("ar71xx-wdt", -1, NULL, 0);
592}
593
594void __init ar71xx_set_mac_base(unsigned char *mac)
595{
596        memcpy(ar71xx_mac_base, mac, ETH_ALEN);
597}
598
599void __init ar71xx_parse_mac_addr(char *mac_str)
600{
601        u8 tmp[ETH_ALEN];
602        int t;
603
604        t = sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
605                        &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
606
607        if (t != ETH_ALEN)
608                t = sscanf(mac_str, "%02hhx.%02hhx.%02hhx.%02hhx.%02hhx.%02hhx",
609                        &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
610
611        if (t == ETH_ALEN)
612                ar71xx_set_mac_base(tmp);
613        else
614                printk(KERN_DEBUG "ar71xx: failed to parse mac address "
615                                "\"%s\"\n", mac_str);
616}
617
618static int __init ar71xx_ethaddr_setup(char *str)
619{
620        ar71xx_parse_mac_addr(str);
621        return 1;
622}
623__setup("ethaddr=", ar71xx_ethaddr_setup);
624
625static int __init ar71xx_kmac_setup(char *str)
626{
627        ar71xx_parse_mac_addr(str);
628        return 1;
629}
630__setup("kmac=", ar71xx_kmac_setup);
Note: See TracBrowser for help on using the repository browser.