xref: /linux/drivers/net/ethernet/ibm/emac/zmii.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
29aa32835SJeff Kirsher /*
33396c782SPaul Gortmaker  * drivers/net/ethernet/ibm/emac/zmii.c
49aa32835SJeff Kirsher  *
59aa32835SJeff Kirsher  * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
69aa32835SJeff Kirsher  *
79aa32835SJeff Kirsher  * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
89aa32835SJeff Kirsher  *                <benh@kernel.crashing.org>
99aa32835SJeff Kirsher  *
109aa32835SJeff Kirsher  * Based on the arch/ppc version of the driver:
119aa32835SJeff Kirsher  *
129aa32835SJeff Kirsher  * Copyright (c) 2004, 2005 Zultys Technologies.
139aa32835SJeff Kirsher  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
149aa32835SJeff Kirsher  *
159aa32835SJeff Kirsher  * Based on original work by
169aa32835SJeff Kirsher  *      Armin Kuster <akuster@mvista.com>
179aa32835SJeff Kirsher  * 	Copyright 2001 MontaVista Softare Inc.
189aa32835SJeff Kirsher  */
199aa32835SJeff Kirsher #include <linux/slab.h>
209aa32835SJeff Kirsher #include <linux/kernel.h>
219aa32835SJeff Kirsher #include <linux/ethtool.h>
223d40aed8SRob Herring #include <linux/mod_devicetable.h>
235af50730SRob Herring #include <linux/of_address.h>
243d40aed8SRob Herring #include <linux/platform_device.h>
259aa32835SJeff Kirsher #include <asm/io.h>
269aa32835SJeff Kirsher 
279aa32835SJeff Kirsher #include "emac.h"
289aa32835SJeff Kirsher #include "core.h"
299aa32835SJeff Kirsher 
309aa32835SJeff Kirsher /* ZMIIx_FER */
319aa32835SJeff Kirsher #define ZMII_FER_MDI(idx)	(0x80000000 >> ((idx) * 4))
329aa32835SJeff Kirsher #define ZMII_FER_MDI_ALL	(ZMII_FER_MDI(0) | ZMII_FER_MDI(1) | \
339aa32835SJeff Kirsher 				 ZMII_FER_MDI(2) | ZMII_FER_MDI(3))
349aa32835SJeff Kirsher 
359aa32835SJeff Kirsher #define ZMII_FER_SMII(idx)	(0x40000000 >> ((idx) * 4))
369aa32835SJeff Kirsher #define ZMII_FER_RMII(idx)	(0x20000000 >> ((idx) * 4))
379aa32835SJeff Kirsher #define ZMII_FER_MII(idx)	(0x10000000 >> ((idx) * 4))
389aa32835SJeff Kirsher 
399aa32835SJeff Kirsher /* ZMIIx_SSR */
409aa32835SJeff Kirsher #define ZMII_SSR_SCI(idx)	(0x40000000 >> ((idx) * 4))
419aa32835SJeff Kirsher #define ZMII_SSR_FSS(idx)	(0x20000000 >> ((idx) * 4))
429aa32835SJeff Kirsher #define ZMII_SSR_SP(idx)	(0x10000000 >> ((idx) * 4))
439aa32835SJeff Kirsher 
449aa32835SJeff Kirsher /* ZMII only supports MII, RMII and SMII
459aa32835SJeff Kirsher  * we also support autodetection for backward compatibility
469aa32835SJeff Kirsher  */
zmii_valid_mode(int mode)479aa32835SJeff Kirsher static inline int zmii_valid_mode(int mode)
489aa32835SJeff Kirsher {
4978b69921SChristian Lamparter 	return  mode == PHY_INTERFACE_MODE_MII ||
5078b69921SChristian Lamparter 		mode == PHY_INTERFACE_MODE_RMII ||
5178b69921SChristian Lamparter 		mode == PHY_INTERFACE_MODE_SMII ||
5278b69921SChristian Lamparter 		mode == PHY_INTERFACE_MODE_NA;
539aa32835SJeff Kirsher }
549aa32835SJeff Kirsher 
zmii_mode_name(int mode)559aa32835SJeff Kirsher static inline const char *zmii_mode_name(int mode)
569aa32835SJeff Kirsher {
579aa32835SJeff Kirsher 	switch (mode) {
5878b69921SChristian Lamparter 	case PHY_INTERFACE_MODE_MII:
599aa32835SJeff Kirsher 		return "MII";
6078b69921SChristian Lamparter 	case PHY_INTERFACE_MODE_RMII:
619aa32835SJeff Kirsher 		return "RMII";
6278b69921SChristian Lamparter 	case PHY_INTERFACE_MODE_SMII:
639aa32835SJeff Kirsher 		return "SMII";
649aa32835SJeff Kirsher 	default:
659aa32835SJeff Kirsher 		BUG();
669aa32835SJeff Kirsher 	}
679aa32835SJeff Kirsher }
689aa32835SJeff Kirsher 
zmii_mode_mask(int mode,int input)699aa32835SJeff Kirsher static inline u32 zmii_mode_mask(int mode, int input)
709aa32835SJeff Kirsher {
719aa32835SJeff Kirsher 	switch (mode) {
7278b69921SChristian Lamparter 	case PHY_INTERFACE_MODE_MII:
739aa32835SJeff Kirsher 		return ZMII_FER_MII(input);
7478b69921SChristian Lamparter 	case PHY_INTERFACE_MODE_RMII:
759aa32835SJeff Kirsher 		return ZMII_FER_RMII(input);
7678b69921SChristian Lamparter 	case PHY_INTERFACE_MODE_SMII:
779aa32835SJeff Kirsher 		return ZMII_FER_SMII(input);
789aa32835SJeff Kirsher 	default:
799aa32835SJeff Kirsher 		return 0;
809aa32835SJeff Kirsher 	}
819aa32835SJeff Kirsher }
829aa32835SJeff Kirsher 
zmii_attach(struct platform_device * ofdev,int input,phy_interface_t * mode)83f9218617SAndrew Lunn int zmii_attach(struct platform_device *ofdev, int input,
84f9218617SAndrew Lunn 		phy_interface_t *mode)
859aa32835SJeff Kirsher {
868513fbd8SJingoo Han 	struct zmii_instance *dev = platform_get_drvdata(ofdev);
879aa32835SJeff Kirsher 	struct zmii_regs __iomem *p = dev->base;
889aa32835SJeff Kirsher 
899aa32835SJeff Kirsher 	ZMII_DBG(dev, "init(%d, %d)" NL, input, *mode);
909aa32835SJeff Kirsher 
919aa32835SJeff Kirsher 	if (!zmii_valid_mode(*mode)) {
929aa32835SJeff Kirsher 		/* Probably an EMAC connected to RGMII,
939aa32835SJeff Kirsher 		 * but it still may need ZMII for MDIO so
949aa32835SJeff Kirsher 		 * we don't fail here.
959aa32835SJeff Kirsher 		 */
969aa32835SJeff Kirsher 		dev->users++;
979aa32835SJeff Kirsher 		return 0;
989aa32835SJeff Kirsher 	}
999aa32835SJeff Kirsher 
1009aa32835SJeff Kirsher 	mutex_lock(&dev->lock);
1019aa32835SJeff Kirsher 
1029aa32835SJeff Kirsher 	/* Autodetect ZMII mode if not specified.
1039aa32835SJeff Kirsher 	 * This is only for backward compatibility with the old driver.
1049aa32835SJeff Kirsher 	 * Please, always specify PHY mode in your board port to avoid
1059aa32835SJeff Kirsher 	 * any surprises.
1069aa32835SJeff Kirsher 	 */
10778b69921SChristian Lamparter 	if (dev->mode == PHY_INTERFACE_MODE_NA) {
10878b69921SChristian Lamparter 		if (*mode == PHY_INTERFACE_MODE_NA) {
1099aa32835SJeff Kirsher 			u32 r = dev->fer_save;
1109aa32835SJeff Kirsher 
1119aa32835SJeff Kirsher 			ZMII_DBG(dev, "autodetecting mode, FER = 0x%08x" NL, r);
1129aa32835SJeff Kirsher 
1139aa32835SJeff Kirsher 			if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1)))
11478b69921SChristian Lamparter 				dev->mode = PHY_INTERFACE_MODE_MII;
1159aa32835SJeff Kirsher 			else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1)))
11678b69921SChristian Lamparter 				dev->mode = PHY_INTERFACE_MODE_RMII;
1179aa32835SJeff Kirsher 			else
11878b69921SChristian Lamparter 				dev->mode = PHY_INTERFACE_MODE_SMII;
11978b69921SChristian Lamparter 		} else {
1209aa32835SJeff Kirsher 			dev->mode = *mode;
12178b69921SChristian Lamparter 		}
122f7ce9103SRob Herring 		printk(KERN_NOTICE "%pOF: bridge in %s mode\n",
123f7ce9103SRob Herring 		       ofdev->dev.of_node,
1249aa32835SJeff Kirsher 		       zmii_mode_name(dev->mode));
1259aa32835SJeff Kirsher 	} else {
1269aa32835SJeff Kirsher 		/* All inputs must use the same mode */
12778b69921SChristian Lamparter 		if (*mode != PHY_INTERFACE_MODE_NA && *mode != dev->mode) {
1289aa32835SJeff Kirsher 			printk(KERN_ERR
129f7ce9103SRob Herring 			       "%pOF: invalid mode %d specified for input %d\n",
130f7ce9103SRob Herring 			       ofdev->dev.of_node, *mode, input);
1319aa32835SJeff Kirsher 			mutex_unlock(&dev->lock);
1329aa32835SJeff Kirsher 			return -EINVAL;
1339aa32835SJeff Kirsher 		}
1349aa32835SJeff Kirsher 	}
1359aa32835SJeff Kirsher 
1369aa32835SJeff Kirsher 	/* Report back correct PHY mode,
1379aa32835SJeff Kirsher 	 * it may be used during PHY initialization.
1389aa32835SJeff Kirsher 	 */
1399aa32835SJeff Kirsher 	*mode = dev->mode;
1409aa32835SJeff Kirsher 
1419aa32835SJeff Kirsher 	/* Enable this input */
1429aa32835SJeff Kirsher 	out_be32(&p->fer, in_be32(&p->fer) | zmii_mode_mask(dev->mode, input));
1439aa32835SJeff Kirsher 	++dev->users;
1449aa32835SJeff Kirsher 
1459aa32835SJeff Kirsher 	mutex_unlock(&dev->lock);
1469aa32835SJeff Kirsher 
1479aa32835SJeff Kirsher 	return 0;
1489aa32835SJeff Kirsher }
1499aa32835SJeff Kirsher 
zmii_get_mdio(struct platform_device * ofdev,int input)1509aa32835SJeff Kirsher void zmii_get_mdio(struct platform_device *ofdev, int input)
1519aa32835SJeff Kirsher {
1528513fbd8SJingoo Han 	struct zmii_instance *dev = platform_get_drvdata(ofdev);
1539aa32835SJeff Kirsher 	u32 fer;
1549aa32835SJeff Kirsher 
1559aa32835SJeff Kirsher 	ZMII_DBG2(dev, "get_mdio(%d)" NL, input);
1569aa32835SJeff Kirsher 
1579aa32835SJeff Kirsher 	mutex_lock(&dev->lock);
1589aa32835SJeff Kirsher 
1599aa32835SJeff Kirsher 	fer = in_be32(&dev->base->fer) & ~ZMII_FER_MDI_ALL;
1609aa32835SJeff Kirsher 	out_be32(&dev->base->fer, fer | ZMII_FER_MDI(input));
1619aa32835SJeff Kirsher }
1629aa32835SJeff Kirsher 
zmii_put_mdio(struct platform_device * ofdev,int input)1639aa32835SJeff Kirsher void zmii_put_mdio(struct platform_device *ofdev, int input)
1649aa32835SJeff Kirsher {
1658513fbd8SJingoo Han 	struct zmii_instance *dev = platform_get_drvdata(ofdev);
1669aa32835SJeff Kirsher 
1679aa32835SJeff Kirsher 	ZMII_DBG2(dev, "put_mdio(%d)" NL, input);
1689aa32835SJeff Kirsher 	mutex_unlock(&dev->lock);
1699aa32835SJeff Kirsher }
1709aa32835SJeff Kirsher 
1719aa32835SJeff Kirsher 
zmii_set_speed(struct platform_device * ofdev,int input,int speed)1729aa32835SJeff Kirsher void zmii_set_speed(struct platform_device *ofdev, int input, int speed)
1739aa32835SJeff Kirsher {
1748513fbd8SJingoo Han 	struct zmii_instance *dev = platform_get_drvdata(ofdev);
1759aa32835SJeff Kirsher 	u32 ssr;
1769aa32835SJeff Kirsher 
1779aa32835SJeff Kirsher 	mutex_lock(&dev->lock);
1789aa32835SJeff Kirsher 
1799aa32835SJeff Kirsher 	ssr = in_be32(&dev->base->ssr);
1809aa32835SJeff Kirsher 
1819aa32835SJeff Kirsher 	ZMII_DBG(dev, "speed(%d, %d)" NL, input, speed);
1829aa32835SJeff Kirsher 
1839aa32835SJeff Kirsher 	if (speed == SPEED_100)
1849aa32835SJeff Kirsher 		ssr |= ZMII_SSR_SP(input);
1859aa32835SJeff Kirsher 	else
1869aa32835SJeff Kirsher 		ssr &= ~ZMII_SSR_SP(input);
1879aa32835SJeff Kirsher 
1889aa32835SJeff Kirsher 	out_be32(&dev->base->ssr, ssr);
1899aa32835SJeff Kirsher 
1909aa32835SJeff Kirsher 	mutex_unlock(&dev->lock);
1919aa32835SJeff Kirsher }
1929aa32835SJeff Kirsher 
zmii_detach(struct platform_device * ofdev,int input)1939aa32835SJeff Kirsher void zmii_detach(struct platform_device *ofdev, int input)
1949aa32835SJeff Kirsher {
1958513fbd8SJingoo Han 	struct zmii_instance *dev = platform_get_drvdata(ofdev);
1969aa32835SJeff Kirsher 
1979aa32835SJeff Kirsher 	BUG_ON(!dev || dev->users == 0);
1989aa32835SJeff Kirsher 
1999aa32835SJeff Kirsher 	mutex_lock(&dev->lock);
2009aa32835SJeff Kirsher 
2019aa32835SJeff Kirsher 	ZMII_DBG(dev, "detach(%d)" NL, input);
2029aa32835SJeff Kirsher 
2039aa32835SJeff Kirsher 	/* Disable this input */
2049aa32835SJeff Kirsher 	out_be32(&dev->base->fer,
2059aa32835SJeff Kirsher 		 in_be32(&dev->base->fer) & ~zmii_mode_mask(dev->mode, input));
2069aa32835SJeff Kirsher 
2079aa32835SJeff Kirsher 	--dev->users;
2089aa32835SJeff Kirsher 
2099aa32835SJeff Kirsher 	mutex_unlock(&dev->lock);
2109aa32835SJeff Kirsher }
2119aa32835SJeff Kirsher 
zmii_get_regs_len(struct platform_device * ofdev)2129aa32835SJeff Kirsher int zmii_get_regs_len(struct platform_device *ofdev)
2139aa32835SJeff Kirsher {
2149aa32835SJeff Kirsher 	return sizeof(struct emac_ethtool_regs_subhdr) +
2159aa32835SJeff Kirsher 		sizeof(struct zmii_regs);
2169aa32835SJeff Kirsher }
2179aa32835SJeff Kirsher 
zmii_dump_regs(struct platform_device * ofdev,void * buf)2189aa32835SJeff Kirsher void *zmii_dump_regs(struct platform_device *ofdev, void *buf)
2199aa32835SJeff Kirsher {
2208513fbd8SJingoo Han 	struct zmii_instance *dev = platform_get_drvdata(ofdev);
2219aa32835SJeff Kirsher 	struct emac_ethtool_regs_subhdr *hdr = buf;
2229aa32835SJeff Kirsher 	struct zmii_regs *regs = (struct zmii_regs *)(hdr + 1);
2239aa32835SJeff Kirsher 
2249aa32835SJeff Kirsher 	hdr->version = 0;
2259aa32835SJeff Kirsher 	hdr->index = 0; /* for now, are there chips with more than one
2269aa32835SJeff Kirsher 			 * zmii ? if yes, then we'll add a cell_index
2279aa32835SJeff Kirsher 			 * like we do for emac
2289aa32835SJeff Kirsher 			 */
2299aa32835SJeff Kirsher 	memcpy_fromio(regs, dev->base, sizeof(struct zmii_regs));
2309aa32835SJeff Kirsher 	return regs + 1;
2319aa32835SJeff Kirsher }
2329aa32835SJeff Kirsher 
zmii_probe(struct platform_device * ofdev)233fe17dc1eSBill Pemberton static int zmii_probe(struct platform_device *ofdev)
2349aa32835SJeff Kirsher {
2359aa32835SJeff Kirsher 	struct device_node *np = ofdev->dev.of_node;
2369aa32835SJeff Kirsher 	struct zmii_instance *dev;
2379aa32835SJeff Kirsher 	struct resource regs;
2389aa32835SJeff Kirsher 	int rc;
2399aa32835SJeff Kirsher 
2409aa32835SJeff Kirsher 	rc = -ENOMEM;
2419aa32835SJeff Kirsher 	dev = kzalloc(sizeof(struct zmii_instance), GFP_KERNEL);
242e404decbSJoe Perches 	if (dev == NULL)
2439aa32835SJeff Kirsher 		goto err_gone;
2449aa32835SJeff Kirsher 
2459aa32835SJeff Kirsher 	mutex_init(&dev->lock);
2469aa32835SJeff Kirsher 	dev->ofdev = ofdev;
24778b69921SChristian Lamparter 	dev->mode = PHY_INTERFACE_MODE_NA;
2489aa32835SJeff Kirsher 
2499aa32835SJeff Kirsher 	rc = -ENXIO;
2509aa32835SJeff Kirsher 	if (of_address_to_resource(np, 0, &regs)) {
251f7ce9103SRob Herring 		printk(KERN_ERR "%pOF: Can't get registers address\n", np);
2529aa32835SJeff Kirsher 		goto err_free;
2539aa32835SJeff Kirsher 	}
2549aa32835SJeff Kirsher 
2559aa32835SJeff Kirsher 	rc = -ENOMEM;
2569aa32835SJeff Kirsher 	dev->base = (struct zmii_regs __iomem *)ioremap(regs.start,
2579aa32835SJeff Kirsher 						sizeof(struct zmii_regs));
2589aa32835SJeff Kirsher 	if (dev->base == NULL) {
259f7ce9103SRob Herring 		printk(KERN_ERR "%pOF: Can't map device registers!\n", np);
2609aa32835SJeff Kirsher 		goto err_free;
2619aa32835SJeff Kirsher 	}
2629aa32835SJeff Kirsher 
2639aa32835SJeff Kirsher 	/* We may need FER value for autodetection later */
2649aa32835SJeff Kirsher 	dev->fer_save = in_be32(&dev->base->fer);
2659aa32835SJeff Kirsher 
2669aa32835SJeff Kirsher 	/* Disable all inputs by default */
2679aa32835SJeff Kirsher 	out_be32(&dev->base->fer, 0);
2689aa32835SJeff Kirsher 
269f7ce9103SRob Herring 	printk(KERN_INFO "ZMII %pOF initialized\n", ofdev->dev.of_node);
2709aa32835SJeff Kirsher 	wmb();
2718513fbd8SJingoo Han 	platform_set_drvdata(ofdev, dev);
2729aa32835SJeff Kirsher 
2739aa32835SJeff Kirsher 	return 0;
2749aa32835SJeff Kirsher 
2759aa32835SJeff Kirsher  err_free:
2769aa32835SJeff Kirsher 	kfree(dev);
2779aa32835SJeff Kirsher  err_gone:
2789aa32835SJeff Kirsher 	return rc;
2799aa32835SJeff Kirsher }
2809aa32835SJeff Kirsher 
zmii_remove(struct platform_device * ofdev)281*ac35a3c4SUwe Kleine-König static void zmii_remove(struct platform_device *ofdev)
2829aa32835SJeff Kirsher {
2838513fbd8SJingoo Han 	struct zmii_instance *dev = platform_get_drvdata(ofdev);
2849aa32835SJeff Kirsher 
2859aa32835SJeff Kirsher 	WARN_ON(dev->users != 0);
2869aa32835SJeff Kirsher 
2879aa32835SJeff Kirsher 	iounmap(dev->base);
2889aa32835SJeff Kirsher 	kfree(dev);
2899aa32835SJeff Kirsher }
2909aa32835SJeff Kirsher 
29147b61667SFabian Frederick static const struct of_device_id zmii_match[] =
2929aa32835SJeff Kirsher {
2939aa32835SJeff Kirsher 	{
2949aa32835SJeff Kirsher 		.compatible	= "ibm,zmii",
2959aa32835SJeff Kirsher 	},
2969aa32835SJeff Kirsher 	/* For backward compat with old DT */
2979aa32835SJeff Kirsher 	{
2989aa32835SJeff Kirsher 		.type		= "emac-zmii",
2999aa32835SJeff Kirsher 	},
3009aa32835SJeff Kirsher 	{},
3019aa32835SJeff Kirsher };
3029aa32835SJeff Kirsher 
3039aa32835SJeff Kirsher static struct platform_driver zmii_driver = {
3049aa32835SJeff Kirsher 	.driver = {
3059aa32835SJeff Kirsher 		.name = "emac-zmii",
3069aa32835SJeff Kirsher 		.of_match_table = zmii_match,
3079aa32835SJeff Kirsher 	},
3089aa32835SJeff Kirsher 	.probe = zmii_probe,
309*ac35a3c4SUwe Kleine-König 	.remove_new = zmii_remove,
3109aa32835SJeff Kirsher };
3119aa32835SJeff Kirsher 
zmii_init(void)3129aa32835SJeff Kirsher int __init zmii_init(void)
3139aa32835SJeff Kirsher {
3149aa32835SJeff Kirsher 	return platform_driver_register(&zmii_driver);
3159aa32835SJeff Kirsher }
3169aa32835SJeff Kirsher 
zmii_exit(void)3179aa32835SJeff Kirsher void zmii_exit(void)
3189aa32835SJeff Kirsher {
3199aa32835SJeff Kirsher 	platform_driver_unregister(&zmii_driver);
3209aa32835SJeff Kirsher }
321