]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - sitara-epos/sitara-epos-kernel.git/blobdiff - arch/arm/mach-omap2/devices.c
arm:omap:am33xx: Don't register McBSP
[sitara-epos/sitara-epos-kernel.git] / arch / arm / mach-omap2 / devices.c
index c15cfada5f13b5975e36c70331e24032f39e2d66..e896e7b3885e9812e700af863dfb53757b734929 100644 (file)
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/davinci_emac.h>
+#include <linux/cpsw.h>
+#include <linux/etherdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/can/platform/d_can.h>
+#include <linux/platform_data/uio_pruss.h>
 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
+#include <mach/board-am335xevm.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 #include <asm/pmu.h>
 
+#ifdef CONFIG_OMAP3_EDMA
+#include <mach/edma.h>
+#endif
+
+#include <asm/hardware/asp.h>
+
 #include <plat/tc.h>
 #include <plat/board.h>
 #include <plat/mcbsp.h>
@@ -33,6 +46,9 @@
 #include <plat/omap_device.h>
 #include <plat/omap4-keypad.h>
 
+/* LCD controller similar DA8xx */
+#include <video/da8xx-fb.h>
+
 #include "mux.h"
 #include "control.h"
 #include "devices.h"
@@ -51,7 +67,7 @@ static int __init omap3_l3_init(void)
         * To avoid code running on other OMAPs in
         * multi-omap builds
         */
-       if (!(cpu_is_omap34xx()))
+       if (!(cpu_is_omap34xx()) || (cpu_is_am33xx()))
                return -ENODEV;
 
        l = snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main");
@@ -126,6 +142,95 @@ static struct platform_device omap2cam_device = {
        .resource       = omap2cam_resources,
 };
 #endif
