Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net
[pandora-kernel.git] / arch / arm / mach-omap2 / am35xx-emac.c
1 /*
2  * Copyright (C) 2011 Ilya Yanok, Emcraft Systems
3  *
4  * Based on mach-omap2/board-am3517evm.c
5  * Copyright (C) 2009 Texas Instruments Incorporated
6  * Author: Ranjith Lohithakshan <ranjithl@ti.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
13  * whether express or implied; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  */
17
18 #include <linux/clk.h>
19 #include <linux/davinci_emac.h>
20 #include <linux/platform_device.h>
21 #include <plat/irqs.h>
22 #include <mach/am35xx.h>
23
24 #include "control.h"
25
26 static struct mdio_platform_data am35xx_emac_mdio_pdata;
27
28 static struct resource am35xx_emac_mdio_resources[] = {
29         DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET, SZ_4K),
30 };
31
32 static struct platform_device am35xx_emac_mdio_device = {
33         .name           = "davinci_mdio",
34         .id             = 0,
35         .num_resources  = ARRAY_SIZE(am35xx_emac_mdio_resources),
36         .resource       = am35xx_emac_mdio_resources,
37         .dev.platform_data = &am35xx_emac_mdio_pdata,
38 };
39
40 static void am35xx_enable_emac_int(void)
41 {
42         u32 regval;
43
44         regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
45         regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
46                   AM35XX_CPGMAC_C0_TX_PULSE_CLR |
47                   AM35XX_CPGMAC_C0_MISC_PULSE_CLR |
48                   AM35XX_CPGMAC_C0_RX_THRESH_CLR);
49         omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
50         regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
51 }
52
53 static void am35xx_disable_emac_int(void)
54 {
55         u32 regval;
56
57         regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
58         regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
59                   AM35XX_CPGMAC_C0_TX_PULSE_CLR);
60         omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
61         regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
62 }
63
64 static struct emac_platform_data am35xx_emac_pdata = {
65         .ctrl_reg_offset        = AM35XX_EMAC_CNTRL_OFFSET,
66         .ctrl_mod_reg_offset    = AM35XX_EMAC_CNTRL_MOD_OFFSET,
67         .ctrl_ram_offset        = AM35XX_EMAC_CNTRL_RAM_OFFSET,
68         .ctrl_ram_size          = AM35XX_EMAC_CNTRL_RAM_SIZE,
69         .hw_ram_addr            = AM35XX_EMAC_HW_RAM_ADDR,
70         .version                = EMAC_VERSION_2,
71         .interrupt_enable       = am35xx_enable_emac_int,
72         .interrupt_disable      = am35xx_disable_emac_int,
73 };
74
75 static struct resource am35xx_emac_resources[] = {
76         DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE, 0x30000),
77         DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RXTHRESH_IRQ),
78         DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RX_PULSE_IRQ),
79         DEFINE_RES_IRQ(INT_35XX_EMAC_C0_TX_PULSE_IRQ),
80         DEFINE_RES_IRQ(INT_35XX_EMAC_C0_MISC_PULSE_IRQ),
81 };
82
83 static struct platform_device am35xx_emac_device = {
84         .name           = "davinci_emac",
85         .id             = -1,
86         .num_resources  = ARRAY_SIZE(am35xx_emac_resources),
87         .resource       = am35xx_emac_resources,
88         .dev            = {
89                 .platform_data  = &am35xx_emac_pdata,
90         },
91 };
92
93 void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
94 {
95         unsigned int regval;
96         int err;
97
98         am35xx_emac_pdata.rmii_en = rmii_en;
99         am35xx_emac_mdio_pdata.bus_freq = mdio_bus_freq;
100         err = platform_device_register(&am35xx_emac_device);
101         if (err) {
102                 pr_err("AM35x: failed registering EMAC device: %d\n", err);
103                 return;
104         }
105
106         err = platform_device_register(&am35xx_emac_mdio_device);
107         if (err) {
108                 pr_err("AM35x: failed registering EMAC MDIO device: %d\n", err);
109                 platform_device_unregister(&am35xx_emac_device);
110                 return;
111         }
112
113         regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
114         regval = regval & (~(AM35XX_CPGMACSS_SW_RST));
115         omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
116         regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
117 }