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

Commit 3da15711 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: emac: Implement PHYLIB framework support"

parents 73cc4d84 be2ce377
Loading
Loading
Loading
Loading
+108 −53
Original line number Diff line number Diff line
Qualcomm MSM Ethernet Controller (EMAC)
Qualcomm Technologies EMAC Gigabit Ethernet Controller

This network controller consists of two devices: a MAC and an
internal PHY (SGMII/RGMII). Each device is represented by a device tree node.
A phandle connects the MAC node to its corresponding internal phy node.
Another phandle points to the external PHY node.

Required properties:
- cell-index : EMAC controller instance number.

MAC node:
- compatible : Should be "qcom,mdm9607-emac" for mdm9607 based EMAC driver
	       Should be "qcom,emac" for other targets based EMAC driver

- reg : Offset and length of the register regions for the device
- reg-names : Register region names referenced in 'reg' above.
	Required register resource entries are:
@@ -13,9 +18,7 @@ Required properties:
	Optional register resource entries are:
	"emac_1588"      : EMAC 1588 (PTP) register block.
			   Required if 'qcom,emac-tstamp-en' is present.
	"emac_sgmii" : EMAC SGMII PHY register block.
		       Required if 'phy-mode' is "sgmii".
- interrupts : Interrupt numbers used by this controller
- interrupts : Interrupt number used by this controller
- interrupt-names : Interrupt resource names referenced in 'interrupts' above.
	Required interrupt resource entries are:
	"emac_core0_irq" : EMAC core0 interrupt.
@@ -23,36 +26,38 @@ Required properties:
	"emac_core2_irq" : EMAC core2 interrupt.
	"emac_core3_irq" : EMAC core3 interrupt.
	Optional interrupt resource entries are:
	"emac_sgmii_irq" : EMAC SGMII interrupt.
			   Required if 'phy-mode' is "sgmii".
	"emac_wol_irq"   : EMAC Wake-On-LAN (WOL) interrupt.
			   Required if WOL is supported.
- qcom,emac-gpio-mdc  : GPIO pin number of the MDC line of MDIO bus.
- qcom,emac-gpio-mdio : GPIO pin number of the MDIO line of MDIO bus.
- phy-mode: String, operation mode of the PHY interface. See ethernet.txt in the
	same directory.
- phy-addr : Specifies phy address on MDIO bus.
	      Required if the optional property "qcom,no-external-phy"
	      is not specified.
- phy-channel : Phy address for internal phy in ACPI mode.
- phy-mode : Specifies PHY type being used (eg., "sgmii", "rgmii", "gmii" etc).
	     For "sgmii", the "emac_sgmii" register base and
	     "emac_sgmii_irq" interrupt must be specified.
- internal-phy : phandle to the internal PHY node
- phy-handle : phandle the the external PHY node

Internal PHY node:
- compatible : Should be "qcom,mdm9607-emac-sgmii" for mdm9607.
	       Should be "qcom,qdf2432-emac-sgmii" for QDF2432
	       Should be "qcom,fsm9900-emac-sgmii" for FSM9900
- reg : Offset and length of the register region(s) for the device
- reg-names : Register region names referenced in 'reg' above.
	"emac_sgmii" : EMAC SGMII PHY register block.
		       Required if 'phy-mode' is "sgmii".
- interrupts : Interrupt number used by this controller
- interrupt-names : Interrupt resource names referenced in 'interrupts' above.
	"emac_sgmii_irq" : EMAC SGMII interrupt.
			   Required if 'phy-mode' is "sgmii".

The external phy child node:
- reg : The phy address

Optional properties:

MAC node:
- qcom,emac-tstamp-en : Enables the PTP (1588) timestamping feature.
		        Include this only if PTP (1588) timestamping
			feature is needed. If included, "emac_1588" register
			base should be specified.
- local-mac-address : The 6-byte MAC address.
		      This field is optional. If present, it is only a
		      placeholder for the MAC address. The correct MAC
		      address is populated in device tree during platform
		      initialization.
