/***********************************************************************************                      I.MX6 PHY fixup 调用流程 hacking* 说明:*     跟一下i.MX6中对PHY进行fixup的代码是如何被调用的。*              *                                          2017-4-14 深圳 龙华民治樟坑村 曾剑锋*********************************************************************************/
static struct platform_driver fec_driver = {  <-----+.driver    = {                                  |.name    = DRIVER_NAME,                     |.owner    = THIS_MODULE,                    |.pm    = &fec_pm_ops,                       |.of_match_table = fec_dt_ids,               |},                                              |.id_table = fec_devtype,               ---------*-+.probe    = fec_probe,                          | |.remove    = fec_drv_remove,                    | |
};                                                  | || |
module_platform_driver(fec_driver);        ---------+ ||
MODULE_ALIAS("platform:"DRIVER_NAME);                 |
MODULE_LICENSE("GPL");                                ||
static int                                            |
fec_probe(struct platform_device *pdev)    <----------+
{struct fec_enet_private *fep;struct fec_platform_data *pdata;struct net_device *ndev;int i, irq, ret = 0;struct resource *r;const struct of_device_id *of_id;static int dev_id;struct device_node *np = pdev->dev.of_node, *phy_node;int num_tx_qs;int num_rx_qs;fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);/* Init network device */ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private),num_tx_qs, num_rx_qs);if (!ndev)return -ENOMEM;SET_NETDEV_DEV(ndev, &pdev->dev);/* setup board info structure */fep = netdev_priv(ndev);of_id = of_match_device(fec_dt_ids, &pdev->dev);if (of_id)pdev->id_entry = of_id->data;fep->quirks = pdev->id_entry->driver_data;fep->netdev = ndev;fep->num_rx_queues = num_rx_qs;fep->num_tx_queues = num_tx_qs;#if !defined(CONFIG_M5272)/* default enable pause frame auto negotiation */if (fep->quirks & FEC_QUIRK_HAS_GBIT)fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG;
#endif/* Select default pin state */pinctrl_pm_select_default_state(&pdev->dev);r = platform_get_resource(pdev, IORESOURCE_MEM, 0);fep->hwp = devm_ioremap_resource(&pdev->dev, r);if (IS_ERR(fep->hwp)) {ret = PTR_ERR(fep->hwp);goto failed_ioremap;}fep->pdev = pdev;fep->dev_id = dev_id++;platform_set_drvdata(pdev, ndev);fec_enet_of_parse_stop_mode(pdev);if (of_get_property(np, "fsl,magic-packet", NULL))fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET;phy_node = of_parse_phandle(np, "phy-handle", 0);if (!phy_node && of_phy_is_fixed_link(np)) {ret = of_phy_register_fixed_link(np);if (ret < 0) {dev_err(&pdev->dev,"broken fixed-link specification\n");goto failed_phy;}phy_node = of_node_get(np);}fep->phy_node = phy_node;ret = of_get_phy_mode(pdev->dev.of_node);if (ret < 0) {pdata = dev_get_platdata(&pdev->dev);if (pdata)fep->phy_interface = pdata->phy;elsefep->phy_interface = PHY_INTERFACE_MODE_MII;} else {fep->phy_interface = ret;}fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg");if (IS_ERR(fep->clk_ipg)) {ret = PTR_ERR(fep->clk_ipg);goto failed_clk;}fep->clk_ahb = devm_clk_get(&pdev->dev, "ahb");if (IS_ERR(fep->clk_ahb)) {ret = PTR_ERR(fep->clk_ahb);goto failed_clk;}fep->itr_clk_rate = clk_get_rate(fep->clk_ahb);/* enet_out is optional, depends on board */fep->clk_enet_out = devm_clk_get(&pdev->dev, "enet_out");if (IS_ERR(fep->clk_enet_out))fep->clk_enet_out = NULL;fep->ptp_clk_on = false;mutex_init(&fep->ptp_clk_mutex);/* clk_ref is optional, depends on board */fep->clk_ref = devm_clk_get(&pdev->dev, "enet_clk_ref");if (IS_ERR(fep->clk_ref))fep->clk_ref = NULL;fep->bufdesc_ex = fep->quirks & FEC_QUIRK_HAS_BUFDESC_EX;fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");if (IS_ERR(fep->clk_ptp)) {fep->clk_ptp = NULL;fep->bufdesc_ex = false;}pm_runtime_enable(&pdev->dev);ret = fec_enet_clk_enable(ndev, true);if (ret)goto failed_clk;fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");if (!IS_ERR(fep->reg_phy)) {ret = regulator_enable(fep->reg_phy);if (ret) {dev_err(&pdev->dev,"Failed to enable phy regulator: %d\n", ret);goto failed_regulator;}} else {fep->reg_phy = NULL;}fec_reset_phy(pdev);if (fep->bufdesc_ex)fec_ptp_init(pdev);ret = fec_enet_init(ndev);               ----------------------------+if (ret)                                                             |goto failed_init;                                                ||for (i = 0; i < FEC_IRQ_NUM; i++) {                                  |irq = platform_get_irq(pdev, i);                                 |if (irq < 0) {                                                   |if (i)                                                       |break;                                                   |ret = irq;                                                   |goto failed_irq;                                             |}                                                                |ret = devm_request_irq(&pdev->dev, irq, fec_enet_interrupt,      |0, pdev->name, ndev);                             |if (ret)                                                         |goto failed_irq;                                             ||fep->irq[i] = irq;                                               |}                                                                    ||ret = of_property_read_u32(np, "fsl,wakeup_irq", &irq);              |if (!ret && irq < FEC_IRQ_NUM)                                       |fep->wake_irq = fep->irq[irq];                                   |else                                                                 |fep->wake_irq = fep->irq[0];                                     ||init_completion(&fep->mdio_done);                                    |ret = fec_enet_mii_init(pdev);                                       |if (ret)                                                             |goto failed_mii_init;                                            ||/* Carrier starts down, phylib will bring it up */                   |netif_carrier_off(ndev);                                             |fec_enet_clk_enable(ndev, false);                                    |pinctrl_pm_select_sleep_state(&pdev->dev);                           ||ret = register_netdev(ndev);                                         |if (ret)                                                             |goto failed_register;                                            ||device_init_wakeup(&ndev->dev, fep->wol_flag &                       |FEC_WOL_HAS_MAGIC_PACKET);                                ||if (fep->bufdesc_ex && fep->ptp_clock)                               |netdev_info(ndev, "registered PHC device %d\n", fep->dev_id);    ||fep->rx_copybreak = COPYBREAK_DEFAULT;                               |INIT_WORK(&fep->tx_timeout_work, fec_enet_timeout_work);             |return 0;                                                            ||
failed_register:                                                         |fec_enet_mii_remove(fep);                                            |
failed_mii_init:                                                         |
failed_irq:                                                              |
failed_init:                                                             |if (fep->reg_phy)                                                    |regulator_disable(fep->reg_phy);                                 |
failed_regulator:                                                        |fec_enet_clk_enable(ndev, false);                                    |
failed_clk:                                                              |
failed_phy:                                                              |of_node_put(phy_node);                                               |
failed_ioremap:                                                          |free_netdev(ndev);                                                   ||return ret;                                                          |
}                                                                        ||/*                                                                      |* XXX:  We need to clean up on failure exits here.                     |*                                                                      |*/                                                                     |
static int fec_enet_init(struct net_device *ndev)      <-----------------+
{struct fec_enet_private *fep = netdev_priv(ndev);struct fec_enet_priv_tx_q *txq;struct fec_enet_priv_rx_q *rxq;struct bufdesc *cbd_base;dma_addr_t bd_dma;int bd_size;unsigned int i;#if defined(CONFIG_ARM)fep->rx_align = 0xf;fep->tx_align = 0xf;
#elsefep->rx_align = 0x3;fep->tx_align = 0x3;
#endiffec_enet_alloc_queue(ndev);if (fep->bufdesc_ex)fep->bufdesc_size = sizeof(struct bufdesc_ex);elsefep->bufdesc_size = sizeof(struct bufdesc);bd_size = (fep->total_tx_ring_size + fep->total_rx_ring_size) *fep->bufdesc_size;/* Allocate memory for buffer descriptors. */cbd_base = dma_alloc_coherent(NULL, bd_size, &bd_dma,GFP_KERNEL);if (!cbd_base) {return -ENOMEM;}memset(cbd_base, 0, bd_size);/* Get the Ethernet address */fec_get_mac(ndev);/* make sure MAC we just acquired is programmed into the hw */fec_set_mac_address(ndev, NULL);/* Set receive and transmit descriptor base. */for (i = 0; i < fep->num_rx_queues; i++) {rxq = fep->rx_queue[i];rxq->index = i;rxq->rx_bd_base = (struct bufdesc *)cbd_base;rxq->bd_dma = bd_dma;if (fep->bufdesc_ex) {bd_dma += sizeof(struct bufdesc_ex) * rxq->rx_ring_size;cbd_base = (struct bufdesc *)(((struct bufdesc_ex *)cbd_base) + rxq->rx_ring_size);} else {bd_dma += sizeof(struct bufdesc) * rxq->rx_ring_size;cbd_base += rxq->rx_ring_size;}}for (i = 0; i < fep->num_tx_queues; i++) {txq = fep->tx_queue[i];txq->index = i;txq->tx_bd_base = (struct bufdesc *)cbd_base;txq->bd_dma = bd_dma;if (fep->bufdesc_ex) {bd_dma += sizeof(struct bufdesc_ex) * txq->tx_ring_size;cbd_base = (struct bufdesc *)(((struct bufdesc_ex *)cbd_base) + txq->tx_ring_size);} else {bd_dma += sizeof(struct bufdesc) * txq->tx_ring_size;cbd_base += txq->tx_ring_size;}}/* The FEC Ethernet specific entries in the device structure */ndev->watchdog_timeo = TX_TIMEOUT;ndev->netdev_ops = &fec_netdev_ops;                --------------------+ndev->ethtool_ops = &fec_enet_ethtool_ops;                             ||writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);                   |netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, NAPI_POLL_WEIGHT);  ||if (fep->quirks & FEC_QUIRK_HAS_VLAN)                                  |/* enable hw VLAN support */                                       |ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;                         ||if (fep->quirks & FEC_QUIRK_HAS_CSUM) {                                |ndev->gso_max_segs = FEC_MAX_TSO_SEGS;                             ||/* enable hw accelerator */                                        |ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM             || NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO);              |fep->csum_flags |= FLAG_RX_CSUM_ENABLED;                           |}                                                                      ||if (fep->quirks & FEC_QUIRK_HAS_AVB) {                                 |fep->tx_align = 0;                                                 |fep->rx_align = 0x3f;                                              |}                                                                      ||ndev->hw_features = ndev->features;                                    ||fec_restart(ndev);                                                     ||return 0;                                                              |
}                                                                          ||
static const struct net_device_ops fec_netdev_ops = {          <-----------+.ndo_open        = fec_enet_open,               ---------+.ndo_stop        = fec_enet_close,                       |.ndo_start_xmit        = fec_enet_start_xmit,            |.ndo_select_queue       = fec_enet_select_queue,         |.ndo_set_rx_mode    = set_multicast_list,                |.ndo_change_mtu        = eth_change_mtu,                 |.ndo_validate_addr    = eth_validate_addr,               |.ndo_tx_timeout        = fec_timeout,                    |.ndo_set_mac_address    = fec_set_mac_address,           |.ndo_do_ioctl        = fec_enet_ioctl,                   |
#ifdef CONFIG_NET_POLL_CONTROLLER                            |.ndo_poll_controller    = fec_poll_controller,           |
#endif                                                       |.ndo_set_features    = fec_set_features,                 |
};                                                           ||
static int                                                   |
fec_enet_open(struct net_device *ndev)              <--------+
{struct fec_enet_private *fep = netdev_priv(ndev);const struct platform_device_id *id_entry =platform_get_device_id(fep->pdev);int ret;pinctrl_pm_select_default_state(&fep->pdev->dev);ret = fec_enet_clk_enable(ndev, true);if (ret)return ret;/* I should reset the ring buffers here, but I don't yet know* a simple way to do that.*/ret = fec_enet_alloc_buffers(ndev);if (ret)goto err_enet_alloc;/* Init MAC firstly for suspend/resume with megafix off case */fec_restart(ndev);/* Probe and connect to PHY when open the interface */ret = fec_enet_mii_probe(ndev);                          -----+if (ret)                                                      |goto err_enet_mii_probe;                                  ||napi_enable(&fep->napi);                                      |phy_start(fep->phy_dev);                                      |netif_tx_start_all_queues(ndev);                              ||pm_runtime_get_sync(ndev->dev.parent);                        |if ((id_entry->driver_data & FEC_QUIRK_BUG_WAITMODE) &&       |!fec_enet_irq_workaround(fep))                            |pm_qos_add_request(&ndev->pm_qos_req,                     |PM_QOS_CPU_DMA_LATENCY,                        |0);                                            |else                                                          |pm_qos_add_request(&ndev->pm_qos_req,                     |PM_QOS_CPU_DMA_LATENCY,                        |PM_QOS_DEFAULT_VALUE);                         ||device_set_wakeup_enable(&ndev->dev, fep->wol_flag &          |FEC_WOL_FLAG_ENABLE);                            |fep->miibus_up_failed = false;                                ||return 0;                                                     ||
err_enet_mii_probe:                                               |fec_enet_free_buffers(ndev);                                  |
err_enet_alloc:                                                   |fep->miibus_up_failed = true;                                 |if (!fep->mii_bus_share)                                      |pinctrl_pm_select_sleep_state(&fep->pdev->dev);           |return ret;                                                   |
}                                                                 ||
static int fec_enet_mii_probe(struct net_device *ndev)       <----+
{struct fec_enet_private *fep = netdev_priv(ndev);struct phy_device *phy_dev = NULL;char mdio_bus_id[MII_BUS_ID_SIZE];char phy_name[MII_BUS_ID_SIZE + 3];int phy_id;int dev_id = fep->dev_id;fep->phy_dev = NULL;if (fep->phy_node) {phy_dev = of_phy_connect(ndev, fep->phy_node,&fec_enet_adjust_link, 0,fep->phy_interface);if (!phy_dev)return -ENODEV;} else {/* check for attached phy */for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {if ((fep->mii_bus->phy_mask & (1 << phy_id)))continue;if (fep->mii_bus->phy_map[phy_id] == NULL)continue;if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)continue;if (dev_id--)continue;strlcpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);break;}if (phy_id >= PHY_MAX_ADDR) {netdev_info(ndev, "no PHY, assuming direct connection to switch\n");strlcpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE);phy_id = 0;}snprintf(phy_name, sizeof(phy_name),PHY_ID_FMT, mdio_bus_id, phy_id);phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link,      ---------------+fep->phy_interface);                                               |}                                                                                    ||if (IS_ERR(phy_dev)) {                                                               |netdev_err(ndev, "could not attach to PHY\n");                                   |return PTR_ERR(phy_dev);                                                         |}                                                                                    ||/* mask with MAC supported features */                                               |if (fep->quirks & FEC_QUIRK_HAS_GBIT) {                                              |phy_dev->supported &= PHY_GBIT_FEATURES;                                         |// phy_dev->supported &= ~SUPPORTED_1000baseT_Half;                              |phy_dev->supported |= SUPPORTED_Pause;                                           |// phy_dev->supported |= SUPPORTED_1000baseT_Half;                               |printk("FEC_QUIRK_HAS_GBIT\n");                                                  |
#if !defined(CONFIG_M5272)                                                               |phy_dev->supported |= SUPPORTED_Pause;                                           |
#endif                                                                                   |phy_dev->advertising = phy_dev->supported;                                       |}                                                                                    |else                                                                                 |{                                                                                    |printk("PHY_BASIC_FEATURES\n");                                                  |// phy_dev->supported &= PHY_BASIC_FEATURES;                                     |phy_dev->advertising = phy_dev->supported & PHY_BASIC_FEATURES;                  |}                                                                                    |// phy_dev->advertising = phy_dev->supported;                                        ||fep->phy_dev = phy_dev;                                                              |fep->link = 0;                                                                       |fep->full_duplex = 0;                                                                ||netdev_info(ndev, "Freescale FEC PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",   |fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev),                       |fep->phy_dev->irq);                                                          ||return 0;                                                                            |
}                                                                                        ||
struct phy_device *phy_connect(struct net_device *dev, const char *bus_id,      <--------+void (*handler)(struct net_device *),phy_interface_t interface)
{struct phy_device *phydev;struct device *d;int rc;/* Search the list of PHY devices on the mdio bus for the* PHY with the requested name*/d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id);if (!d) {pr_err("PHY %s not found\n", bus_id);return ERR_PTR(-ENODEV);}phydev = to_phy_device(d);rc = phy_connect_direct(dev, phydev, handler, interface);      --------------+if (rc)                                                                      |return ERR_PTR(rc);                                                      ||return phydev;                                                               |
}                                                                                |
EXPORT_SYMBOL(phy_connect);                                                      ||
int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,   <----+void (*handler)(struct net_device *),phy_interface_t interface)
{int rc;rc = phy_attach_direct(dev, phydev, phydev->dev_flags, interface);    --------+if (rc)                                                                       |return rc;                                                                ||phy_prepare_link(phydev, handler);                                            |phy_start_machine(phydev);                                                    |if (phydev->irq > 0)                                                          |phy_start_interrupts(phydev);                                             ||return 0;                                                                     |
}                                                                                 |
EXPORT_SYMBOL(phy_connect_direct);                                                ||
int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,  <-------+u32 flags, phy_interface_t interface)
{struct device *d = &phydev->dev;int err;/* Assume that if there is no driver, that it doesn't* exist, and we should use the genphy driver.*/if (NULL == d->driver) {if (phydev->is_c45)d->driver = &genphy_driver[GENPHY_DRV_10G].driver;elsed->driver = &genphy_driver[GENPHY_DRV_1G].driver;err = d->driver->probe(d);if (err >= 0)err = device_bind_driver(d);if (err)return err;}if (phydev->attached_dev) {dev_err(&dev->dev, "PHY already attached\n");return -EBUSY;}phydev->attached_dev = dev;dev->phydev = phydev;phydev->dev_flags = flags;phydev->interface = interface;phydev->state = PHY_READY;/* Do initial configuration here, now that* we have certain key parameters* (dev_flags and interface)*/err = phy_init_hw(phydev);          --------------------+if (err)                                                |phy_detach(phydev);                                 |else                                                    |phy_resume(phydev);                                 ||return err;                                             |
}                                                           |
EXPORT_SYMBOL(phy_attach_direct);                           ||
int phy_init_hw(struct phy_device *phydev)     <------------+
{int ret;if (!phydev->drv || !phydev->drv->config_init)return 0;ret = phy_write(phydev, MII_BMCR, BMCR_RESET);if (ret < 0)return ret;ret = phy_poll_reset(phydev);if (ret < 0)return ret;ret = phy_scan_fixups(phydev);             -------------+if (ret < 0)                                            |return ret;                                         ||return phydev->drv->config_init(phydev);                |
}                                                           |
EXPORT_SYMBOL(phy_init_hw);                                 ||
/* Runs any matching fixups for this phydev */              |
int phy_scan_fixups(struct phy_device *phydev)     <--------+
{struct phy_fixup *fixup;mutex_lock(&phy_fixup_lock);list_for_each_entry(fixup, &phy_fixup_list, list) {      ------------------+if (phy_needs_fixup(phydev, fixup)) {      --------+                   |int err = fixup->run(phydev);                  |                   ||                   |if (err < 0) {                                 |                   |mutex_unlock(&phy_fixup_lock);             |                   |return err;                                |                   |}                                              |                   |}                                                  |                   |}                                                      |                   |mutex_unlock(&phy_fixup_lock);                         |                   ||                   |return 0;                                              |                   |
}                                                          |                   |
EXPORT_SYMBOL(phy_scan_fixups);                            |                   |v--------------------------------------+                   |
static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup) |
{                                                                              |if (strcmp(fixup->bus_id, dev_name(&phydev->dev)) != 0)                    |if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0)                            |return 0;                                                          ||if ((fixup->phy_uid & fixup->phy_uid_mask) !=                              |(phydev->phy_id & fixup->phy_uid_mask))                                |if (fixup->phy_uid != PHY_ANY_UID)                                     |return 0;                                                          ||return 1;                                                                  |
}                                                                              ||
static LIST_HEAD(phy_fixup_list);                            <-----------------+|
int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,  ----*-+int (*run)(struct phy_device *))                                | |
{                                                                              | |struct phy_fixup *fixup = kzalloc(sizeof(*fixup), GFP_KERNEL);             | || |if (!fixup)                                                                | |return -ENOMEM;                                                        | || |strlcpy(fixup->bus_id, bus_id, sizeof(fixup->bus_id));                     | |fixup->phy_uid = phy_uid;                                                  | |fixup->phy_uid_mask = phy_uid_mask;                                        | |fixup->run = run;                                                          | || |mutex_lock(&phy_fixup_lock);                                               | |list_add_tail(&fixup->list, &phy_fixup_list);            <-----------------+ |mutex_unlock(&phy_fixup_lock);                                               ||return 0;                                                                    |
}                                                                                |
EXPORT_SYMBOL(phy_register_fixup);                                               ||
static void __init imx6q_enet_phy_init(void)                  -------------------*-+
{                                                                                | |if (IS_BUILTIN(CONFIG_PHYLIB)) {                                             | |phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,           | |ksz9021rn_phy_fixup);                                            | |phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,           | |ksz9031rn_phy_fixup);                                            | |phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,      <-------------+ |ar8031_phy_fixup);                                 --------------+ |phy_register_fixup_for_uid(PHY_ID_AR8035, 0xffffffef,                    | |ar8035_phy_fixup);                                               | |}                                                                            | |
}                                                                                | || |
static int ar8031_phy_fixup(struct phy_device *dev)                <-------------+ |
{                                                                                  |u16 val;                                                                       ||/* Set RGMII IO voltage to 1.8V */                                             |phy_write(dev, 0x1d, 0x1f);                                                    |phy_write(dev, 0x1e, 0x8);                                                     ||/* disable phy AR8031 SmartEEE function. */                                    |phy_write(dev, 0xd, 0x3);                                                      |phy_write(dev, 0xe, 0x805d);                                                   |phy_write(dev, 0xd, 0x4003);                                                   |val = phy_read(dev, 0xe);                                                      |val &= ~(0x1 << 8);                                                            |phy_write(dev, 0xe, val);                                                      ||/* To enable AR8031 output a 125MHz clk from CLK_25M */                        |phy_write(dev, 0xd, 0x7);                                                      |phy_write(dev, 0xe, 0x8016);                                                   |phy_write(dev, 0xd, 0x4007);                                                   ||val = phy_read(dev, 0xe);                                                      |val &= 0xffe3;                                                                 |val |= 0x18;                                                                   |phy_write(dev, 0xe, val);                                                      ||/* introduce tx clock delay */                                                 |phy_write(dev, 0x1d, 0x5);                                                     |val = phy_read(dev, 0x1e);                                                     |val |= 0x0100;                                                                 |phy_write(dev, 0x1e, val);                                                     ||return 0;                                                                      |
}                                                                                  ||
static inline void imx6q_enet_init(void)        -----------------------------------*-+
{                                                                                  | |imx6_enet_mac_init("fsl,imx6q-fec");                                           | |imx6q_enet_phy_init();                     <-----------------------------------+ |imx6q_1588_init();                                                               |if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)           |imx6q_enet_clk_sel();                                                        |imx6q_enet_plt_init();                                                           |
}                                                                                    ||
static void __init imx6q_init_machine(void)                                          |
{                                                                                    |struct device *parent;                                                           ||if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)           |imx_print_silicon_rev("i.MX6QP", IMX_CHIP_REVISION_1_0);                     |else                                                                             |imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",                |imx_get_soc_revision());                                            ||mxc_arch_reset_init_dt();                                                        ||parent = imx_soc_device_init();                                                  |if (parent == NULL)                                                              |pr_warn("failed to initialize soc device\n");                                ||of_platform_populate(NULL, of_default_bus_match_table,                           |imx6q_auxdata_lookup, parent);                                   ||imx6q_enet_init();                                   <---------------------------+imx_anatop_init();imx6q_csi_mux_init();cpu_is_imx6q() ?  imx6q_pm_init() : imx6dl_pm_init();imx6q_mini_pcie_init();
}

