]> Pileus Git - ~andy/linux/blob - arch/arm/mach-omap2/am35xx-emac.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[~andy/linux] / 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 v;
43
44         v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
45         v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR |
46               AM35XX_CPGMAC_C0_MISC_PULSE_CLR | AM35XX_CPGMAC_C0_RX_THRESH_CLR);
47         omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
48         omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
49 }
50
51 static void am35xx_disable_emac_int(void)
52 {
53         u32 v;
54
55         v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
56         v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR);
57         omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
58         omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
59 }
60
61 static struct emac_platform_data am35xx_emac_pdata = {
62         .ctrl_reg_offset        = AM35XX_EMAC_CNTRL_OFFSET,
63         .ctrl_mod_reg_offset    = AM35XX_EMAC_CNTRL_MOD_OFFSET,
64         .ctrl_ram_offset        = AM35XX_EMAC_CNTRL_RAM_OFFSET,
65         .ctrl_ram_size          = AM35XX_EMAC_CNTRL_RAM_SIZE,
66         .hw_ram_addr            = AM35XX_EMAC_HW_RAM_ADDR,
67         .version                = EMAC_VERSION_2,
68         .interrupt_enable       = am35xx_enable_emac_int,
69         .interrupt_disable      = am35xx_disable_emac_int,
70 };
71
72 static struct resource am35xx_emac_resources[] = {
73         DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE, 0x30000),
74         DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RXTHRESH_IRQ),
75         DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RX_PULSE_IRQ),
76         DEFINE_RES_IRQ(INT_35XX_EMAC_C0_TX_PULSE_IRQ),
77         DEFINE_RES_IRQ(INT_35XX_EMAC_C0_MISC_PULSE_IRQ),
78 };
79
80 static struct platform_device am35xx_emac_device = {
81         .name           = "davinci_emac",
82         .id             = -1,
83         .num_resources  = ARRAY_SIZE(am35xx_emac_resources),
84         .resource       = am35xx_emac_resources,
85         .dev            = {
86                 .platform_data  = &am35xx_emac_pdata,
87         },
88 };
89
90 void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
91 {
92         u32 v;
93         int err;
94
95         am35xx_emac_pdata.rmii_en = rmii_en;
96         am35xx_emac_mdio_pdata.bus_freq = mdio_bus_freq;
97         err = platform_device_register(&am35xx_emac_device);
98         if (err) {
99                 pr_err("AM35x: failed registering EMAC device: %d\n", err);
100                 return;
101         }
102
103         err = platform_device_register(&am35xx_emac_mdio_device);
104         if (err) {
105                 pr_err("AM35x: failed registering EMAC MDIO device: %d\n", err);
106                 platform_device_unregister(&am35xx_emac_device);
107                 return;
108         }
109
110         v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
111         v &= ~AM35XX_CPGMACSS_SW_RST;
112         omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET);
113         omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */
114 }