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>
#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"
* 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");
.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[] = {
{
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()) {
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>
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,
{
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;
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 {
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 {
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)
*/
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)
{