- mac-address : 6- bytes MAC address in ACPI mode.
		This field is optional. If present, it is only a placeholder
		for the MAC address. The correct MAC address is populated in
		device tree during platform initialization.
- mac-address : The 6-byte MAC address. If present, it is the default
	MAC address.
- qcom,no-external-phy : Indicates there is no external PHY connected to EMAC.
			 Include this only if the EMAC is directly connected to
			 the peer end without EPHY.
@@ -66,7 +71,6 @@ Optional properties:
			     table entry, the first field indicates the RTC
			     reference clock rate. The second field indicates
			     the number of adjustment in 2 ^ -26 ns.
- no-ephy : Specifies in case there is no external phy present in ACPI mode.
- tstamp-eble : Enables the PTP (1588) timestamping feature in ACPI mode.
- <supply-name>-supply: phandle to the regulator device tree node
			Required "supply-name" are "emac_vreg*"
@@ -74,45 +78,81 @@ Optional properties:
        values (max voltage value for supply 1/2/3/4/5) where each value
	represents a voltage in microvolts.

Example1:
	emac0: qcom,emac@feb20000 {
		cell-index = <0>;
		compatible = "qcom,emac";
		reg-names = "emac", "emac_csr", "emac_1588", "emac_sgmii";

Example:

FSM9900:

soc {
	#address-cells = <1>;
	#size-cells = <1>;

	emac0: ethernet@feb20000 {
		compatible = "qcom,fsm9900-emac";
		reg-names = "emac", "emac_csr", "emac_1588";
		reg = <0xfeb20000 0x10000>,
		      <0xfeb36000 0x1000>,
		      <0xfeb3c000 0x4000>,
		      <0xfeb13800 0x400>;
		interrupts = <0 76 0>, <0 77 0>, <0 78 0>, <0 79 0>;
		interrupt-names = "emac_core0_irq", "emac_core1_irq",
				  "emac_core2_irq", "emac_core3_irq";
		qcom,emac-gpio-mdc = <&msmgpio 123 0>;
		qcom,emac-gpio-mdio = <&msmgpio 124 0>;
		qcom,emac-tstamp-en;
		phy-mode = "sgmii";
		phy-addr = <0>;

		clocks = <&gcc 0>, <&gcc 1>, <&gcc 3>, <&gcc 4>, <&gcc 5>,
			<&gcc 6>, <&gcc 7>;
		clock-names = "axi_clk", "cfg_ahb_clk", "high_speed_clk",
			"mdio_clk", "tx_clk", "rx_clk", "sys_clk";

		internal-phy = <&emac_sgmii>;

		phy-handle = <&phy0>;

		#address-cells = <1>;
		#size-cells = <0>;
		phy0: ethernet-phy@0 {
			reg = <0>;
		};

		pinctrl-names = "default";
		pinctrl-0 = <&mdio_pins_a>;
	};

	emac_sgmii: ethernet@feb38000 {
		compatible = "qcom,fsm9900-emac-sgmii";
		reg-names = "emac_sgmii";
		reg = <0xfeb38000 0x1000>;
		interrupts = <80>;
	};

Example2:
	tlmm: pinctrl@fd510000 {
		compatible = "qcom,fsm9900-pinctrl";

		mdio_pins_a: mdio {
			state {
				pins = "gpio123", "gpio124";
				function = "mdio";
			};
		};
	};


MDM9607:

        emac0: qcom,emac@7c40000 {
                cell-index = <0>;
                compatible = "qcom,mdm9607-emac";
                reg-names = "emac", "emac_csr", "emac_1588", "emac_sgmii";
                reg-names = "emac", "emac_csr", "emac_1588";
                reg = <0x7c40000 0x10000>,
                        <0x7c56000 0x1000>,
                        <0x7c5C000 0x4000>,
                        <0x7c58000 0x400>;
                        <0x7c5c000 0x4000>;

                #address-cells = <0>;
                interrupt-parent = <&emac0>;
                #interrupt-cells = <1>;
                interrupts = <0 1 2>;
                interrupts = <0 1>;
                interrupt-map-mask = <0xffffffff>;
                interrupt-map = <0 &intc 0 76 0
                                1 &intc 0 80 0
                                2 &tlmm_pinmux 30 0x8>;
                interrupt-names = "emac_core0_irq",
                                "emac_sgmii_irq",
                                "emac_wol_irq";
                                1 &tlmm_pinmux 30 0x8>;
                interrupt-names = "emac_core0_irq", "emac_wol_irq";

                emac_vreg1-supply = <&mdm9607_l1>;
                emac_vreg2-supply = <&mdm9607_l3>;
                emac_vreg3-supply = <&mdm9607_l5>;
@@ -126,8 +166,13 @@ Example2:
                         <&clock_gcc clk_gcc_emac_0_tx_clk>,
                         <&clock_gcc clk_gcc_emac_0_rx_clk>,
                         <&clock_gcc clk_gcc_emac_0_sys_clk>;
                clock-names = "axi_clk", "cfg_ahb_clk", "125m_clk",
                        "25m_clk", "tx_clk", "rx_clk", "sys_clk";
                clock-names = "axi_clk", "cfg_ahb_clk", "high_speed_clk",
                        "mdio_clk", "tx_clk", "rx_clk", "sys_clk";

                internal-phy = <&emac_sgmii>;
                phy-handle = <&phy0>;
                phy-mode = "sgmii";

                pinctrl-names = "emac_mdio_active", "emac_mdio_sleep",
                        "emac_ephy_active", "emac_ephy_sleep";
                pinctrl-0 = <&emac0_mdio_active>;
@@ -136,7 +181,17 @@ Example2:
                pinctrl-3 = <&emac0_ephy_sleep>;
                qcom,emac-tstamp-en;
                qcom,emac-ptp-frac-ns-adj = <125000000 1>;
                phy-mode = "sgmii";
                phy-addr = <0>;
                status = "disable";

                phy0: ethernet-phy@0 {
                        reg = <0>;
                };
        };

        emac_sgmii: ethernet@7c58000 {
                compatible = "qcom,mdm9607-emac-sgmii";
                reg-names = "emac_sgmii";
                reg = <0x7c58000 0x400>;
                interrupt-names = "emac_sgmii_irq";
                interrupts = <0 80 0>;
        };
+27 −14
Original line number Diff line number Diff line
@@ -1572,24 +1572,21 @@
	};

	emac0: qcom,emac@7c40000 {
		cell-index = <0>;
		compatible = "qcom,mdm9607-emac";
		reg-names = "emac", "emac_csr", "emac_1588", "emac_sgmii";
		reg-names = "emac", "emac_csr", "emac_1588";
		reg = <0x7c40000 0x10000>,
			<0x7c56000 0x1000>,
			<0x7c5C000 0x4000>,
			<0x7c58000 0x400>;
			<0x7c5c000 0x4000>;

		#address-cells = <0>;
		interrupt-parent = <&emac0>;
		#interrupt-cells = <1>;
		interrupts = <0 1 2>;
		interrupts = <0 1>;
		interrupt-map-mask = <0xffffffff>;
		interrupt-map = <0 &intc 0 76 0
				1 &intc 0 80 0
				2 &tlmm_pinmux 30 0x8>;
		interrupt-names = "emac_core0_irq",
				"emac_sgmii_irq",
				"emac_wol_irq";
				1 &tlmm_pinmux 30 0x8>;
		interrupt-names = "emac_core0_irq", "emac_wol_irq";

		emac_vreg1-supply = <&mdm9607_l1>;
		emac_vreg2-supply = <&mdm9607_l3>;
		emac_vreg3-supply = <&mdm9607_l5>;
@@ -1603,8 +1600,13 @@
			 <&clock_gcc clk_gcc_emac_0_tx_clk>,
			 <&clock_gcc clk_gcc_emac_0_rx_clk>,
			 <&clock_gcc clk_gcc_emac_0_sys_clk>;
		clock-names = "axi_clk", "cfg_ahb_clk", "125m_clk",
			"25m_clk", "tx_clk", "rx_clk", "sys_clk";
		clock-names = "axi_clk", "cfg_ahb_clk", "high_speed_clk",
			"mdio_clk", "tx_clk", "rx_clk", "sys_clk";

		internal-phy = <&emac_sgmii>;
		phy-handle = <&phy0>;
		phy-mode = "sgmii";

		pinctrl-names = "emac_mdio_active", "emac_mdio_sleep",
			"emac_ephy_active", "emac_ephy_sleep";
		pinctrl-0 = <&emac0_mdio_active>;
@@ -1613,10 +1615,21 @@
		pinctrl-3 = <&emac0_ephy_sleep>;
		qcom,emac-tstamp-en;
		qcom,emac-ptp-frac-ns-adj = <125000000 1>;
		phy-mode = "sgmii";
		phy-addr = <0>;
		status = "disable";

		phy0: ethernet-phy@0 {
			reg = <0>;
		};
	};

	emac_sgmii: ethernet@7c58000 {
		compatible = "qcom,mdm9607-emac-sgmii";
		reg-names = "emac_sgmii";
		reg = <0x7c58000 0x400>;
		interrupt-names = "emac_sgmii_irq";
		interrupts = <0 80 0>;
	};

	pps {
		compatible = "pps-gpio";
		pinctrl-names = "default";
+9 −3
Original line number Diff line number Diff line
@@ -28,10 +28,16 @@ config QCA7000

config QCOM_EMAC
	tristate "Qualcomm Technologies, Inc. EMAC Gigabit Ethernet support"
	default n
	depends on HAS_DMA && HAS_IOMEM
	select CRC32
	select PHYLIB
	select OF_MDIO
	---help---
	  This driver supports the Qualcomm Technologies, Inc. EMAC Gigabit
	  Ethernet controller.
	  This driver supports the Qualcomm Technologies, Inc. Gigabit
          Ethernet Media Access Controller (EMAC). The controller
          supports IEEE 802.3-2002, half-duplex mode at 10/100 Mb/s,
          full-duplex mode at 10/100/1000Mb/s, Wake On LAN (WOL) for
          low power, Receive-Side Scaling (RSS), and IEEE 1588-2008
          Precision Clock Synchronization Protocol.

endif # NET_VENDOR_QUALCOMM
+1 −2
Original line number Diff line number Diff line
@@ -5,5 +5,4 @@
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
qcom_emac-objs += emac_sgmii.o emac_sgmii_v1.o emac_sgmii_v2.o
qcom_emac-objs += emac_phy.o emac_rgmii.o emac_sgmii.o
+19 −28
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/wakelock.h>

#include "emac_phy.h"

/* Device IDs */
@@ -44,6 +45,8 @@
/* mdio/mdc gpios */
#define EMAC_GPIO_CNT		2

#define EMAC_ADPT_RESET_WAIT_TIME	20

enum emac_vreg_id {
	EMAC_VREG1,
	EMAC_VREG2,
@@ -56,8 +59,8 @@ enum emac_vreg_id {
enum emac_clk_id {
	EMAC_CLK_AXI,
	EMAC_CLK_CFG_AHB,
	EMAC_CLK_125M,
	EMAC_CLK_SYS_25M,
	EMAC_CLK_HIGH_SPEED,
	EMAC_CLK_MDIO,
	EMAC_CLK_TX,
	EMAC_CLK_RX,
	EMAC_CLK_SYS,
@@ -108,12 +111,6 @@ enum emac_dma_order {
	emac_dma_ord_out = 4
};

enum emac_mac_speed {
	emac_mac_speed_0 = 0,
	emac_mac_speed_10_100 = 1,
	emac_mac_speed_1000 = 2
};

enum emac_dma_req_block {
	emac_dma_req_128 = 0,
	emac_dma_req_256 = 1,
@@ -189,6 +186,8 @@ struct emac_hw_stats {
	u64 tx_bcast_byte;      /* broadcast packets byte count (without FCS) */
	u64 tx_mcast_byte;      /* multicast packets byte count (without FCS) */
	u64 tx_col;             /* collisions */

	spinlock_t lock;	/* prevent multiple simultaneous readers */
};

enum emac_hw_flags {
@@ -233,11 +232,6 @@ struct emac_hw {
	enum emac_dma_req_block   dmaw_block;
	enum emac_dma_order       dma_order;

	/* MAC parameter */
	u8      mac_addr[ETH_ALEN];
	u8      mac_perm_addr[ETH_ALEN];
	u32     mtu;

	/* RSS parameter */
	u8      rss_hstype;
	u8      rss_base_cpu;
@@ -678,6 +672,12 @@ struct emac_tx_queue {
/* driver private data structure */
struct emac_adapter {
	struct net_device		*netdev;
	struct mii_bus			*mii_bus;
	struct phy_device		*phydev;
	struct emac_phy			phy;
	struct emac_hw			hw;
	struct emac_hw_stats		hw_stats;
	int irq_status;

	struct emac_irq_per_dev		irq[EMAC_IRQ_CNT];
	unsigned int			gpio[EMAC_GPIO_CNT];
@@ -703,10 +703,6 @@ struct emac_adapter {

	u32 rxbuf_size;

	struct emac_phy phy;
	struct emac_hw hw;
	struct emac_hw_stats hw_stats;

	/* tx timestamping queue */
	struct sk_buff_head         hwtxtstamp_pending_queue;
	struct sk_buff_head         hwtxtstamp_ready_queue;
@@ -714,7 +710,7 @@ struct emac_adapter {
	spinlock_t                  hwtxtstamp_lock; /* lock for hwtxtstamp */
	struct emac_tx_tstamp_stats hwtxtstamp_stats;

	struct work_struct emac_task;
	struct work_struct work_thread;
	struct timer_list  emac_timer;
	unsigned long	link_jiffies;

@@ -730,9 +726,6 @@ struct emac_adapter {
	int	(*gpio_on)(struct emac_adapter *adpt, bool mdio, bool ephy);
	int	(*gpio_off)(struct emac_adapter *adpt, bool mdio, bool ephy);
	struct wakeup_source link_wlock;
	bool		runtime_enable;
	bool		is_wol_enabled;
	spinlock_t	wol_irq_lock; /* lock for wol irq gpio enablement */
};

static inline struct emac_adapter *emac_hw_get_adap(struct emac_hw *hw)
@@ -753,18 +746,16 @@ struct emac_adapter *emac_irq_get_adpt(struct emac_irq_per_dev *irq)
}

/* default to trying for four seconds */
#define EMAC_TRY_LINK_TIMEOUT     (4 * HZ)
#define EMAC_TRY_LINK_TIMEOUT     (4 * 1000)

#define EMAC_HW_CTRL_RESET_MAC         0x00000001

extern char emac_drv_name[];
extern const char emac_drv_version[];
void emac_set_ethtool_ops(struct net_device *netdev);
void emac_reinit_locked(struct emac_adapter *adpt);
int emac_reinit_locked(struct emac_adapter *adpt);
void emac_update_hw_stats(struct emac_adapter *adpt);
int emac_resize_rings(struct net_device *netdev);
int emac_up(struct emac_adapter *adpt);
void emac_down(struct emac_adapter *adpt, u32 ctrl);
int emac_mac_up(struct emac_adapter *adpt);
void emac_mac_down(struct emac_adapter *adpt, u32 ctrl);
int emac_clk_set_rate(struct emac_adapter *adpt, enum emac_clk_id id,
		      enum emac_clk_rate rate);
void emac_task_schedule(struct emac_adapter *adpt);
Loading