+#define L4_PER_LCDC_PHYS        0x4830E000
+
+static struct resource am33xx_lcdc_resources[] = {
+       [0] = { /* registers */
+               .start  = L4_PER_LCDC_PHYS,
+               .end    = L4_PER_LCDC_PHYS + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = { /* interrupt */
+               .start  = AM33XX_IRQ_LCD,
+               .end    = AM33XX_IRQ_LCD,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device am33xx_lcdc_device = {
+       .name           = "da8xx_lcdc",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(am33xx_lcdc_resources),
+       .resource       = am33xx_lcdc_resources,
+};
+
+void __init am33xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata)
+{
+       int ret;
+
+       am33xx_lcdc_device.dev.platform_data = pdata;
+
+       ret = platform_device_register(&am33xx_lcdc_device);
+       if (ret)
+               pr_warning("am33xx_register_lcdc: lcdc registration failed: %d\n",
+                               ret);
+
+}
+
+#if defined(CONFIG_SND_AM335X_SOC_EVM) || \
+                               defined(CONFIG_SND_AM335X_SOC_EVM_MODULE)
+static struct resource am335x_mcasp1_resource[] = {
+       {
+               .name = "mcasp1",
+               .start = AM33XX_ASP1_BASE,
+               .end = AM33XX_ASP1_BASE + (SZ_1K * 12) - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       /* TX event */
+       {
+               .start = AM33XX_DMA_MCASP1_X,
+               .end = AM33XX_DMA_MCASP1_X,
+               .flags = IORESOURCE_DMA,
+       },
+       /* RX event */
+       {
+               .start = AM33XX_DMA_MCASP1_R,
+               .end = AM33XX_DMA_MCASP1_R,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+static struct platform_device am335x_mcasp1_device = {
+       .name = "davinci-mcasp",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(am335x_mcasp1_resource),
+       .resource = am335x_mcasp1_resource,
+};
+
+void __init am335x_register_mcasp1(struct snd_platform_data *pdata)
+{
+       am335x_mcasp1_device.dev.platform_data = pdata;
+       platform_device_register(&am335x_mcasp1_device);
+}
+
+#else
+void __init am335x_register_mcasp1(struct snd_platform_data *pdata) {}
+#endif
+
+#if (defined(CONFIG_SND_AM33XX_SOC) || (defined(CONFIG_SND_AM33XX_SOC_MODULE)))
+struct platform_device am33xx_pcm_device = {
+       .name           = "davinci-pcm-audio",
+       .id             = -1,
+};
+
+static void am33xx_init_pcm(void)
+{
+       platform_device_register(&am33xx_pcm_device);
+}
+
+#else
+static inline void am33xx_init_pcm(void) {}
+#endif
 
 static struct resource omap3isp_resources[] = {
        {
@@ -299,6 +404,9 @@ OMAP_MCBSP_PLATFORM_DEVICE(5);
 
 static void omap_init_audio(void)
 {
+       if (cpu_is_am33xx())
+               return;
+
        platform_device_register(&omap_mcbsp1);
        platform_device_register(&omap_mcbsp2);
        if (cpu_is_omap243x() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
@@ -336,6 +444,27 @@ static void omap_init_mcpdm(void)
 static inline void omap_init_mcpdm(void) {}
 #endif
 
+#if defined(CONFIG_SND_OMAP_SOC_DMIC) || \
+               defined(CONFIG_SND_OMAP_SOC_DMIC_MODULE)
+
+static void omap_init_dmic(void)
+{
+       struct omap_hwmod *oh;
+       struct platform_device *pdev;
+
+       oh = omap_hwmod_lookup("dmic");
+       if (!oh) {
+               printk(KERN_ERR "Could not look up mcpdm hw_mod\n");
+               return;
+       }
+
+       pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0, NULL, 0, 0);
+       WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n");
+}
+#else
+static inline void omap_init_dmic(void) {}
+#endif
+
 #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
 
 #include <plat/mcspi.h>
@@ -386,6 +515,33 @@ static void omap_init_mcspi(void)
 static inline void omap_init_mcspi(void) {}
 #endif
 
+#ifdef CONFIG_SOC_OMAPAM33XX
+
+static int omap_elm_init(struct omap_hwmod *oh, void *unused)
+{
+       struct platform_device *pdev;
+       char *name = "omap2_elm";
+       static int elm_num;
+
+
+       elm_num++;
+       pdev = omap_device_build(name, elm_num, oh, NULL,
+                               0,      NULL,
+                               0, 0);
+       return 0;
+}
+
+static void omap_init_elm(void)
+{
+
+       omap_hwmod_for_each_by_class("elm", omap_elm_init, NULL);
+}
+
+#else
+static void omap_init_elm(void) {}
+#endif
+
+
 static struct resource omap2_pmu_resource = {
        .start  = 3,
        .end    = 3,
@@ -408,7 +564,7 @@ static void omap_init_pmu(void)
 {
        if (cpu_is_omap24xx())
                omap_pmu_device.resource = &omap2_pmu_resource;
-       else if (cpu_is_omap34xx())
+       else if (cpu_is_omap34xx() && !cpu_is_am33xx())
                omap_pmu_device.resource = &omap3_pmu_resource;
        else
                return;
@@ -469,7 +625,7 @@ static void omap_init_sham(void)
        if (cpu_is_omap24xx()) {
                sham_device.resource = omap2_sham_resources;
                sham_device.num_resources = omap2_sham_resources_sz;
-       } else if (cpu_is_omap34xx()) {
+       } else if (cpu_is_omap34xx() && !cpu_is_am33xx()) {
                sham_device.resource = omap3_sham_resources;
                sham_device.num_resources = omap3_sham_resources_sz;
        } else {
@@ -538,7 +694,7 @@ static void omap_init_aes(void)
        if (cpu_is_omap24xx()) {
                aes_device.resource = omap2_aes_resources;
                aes_device.num_resources = omap2_aes_resources_sz;
-       } else if (cpu_is_omap34xx()) {
+       } else if (cpu_is_omap34xx() && !cpu_is_am33xx()) {
                aes_device.resource = omap3_aes_resources;
                aes_device.num_resources = omap3_aes_resources_sz;
        } else {
@@ -671,6 +827,318 @@ static void omap_init_vout(void)
 static inline void omap_init_vout(void) {}
 #endif
 
+#if defined(CONFIG_SOC_OMAPAM33XX) && defined(CONFIG_OMAP3_EDMA)
+
+#define AM33XX_TPCC_BASE               0x49000000
+#define AM33XX_TPTC0_BASE              0x49800000
+#define AM33XX_TPTC1_BASE              0x49900000
+#define AM33XX_TPTC2_BASE              0x49a00000
+
+#define AM33XX_SCM_BASE_EDMA           0x00000f90
+
+static struct resource am33xx_edma_resources[] = {
+       {
+               .name   = "edma_cc0",
+               .start  = AM33XX_TPCC_BASE,
+               .end    = AM33XX_TPCC_BASE + SZ_32K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .name   = "edma_tc0",
+               .start  = AM33XX_TPTC0_BASE,
+               .end    = AM33XX_TPTC0_BASE + SZ_1K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .name   = "edma_tc1",
+               .start  = AM33XX_TPTC1_BASE,
+               .end    = AM33XX_TPTC1_BASE + SZ_1K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .name   = "edma_tc2",
+               .start  = AM33XX_TPTC2_BASE,
+               .end    = AM33XX_TPTC2_BASE + SZ_1K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .name   = "edma0",
+               .start  = AM33XX_IRQ_TPCC0_INT_PO0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .name   = "edma0_err",
+               .start  = AM33XX_IRQ_TPCC0_ERRINT_PO,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static const s16 am33xx_dma_rsv_chans[][2] = {
+       /* (offset, number) */
+       {0, 2},
+       {14, 2},
+       {26, 6},
+       {48, 4},
+       {56, 8},
+       {-1, -1}
+};
+
+static const s16 am33xx_dma_rsv_slots[][2] = {
+       /* (offset, number) */
+       {0, 2},
+       {14, 2},
+       {26, 6},
+       {48, 4},
+       {56, 8},
+       {64, 127},
+       {-1, -1}
+};
+
+/* Three Transfer Controllers on AM33XX */
+static const s8 am33xx_queue_tc_mapping[][2] = {
+       /* {event queue no, TC no} */
+       {0, 0},
+       {1, 1},
+       {2, 2},
+       {-1, -1}
+};
+
+static const s8 am33xx_queue_priority_mapping[][2] = {
+       /* {event queue no, Priority} */
+       {0, 0},
+       {1, 1},
+       {2, 2},
+       {-1, -1}
+};
+
+static struct event_to_channel_map am33xx_xbar_event_mapping[] = {
+       /* {xbar event no, Channel} */
+       {1, 12},        /* SDTXEVT1 -> MMCHS2 */
+       {2, 13},        /* SDRXEVT1 -> MMCHS2 */
+       {3, -1},
+       {4, -1},
+       {5, -1},
+       {6, -1},
+       {7, -1},
+       {8, -1},
+       {9, -1},
+       {10, -1},
+       {11, -1},
+       {12, -1},
+       {13, -1},
+       {14, -1},
+       {15, -1},
+       {16, -1},
+       {17, -1},
+       {18, -1},
+       {19, -1},
+       {20, -1},
+       {21, -1},
+       {22, -1},
+       {23, -1},
+       {24, -1},
+       {25, -1},
+       {26, -1},
+       {27, -1},
+       {28, -1},
+       {29, -1},
+       {30, -1},
+       {31, -1},
+       {-1, -1}
+};
+
+/**
+ * map_xbar_event_to_channel - maps a crossbar event to a DMA channel
+ * according to the configuration provided
+ * @event: the event number for which mapping is required
+ * @channel: channel being activated
+ * @xbar_event_mapping: array that has the event to channel map
+ *
+ * Events that are routed by default are not mapped. Only events that
+ * are crossbar mapped are routed to available channels according to
+ * the configuration provided
+ *
+ * Returns zero on success, else negative errno.
+ */
+int map_xbar_event_to_channel(unsigned int event, unsigned int *channel,
+                       struct event_to_channel_map *xbar_event_mapping)
+{
+       unsigned int ctrl = 0;
+       unsigned int xbar_evt_no = 0;
+       unsigned int val = 0;
+       unsigned int offset = 0;
+       unsigned int mask = 0;
+
+       ctrl = EDMA_CTLR(event);
+       xbar_evt_no = event - (edma_info[ctrl]->num_channels);
+
+       if (event < edma_info[ctrl]->num_channels) {
+               *channel = event;
+       } else if (event < edma_info[ctrl]->num_events) {
+               *channel = xbar_event_mapping[xbar_evt_no].channel_no;
+               /* confirm the range */
+               if (*channel < EDMA_MAX_DMACH)
+                       clear_bit(*channel, edma_info[ctrl]->edma_unused);
+               mask = (*channel)%4;
+               offset = (*channel)/4;
+               offset *= 4;
+               offset += mask;
+               val = (unsigned int)__raw_readl(AM33XX_CTRL_REGADDR(
+                                       AM33XX_SCM_BASE_EDMA + offset));
+               val = val & (~(0xFF));
+               val = val | (xbar_event_mapping[xbar_evt_no].xbar_event_no);
+               __raw_writel(val,
+                       AM33XX_CTRL_REGADDR(AM33XX_SCM_BASE_EDMA + offset));
+               return 0;
+       } else {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct edma_soc_info am33xx_edma_info[] = {
+       {
+               .n_channel              = 64,
+               .n_region               = 4,
+               .n_slot                 = 256,
+               .n_tc                   = 3,
+               .n_cc                   = 1,
+               .rsv_chans              = am33xx_dma_rsv_chans,
+               .rsv_slots              = am33xx_dma_rsv_slots,
+               .queue_tc_mapping       = am33xx_queue_tc_mapping,
+               .queue_priority_mapping = am33xx_queue_priority_mapping,
+               .is_xbar                = 1,
+               .n_events               = 95,
+               .xbar_event_mapping     = am33xx_xbar_event_mapping,
+               .map_xbar_channel       = map_xbar_event_to_channel,
+       },
+};
+
+static struct platform_device am33xx_edma_device = {
+       .name           = "edma",
+       .id             = -1,
+       .dev = {
+               .platform_data = am33xx_edma_info,
+       },
+       .num_resources  = ARRAY_SIZE(am33xx_edma_resources),
+       .resource       = am33xx_edma_resources,
+};
+
+int __init am33xx_register_edma(void)
+{
+       struct platform_device *pdev;
+       static struct clk *edma_clk;
+
+       if (cpu_is_am33xx())
+               pdev = &am33xx_edma_device;
+       else {
+               pr_err("%s: platform not supported\n", __func__);
+               return -ENODEV;
+       }
+
+       edma_clk = clk_get(NULL, "tpcc_ick");
+       if (IS_ERR(edma_clk)) {
+               printk(KERN_ERR "EDMA: Failed to get clock\n");
+               return -EBUSY;
+       }
+       clk_enable(edma_clk);
+       edma_clk = clk_get(NULL, "tptc0_ick");
+       if (IS_ERR(edma_clk)) {
+               printk(KERN_ERR "EDMA: Failed to get clock\n");
+               return -EBUSY;
+       }
+       clk_enable(edma_clk);
+       edma_clk = clk_get(NULL, "tptc1_ick");
+       if (IS_ERR(edma_clk)) {
+               printk(KERN_ERR "EDMA: Failed to get clock\n");
+               return -EBUSY;
+       }
+       clk_enable(edma_clk);
+       edma_clk = clk_get(NULL, "tptc2_ick");
+       if (IS_ERR(edma_clk)) {
+               printk(KERN_ERR "EDMA: Failed to get clock\n");
+               return -EBUSY;
+       }
+       clk_enable(edma_clk);
+
+       return platform_device_register(pdev);
+}
+
+#else
+static inline void am33xx_register_edma(void) {}
+#endif
+
+#if defined (CONFIG_SOC_OMAPAM33XX)
+struct uio_pruss_pdata am335x_pruss_uio_pdata = {
+       .pintc_base     = 0x20000,
+};
+
+static struct resource am335x_pruss_resources[] = {
+       {
+               .start  = AM33XX_ICSS_BASE,
+               .end    = AM33XX_ICSS_BASE + AM33XX_ICSS_LEN,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = AM33XX_IRQ_ICSS0_0,
+               .end    = AM33XX_IRQ_ICSS0_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AM33XX_IRQ_ICSS0_1,
+               .end    = AM33XX_IRQ_ICSS0_1,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AM33XX_IRQ_ICSS0_2,
+               .end    = AM33XX_IRQ_ICSS0_2,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AM33XX_IRQ_ICSS0_3,
+               .end    = AM33XX_IRQ_ICSS0_3,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AM33XX_IRQ_ICSS0_4,
+               .end    = AM33XX_IRQ_ICSS0_4,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AM33XX_IRQ_ICSS0_5,
+               .end    = AM33XX_IRQ_ICSS0_5,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AM33XX_IRQ_ICSS0_6,
+               .end    = AM33XX_IRQ_ICSS0_6,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AM33XX_IRQ_ICSS0_7,
+               .end    = AM33XX_IRQ_ICSS0_7,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device am335x_pruss_uio_dev = {
+       .name           = "pruss_uio",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(am335x_pruss_resources),
+       .resource       = am335x_pruss_resources,
+       .dev     =      {
+               .coherent_dma_mask = 0xffffffff,
+       }
+};
+
+int __init am335x_register_pruss_uio(struct uio_pruss_pdata *config)
+{
+       am335x_pruss_uio_dev.dev.platform_data = config;
+       return platform_device_register(&am335x_pruss_uio_dev);
+}
+#endif
+
 /*-------------------------------------------------------------------------*/
 
 static int __init omap2_init_devices(void)
@@ -681,20 +1149,341 @@ static int __init omap2_init_devices(void)
         */
        omap_init_audio();
        omap_init_mcpdm();
+       omap_init_dmic();
        omap_init_camera();
        omap_init_mbox();
        omap_init_mcspi();
+       omap_init_elm();
        omap_init_pmu();
        omap_hdq_init();
        omap_init_sti();
        omap_init_sham();
        omap_init_aes();
        omap_init_vout();
-
+       am33xx_register_edma();
+       am33xx_init_pcm();
+#if defined (CONFIG_SOC_OMAPAM33XX)
+       am335x_register_pruss_uio(&am335x_pruss_uio_pdata);
+#endif
        return 0;
 }
 arch_initcall(omap2_init_devices);
 
+#define AM33XX_EMAC_MDIO_FREQ          (1000000)
+
+static u64 am33xx_cpsw_dmamask = DMA_BIT_MASK(32);
+/* TODO : Verify the offsets */
+static struct cpsw_slave_data am33xx_cpsw_slaves[] = {
+       {
+               .slave_reg_ofs  = 0x208,
+               .sliver_reg_ofs = 0xd80,
+               .phy_id         = "0:00",
+       },
+       {
+               .slave_reg_ofs  = 0x308,
+               .sliver_reg_ofs = 0xdc0,
+               .phy_id         = "0:01",
+       },
+};
+
+static struct cpsw_platform_data am33xx_cpsw_pdata = {
+       .ss_reg_ofs             = 0x1200,
+       .channels               = 8,
+       .cpdma_reg_ofs          = 0x800,
+       .slaves                 = 2,
+       .slave_data             = am33xx_cpsw_slaves,
+       .ale_reg_ofs            = 0xd00,
+       .ale_entries            = 1024,
+       .host_port_reg_ofs      = 0x108,
+       .hw_stats_reg_ofs       = 0x900,
+       .bd_ram_ofs             = 0x2000,
+       .bd_ram_size            = SZ_8K,
+       .rx_descs               = 64,
+       .mac_control            = BIT(5), /* MIIEN */
+       .gigabit_en             = 1,
+       .host_port_num          = 0,
+       .no_bd_ram              = false,
+       .version                = CPSW_VERSION_2,
+};
+
+static struct mdio_platform_data am33xx_cpsw_mdiopdata = {
+       .bus_freq       = AM33XX_EMAC_MDIO_FREQ,
+};
+
+static struct resource am33xx_cpsw_mdioresources[] = {
+       {
+               .start  = AM33XX_CPSW_MDIO_BASE,
+               .end    = AM33XX_CPSW_MDIO_BASE + SZ_256 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device am33xx_cpsw_mdiodevice = {
+       .name           = "davinci_mdio",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(am33xx_cpsw_mdioresources),
+       .resource       = am33xx_cpsw_mdioresources,
+       .dev.platform_data = &am33xx_cpsw_mdiopdata,
+};
+
+static struct resource am33xx_cpsw_resources[] = {
+       {
+               .start  = AM33XX_CPSW_BASE,
+               .end    = AM33XX_CPSW_BASE + SZ_2K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = AM33XX_CPSW_SS_BASE,
+               .end    = AM33XX_CPSW_SS_BASE + SZ_256 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = AM33XX_IRQ_CPSW_C0_RX,
+               .end    = AM33XX_IRQ_CPSW_C0_RX,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AM33XX_IRQ_DMTIMER5,
+               .end    = AM33XX_IRQ_DMTIMER5,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AM33XX_IRQ_DMTIMER6,
+               .end    = AM33XX_IRQ_DMTIMER6,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AM33XX_IRQ_CPSW_C0,
+               .end    = AM33XX_IRQ_CPSW_C0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device am33xx_cpsw_device = {
+       .name           =       "cpsw",
+       .id             =       0,
+       .num_resources  =       ARRAY_SIZE(am33xx_cpsw_resources),
+       .resource       =       am33xx_cpsw_resources,
+       .dev            =       {
+                                       .platform_data  = &am33xx_cpsw_pdata,
+                                       .dma_mask       = &am33xx_cpsw_dmamask,
+                                       .coherent_dma_mask = DMA_BIT_MASK(32),
+                               },
+};
+
+static unsigned char  am33xx_macid0[ETH_ALEN];
+static unsigned char  am33xx_macid1[ETH_ALEN];
+static unsigned int   am33xx_evmid;
+
+/*
+* am33xx_evmid_fillup - set up board evmid
+* @evmid - evm id which needs to be configured
+*
+* This function is called to configure board evm id.
+* IA Motor Control EVM needs special setting of MAC PHY Id.
+* This function is called when IA Motor Control EVM is detected
+* during boot-up.
+*/
+void am33xx_evmid_fillup(unsigned int evmid)
+{
+       am33xx_evmid = evmid;
+       return;
+}
+
+/*
+* am33xx_cpsw_macidfillup - setup mac adrresses
+* @eeprommacid0 - mac id 0 which needs to be configured
+* @eeprommacid1 - mac id 1 which needs to be configured
+*
+* This function is called to configure mac addresses.
+* Mac addresses are read from eeprom and this function is called
+* to store those mac adresses in am33xx_macid0 and am33xx_macid1.
+* In case, mac address read from eFuse are invalid, mac addresses
+* stored in these variable are used.
+*/
+void am33xx_cpsw_macidfillup(char *eeprommacid0, char *eeprommacid1)
+{
+       u32 i;
+
+       /* Fillup these mac addresses with the mac adresses from eeprom */
+       for (i = 0; i < ETH_ALEN; i++) {
+               am33xx_macid0[i] = eeprommacid0[i];
+               am33xx_macid1[i] = eeprommacid1[i];
+       }
+
+       return;
+}
+
+void am33xx_cpsw_init(unsigned int gigen)
+{
+       u32 mac_lo, mac_hi;
+       u32 i;
+
+       mac_lo = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID0_LO);
+       mac_hi = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID0_HI);
+       am33xx_cpsw_slaves[0].mac_addr[0] = mac_hi & 0xFF;
+       am33xx_cpsw_slaves[0].mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+       am33xx_cpsw_slaves[0].mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+       am33xx_cpsw_slaves[0].mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+       am33xx_cpsw_slaves[0].mac_addr[4] = mac_lo & 0xFF;
+       am33xx_cpsw_slaves[0].mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+
+       /* Read MACID0 from eeprom if eFuse MACID is invalid */
+       if (!is_valid_ether_addr(am33xx_cpsw_slaves[0].mac_addr)) {
+               for (i = 0; i < ETH_ALEN; i++)
+                       am33xx_cpsw_slaves[0].mac_addr[i] = am33xx_macid0[i];
+       }
+
+       mac_lo = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID1_LO);
+       mac_hi = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID1_HI);
+       am33xx_cpsw_slaves[1].mac_addr[0] = mac_hi & 0xFF;
+       am33xx_cpsw_slaves[1].mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+       am33xx_cpsw_slaves[1].mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+       am33xx_cpsw_slaves[1].mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+       am33xx_cpsw_slaves[1].mac_addr[4] = mac_lo & 0xFF;
+       am33xx_cpsw_slaves[1].mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+
+       /* Read MACID1 from eeprom if eFuse MACID is invalid */
+       if (!is_valid_ether_addr(am33xx_cpsw_slaves[1].mac_addr)) {
+               for (i = 0; i < ETH_ALEN; i++)
+                       am33xx_cpsw_slaves[1].mac_addr[i] = am33xx_macid1[i];
+       }
+
+       if (am33xx_evmid == IND_AUT_MTR_EVM) {
+               am33xx_cpsw_slaves[0].phy_id = "0:1e";
+               am33xx_cpsw_slaves[1].phy_id = "0:00";
+       }
+
+       am33xx_cpsw_pdata.gigabit_en = gigen;
+
+       memcpy(am33xx_cpsw_pdata.mac_addr,
+                       am33xx_cpsw_slaves[0].mac_addr, ETH_ALEN);
+       platform_device_register(&am33xx_cpsw_mdiodevice);
+       platform_device_register(&am33xx_cpsw_device);
+       clk_add_alias(NULL, dev_name(&am33xx_cpsw_mdiodevice.dev),
+                       NULL, &am33xx_cpsw_device.dev);
+}
+
+#define AM33XX_D_CAN_RAM_BASE                  0x1000
+#define AM33XX_D_CAN_NUM_MSG_OBJS              64
+#define AM33XX_CTL_DCAN_RAMINIT_OFFSET         0x644
+#define AM33XX_D_CAN_RAMINIT_START(n)          (0x1 << n)
+
+static void d_can_hw_raminit(unsigned int instance)
+{
+       u32 val;
+
+       /* Read the value */
+       val = __raw_readl(AM33XX_CTRL_REGADDR(AM33XX_CTL_DCAN_RAMINIT_OFFSET));
+
+       /* Modify by setting "0" */
+       val &= ~AM33XX_D_CAN_RAMINIT_START(instance);
+       __raw_writel(val, AM33XX_CTRL_REGADDR(AM33XX_CTL_DCAN_RAMINIT_OFFSET));
+
+       /* Reset to one */
+       val |= AM33XX_D_CAN_RAMINIT_START(instance);
+       __raw_writel(val, AM33XX_CTRL_REGADDR(AM33XX_CTL_DCAN_RAMINIT_OFFSET));
+
+       /* Give some time delay for transition from 0 -> 1 */
+       udelay(1);
+}
+
+static struct d_can_platform_data am33xx_evm_d_can0_pdata = {
+       .d_can_offset           = 0,
+       .d_can_ram_offset       = AM33XX_D_CAN_RAM_BASE,
+       .num_of_msg_objs        = AM33XX_D_CAN_NUM_MSG_OBJS,
+       .dma_support            = false,
+       .parity_check           = false,
+       .fck_name               = "dcan0_fck",
+       .ick_name               = "dcan0_ick",
+};
+
+static struct resource am33xx_d_can0_resources[] = {
+       {
+               .start  = AM33XX_D_CAN0_BASE,
+               .end    = AM33XX_D_CAN0_BASE + 0x3FFF,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .name   = "int0",
+               .start  = AM33XX_IRQ_DCAN0_0,
+               .end    = AM33XX_IRQ_DCAN0_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .name   = "int1",
+               .start  = AM33XX_IRQ_DCAN0_1,
+               .end    = AM33XX_IRQ_DCAN0_1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device am33xx_d_can0_device = {
+       .dev            = {
+               .platform_data = &am33xx_evm_d_can0_pdata,
+       },
+       .name           = "d_can",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(am33xx_d_can0_resources),
+       .resource       = am33xx_d_can0_resources,
+};
+
+static struct resource am33xx_d_can1_resources[] = {
+       {
+               .start  = AM33XX_D_CAN1_BASE,
+               .end    = AM33XX_D_CAN1_BASE + 0x3FFF,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .name   = "int0",
+               .start  = AM33XX_IRQ_DCAN1_0,
+               .end    = AM33XX_IRQ_DCAN1_0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .name   = "int1",
+               .start  = AM33XX_IRQ_DCAN1_1,
+               .end    = AM33XX_IRQ_DCAN1_1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct d_can_platform_data am33xx_evm_d_can1_pdata = {
+       .d_can_offset           = 0,
+       .d_can_ram_offset       = AM33XX_D_CAN_RAM_BASE,
+       .num_of_msg_objs        = AM33XX_D_CAN_NUM_MSG_OBJS,
+       .dma_support            = false,
+       .parity_check           = false,
+       .fck_name               = "dcan1_fck",
+       .ick_name               = "dcan1_ick",
+};
+
+static struct platform_device am33xx_d_can1_device = {
+       .dev            = {
+               .platform_data = &am33xx_evm_d_can1_pdata,
+       },
+       .name           = "d_can",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(am33xx_d_can1_resources),
+       .resource       = am33xx_d_can1_resources,
+};
+
+void am33xx_d_can_init(unsigned int instance)
+{
+       switch (instance) {
+       case 0:
+               d_can_hw_raminit(instance);
+               platform_device_register(&am33xx_d_can0_device);
+               break;
+       case 1:
+               d_can_hw_raminit(instance);
+               platform_device_register(&am33xx_d_can1_device);
+               break;
+       default:
+               break;
+       }
+}
+
 #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
 static int __init omap_init_wdt(void)
 {