xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun // Copyright (c) 2018-19, Linaro Limited
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include <linux/module.h>
5*4882a593Smuzhiyun #include <linux/of.h>
6*4882a593Smuzhiyun #include <linux/of_device.h>
7*4882a593Smuzhiyun #include <linux/platform_device.h>
8*4882a593Smuzhiyun #include <linux/phy.h>
9*4882a593Smuzhiyun #include "stmmac.h"
10*4882a593Smuzhiyun #include "stmmac_platform.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #define RGMII_IO_MACRO_CONFIG		0x0
13*4882a593Smuzhiyun #define SDCC_HC_REG_DLL_CONFIG		0x4
14*4882a593Smuzhiyun #define SDCC_HC_REG_DDR_CONFIG		0xC
15*4882a593Smuzhiyun #define SDCC_HC_REG_DLL_CONFIG2		0x10
16*4882a593Smuzhiyun #define SDC4_STATUS			0x14
17*4882a593Smuzhiyun #define SDCC_USR_CTL			0x18
18*4882a593Smuzhiyun #define RGMII_IO_MACRO_CONFIG2		0x1C
19*4882a593Smuzhiyun #define RGMII_IO_MACRO_DEBUG1		0x20
20*4882a593Smuzhiyun #define EMAC_SYSTEM_LOW_POWER_DEBUG	0x28
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun /* RGMII_IO_MACRO_CONFIG fields */
23*4882a593Smuzhiyun #define RGMII_CONFIG_FUNC_CLK_EN		BIT(30)
24*4882a593Smuzhiyun #define RGMII_CONFIG_POS_NEG_DATA_SEL		BIT(23)
25*4882a593Smuzhiyun #define RGMII_CONFIG_GPIO_CFG_RX_INT		GENMASK(21, 20)
26*4882a593Smuzhiyun #define RGMII_CONFIG_GPIO_CFG_TX_INT		GENMASK(19, 17)
27*4882a593Smuzhiyun #define RGMII_CONFIG_MAX_SPD_PRG_9		GENMASK(16, 8)
28*4882a593Smuzhiyun #define RGMII_CONFIG_MAX_SPD_PRG_2		GENMASK(7, 6)
29*4882a593Smuzhiyun #define RGMII_CONFIG_INTF_SEL			GENMASK(5, 4)
30*4882a593Smuzhiyun #define RGMII_CONFIG_BYPASS_TX_ID_EN		BIT(3)
31*4882a593Smuzhiyun #define RGMII_CONFIG_LOOPBACK_EN		BIT(2)
32*4882a593Smuzhiyun #define RGMII_CONFIG_PROG_SWAP			BIT(1)
33*4882a593Smuzhiyun #define RGMII_CONFIG_DDR_MODE			BIT(0)
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /* SDCC_HC_REG_DLL_CONFIG fields */
36*4882a593Smuzhiyun #define SDCC_DLL_CONFIG_DLL_RST			BIT(30)
37*4882a593Smuzhiyun #define SDCC_DLL_CONFIG_PDN			BIT(29)
38*4882a593Smuzhiyun #define SDCC_DLL_CONFIG_MCLK_FREQ		GENMASK(26, 24)
39*4882a593Smuzhiyun #define SDCC_DLL_CONFIG_CDR_SELEXT		GENMASK(23, 20)
40*4882a593Smuzhiyun #define SDCC_DLL_CONFIG_CDR_EXT_EN		BIT(19)
41*4882a593Smuzhiyun #define SDCC_DLL_CONFIG_CK_OUT_EN		BIT(18)
42*4882a593Smuzhiyun #define SDCC_DLL_CONFIG_CDR_EN			BIT(17)
43*4882a593Smuzhiyun #define SDCC_DLL_CONFIG_DLL_EN			BIT(16)
44*4882a593Smuzhiyun #define SDCC_DLL_MCLK_GATING_EN			BIT(5)
45*4882a593Smuzhiyun #define SDCC_DLL_CDR_FINE_PHASE			GENMASK(3, 2)
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun /* SDCC_HC_REG_DDR_CONFIG fields */
48*4882a593Smuzhiyun #define SDCC_DDR_CONFIG_PRG_DLY_EN		BIT(31)
49*4882a593Smuzhiyun #define SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY	GENMASK(26, 21)
50*4882a593Smuzhiyun #define SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE	GENMASK(29, 27)
51*4882a593Smuzhiyun #define SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN	BIT(30)
52*4882a593Smuzhiyun #define SDCC_DDR_CONFIG_PRG_RCLK_DLY		GENMASK(8, 0)
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /* SDCC_HC_REG_DLL_CONFIG2 fields */
55*4882a593Smuzhiyun #define SDCC_DLL_CONFIG2_DLL_CLOCK_DIS		BIT(21)
56*4882a593Smuzhiyun #define SDCC_DLL_CONFIG2_MCLK_FREQ_CALC		GENMASK(17, 10)
57*4882a593Smuzhiyun #define SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SEL	GENMASK(3, 2)
58*4882a593Smuzhiyun #define SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SW	BIT(1)
59*4882a593Smuzhiyun #define SDCC_DLL_CONFIG2_DDR_CAL_EN		BIT(0)
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /* SDC4_STATUS bits */
62*4882a593Smuzhiyun #define SDC4_STATUS_DLL_LOCK			BIT(7)
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun /* RGMII_IO_MACRO_CONFIG2 fields */
65*4882a593Smuzhiyun #define RGMII_CONFIG2_RSVD_CONFIG15		GENMASK(31, 17)
66*4882a593Smuzhiyun #define RGMII_CONFIG2_RGMII_CLK_SEL_CFG		BIT(16)
67*4882a593Smuzhiyun #define RGMII_CONFIG2_TX_TO_RX_LOOPBACK_EN	BIT(13)
68*4882a593Smuzhiyun #define RGMII_CONFIG2_CLK_DIVIDE_SEL		BIT(12)
69*4882a593Smuzhiyun #define RGMII_CONFIG2_RX_PROG_SWAP		BIT(7)
70*4882a593Smuzhiyun #define RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL	BIT(6)
71*4882a593Smuzhiyun #define RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN	BIT(5)
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun struct ethqos_emac_por {
74*4882a593Smuzhiyun 	unsigned int offset;
75*4882a593Smuzhiyun 	unsigned int value;
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun struct ethqos_emac_driver_data {
79*4882a593Smuzhiyun 	const struct ethqos_emac_por *por;
80*4882a593Smuzhiyun 	unsigned int num_por;
81*4882a593Smuzhiyun };
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun struct qcom_ethqos {
84*4882a593Smuzhiyun 	struct platform_device *pdev;
85*4882a593Smuzhiyun 	void __iomem *rgmii_base;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	unsigned int rgmii_clk_rate;
88*4882a593Smuzhiyun 	struct clk *rgmii_clk;
89*4882a593Smuzhiyun 	unsigned int speed;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	const struct ethqos_emac_por *por;
92*4882a593Smuzhiyun 	unsigned int num_por;
93*4882a593Smuzhiyun };
94*4882a593Smuzhiyun 
rgmii_readl(struct qcom_ethqos * ethqos,unsigned int offset)95*4882a593Smuzhiyun static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun 	return readl(ethqos->rgmii_base + offset);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
rgmii_writel(struct qcom_ethqos * ethqos,int value,unsigned int offset)100*4882a593Smuzhiyun static void rgmii_writel(struct qcom_ethqos *ethqos,
101*4882a593Smuzhiyun 			 int value, unsigned int offset)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun 	writel(value, ethqos->rgmii_base + offset);
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun 
rgmii_updatel(struct qcom_ethqos * ethqos,int mask,int val,unsigned int offset)106*4882a593Smuzhiyun static void rgmii_updatel(struct qcom_ethqos *ethqos,
107*4882a593Smuzhiyun 			  int mask, int val, unsigned int offset)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun 	unsigned int temp;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	temp =  rgmii_readl(ethqos, offset);
112*4882a593Smuzhiyun 	temp = (temp & ~(mask)) | val;
113*4882a593Smuzhiyun 	rgmii_writel(ethqos, temp, offset);
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun 
rgmii_dump(struct qcom_ethqos * ethqos)116*4882a593Smuzhiyun static void rgmii_dump(struct qcom_ethqos *ethqos)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun 	dev_dbg(&ethqos->pdev->dev, "Rgmii register dump\n");
119*4882a593Smuzhiyun 	dev_dbg(&ethqos->pdev->dev, "RGMII_IO_MACRO_CONFIG: %x\n",
120*4882a593Smuzhiyun 		rgmii_readl(ethqos, RGMII_IO_MACRO_CONFIG));
121*4882a593Smuzhiyun 	dev_dbg(&ethqos->pdev->dev, "SDCC_HC_REG_DLL_CONFIG: %x\n",
122*4882a593Smuzhiyun 		rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG));
123*4882a593Smuzhiyun 	dev_dbg(&ethqos->pdev->dev, "SDCC_HC_REG_DDR_CONFIG: %x\n",
124*4882a593Smuzhiyun 		rgmii_readl(ethqos, SDCC_HC_REG_DDR_CONFIG));
125*4882a593Smuzhiyun 	dev_dbg(&ethqos->pdev->dev, "SDCC_HC_REG_DLL_CONFIG2: %x\n",
126*4882a593Smuzhiyun 		rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG2));
127*4882a593Smuzhiyun 	dev_dbg(&ethqos->pdev->dev, "SDC4_STATUS: %x\n",
128*4882a593Smuzhiyun 		rgmii_readl(ethqos, SDC4_STATUS));
129*4882a593Smuzhiyun 	dev_dbg(&ethqos->pdev->dev, "SDCC_USR_CTL: %x\n",
130*4882a593Smuzhiyun 		rgmii_readl(ethqos, SDCC_USR_CTL));
131*4882a593Smuzhiyun 	dev_dbg(&ethqos->pdev->dev, "RGMII_IO_MACRO_CONFIG2: %x\n",
132*4882a593Smuzhiyun 		rgmii_readl(ethqos, RGMII_IO_MACRO_CONFIG2));
133*4882a593Smuzhiyun 	dev_dbg(&ethqos->pdev->dev, "RGMII_IO_MACRO_DEBUG1: %x\n",
134*4882a593Smuzhiyun 		rgmii_readl(ethqos, RGMII_IO_MACRO_DEBUG1));
135*4882a593Smuzhiyun 	dev_dbg(&ethqos->pdev->dev, "EMAC_SYSTEM_LOW_POWER_DEBUG: %x\n",
136*4882a593Smuzhiyun 		rgmii_readl(ethqos, EMAC_SYSTEM_LOW_POWER_DEBUG));
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun /* Clock rates */
140*4882a593Smuzhiyun #define RGMII_1000_NOM_CLK_FREQ			(250 * 1000 * 1000UL)
141*4882a593Smuzhiyun #define RGMII_ID_MODE_100_LOW_SVS_CLK_FREQ	 (50 * 1000 * 1000UL)
142*4882a593Smuzhiyun #define RGMII_ID_MODE_10_LOW_SVS_CLK_FREQ	  (5 * 1000 * 1000UL)
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun static void
ethqos_update_rgmii_clk(struct qcom_ethqos * ethqos,unsigned int speed)145*4882a593Smuzhiyun ethqos_update_rgmii_clk(struct qcom_ethqos *ethqos, unsigned int speed)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	switch (speed) {
148*4882a593Smuzhiyun 	case SPEED_1000:
149*4882a593Smuzhiyun 		ethqos->rgmii_clk_rate =  RGMII_1000_NOM_CLK_FREQ;
150*4882a593Smuzhiyun 		break;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	case SPEED_100:
153*4882a593Smuzhiyun 		ethqos->rgmii_clk_rate =  RGMII_ID_MODE_100_LOW_SVS_CLK_FREQ;
154*4882a593Smuzhiyun 		break;
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	case SPEED_10:
157*4882a593Smuzhiyun 		ethqos->rgmii_clk_rate =  RGMII_ID_MODE_10_LOW_SVS_CLK_FREQ;
158*4882a593Smuzhiyun 		break;
159*4882a593Smuzhiyun 	}
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	clk_set_rate(ethqos->rgmii_clk, ethqos->rgmii_clk_rate);
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun 
ethqos_set_func_clk_en(struct qcom_ethqos * ethqos)164*4882a593Smuzhiyun static void ethqos_set_func_clk_en(struct qcom_ethqos *ethqos)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	rgmii_updatel(ethqos, RGMII_CONFIG_FUNC_CLK_EN,
167*4882a593Smuzhiyun 		      RGMII_CONFIG_FUNC_CLK_EN, RGMII_IO_MACRO_CONFIG);
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun static const struct ethqos_emac_por emac_v2_3_0_por[] = {
171*4882a593Smuzhiyun 	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x00C01343 },
172*4882a593Smuzhiyun 	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642C },
173*4882a593Smuzhiyun 	{ .offset = SDCC_HC_REG_DDR_CONFIG,	.value = 0x00000000 },
174*4882a593Smuzhiyun 	{ .offset = SDCC_HC_REG_DLL_CONFIG2,	.value = 0x00200000 },
175*4882a593Smuzhiyun 	{ .offset = SDCC_USR_CTL,		.value = 0x00010800 },
176*4882a593Smuzhiyun 	{ .offset = RGMII_IO_MACRO_CONFIG2,	.value = 0x00002060 },
177*4882a593Smuzhiyun };
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun static const struct ethqos_emac_driver_data emac_v2_3_0_data = {
180*4882a593Smuzhiyun 	.por = emac_v2_3_0_por,
181*4882a593Smuzhiyun 	.num_por = ARRAY_SIZE(emac_v2_3_0_por),
182*4882a593Smuzhiyun };
183*4882a593Smuzhiyun 
ethqos_dll_configure(struct qcom_ethqos * ethqos)184*4882a593Smuzhiyun static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun 	unsigned int val;
187*4882a593Smuzhiyun 	int retry = 1000;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	/* Set CDR_EN */
190*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CDR_EN,
191*4882a593Smuzhiyun 		      SDCC_DLL_CONFIG_CDR_EN, SDCC_HC_REG_DLL_CONFIG);
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	/* Set CDR_EXT_EN */
194*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CDR_EXT_EN,
195*4882a593Smuzhiyun 		      SDCC_DLL_CONFIG_CDR_EXT_EN, SDCC_HC_REG_DLL_CONFIG);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	/* Clear CK_OUT_EN */
198*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CK_OUT_EN,
199*4882a593Smuzhiyun 		      0, SDCC_HC_REG_DLL_CONFIG);
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	/* Set DLL_EN */
202*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_DLL_EN,
203*4882a593Smuzhiyun 		      SDCC_DLL_CONFIG_DLL_EN, SDCC_HC_REG_DLL_CONFIG);
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_MCLK_GATING_EN,
206*4882a593Smuzhiyun 		      0, SDCC_HC_REG_DLL_CONFIG);
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CDR_FINE_PHASE,
209*4882a593Smuzhiyun 		      0, SDCC_HC_REG_DLL_CONFIG);
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	/* Wait for CK_OUT_EN clear */
212*4882a593Smuzhiyun 	do {
213*4882a593Smuzhiyun 		val = rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG);
214*4882a593Smuzhiyun 		val &= SDCC_DLL_CONFIG_CK_OUT_EN;
215*4882a593Smuzhiyun 		if (!val)
216*4882a593Smuzhiyun 			break;
217*4882a593Smuzhiyun 		mdelay(1);
218*4882a593Smuzhiyun 		retry--;
219*4882a593Smuzhiyun 	} while (retry > 0);
220*4882a593Smuzhiyun 	if (!retry)
221*4882a593Smuzhiyun 		dev_err(&ethqos->pdev->dev, "Clear CK_OUT_EN timedout\n");
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	/* Set CK_OUT_EN */
224*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CK_OUT_EN,
225*4882a593Smuzhiyun 		      SDCC_DLL_CONFIG_CK_OUT_EN, SDCC_HC_REG_DLL_CONFIG);
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	/* Wait for CK_OUT_EN set */
228*4882a593Smuzhiyun 	retry = 1000;
229*4882a593Smuzhiyun 	do {
230*4882a593Smuzhiyun 		val = rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG);
231*4882a593Smuzhiyun 		val &= SDCC_DLL_CONFIG_CK_OUT_EN;
232*4882a593Smuzhiyun 		if (val)
233*4882a593Smuzhiyun 			break;
234*4882a593Smuzhiyun 		mdelay(1);
235*4882a593Smuzhiyun 		retry--;
236*4882a593Smuzhiyun 	} while (retry > 0);
237*4882a593Smuzhiyun 	if (!retry)
238*4882a593Smuzhiyun 		dev_err(&ethqos->pdev->dev, "Set CK_OUT_EN timedout\n");
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	/* Set DDR_CAL_EN */
241*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_CAL_EN,
242*4882a593Smuzhiyun 		      SDCC_DLL_CONFIG2_DDR_CAL_EN, SDCC_HC_REG_DLL_CONFIG2);
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DLL_CLOCK_DIS,
245*4882a593Smuzhiyun 		      0, SDCC_HC_REG_DLL_CONFIG2);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_MCLK_FREQ_CALC,
248*4882a593Smuzhiyun 		      0x1A << 10, SDCC_HC_REG_DLL_CONFIG2);
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SEL,
251*4882a593Smuzhiyun 		      BIT(2), SDCC_HC_REG_DLL_CONFIG2);
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SW,
254*4882a593Smuzhiyun 		      SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SW,
255*4882a593Smuzhiyun 		      SDCC_HC_REG_DLL_CONFIG2);
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	return 0;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun 
ethqos_rgmii_macro_init(struct qcom_ethqos * ethqos)260*4882a593Smuzhiyun static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun 	/* Disable loopback mode */
263*4882a593Smuzhiyun 	rgmii_updatel(ethqos, RGMII_CONFIG2_TX_TO_RX_LOOPBACK_EN,
264*4882a593Smuzhiyun 		      0, RGMII_IO_MACRO_CONFIG2);
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	/* Select RGMII, write 0 to interface select */
267*4882a593Smuzhiyun 	rgmii_updatel(ethqos, RGMII_CONFIG_INTF_SEL,
268*4882a593Smuzhiyun 		      0, RGMII_IO_MACRO_CONFIG);
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	switch (ethqos->speed) {
271*4882a593Smuzhiyun 	case SPEED_1000:
272*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_DDR_MODE,
273*4882a593Smuzhiyun 			      RGMII_CONFIG_DDR_MODE, RGMII_IO_MACRO_CONFIG);
274*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_BYPASS_TX_ID_EN,
275*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG);
276*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_POS_NEG_DATA_SEL,
277*4882a593Smuzhiyun 			      RGMII_CONFIG_POS_NEG_DATA_SEL,
278*4882a593Smuzhiyun 			      RGMII_IO_MACRO_CONFIG);
279*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_PROG_SWAP,
280*4882a593Smuzhiyun 			      RGMII_CONFIG_PROG_SWAP, RGMII_IO_MACRO_CONFIG);
281*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,
282*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG2);
283*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
284*4882a593Smuzhiyun 			      RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
285*4882a593Smuzhiyun 			      RGMII_IO_MACRO_CONFIG2);
286*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
287*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG2);
288*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
289*4882a593Smuzhiyun 			      RGMII_CONFIG2_RX_PROG_SWAP,
290*4882a593Smuzhiyun 			      RGMII_IO_MACRO_CONFIG2);
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 		/* Set PRG_RCLK_DLY to 57 for 1.8 ns delay */
293*4882a593Smuzhiyun 		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_RCLK_DLY,
294*4882a593Smuzhiyun 			      57, SDCC_HC_REG_DDR_CONFIG);
295*4882a593Smuzhiyun 		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_DLY_EN,
296*4882a593Smuzhiyun 			      SDCC_DDR_CONFIG_PRG_DLY_EN,
297*4882a593Smuzhiyun 			      SDCC_HC_REG_DDR_CONFIG);
298*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
299*4882a593Smuzhiyun 			      RGMII_CONFIG_LOOPBACK_EN, RGMII_IO_MACRO_CONFIG);
300*4882a593Smuzhiyun 		break;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	case SPEED_100:
303*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_DDR_MODE,
304*4882a593Smuzhiyun 			      RGMII_CONFIG_DDR_MODE, RGMII_IO_MACRO_CONFIG);
305*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_BYPASS_TX_ID_EN,
306*4882a593Smuzhiyun 			      RGMII_CONFIG_BYPASS_TX_ID_EN,
307*4882a593Smuzhiyun 			      RGMII_IO_MACRO_CONFIG);
308*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_POS_NEG_DATA_SEL,
309*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG);
310*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_PROG_SWAP,
311*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG);
312*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,
313*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG2);
314*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
315*4882a593Smuzhiyun 			      RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
316*4882a593Smuzhiyun 			      RGMII_IO_MACRO_CONFIG2);
317*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_2,
318*4882a593Smuzhiyun 			      BIT(6), RGMII_IO_MACRO_CONFIG);
319*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
320*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG2);
321*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
322*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG2);
323*4882a593Smuzhiyun 		/* Write 0x5 to PRG_RCLK_DLY_CODE */
324*4882a593Smuzhiyun 		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
325*4882a593Smuzhiyun 			      (BIT(29) | BIT(27)), SDCC_HC_REG_DDR_CONFIG);
326*4882a593Smuzhiyun 		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,
327*4882a593Smuzhiyun 			      SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,
328*4882a593Smuzhiyun 			      SDCC_HC_REG_DDR_CONFIG);
329*4882a593Smuzhiyun 		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
330*4882a593Smuzhiyun 			      SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
331*4882a593Smuzhiyun 			      SDCC_HC_REG_DDR_CONFIG);
332*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
333*4882a593Smuzhiyun 			      RGMII_CONFIG_LOOPBACK_EN, RGMII_IO_MACRO_CONFIG);
334*4882a593Smuzhiyun 		break;
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	case SPEED_10:
337*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_DDR_MODE,
338*4882a593Smuzhiyun 			      RGMII_CONFIG_DDR_MODE, RGMII_IO_MACRO_CONFIG);
339*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_BYPASS_TX_ID_EN,
340*4882a593Smuzhiyun 			      RGMII_CONFIG_BYPASS_TX_ID_EN,
341*4882a593Smuzhiyun 			      RGMII_IO_MACRO_CONFIG);
342*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_POS_NEG_DATA_SEL,
343*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG);
344*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_PROG_SWAP,
345*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG);
346*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,
347*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG2);
348*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
349*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG2);
350*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_9,
351*4882a593Smuzhiyun 			      BIT(12) | GENMASK(9, 8),
352*4882a593Smuzhiyun 			      RGMII_IO_MACRO_CONFIG);
353*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
354*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG2);
355*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
356*4882a593Smuzhiyun 			      0, RGMII_IO_MACRO_CONFIG2);
357*4882a593Smuzhiyun 		/* Write 0x5 to PRG_RCLK_DLY_CODE */
358*4882a593Smuzhiyun 		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
359*4882a593Smuzhiyun 			      (BIT(29) | BIT(27)), SDCC_HC_REG_DDR_CONFIG);
360*4882a593Smuzhiyun 		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,
361*4882a593Smuzhiyun 			      SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY,
362*4882a593Smuzhiyun 			      SDCC_HC_REG_DDR_CONFIG);
363*4882a593Smuzhiyun 		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
364*4882a593Smuzhiyun 			      SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
365*4882a593Smuzhiyun 			      SDCC_HC_REG_DDR_CONFIG);
366*4882a593Smuzhiyun 		rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
367*4882a593Smuzhiyun 			      RGMII_CONFIG_LOOPBACK_EN, RGMII_IO_MACRO_CONFIG);
368*4882a593Smuzhiyun 		break;
369*4882a593Smuzhiyun 	default:
370*4882a593Smuzhiyun 		dev_err(&ethqos->pdev->dev,
371*4882a593Smuzhiyun 			"Invalid speed %d\n", ethqos->speed);
372*4882a593Smuzhiyun 		return -EINVAL;
373*4882a593Smuzhiyun 	}
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	return 0;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun 
ethqos_configure(struct qcom_ethqos * ethqos)378*4882a593Smuzhiyun static int ethqos_configure(struct qcom_ethqos *ethqos)
379*4882a593Smuzhiyun {
380*4882a593Smuzhiyun 	volatile unsigned int dll_lock;
381*4882a593Smuzhiyun 	unsigned int i, retry = 1000;
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	/* Reset to POR values and enable clk */
384*4882a593Smuzhiyun 	for (i = 0; i < ethqos->num_por; i++)
385*4882a593Smuzhiyun 		rgmii_writel(ethqos, ethqos->por[i].value,
386*4882a593Smuzhiyun 			     ethqos->por[i].offset);
387*4882a593Smuzhiyun 	ethqos_set_func_clk_en(ethqos);
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	/* Initialize the DLL first */
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	/* Set DLL_RST */
392*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_DLL_RST,
393*4882a593Smuzhiyun 		      SDCC_DLL_CONFIG_DLL_RST, SDCC_HC_REG_DLL_CONFIG);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	/* Set PDN */
396*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_PDN,
397*4882a593Smuzhiyun 		      SDCC_DLL_CONFIG_PDN, SDCC_HC_REG_DLL_CONFIG);
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 	/* Clear DLL_RST */
400*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_DLL_RST, 0,
401*4882a593Smuzhiyun 		      SDCC_HC_REG_DLL_CONFIG);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	/* Clear PDN */
404*4882a593Smuzhiyun 	rgmii_updatel(ethqos, SDCC_DLL_CONFIG_PDN, 0,
405*4882a593Smuzhiyun 		      SDCC_HC_REG_DLL_CONFIG);
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	if (ethqos->speed != SPEED_100 && ethqos->speed != SPEED_10) {
408*4882a593Smuzhiyun 		/* Set DLL_EN */
409*4882a593Smuzhiyun 		rgmii_updatel(ethqos, SDCC_DLL_CONFIG_DLL_EN,
410*4882a593Smuzhiyun 			      SDCC_DLL_CONFIG_DLL_EN, SDCC_HC_REG_DLL_CONFIG);
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 		/* Set CK_OUT_EN */
413*4882a593Smuzhiyun 		rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CK_OUT_EN,
414*4882a593Smuzhiyun 			      SDCC_DLL_CONFIG_CK_OUT_EN,
415*4882a593Smuzhiyun 			      SDCC_HC_REG_DLL_CONFIG);
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 		/* Set USR_CTL bit 26 with mask of 3 bits */
418*4882a593Smuzhiyun 		rgmii_updatel(ethqos, GENMASK(26, 24), BIT(26), SDCC_USR_CTL);
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun 		/* wait for DLL LOCK */
421*4882a593Smuzhiyun 		do {
422*4882a593Smuzhiyun 			mdelay(1);
423*4882a593Smuzhiyun 			dll_lock = rgmii_readl(ethqos, SDC4_STATUS);
424*4882a593Smuzhiyun 			if (dll_lock & SDC4_STATUS_DLL_LOCK)
425*4882a593Smuzhiyun 				break;
426*4882a593Smuzhiyun 			retry--;
427*4882a593Smuzhiyun 		} while (retry > 0);
428*4882a593Smuzhiyun 		if (!retry)
429*4882a593Smuzhiyun 			dev_err(&ethqos->pdev->dev,
430*4882a593Smuzhiyun 				"Timeout while waiting for DLL lock\n");
431*4882a593Smuzhiyun 	}
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	if (ethqos->speed == SPEED_1000)
434*4882a593Smuzhiyun 		ethqos_dll_configure(ethqos);
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	ethqos_rgmii_macro_init(ethqos);
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	return 0;
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun 
ethqos_fix_mac_speed(void * priv,unsigned int speed)441*4882a593Smuzhiyun static void ethqos_fix_mac_speed(void *priv, unsigned int speed)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun 	struct qcom_ethqos *ethqos = priv;
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	ethqos->speed = speed;
446*4882a593Smuzhiyun 	ethqos_update_rgmii_clk(ethqos, speed);
447*4882a593Smuzhiyun 	ethqos_configure(ethqos);
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun 
qcom_ethqos_probe(struct platform_device * pdev)450*4882a593Smuzhiyun static int qcom_ethqos_probe(struct platform_device *pdev)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun 	struct device_node *np = pdev->dev.of_node;
453*4882a593Smuzhiyun 	struct plat_stmmacenet_data *plat_dat;
454*4882a593Smuzhiyun 	struct stmmac_resources stmmac_res;
455*4882a593Smuzhiyun 	const struct ethqos_emac_driver_data *data;
456*4882a593Smuzhiyun 	struct qcom_ethqos *ethqos;
457*4882a593Smuzhiyun 	struct resource *res;
458*4882a593Smuzhiyun 	int ret;
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
461*4882a593Smuzhiyun 	if (ret)
462*4882a593Smuzhiyun 		return ret;
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
465*4882a593Smuzhiyun 	if (IS_ERR(plat_dat)) {
466*4882a593Smuzhiyun 		dev_err(&pdev->dev, "dt configuration failed\n");
467*4882a593Smuzhiyun 		return PTR_ERR(plat_dat);
468*4882a593Smuzhiyun 	}
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	ethqos = devm_kzalloc(&pdev->dev, sizeof(*ethqos), GFP_KERNEL);
471*4882a593Smuzhiyun 	if (!ethqos) {
472*4882a593Smuzhiyun 		ret = -ENOMEM;
473*4882a593Smuzhiyun 		goto err_mem;
474*4882a593Smuzhiyun 	}
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun 	ethqos->pdev = pdev;
477*4882a593Smuzhiyun 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rgmii");
478*4882a593Smuzhiyun 	ethqos->rgmii_base = devm_ioremap_resource(&pdev->dev, res);
479*4882a593Smuzhiyun 	if (IS_ERR(ethqos->rgmii_base)) {
480*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Can't get rgmii base\n");
481*4882a593Smuzhiyun 		ret = PTR_ERR(ethqos->rgmii_base);
482*4882a593Smuzhiyun 		goto err_mem;
483*4882a593Smuzhiyun 	}
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	data = of_device_get_match_data(&pdev->dev);
486*4882a593Smuzhiyun 	ethqos->por = data->por;
487*4882a593Smuzhiyun 	ethqos->num_por = data->num_por;
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 	ethqos->rgmii_clk = devm_clk_get(&pdev->dev, "rgmii");
490*4882a593Smuzhiyun 	if (IS_ERR(ethqos->rgmii_clk)) {
491*4882a593Smuzhiyun 		ret = PTR_ERR(ethqos->rgmii_clk);
492*4882a593Smuzhiyun 		goto err_mem;
493*4882a593Smuzhiyun 	}
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	ret = clk_prepare_enable(ethqos->rgmii_clk);
496*4882a593Smuzhiyun 	if (ret)
497*4882a593Smuzhiyun 		goto err_mem;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	ethqos->speed = SPEED_1000;
500*4882a593Smuzhiyun 	ethqos_update_rgmii_clk(ethqos, SPEED_1000);
501*4882a593Smuzhiyun 	ethqos_set_func_clk_en(ethqos);
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	plat_dat->bsp_priv = ethqos;
504*4882a593Smuzhiyun 	plat_dat->fix_mac_speed = ethqos_fix_mac_speed;
505*4882a593Smuzhiyun 	plat_dat->has_gmac4 = 1;
506*4882a593Smuzhiyun 	plat_dat->pmt = 1;
507*4882a593Smuzhiyun 	plat_dat->tso_en = of_property_read_bool(np, "snps,tso");
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
510*4882a593Smuzhiyun 	if (ret)
511*4882a593Smuzhiyun 		goto err_clk;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	rgmii_dump(ethqos);
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	return ret;
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun err_clk:
518*4882a593Smuzhiyun 	clk_disable_unprepare(ethqos->rgmii_clk);
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun err_mem:
521*4882a593Smuzhiyun 	stmmac_remove_config_dt(pdev, plat_dat);
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	return ret;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun 
qcom_ethqos_remove(struct platform_device * pdev)526*4882a593Smuzhiyun static int qcom_ethqos_remove(struct platform_device *pdev)
527*4882a593Smuzhiyun {
528*4882a593Smuzhiyun 	struct qcom_ethqos *ethqos;
529*4882a593Smuzhiyun 	int ret;
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	ethqos = get_stmmac_bsp_priv(&pdev->dev);
532*4882a593Smuzhiyun 	if (!ethqos)
533*4882a593Smuzhiyun 		return -ENODEV;
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	ret = stmmac_pltfr_remove(pdev);
536*4882a593Smuzhiyun 	clk_disable_unprepare(ethqos->rgmii_clk);
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	return ret;
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun static const struct of_device_id qcom_ethqos_match[] = {
542*4882a593Smuzhiyun 	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_data},
543*4882a593Smuzhiyun 	{ }
544*4882a593Smuzhiyun };
545*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, qcom_ethqos_match);
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun static struct platform_driver qcom_ethqos_driver = {
548*4882a593Smuzhiyun 	.probe  = qcom_ethqos_probe,
549*4882a593Smuzhiyun 	.remove = qcom_ethqos_remove,
550*4882a593Smuzhiyun 	.driver = {
551*4882a593Smuzhiyun 		.name           = "qcom-ethqos",
552*4882a593Smuzhiyun 		.pm		= &stmmac_pltfr_pm_ops,
553*4882a593Smuzhiyun 		.of_match_table = of_match_ptr(qcom_ethqos_match),
554*4882a593Smuzhiyun 	},
555*4882a593Smuzhiyun };
556*4882a593Smuzhiyun module_platform_driver(qcom_ethqos_driver);
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun MODULE_DESCRIPTION("Qualcomm ETHQOS driver");
559*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
560