Hi,
Code flow for EVM board is as follows
arch/arm/mach-omap2/board-ti8148evm.c
----------------------------------------------------------
MACHINE_START(TI8148EVM, "ti8148evm")
/* Maintainer: Texas Instruments */
.boot_params = 0x80000100,
.map_io = ti8148_evm_map_io,
.reserve = ti81xx_reserve,
.init_irq = ti8148_evm_init_irq,
.init_machine = ti8148_evm_init,
.timer = &omap_timer,
MACHINE_END
48 #ifdef CONFIG_OMAP_MUX
49 static struct omap_board_mux board_mux[] __initdata = {
50 { .reg_offset = OMAP_MUX_TERMINATOR },
51 };
52 #else
53 #define board_mux NULL
54 #endif
static void __init ti8148_evm_init(void)
271 {
272 printk(KERN_CRIT "ETHERNET:inside ti8148_evm_init b4 calling the ti814x_mux_init\n");
273 ti814x_mux_init(board_mux);
arch/arm/mach-omap2/muxti814x.c
------------------------------------------------
int __init ti814x_mux_init(struct omap_board_mux *board_subset)
833 {
834 printk(KERN_CRIT "ETHERNET:Inside the ti814x_mux_init b4 calling omap_mux_init with 8 args\n");
835 return omap_mux_init("core", OMAP_MUX_REG_32BIT,
836 TI81XX_CONTROL_PADCONF_MUX_PBASE,
837 TI814X_CONTROL_PADCONF_MUX_SIZE, ti814x_muxmodes, NULL,
838 board_subset, NULL);
839 }
arch/arm/mach-omap2/mux.c
----------------------------------------
1023 int __init omap_mux_init(const char *name, u32 flags,
1024 u32 mux_pbase, u32 mux_size,
1025 struct omap_mux *superset,
1026 struct omap_mux *package_subset,
1027 struct omap_board_mux *board_mux,
1028 struct omap_ball *package_balls)
1029 {
1030 struct omap_mux_partition *partition;
1031
1032 printk(KERN_CRIT "ETHERNET:inside the omap_mux_init\n");
1033 partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);
1034 if (!partition)
1035 return -ENOMEM;
1036
1037 partition->name = name;
1038 partition->flags = flags;
1039 partition->size = mux_size;
1040 partition->phys = mux_pbase;
1041 partition->base = ioremap(mux_pbase, mux_size);
1042 if (!partition->base) {
1043 pr_err("%s: Could not ioremap mux partition at 0x%08x\n",
1044 __func__, partition->phys);
1045 return -ENODEV;
1046 }
1047
1048 INIT_LIST_HEAD(&partition->muxmodes);
1049
1050 list_add_tail(&partition->node, &mux_partitions);
1051 mux_partitions_cnt++;
1052 pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__,
1053 mux_partitions_cnt, partition->name, partition->flags);
1054
1055 omap_mux_init_package(superset, package_subset, package_balls);
1056 omap_mux_init_list(partition, superset);
1057 omap_mux_init_signals(partition, board_mux);
1058
1059 return 0;
1060 }
998 static void omap_mux_init_signals(struct omap_mux_partition *partition,
999 struct omap_board_mux *board_mux)
1000 {
1001 printk(KERN_CRIT "ETHERNET:inside omap_mux_init_signals b4 calling omap_mux_set_cmdline_signals\n");
1002 omap_mux_set_cmdline_signals();
1003 omap_mux_write_array(partition, board_mux);
1004 }
785 static void __init omap_mux_set_cmdline_signals(void)
786 {
787 char *options, *next_opt, *token;
788
789 printk(KERN_CRIT "ETHERNET:inside omap_mux_set_cmdline_signals\n");
790
791 if (!omap_mux_options)
{ printk(KERN_CRIT”gets returned here\n”);
return;
}
793
794 options = kmalloc(strlen(omap_mux_options) + 1, GFP_KERNEL);
795 if (!options)
796 return;
797
798 strcpy(options, omap_mux_options);
799 next_opt = options;
800
801 while ((token = strsep(&next_opt, ",")) != NULL) {
802 char *keyval, *name;
803 unsigned long val;
804
805 keyval = token;
806 name = strsep(&keyval, "=");
807 if (name) {
808 int res;
809
810 res = strict_strtoul(keyval, 0x10, &val);
811 if (res < 0)
812 continue;
813
814 printk(KERN_CRIT "ETHERNET:inside while of omap_mux_set_cmdline_signals\n");
815 omap_mux_init_signal(name, (int)val);
816 }
817 }
818
819 kfree(options);
820 }
253 int __init omap_mux_init_signal(const char *muxname, int val)
254 {
255 struct omap_mux_partition *partition = NULL;
256 struct omap_mux *mux = NULL;
257 u16 old_mode;
258 int mux_mode;
259
260 printk(KERN_CRIT "ETHERNET:inside omap_mux_init_signal\n");
261 mux_mode = omap_mux_get_by_name(muxname, &partition, &mux);
262 if (mux_mode < 0)
263 return mux_mode;
264
265 old_mode = omap_mux_read(partition, mux->reg_offset);
266
267 mux_mode |= val;
268 pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n",
269 __func__, muxname, old_mode, mux_mode);
270 omap_mux_write(partition, mux_mode, mux->reg_offset);
271
272 return 0;
273 }
76 void omap_mux_write(struct omap_mux_partition *partition, u32 val,
77 u16 reg)
78 {
79 /* Avoid unintentional change of bits 18-31 on TI814x */
80 //printk(KERN_CRIT "ETHERNET:inside the omap_mux_write\n");
81 printk(KERN_CRIT "ETHERNET:inside the omap_mux_write\n");
82 if (cpu_is_ti814x())
83 val |= __raw_readl(partition->base + reg) & 0xFFFC0000;
84
85 if (partition->flags & OMAP_MUX_REG_8BIT)
86 __raw_writeb(val, partition->base + reg);
87 if (partition->flags & OMAP_MUX_REG_32BIT)
88 __raw_writel(val, partition->base + reg);
89 else
90 __raw_writew(val, partition->base + reg);
91 }
93 void omap_mux_write_array(struct omap_mux_partition *partition,
94 struct omap_board_mux *board_mux)
95 {
96 printk(KERN_CRIT "ETHERNET:inside omap_mux_write_array\n");
97 while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
98 printk(KERN_CRIT "ETHERNET:inside omap_mux_write_array\n");
99 omap_mux_write(partition, board_mux->value,
100 board_mux->reg_offset);
101 board_mux++;
102 }
#ifdef CONFIG_OMAP_MUX
#define _TI814X_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
{ \
.reg_offset = (TI814X_CONTROL_PADCONF_##M0##_OFFSET), \
.gpio = (g), \
.muxnames = { m0, m1, m2, m3, m4, m5, m6, m7 }, \
}
/*
* Superset of all mux modes for TI814X
*/
static struct omap_mux __initdata ti814x_muxmodes[] = {
_TI814X_MUXENTRY(MMC1_CLK, 0,
"mmc1_clk", NULL, NULL, NULL,
:
:
:
_TI814X_MUXENTRY(GMII0_COL, 0, "gmii0_col", "vin1b_d1", "rmii0_rxd0", NULL, NULL, NULL, NULL, "gpio3_24"), _TI814X_MUXENTRY(GMII0_CRS, 0, "gmii0_crs", "vin1b_d2", "rmii0_rxd1", NULL, NULL, NULL, NULL, "gpio3_25"), _TI814X_MUXENTRY(GMII0_RXER, 0, "gmii0_rxer", "vin1b_d3", "rmii0_rxer", NULL, NULL, NULL, NULL, "gpio3_26"), _TI814X_MUXENTRY(GMII0_RXCLK, 0, "gmii0_rxclk", "vin1b_d4", "rmii0_crs", NULL, NULL, "spi3_cs2", NULL, "gpio3_27"), _TI814X_MUXENTRY(GMII0_RXD0, 0, "gmii0_rxd0", "vin1b_d5", "rmii0_txd0", NULL, NULL, NULL, NULL, "gpio3_28"), _TI814X_MUXENTRY(GMII0_RXD1, 0, "gmii0_rxd1", "vin1b_d6", "rmii0_txd1", NULL, NULL, NULL, NULL, "gpio3_29"), _TI814X_MUXENTRY(GMII0_RXD2, 0, "gmii0_rxd2", "vin1b_d7", "rmii0_txen", NULL, NULL, NULL, NULL, "gpio3_30_mux0"),
:
:
:
_TI814X_MUXENTRY(RMII_REFCLK, 0,
"rmii_refclk", NULL, NULL, NULL, NULL, NULL,
"timer2_mux3", "gpio1_10_mux0"),
_TI814X_MUXENTRY(MDIO_MCLK, 0,
"mdio_mclk", NULL, NULL, NULL, NULL, NULL, NULL,
"gpio1_11_mux0"),
_TI814X_MUXENTRY(MDIO_D, 0,
"mdio_d", NULL, NULL, NULL, NULL, NULL, NULL,
"gpio1_12_mux0"),
:
:
:
After all the above thing we come for
arch/arm/mach-omap2/devices.c#
============================
#ifdef CONFIG_ARCH_TI814X
#define TI814X_CPSW_BASE (0x4A100000)
#define TI814X_CPSW_MDIO_BASE (0x4A100800)
#define TI814X_CPSW_SS_BASE (0x4A100900)
#define TI814X_EMAC_MDIO_FREQ (1000000)
static u64 cpsw_dma_mask = DMA_BIT_MASK(32);
/* TODO : Verify the offsets */
struct cpsw_slave_data cpsw_slaves[] = {
{
.slave_reg_ofs = 0x50,
.sliver_reg_ofs = 0x700,
.phy_id = "0:00",
},
{
.slave_reg_ofs = 0x90,
.sliver_reg_ofs = 0x740,
.phy_id = "0:01",
},
};
static struct cpsw_platform_data ti814x_cpsw_pdata = {
.ss_reg_ofs = 0x900,
.channels = 8,
.cpdma_reg_ofs = 0x100,
.slaves = 1,
.slave_data = cpsw_slaves,
.ale_reg_ofs = 0x600,
.ale_entries = 1024,
.host_port_reg_ofs = 0x28,
.hw_stats_reg_ofs = 0x400,
.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,
};
static struct resource ti814x_cpsw_resources[] = {
{
.start = TI814X_CPSW_BASE,
.end = TI814X_CPSW_BASE + SZ_2K - 1,
.flags = IORESOURCE_MEM,
},
{
.start = TI814X_CPSW_SS_BASE,
.end = TI814X_CPSW_SS_BASE + SZ_256 - 1,
.flags = IORESOURCE_MEM,
},
{
.start = TI814X_IRQ_GSWRXTHR0,
.end = TI814X_IRQ_GSWRXTHR0,
.flags = IORESOURCE_IRQ,
},
{
.start = TI814X_IRQ_GSWRXINT0,
.end = TI814X_IRQ_GSWRXINT0,
.flags = IORESOURCE_IRQ,
},
{
.start = TI814X_IRQ_GSWTXINT0,
.end = TI814X_IRQ_GSWTXINT0,
.flags = IORESOURCE_IRQ,
},
{
.start = TI814X_IRQ_GSWMISC0,
.end = TI814X_IRQ_GSWMISC0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device ti814x_cpsw_device = {
.name = "cpsw",
.id = 0,
.num_resources = ARRAY_SIZE(ti814x_cpsw_resources),
.resource = ti814x_cpsw_resources,
.dev = {
.platform_data = &ti814x_cpsw_pdata,
.dma_mask = &cpsw_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
static int __init omap2_init_devices(void)
{
/*
* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
omap_hsmmc_reset();
#if !defined(CONFIG_ARCH_TI81XX)
omap_init_audio();
#endif
omap_init_camera();
omap_init_mbox();
omap_init_mcspi();
omap_init_pmu();
omap_hdq_init();
omap_init_sti();
omap_init_sham();
omap_init_aes();
omap_init_vout();
#ifdef CONFIG_ARCH_TI81XX
ti81xx_ethernet_init();
ti816x_init_pcie();
ti81xx_register_edma();
ti81xx_init_pcm();
ti816x_sr_init();
#endif
omap_init_ahci();
return 0;
}
arch_initcall(omap2_init_devices);
1879 #ifdef CONFIG_ARCH_TI81XX
1880 static void ti81xx_ethernet_init(void)
1881 {
1882 printk(KERN_CRIT "ETHERNET:inside ti81xx_ethernet_init\n");
1883 if (cpu_is_ti816x())
1884 ti816x_ethernet_init();
1885 else
1886 ti814x_cpsw_init();
1887 }
void ti814x_cpsw_init(void)
{
u32 mac_lo, mac_hi;
printk(KERN_CRIT "ETHERNET:inside ti814x_cpsw_init\n");
mac_lo = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID0_LO);
mac_hi = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID0_HI);
cpsw_slaves[0].mac_addr[0] = mac_hi & 0xFF;
cpsw_slaves[0].mac_addr[1] = (mac_hi & 0xFF00) >> 8;
cpsw_slaves[0].mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
cpsw_slaves[0].mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
cpsw_slaves[0].mac_addr[4] = mac_lo & 0xFF;
cpsw_slaves[0].mac_addr[5] = (mac_lo & 0xFF00) >> 8;
mac_lo = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID1_LO);
mac_hi = omap_ctrl_readl(TI81XX_CONTROL_MAC_ID1_HI);
cpsw_slaves[1].mac_addr[0] = mac_hi & 0xFF;
cpsw_slaves[1].mac_addr[1] = (mac_hi & 0xFF00) >> 8;
cpsw_slaves[1].mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
cpsw_slaves[1].mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
cpsw_slaves[1].mac_addr[4] = mac_lo & 0xFF;
cpsw_slaves[1].mac_addr[5] = (mac_lo & 0xFF00) >> 8;
#if 0
ti814x_cpsw_mux();
#endif
if (omap_rev() == TI8148_REV_ES1_0)
cpsw_slaves[0].phy_id = "0:01";
else {
cpsw_slaves[0].phy_id = "0:00";
cpsw_slaves[1].phy_id = "0:01";
}
platform_device_register(&cpsw_mdio_device);
platform_device_register(&ti814x_cpsw_device);
clk_add_alias(NULL, dev_name(&cpsw_mdio_device.dev),
NULL, &ti814x_cpsw_device.dev);
}
#else
static inline void ti814x_cpsw_init(void) {}
#endif
void ti814x_cpsw_mux(void)
{
#if 0 /* No pinmux for now */
omap_mux_init_signal("gmii1_rxclk", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_rxd0", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_rxd1", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_rxd2", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_rxd3", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_rxd4", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_rxd5", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_rxd6", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_rxd7", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_rxdv", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_gtxclk", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_txd0", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_txd1", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_txd2", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_txd3", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_txd4", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_txd5", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_txd6", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_txd7", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_txen", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_txclk", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_col", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_crs", OMAP_MUX_MODE1);
omap_mux_init_signal("gmii1_rxer", OMAP_MUX_MODE1);
#endif
}
Now in docs section of TI814X-LINUX-PSP-04.01.00.05, in DM814x C6A814x AM387x PSP User Guide
under the section its told that
Modifying Pin Mux settings
=====================
On DM814x devices, the pins are tri-stated and set to Mode 0 or any other mode as required for specific module
(e.g., MMC) in U-Boot. If you desire to use a particular pin to any other function than Mode 0 or override any other
pin mode which was already set in U-Boot, the kernel needs to be modified and rebuilt.
You can change default mux mode by adding specific mux entry in the beginning of board_mux array in
arch/arm/mach-omap2/board-ti8148evm.c or calling omap_mux_init_signal() during
initialization (e.g., in device specific initialization function called from omap2_init_devices() in
arch/arm/mach-omap2/devices.c).
The names of multiplexed signals are specified in arch/arm/mach-omap2/mux814x.c file in kernel source directory.
e.g., for setting xref_clk0 pin (mode 0) to usb1_drvvbus (mode 7 or FUNCTION 8), add
TI814X_MUX(XREF_CLK0, OMAP_MUX_MODE7) to board_mux structure in board file or call
omap_mux_init_signal("xref_clk0", OMAP_MUX_MODE7)
The API approach is useful if you desire to set the pin-mux run time depending upon the board/hardware detected
without need of maintaining separate kernel binaries.
Note: On DM814x devices, the bit positions for pull up/down are different and hence use macros
TI814X_PULL_DIS (to disable pull up/down) or TI814X_PULL_UP to select pull up.
So now to make our custom board work is it enough if we give something like
omap_mux_init_signal("rmii0_rxer", OMAP_MUX_MODE2);
omap_mux_init_signal("rmii0_rxd1", OMAP_MUX_MODE2);
omap_mux_init_signal("rmii0_rxd0", OMAP_MUX_MODE2);
omap_mux_init_signal("rmii0_crs", OMAP_MUX_MODE2);
omap_mux_init_signal("rmii0_txd0" , OMAP_MUX_MODE2);
omap_mux_init_signal("rmii0_txd0" , OMAP_MUX_MODE2); omap_mux_init_signal("rmii0_txen" , OMAP_MUX_MODE2); omap_mux_init_signal("rmii_refclk" , OMAP_MUX_MODE0); in
void ti814x_cpsw_mux(void) {
} in as datsheet says the same. Without doing this right now we get the error when we execute the function davinci_mdio_reset static void __davinci_mdio_reset(struct davinci_mdio_data *data) { u32 mdio_in, div, mdio_out_khz, access_time; mdio_in = clk_get_rate(data->clk); div = (mdio_in / data->pdata.bus_freq) - 1; if (div > CONTROL_MAX_DIV) div = CONTROL_MAX_DIV; /* set enable and clock divider */ __raw_writel(div | CONTROL_ENABLE, &data->regs->control); /* * One mdio transaction consists of: * 32 bits of preamble * 32 bits of transferred data * 24 bits of bus yield (not needed unless shared?) */ mdio_out_khz = mdio_in / (1000 * (div + 1)); access_time = (88 * 1000) / mdio_out_khz; /* * In the worst case, we could be kicking off a user-access immediately * after the mdio bus scan state-machine triggered its own read. If * so, our request could get deferred by one access cycle. We * defensively allow for 4 access cycles. */ data->access_time = usecs_to_jiffies(access_time * 4); if (!data->access_time) data->access_time = 1; } static int davinci_mdio_reset(struct mii_bus *bus) { struct davinci_mdio_data *data = bus->priv; u32 phy_mask, ver; printk(KERN_CRIT "ETHERNET:inside the davinci_mdio_reset\n"); __davinci_mdio_reset(data); /* wait for scan logic to settle */ msleep(PHY_MAX_ADDR * data->access_time); /* dump hardware version info */ ver = __raw_readl(&data->regs->version); dev_info(data->dev, "davinci mdio revision %d.%d\n", (ver >> 8) & 0xff, ver & 0xff); /* get phy mask from the alive register */ phy_mask = __raw_readl(&data->regs->alive); if (phy_mask) { /* restrict mdio bus to live phys only */ dev_info(data->dev, "detected phy mask %x\n", ~phy_mask);//things will go wrong here as no clock as pimuxing not done phy_mask = ~phy_mask; } else { /* desperately scan all phys */ dev_warn(data->dev, "no live phy, scanning all\n"); phy_mask = 0; } data->bus->phy_mask = phy_mask; return 0; } /* wait until hardware is ready for another user access */ static inline int wait_for_user_access(struct davinci_mdio_data *data) { struct davinci_mdio_regs __iomem *regs = data->regs; unsigned long timeout = jiffies + msecs_to_jiffies(MDIO_TIMEOUT); u32 reg; while (time_after(timeout, jiffies)) { reg = __raw_readl(®s->user[0].access); if ((reg & USERACCESS_GO) == 0) return 0; reg = __raw_readl(®s->control); if ((reg & CONTROL_IDLE) == 0) continue; /* * An emac soft_reset may have clobbered the mdio controller's * state machine. We need to reset and retry the current * operation */ dev_warn(data->dev, "resetting idled controller\n"); __davinci_mdio_reset(data); return -EAGAIN; } dev_err(data->dev, "timed out waiting for user access\n"); return -ETIMEDOUT; } /* wait until hardware state machine is idle */ static inline int wait_for_idle(struct davinci_mdio_data *data) { struct davinci_mdio_regs __iomem *regs = data->regs; unsigned long timeout = jiffies + msecs_to_jiffies(MDIO_TIMEOUT); while (time_after(timeout, jiffies)) { if (__raw_readl(®s->control) & CONTROL_IDLE) return 0; } dev_err(data->dev, "timed out waiting for idle\n"); return -ETIMEDOUT; } static int davinci_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg) { struct davinci_mdio_data *data = bus->priv; u32 reg; int ret; if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK) return -EINVAL; spin_lock(&data->lock); if (data->suspended) { spin_unlock(&data->lock); return -ENODEV; } reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) | (phy_id << 16)); while (1) { ret = wait_for_user_access(data); if (ret == -EAGAIN) continue; if (ret < 0) break; __raw_writel(reg, &data->regs->user[0].access); ret = wait_for_user_access(data); if (ret == -EAGAIN) continue; if (ret < 0) break; reg = __raw_readl(&data->regs->user[0].access); ret = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -EIO; break; } spin_unlock(&data->lock); return ret; } static int davinci_mdio_write(struct mii_bus *bus, int phy_id, int phy_reg, u16 phy_data) { struct davinci_mdio_data *data = bus->priv; u32 reg; int ret; if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK) return -EINVAL; spin_lock(&data->lock); if (data->suspended) { spin_unlock(&data->lock); return -ENODEV; } reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) | (phy_id << 16) | (phy_data & USERACCESS_DATA)); while (1) { ret = wait_for_user_access(data); if (ret == -EAGAIN) continue; if (ret < 0) break; __raw_writel(reg, &data->regs->user[0].access); ret = wait_for_user_access(data); if (ret == -EAGAIN) continue; break; } spin_unlock(&data->lock); return 0; } static int __devinit davinci_mdio_probe(struct platform_device *pdev) { struct mdio_platform_data *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; struct davinci_mdio_data *data; struct resource *res; struct phy_device *phy; int ret, addr; printk(KERN_CRIT "ETHERNET:inside the davinci_mdio_probe\n"); data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { dev_err(dev, "failed to alloc device data\n"); return -ENOMEM; } data->pdata = pdata ? (*pdata) : default_pdata; data->bus = mdiobus_alloc(); if (!data->bus) { dev_err(dev, "failed to alloc mii bus\n"); ret = -ENOMEM; goto bail_out; } data->bus->name = dev_name(dev); data->bus->read = davinci_mdio_read, data->bus->write = davinci_mdio_write, data->bus->reset = davinci_mdio_reset, data->bus->parent = dev; data->bus->priv = data; snprintf(data->bus->id, MII_BUS_ID_SIZE, "%x", pdev->id); data->clk = clk_get(dev, NULL); if (IS_ERR(data->clk)) { data->clk = NULL; dev_err(dev, "failed to get device clock\n"); // ret = PTR_ERR(data->clk); // goto bail_out; } printk(KERN_CRIT "ETHERNET:inside davinci mdio_probe b4 clk_enable\n"); clk_enable(data->clk); printk(KERN_CRIT "ETHERNET:inside davinci mdio_probe after clk_enable b4 dev_set_drvdata\n"); dev_set_drvdata(dev, data); printk(KERN_CRIT "ETHERNET:inside davinci mdio_probe after dev_set_drvdata\n"); data->dev = dev; spin_lock_init(&data->lock); printk(KERN_CRIT "ETHERNET:inside davinci mdio_probe b4 calling platform_get_resource\n"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "could not find register map resource\n"); ret = -ENOENT; goto bail_out; } printk(KERN_CRIT "ETHERNET:inside davinci mdio_probe b4 calling devm_request_mem_region\n"); res = devm_request_mem_region(dev, res->start, resource_size(res), dev_name(dev)); if (!res) { dev_err(dev, "could not allocate register map resource\n"); ret = -ENXIO; goto bail_out; } printk(KERN_CRIT "ETHERNET:inside davinci mdio_probe b4 calling devm_ioremap_nocache\n"); data->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!data->regs) { dev_err(dev, "could not map mdio registers\n"); ret = -ENOMEM; goto bail_out; } /* register the mii bus */ printk(KERN_CRIT "ETHERNET:inside davinci mdio_probe b4 calling mdiobus_register\n"); ret = mdiobus_register(data->bus); //after this davinci_mdio_reset gets called if (ret) goto bail_out; /* scan and dump the bus */ for (addr = 0; addr < PHY_MAX_ADDR; addr++) { phy = data->bus->phy_map[addr]; if (phy) { dev_info(dev, "phy[%d]: device %s, driver %s\n", phy->addr, dev_name(&phy->dev), phy->drv ? phy->drv->name : "unknown"); } } return 0; bail_out: if (data->bus) mdiobus_free(data->bus); if (data->clk) { clk_disable(data->clk); clk_put(data->clk); } kfree(data); return ret; } static int __devexit davinci_mdio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct davinci_mdio_data *data = dev_get_drvdata(dev); if (data->bus) mdiobus_free(data->bus); if (data->clk) { clk_disable(data->clk); clk_put(data->clk); } dev_set_drvdata(dev, NULL); kfree(data); return 0; } static int davinci_mdio_suspend(struct device *dev) { struct davinci_mdio_data *data = dev_get_drvdata(dev); u32 ctrl; spin_lock(&data->lock); /* shutdown the scan state machine */ ctrl = __raw_readl(&data->regs->control); ctrl &= ~CONTROL_ENABLE; __raw_writel(ctrl, &data->regs->control); wait_for_idle(data); if (data->clk) clk_disable(data->clk); data->suspended = true; spin_unlock(&data->lock); return 0; } static int davinci_mdio_resume(struct device *dev) { struct davinci_mdio_data *data = dev_get_drvdata(dev); u32 ctrl; spin_lock(&data->lock); if (data->clk) clk_enable(data->clk); /* restart the scan state machine */ ctrl = __raw_readl(&data->regs->control); ctrl |= CONTROL_ENABLE; __raw_writel(ctrl, &data->regs->control); data->suspended = false; spin_unlock(&data->lock); return 0; } static const struct dev_pm_ops davinci_mdio_pm_ops = { .suspend = davinci_mdio_suspend, .resume = davinci_mdio_resume, }; static struct platform_driver davinci_mdio_driver = { .driver = { .name = "davinci_mdio", .owner = THIS_MODULE, .pm = &davinci_mdio_pm_ops, }, .probe = davinci_mdio_probe, .remove = __devexit_p(davinci_mdio_remove), }; static int __init davinci_mdio_init(void) { return platform_driver_register(&davinci_mdio_driver); } device_initcall(davinci_mdio_init); static void __exit davinci_mdio_exit(void) { platform_driver_unregister(&davinci_mdio_driver); } module_exit(davinci_mdio_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DaVinci MDIO driver");
So adding just the pinmuxing will it do for phy to be recognised and start working in RMII mode.
or more has to be done like at
static struct cpsw_platform_data ti814x_cpsw_pdata = {
.ss_reg_ofs = 0x900,
.channels = 8,
.cpdma_reg_ofs = 0x100,
.slaves = 1,
.slave_data = cpsw_slaves,
.ale_reg_ofs = 0x600,
.ale_entries = 1024,
.host_port_reg_ofs = 0x28,
.hw_stats_reg_ofs = 0x400,
.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,
};
Thanks and Regards,
-P