I.MX6 PHY fixup 调用流程 hacking相关推荐

  1. I.MX6 ar1020 SPI device driver hacking

    /************************************************************************************* I.MX6 ar1020 ...

  2. I.MX6 Linux Qt 启动流程跟踪

    /*************************************************************************** I.MX6 Linux Qt 启动流程跟踪* ...

  3. I.MX6 Linux Serial Baud Rate hacking

    /********************************************************************************* I.MX6 Linux Seria ...

  4. RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别

    1. 基本概念 PRC 远程过程调用 Remote Procedure Call,其就是一个节点请求另外一个节点提供的服务.当两个物理分离的子系统需要建立逻辑上的关联时,RPC 是牵线搭桥的常见技术手 ...

  5. novaclient的api调用流程与开发

    novaclient的api调用流程与开发 2015年07月05日 19:27:17 qiushanjushi 阅读数:3915 http://blog.csdn.net/tpiperatgod/ar ...

  6. java 操作uart串口_【tty】应用程序调用write写串口调用流程

    这几天在跟进串口使能流控后收发异常问题,特简单梳理了下应用程序执行write操作的调用流程,在这简单记录下,平台为全志方案 tty_io.c         tty_io.c              ...

  7. go语言基础之递归函数的调用流程

    一.递归函数的调用流程 package main //必须import "fmt"func test(a int) {if a == 1 { //函数终止调用的条件,非常重要fmt ...

  8. 【Android 逆向】Android 进程代码注入原理 ( 进程注入原理 | 远程调用流程 | 获取函数地址 | 设置 IP 寄存器 | mmap 申请内存 | 设置 SP 寄存器 )

    文章目录 一.进程注入原理 二.远程调用流程 ( 获取 so 动态库地址 | 获取函数地址 | 设置 IP 寄存器 | mmap 申请内存 | 设置 SP 寄存器 ) 一.进程注入原理 调试进程 At ...

  9. Retrofit2源码解析——网络调用流程(下)

    Retrofit2源码解析系列 Retrofit2源码解析(一) Retrofit2源码解析--网络调用流程(上) 本文基于Retrofit2的2.4.0版本 implementation 'com. ...

最新文章

  1. SQLite.swift的简单使用
  2. Golang协程goroutine和管道channel结合案例
  3. Java死锁、活锁,悲观锁、乐观锁
  4. 图形工具包 linux,GTK 4.0图形工具包正式发布:时隔四年的重大版本!
  5. multism中ui和uo应该怎么表示_王者荣耀:梦泪直播时谈到体验服大改动,表示装备的改动很关键...
  6. sae 微信 java web_[1] 微信公众号与sae的web应用之间的配置
  7. Linux命令解释之mkfs.ext3
  8. Codeforces Round #511 (Div. 1) 题解
  9. SQL入门教程(一):基础知识
  10. 测试人员必会用例设计方法--正交表
  11. 计算机中存储单位的换算
  12. 跟我学c++中级篇——decay
  13. sina股票接口更新:Kinsoku jikou desu
  14. win7系统如何映射服务器,教你win7系统映射网络驱动器的操作方法
  15. JavaSE学习笔记之网络编程
  16. 要学就学透彻!Spring Security 中 CSRF 防御源码解析
  17. 机器学习中的ground truth
  18. 我要搬家到51CTO了
  19. INE深圳硅谷双线发布演讲实录 | CEOCTO羽睿-去中心化的最后一块版图
  20. c语言为什么运行不出数据,程序运行后可以输入数据,但是之后为什么没有显示?...

热门文章

  1. Selenium自动化之最大化浏览器操作
  2. linux shell 编辑文件内容,Shell编辑与文本处理(Bash sed文本编辑)
  3. numpy numpy.concatenate()函数
  4. Web 应用性能和压力测试工具 Gor
  5. 你的团队是王者还是青铜(下)
  6. 【论文精读】Smoothly Varying Affine Stitching
  7. 读人工智能发展报告学习心得(大纲)
  8. java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
  9. 【玩转嵌入式屏幕显示】(七)LCD中文字符显示机制
  10. 联科教育【免费公开课】每周一和周三晚19:30分:C#程序设计--基础篇,赶快围观啦~~~