am35xx-emac.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. #include <linux/clk.h>
  18. #include <linux/davinci_emac.h>
  19. #include <linux/platform_device.h>
  20. #include <plat/irqs.h>
  21. #include <mach/am35xx.h>
  22. #include "control.h"
  23. static struct mdio_platform_data am35xx_emac_mdio_pdata;
  24. static struct resource am35xx_emac_mdio_resources[] = {
  25. DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET, SZ_4K),
  26. };
  27. static struct platform_device am35xx_emac_mdio_device = {
  28. .name = "davinci_mdio",
  29. .id = 0,
  30. .num_resources = ARRAY_SIZE(am35xx_emac_mdio_resources),
  31. .resource = am35xx_emac_mdio_resources,
  32. .dev.platform_data = &am35xx_emac_mdio_pdata,
  33. };
  34. static void am35xx_enable_emac_int(void)
  35. {
  36. u32 v;
  37. v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
  38. v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR |
  39. AM35XX_CPGMAC_C0_MISC_PULSE_CLR | AM35XX_CPGMAC_C0_RX_THRESH_CLR);
  40. omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
  41. omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
  42. }
  43. static void am35xx_disable_emac_int(void)
  44. {
  45. u32 v;
  46. v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
  47. v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR);
  48. omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
  49. omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
  50. }
  51. static struct emac_platform_data am35xx_emac_pdata = {
  52. .ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET,
  53. .ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET,
  54. .ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET,
  55. .ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE,
  56. .hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR,
  57. .version = EMAC_VERSION_2,
  58. .interrupt_enable = am35xx_enable_emac_int,
  59. .interrupt_disable = am35xx_disable_emac_int,
  60. };
  61. static struct resource am35xx_emac_resources[] = {
  62. DEFINE_RES_MEM(AM35XX_IPSS_EMAC_BASE, 0x30000),
  63. DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RXTHRESH_IRQ),
  64. DEFINE_RES_IRQ(INT_35XX_EMAC_C0_RX_PULSE_IRQ),
  65. DEFINE_RES_IRQ(INT_35XX_EMAC_C0_TX_PULSE_IRQ),
  66. DEFINE_RES_IRQ(INT_35XX_EMAC_C0_MISC_PULSE_IRQ),
  67. };
  68. static struct platform_device am35xx_emac_device = {
  69. .name = "davinci_emac",
  70. .id = -1,
  71. .num_resources = ARRAY_SIZE(am35xx_emac_resources),
  72. .resource = am35xx_emac_resources,
  73. .dev = {
  74. .platform_data = &am35xx_emac_pdata,
  75. },
  76. };
  77. void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
  78. {
  79. u32 v;
  80. int err;
  81. am35xx_emac_pdata.rmii_en = rmii_en;
  82. am35xx_emac_mdio_pdata.bus_freq = mdio_bus_freq;
  83. err = platform_device_register(&am35xx_emac_device);
  84. if (err) {
  85. pr_err("AM35x: failed registering EMAC device: %d\n", err);
  86. return;
  87. }
  88. err = platform_device_register(&am35xx_emac_mdio_device);
  89. if (err) {
  90. pr_err("AM35x: failed registering EMAC MDIO device: %d\n", err);
  91. platform_device_unregister(&am35xx_emac_device);
  92. return;
  93. }
  94. v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
  95. v &= ~AM35XX_CPGMACSS_SW_RST;
  96. omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET);
  97. omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */
  98. }