aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/nxp/lpc_eth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/nxp/lpc_eth.c')
-rw-r--r--drivers/net/ethernet/nxp/lpc_eth.c71
1 files changed, 50 insertions, 21 deletions
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
index 6dfc26d85e47..52deec0b22ea 100644
--- a/drivers/net/ethernet/nxp/lpc_eth.c
+++ b/drivers/net/ethernet/nxp/lpc_eth.c
@@ -40,6 +40,7 @@
40#include <linux/skbuff.h> 40#include <linux/skbuff.h>
41#include <linux/phy.h> 41#include <linux/phy.h>
42#include <linux/dma-mapping.h> 42#include <linux/dma-mapping.h>
43#include <linux/of.h>
43#include <linux/of_net.h> 44#include <linux/of_net.h>
44#include <linux/types.h> 45#include <linux/types.h>
45 46
@@ -340,13 +341,17 @@
340 */ 341 */
341#define LPC_POWERDOWN_MACAHB (1 << 31) 342#define LPC_POWERDOWN_MACAHB (1 << 31)
342 343
343/* Upon the upcoming introduction of device tree usage in LPC32xx, 344static phy_interface_t lpc_phy_interface_mode(struct device *dev)
344 * lpc_phy_interface_mode() and use_iram_for_net() will be extended with a
345 * device parameter for access to device tree information at runtime, instead
346 * of defining the values at compile time
347 */
348static inline phy_interface_t lpc_phy_interface_mode(void)
349{ 345{
346 if (dev && dev->of_node) {
347 const char *mode = of_get_property(dev->of_node,
348 "phy-mode", NULL);
349 if (mode && !strcmp(mode, "mii"))
350 return PHY_INTERFACE_MODE_MII;
351 return PHY_INTERFACE_MODE_RMII;
352 }
353
354 /* non-DT */
350#ifdef CONFIG_ARCH_LPC32XX_MII_SUPPORT 355#ifdef CONFIG_ARCH_LPC32XX_MII_SUPPORT
351 return PHY_INTERFACE_MODE_MII; 356 return PHY_INTERFACE_MODE_MII;
352#else 357#else
@@ -354,12 +359,16 @@ static inline phy_interface_t lpc_phy_interface_mode(void)
354#endif 359#endif
355} 360}
356 361
357static inline int use_iram_for_net(void) 362static bool use_iram_for_net(struct device *dev)
358{ 363{
364 if (dev && dev->of_node)
365 return of_property_read_bool(dev->of_node, "use-iram");
366
367 /* non-DT */
359#ifdef CONFIG_ARCH_LPC32XX_IRAM_FOR_NET 368#ifdef CONFIG_ARCH_LPC32XX_IRAM_FOR_NET
360 return 1; 369 return true;
361#else 370#else
362 return 0; 371 return false;
363#endif 372#endif
364} 373}
365 374
@@ -664,7 +673,7 @@ static void __lpc_eth_init(struct netdata_local *pldat)
664 LPC_ENET_CLRT(pldat->net_base)); 673 LPC_ENET_CLRT(pldat->net_base));
665 writel(LPC_IPGR_LOAD_PART2(0x12), LPC_ENET_IPGR(pldat->net_base)); 674 writel(LPC_IPGR_LOAD_PART2(0x12), LPC_ENET_IPGR(pldat->net_base));
666 675
667 if (lpc_phy_interface_mode() == PHY_INTERFACE_MODE_MII) 676 if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII)
668 writel(LPC_COMMAND_PASSRUNTFRAME, 677 writel(LPC_COMMAND_PASSRUNTFRAME,
669 LPC_ENET_COMMAND(pldat->net_base)); 678 LPC_ENET_COMMAND(pldat->net_base));
670 else { 679 else {
@@ -804,12 +813,13 @@ static int lpc_mii_probe(struct net_device *ndev)
804 } 813 }
805 814
806 /* Attach to the PHY */ 815 /* Attach to the PHY */
807 if (lpc_phy_interface_mode() == PHY_INTERFACE_MODE_MII) 816 if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII)
808 netdev_info(ndev, "using MII interface\n"); 817 netdev_info(ndev, "using MII interface\n");
809 else 818 else
810 netdev_info(ndev, "using RMII interface\n"); 819 netdev_info(ndev, "using RMII interface\n");
811 phydev = phy_connect(ndev, dev_name(&phydev->dev), 820 phydev = phy_connect(ndev, dev_name(&phydev->dev),
812 &lpc_handle_link_change, 0, lpc_phy_interface_mode()); 821 &lpc_handle_link_change, 0,
822 lpc_phy_interface_mode(&pldat->pdev->dev));
813 823
814 if (IS_ERR(phydev)) { 824 if (IS_ERR(phydev)) {
815 netdev_err(ndev, "Could not attach to PHY\n"); 825 netdev_err(ndev, "Could not attach to PHY\n");
@@ -843,7 +853,7 @@ static int lpc_mii_init(struct netdata_local *pldat)
843 } 853 }
844 854
845 /* Setup MII mode */ 855 /* Setup MII mode */
846 if (lpc_phy_interface_mode() == PHY_INTERFACE_MODE_MII) 856 if (lpc_phy_interface_mode(&pldat->pdev->dev) == PHY_INTERFACE_MODE_MII)
847 writel(LPC_COMMAND_PASSRUNTFRAME, 857 writel(LPC_COMMAND_PASSRUNTFRAME,
848 LPC_ENET_COMMAND(pldat->net_base)); 858 LPC_ENET_COMMAND(pldat->net_base));
849 else { 859 else {
@@ -1315,18 +1325,26 @@ static const struct net_device_ops lpc_netdev_ops = {
1315static int lpc_eth_drv_probe(struct platform_device *pdev) 1325static int lpc_eth_drv_probe(struct platform_device *pdev)
1316{ 1326{
1317 struct resource *res; 1327 struct resource *res;
1318 struct resource *dma_res;
1319 struct net_device *ndev; 1328 struct net_device *ndev;
1320 struct netdata_local *pldat; 1329 struct netdata_local *pldat;
1321 struct phy_device *phydev; 1330 struct phy_device *phydev;
1322 dma_addr_t dma_handle; 1331 dma_addr_t dma_handle;
1323 int irq, ret; 1332 int irq, ret;
1333 u32 tmp;
1334
1335 /* Setup network interface for RMII or MII mode */
1336 tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
1337 tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
1338 if (lpc_phy_interface_mode(&pdev->dev) == PHY_INTERFACE_MODE_MII)
1339 tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS;
1340 else
1341 tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
1342 __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
1324 1343
1325 /* Get platform resources */ 1344 /* Get platform resources */
1326 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1345 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1327 dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1328 irq = platform_get_irq(pdev, 0); 1346 irq = platform_get_irq(pdev, 0);
1329 if ((!res) || (!dma_res) || (irq < 0) || (irq >= NR_IRQS)) { 1347 if ((!res) || (irq < 0) || (irq >= NR_IRQS)) {
1330 dev_err(&pdev->dev, "error getting resources.\n"); 1348 dev_err(&pdev->dev, "error getting resources.\n");
1331 ret = -ENXIO; 1349 ret = -ENXIO;
1332 goto err_exit; 1350 goto err_exit;
@@ -1389,17 +1407,19 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
1389 sizeof(struct txrx_desc_t) + sizeof(struct rx_status_t)); 1407 sizeof(struct txrx_desc_t) + sizeof(struct rx_status_t));
1390 pldat->dma_buff_base_v = 0; 1408 pldat->dma_buff_base_v = 0;
1391 1409
1392 if (use_iram_for_net()) { 1410 if (use_iram_for_net(&pldat->pdev->dev)) {
1393 dma_handle = dma_res->start; 1411 dma_handle = LPC32XX_IRAM_BASE;
1394 if (pldat->dma_buff_size <= lpc32xx_return_iram_size()) 1412 if (pldat->dma_buff_size <= lpc32xx_return_iram_size())
1395 pldat->dma_buff_base_v = 1413 pldat->dma_buff_base_v =
1396 io_p2v(dma_res->start); 1414 io_p2v(LPC32XX_IRAM_BASE);
1397 else 1415 else
1398 netdev_err(ndev, 1416 netdev_err(ndev,
1399 "IRAM not big enough for net buffers, using SDRAM instead.\n"); 1417 "IRAM not big enough for net buffers, using SDRAM instead.\n");
1400 } 1418 }
1401 1419
1402 if (pldat->dma_buff_base_v == 0) { 1420 if (pldat->dma_buff_base_v == 0) {
1421 pldat->pdev->dev.coherent_dma_mask = 0xFFFFFFFF;
1422 pldat->pdev->dev.dma_mask = &pldat->pdev->dev.coherent_dma_mask;
1403 pldat->dma_buff_size = PAGE_ALIGN(pldat->dma_buff_size); 1423 pldat->dma_buff_size = PAGE_ALIGN(pldat->dma_buff_size);
1404 1424
1405 /* Allocate a chunk of memory for the DMA ethernet buffers 1425 /* Allocate a chunk of memory for the DMA ethernet buffers
@@ -1488,7 +1508,7 @@ err_out_unregister_netdev:
1488 platform_set_drvdata(pdev, NULL); 1508 platform_set_drvdata(pdev, NULL);
1489 unregister_netdev(ndev); 1509 unregister_netdev(ndev);
1490err_out_dma_unmap: 1510err_out_dma_unmap:
1491 if (!use_iram_for_net() || 1511 if (!use_iram_for_net(&pldat->pdev->dev) ||
1492 pldat->dma_buff_size > lpc32xx_return_iram_size()) 1512 pldat->dma_buff_size > lpc32xx_return_iram_size())
1493 dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size, 1513 dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size,
1494 pldat->dma_buff_base_v, 1514 pldat->dma_buff_base_v,
@@ -1515,7 +1535,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
1515 unregister_netdev(ndev); 1535 unregister_netdev(ndev);
1516 platform_set_drvdata(pdev, NULL); 1536 platform_set_drvdata(pdev, NULL);
1517 1537
1518 if (!use_iram_for_net() || 1538 if (!use_iram_for_net(&pldat->pdev->dev) ||
1519 pldat->dma_buff_size > lpc32xx_return_iram_size()) 1539 pldat->dma_buff_size > lpc32xx_return_iram_size())
1520 dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size, 1540 dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size,
1521 pldat->dma_buff_base_v, 1541 pldat->dma_buff_base_v,
@@ -1584,6 +1604,14 @@ static int lpc_eth_drv_resume(struct platform_device *pdev)
1584} 1604}
1585#endif 1605#endif
1586 1606
1607#ifdef CONFIG_OF
1608static const struct of_device_id lpc_eth_match[] = {
1609 { .compatible = "nxp,lpc-eth" },
1610 { }
1611};
1612MODULE_DEVICE_TABLE(of, lpc_eth_match);
1613#endif
1614
1587static struct platform_driver lpc_eth_driver = { 1615static struct platform_driver lpc_eth_driver = {
1588 .probe = lpc_eth_drv_probe, 1616 .probe = lpc_eth_drv_probe,
1589 .remove = __devexit_p(lpc_eth_drv_remove), 1617 .remove = __devexit_p(lpc_eth_drv_remove),
@@ -1593,6 +1621,7 @@ static struct platform_driver lpc_eth_driver = {
1593#endif 1621#endif
1594 .driver = { 1622 .driver = {
1595 .name = MODNAME, 1623 .name = MODNAME,
1624 .of_match_table = of_match_ptr(lpc_eth_match),
1596 }, 1625 },
1597}; 1626};
1598 1627