Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e51d54d3 authored by Alok Chauhan's avatar Alok Chauhan
Browse files

msm: emac: Add new SGMII controller support



A separate phy initialization function is added to support the new SGMII
controller. This patch introduces the version concept to call HW specific
initialization routines at runtime. The phy version can be specified
through the _DSD/DTS property "phy-version".

Change-Id: I6bce468db0d9934fbbc32b78a4a7ee4ae4b9707e
Signed-off-by: default avatarShanker Donthineni <shankerd@codeaurora.org>
Signed-off-by: default avatarGilad Avidov <gavidov@codeaurora.org>
Signed-off-by: default avatarAlok Chauhan <alokc@codeaurora.org>
parent 7b2cbf75
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -5,4 +5,5 @@
obj-$(CONFIG_QCOM_EMAC) += qcom_emac.o

qcom_emac-objs := emac_main.o emac_hw.o emac_ethtool.o emac_ptp.o
qcom_emac-objs += emac_phy.o emac_rgmii.o emac_sgmii_v1.o
qcom_emac-objs += emac_phy.o emac_rgmii.o
qcom_emac-objs += emac_sgmii.o emac_sgmii_v1.o emac_sgmii_v2.o
+26 −12
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@

char emac_drv_name[] = "qcom_emac";
const char emac_drv_description[] =
			      "Qualcomm Technologies Inc EMAC Ethernet Driver";
			     "Qualcomm Technologies, Inc. EMAC Ethernet Driver";
const char emac_drv_version[] = DRV_VERSION;

#define EMAC_MSG_DEFAULT (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK |  \
@@ -271,8 +271,13 @@ static int emac_acpi_get_properties(struct platform_device *pdev,
		return -EINVAL;
	}

	adpt->no_ephy = emac_device_property_read_bool(dev, "no-ephy");
	adpt->tstamp_en = emac_device_property_read_bool(dev, "tstamp-eble");
	ret = emac_device_property_read_u32(dev, "phy-version",
					    &adpt->hw.phy_version);
	if (ret < 0)
		adpt->hw.phy_version = 0;

	adpt->phy.external = !emac_device_property_read_bool(dev, "no-ephy");
	adpt->tstamp_en = device_property_read_bool(dev, "tstamp-eble");
	ether_addr_copy(adpt->hw.mac_perm_addr, maddr);
	return 0;
}
@@ -285,6 +290,7 @@ static int emac_acpi_get_resources(struct platform_device *pdev,
	struct emac_irq_info *irq_info;
	union acpi_object *obj;
	struct resource *res;
	void __iomem *regmap;
	int i, retval;
	const char duuid[16];
	u16 irq_map[EMAC_NUM_IRQ] = {EMAC_CORE0_IRQ, EMAC_CORE3_IRQ,
@@ -308,10 +314,10 @@ static int emac_acpi_get_resources(struct platform_device *pdev,
	}
	ACPI_FREE(obj);

	emac_dbg(adpt, probe, "MAC Address %pM\n", adpt->hw.mac_perm_addr);
	dev_info(&pdev->dev, "MAC address %pM\n", adpt->hw.mac_perm_addr);

	/* set phy address to zero for internal phy */
	if (adpt->no_ephy)
	if (!adpt->phy.external)
		adpt->hw.phy_addr = 0;

	/* check phy mode */
@@ -321,7 +327,7 @@ static int emac_acpi_get_resources(struct platform_device *pdev,
	}

	/* Assume GPIOs required for MDC/MDIO are enabled in firmware */
	adpt->no_mdio_gpio = true;
	adpt->phy.uses_gpios = true;

	/* get irqs */
	for (i = 0; i < EMAC_NUM_IRQ; i++) {
@@ -360,14 +366,22 @@ static int emac_acpi_get_resources(struct platform_device *pdev,
			return -ENOMEM;
		}

		if (!devm_request_mem_region(&pdev->dev, res->start,
					     resource_size(res), pdev->name)) {
			emac_err(adpt, "can't claim region %pR\n", res);
			return -EBUSY;
		regmap = devm_ioremap(&pdev->dev, res->start,
				      resource_size(res));
		/**
		 * SGMII-v2 controller has two CSRs one per lane digital part
		 * and second one for per lane analog part. The PHY regmap is
		 * compatible to SGMII-v1 controller and will be used in PHY
		 * common code and sgmii_laned regmap referenced in SGMII-v2
		 * specific initialization code.
		 */
		if ((i == EMAC_SGMII_PHY) &&
		    (adpt->hw.phy_version == SGMII_PHY_VERSION_2)) {
			adpt->hw.sgmii_laned = regmap;
			regmap += SGMII_PHY_LN_OFFSET;
		}
		adpt->hw.reg_addr[i] = regmap;

		adpt->hw.reg_addr[i] = devm_ioremap(&pdev->dev, res->start,
						    resource_size(res));
		if (!adpt->hw.reg_addr[i]) {
			emac_err(adpt, "can't ioremap %pR\n", res);
			return -EFAULT;
+10 −0
Original line number Diff line number Diff line
@@ -454,6 +454,7 @@ int emac_phy_config(struct platform_device *pdev, struct emac_adapter *adpt)
		return ret;

	phy->phy_mode = ret;
	/* sgmii v2 is always using ACPI */
	phy->ops = (phy->phy_mode == PHY_INTERFACE_MODE_RGMII) ?
		    emac_rgmii_ops : emac_sgmii_v1_ops;

@@ -564,3 +565,12 @@ int emac_phy_config_fc(struct emac_adapter *adpt)
	wmb();
	return 0;
}

void emac_reg_write_all(void __iomem *base, const struct emac_reg_write *itr,
			size_t size)
{
	size_t i;

	for (i = 0; i < size; ++itr, ++i)
		writel_relaxed(itr->val, base + itr->offset);
}
+10 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ enum emac_flow_ctrl {
 */
struct emac_phy {
	int				phy_mode;
	u32				phy_version;
	bool				external;
	bool				uses_gpios;
	u32				addr;
@@ -82,4 +83,13 @@ int emac_phy_check_link(struct emac_adapter *adpt, u32 *speed, bool *link_up);
int emac_phy_get_lpa_speed(struct emac_adapter *adpt, u32 *speed);
int emac_phy_config_fc(struct emac_adapter *adpt);

struct emac_reg_write {
	ulong		offset;
#define END_MARKER	0xffffffff
	u32		val;
};

void emac_reg_write_all(void __iomem *base, const struct emac_reg_write *itr,
			size_t size);

#endif /* __EMAC_PHY_H__ */
+3 −0
Original line number Diff line number Diff line
@@ -13,6 +13,9 @@
#ifndef __EMAC_REGS_H__
#define __EMAC_REGS_H__

#define SGMII_PHY_VERSION_1 1
#define SGMII_PHY_VERSION_2 2

/* EMAC register offsets */
#define EMAC_DMA_MAS_CTRL                        0x001400
#define EMAC_TIMER_INIT_VALUE                    0x001404
Loading