linux/arch/arm/mach-omap2/am35xx-emac.c
<<
>>
Prefs
   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/err.h>
  19#include <linux/davinci_emac.h>
  20#include <asm/system.h>
  21#include "omap_device.h"
  22#include "am35xx.h"
  23#include "control.h"
  24#include "am35xx-emac.h"
  25
  26static void am35xx_enable_emac_int(void)
  27{
  28        u32 v;
  29
  30        v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
  31        v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR |
  32              AM35XX_CPGMAC_C0_MISC_PULSE_CLR | AM35XX_CPGMAC_C0_RX_THRESH_CLR);
  33        omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
  34        omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
  35}
  36
  37static void am35xx_disable_emac_int(void)
  38{
  39        u32 v;
  40
  41        v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
  42        v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR);
  43        omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
  44        omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
  45}
  46
  47static struct emac_platform_data am35xx_emac_pdata = {
  48        .ctrl_reg_offset        = AM35XX_EMAC_CNTRL_OFFSET,
  49        .ctrl_mod_reg_offset    = AM35XX_EMAC_CNTRL_MOD_OFFSET,
  50        .ctrl_ram_offset        = AM35XX_EMAC_CNTRL_RAM_OFFSET,
  51        .ctrl_ram_size          = AM35XX_EMAC_CNTRL_RAM_SIZE,
  52        .hw_ram_addr            = AM35XX_EMAC_HW_RAM_ADDR,
  53        .version                = EMAC_VERSION_2,
  54        .interrupt_enable       = am35xx_enable_emac_int,
  55        .interrupt_disable      = am35xx_disable_emac_int,
  56};
  57
  58static struct mdio_platform_data am35xx_mdio_pdata;
  59
  60static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh,
  61                void *pdata, int pdata_len)
  62{
  63        struct platform_device *pdev;
  64
  65        pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len);
  66        if (IS_ERR(pdev)) {
  67                WARN(1, "Can't build omap_device for %s:%s.\n",
  68                     oh->class->name, oh->name);
  69                return PTR_ERR(pdev);
  70        }
  71
  72        return 0;
  73}
  74
  75void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
  76{
  77        struct omap_hwmod *oh;
  78        u32 v;
  79        int ret;
  80
  81        oh = omap_hwmod_lookup("davinci_mdio");
  82        if (!oh) {
  83                pr_err("Could not find davinci_mdio hwmod\n");
  84                return;
  85        }
  86
  87        am35xx_mdio_pdata.bus_freq = mdio_bus_freq;
  88
  89        ret = omap_davinci_emac_dev_init(oh, &am35xx_mdio_pdata,
  90                                         sizeof(am35xx_mdio_pdata));
  91        if (ret) {
  92                pr_err("Could not build davinci_mdio hwmod device\n");
  93                return;
  94        }
  95
  96        oh = omap_hwmod_lookup("davinci_emac");
  97        if (!oh) {
  98                pr_err("Could not find davinci_emac hwmod\n");
  99                return;
 100        }
 101
 102        am35xx_emac_pdata.rmii_en = rmii_en;
 103
 104        ret = omap_davinci_emac_dev_init(oh, &am35xx_emac_pdata,
 105                                         sizeof(am35xx_emac_pdata));
 106        if (ret) {
 107                pr_err("Could not build davinci_emac hwmod device\n");
 108                return;
 109        }
 110
 111        v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
 112        v &= ~AM35XX_CPGMACSS_SW_RST;
 113        omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET);
 114        omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */
 115}
 116