xref: /OK3568_Linux_fs/kernel/drivers/usb/host/xhci-pci-renesas.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* Copyright (C) 2019-2020 Linaro Limited */
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #include <linux/acpi.h>
5*4882a593Smuzhiyun #include <linux/firmware.h>
6*4882a593Smuzhiyun #include <linux/module.h>
7*4882a593Smuzhiyun #include <linux/pci.h>
8*4882a593Smuzhiyun #include <linux/slab.h>
9*4882a593Smuzhiyun #include <asm/unaligned.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include "xhci.h"
12*4882a593Smuzhiyun #include "xhci-trace.h"
13*4882a593Smuzhiyun #include "xhci-pci.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #define RENESAS_FW_VERSION				0x6C
16*4882a593Smuzhiyun #define RENESAS_ROM_CONFIG				0xF0
17*4882a593Smuzhiyun #define RENESAS_FW_STATUS				0xF4
18*4882a593Smuzhiyun #define RENESAS_FW_STATUS_MSB				0xF5
19*4882a593Smuzhiyun #define RENESAS_ROM_STATUS				0xF6
20*4882a593Smuzhiyun #define RENESAS_ROM_STATUS_MSB				0xF7
21*4882a593Smuzhiyun #define RENESAS_DATA0					0xF8
22*4882a593Smuzhiyun #define RENESAS_DATA1					0xFC
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #define RENESAS_FW_VERSION_FIELD			GENMASK(23, 7)
25*4882a593Smuzhiyun #define RENESAS_FW_VERSION_OFFSET			8
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define RENESAS_FW_STATUS_DOWNLOAD_ENABLE		BIT(0)
28*4882a593Smuzhiyun #define RENESAS_FW_STATUS_LOCK				BIT(1)
29*4882a593Smuzhiyun #define RENESAS_FW_STATUS_RESULT			GENMASK(6, 4)
30*4882a593Smuzhiyun   #define RENESAS_FW_STATUS_INVALID			0
31*4882a593Smuzhiyun   #define RENESAS_FW_STATUS_SUCCESS			BIT(4)
32*4882a593Smuzhiyun   #define RENESAS_FW_STATUS_ERROR			BIT(5)
33*4882a593Smuzhiyun #define RENESAS_FW_STATUS_SET_DATA0			BIT(8)
34*4882a593Smuzhiyun #define RENESAS_FW_STATUS_SET_DATA1			BIT(9)
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #define RENESAS_ROM_STATUS_ACCESS			BIT(0)
37*4882a593Smuzhiyun #define RENESAS_ROM_STATUS_ERASE			BIT(1)
38*4882a593Smuzhiyun #define RENESAS_ROM_STATUS_RELOAD			BIT(2)
39*4882a593Smuzhiyun #define RENESAS_ROM_STATUS_RESULT			GENMASK(6, 4)
40*4882a593Smuzhiyun   #define RENESAS_ROM_STATUS_NO_RESULT			0
41*4882a593Smuzhiyun   #define RENESAS_ROM_STATUS_SUCCESS			BIT(4)
42*4882a593Smuzhiyun   #define RENESAS_ROM_STATUS_ERROR			BIT(5)
43*4882a593Smuzhiyun #define RENESAS_ROM_STATUS_SET_DATA0			BIT(8)
44*4882a593Smuzhiyun #define RENESAS_ROM_STATUS_SET_DATA1			BIT(9)
45*4882a593Smuzhiyun #define RENESAS_ROM_STATUS_ROM_EXISTS			BIT(15)
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun #define RENESAS_ROM_ERASE_MAGIC				0x5A65726F
48*4882a593Smuzhiyun #define RENESAS_ROM_WRITE_MAGIC				0x53524F4D
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #define RENESAS_RETRY	10000
51*4882a593Smuzhiyun #define RENESAS_DELAY	10
52*4882a593Smuzhiyun 
renesas_fw_download_image(struct pci_dev * dev,const u32 * fw,size_t step,bool rom)53*4882a593Smuzhiyun static int renesas_fw_download_image(struct pci_dev *dev,
54*4882a593Smuzhiyun 				     const u32 *fw, size_t step, bool rom)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun 	size_t i;
57*4882a593Smuzhiyun 	int err;
58*4882a593Smuzhiyun 	u8 fw_status;
59*4882a593Smuzhiyun 	bool data0_or_data1;
60*4882a593Smuzhiyun 	u32 status_reg;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	if (rom)
63*4882a593Smuzhiyun 		status_reg = RENESAS_ROM_STATUS_MSB;
64*4882a593Smuzhiyun 	else
65*4882a593Smuzhiyun 		status_reg = RENESAS_FW_STATUS_MSB;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	/*
68*4882a593Smuzhiyun 	 * The hardware does alternate between two 32-bit pages.
69*4882a593Smuzhiyun 	 * (This is because each row of the firmware is 8 bytes).
70*4882a593Smuzhiyun 	 *
71*4882a593Smuzhiyun 	 * for even steps we use DATA0, for odd steps DATA1.
72*4882a593Smuzhiyun 	 */
73*4882a593Smuzhiyun 	data0_or_data1 = (step & 1) == 1;
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	/* step+1. Read "Set DATAX" and confirm it is cleared. */
76*4882a593Smuzhiyun 	for (i = 0; i < RENESAS_RETRY; i++) {
77*4882a593Smuzhiyun 		err = pci_read_config_byte(dev, status_reg, &fw_status);
78*4882a593Smuzhiyun 		if (err) {
79*4882a593Smuzhiyun 			dev_err(&dev->dev, "Read Status failed: %d\n",
80*4882a593Smuzhiyun 				pcibios_err_to_errno(err));
81*4882a593Smuzhiyun 			return pcibios_err_to_errno(err);
82*4882a593Smuzhiyun 		}
83*4882a593Smuzhiyun 		if (!(fw_status & BIT(data0_or_data1)))
84*4882a593Smuzhiyun 			break;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 		udelay(RENESAS_DELAY);
87*4882a593Smuzhiyun 	}
88*4882a593Smuzhiyun 	if (i == RENESAS_RETRY) {
89*4882a593Smuzhiyun 		dev_err(&dev->dev, "Timeout for Set DATAX step: %zd\n", step);
90*4882a593Smuzhiyun 		return -ETIMEDOUT;
91*4882a593Smuzhiyun 	}
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	/*
94*4882a593Smuzhiyun 	 * step+2. Write FW data to "DATAX".
95*4882a593Smuzhiyun 	 * "LSB is left" => force little endian
96*4882a593Smuzhiyun 	 */
97*4882a593Smuzhiyun 	err = pci_write_config_dword(dev, data0_or_data1 ?
98*4882a593Smuzhiyun 				     RENESAS_DATA1 : RENESAS_DATA0,
99*4882a593Smuzhiyun 				     (__force u32)cpu_to_le32(fw[step]));
100*4882a593Smuzhiyun 	if (err) {
101*4882a593Smuzhiyun 		dev_err(&dev->dev, "Write to DATAX failed: %d\n",
102*4882a593Smuzhiyun 			pcibios_err_to_errno(err));
103*4882a593Smuzhiyun 		return pcibios_err_to_errno(err);
104*4882a593Smuzhiyun 	}
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	udelay(100);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	/* step+3. Set "Set DATAX". */
109*4882a593Smuzhiyun 	err = pci_write_config_byte(dev, status_reg, BIT(data0_or_data1));
110*4882a593Smuzhiyun 	if (err) {
111*4882a593Smuzhiyun 		dev_err(&dev->dev, "Write config for DATAX failed: %d\n",
112*4882a593Smuzhiyun 			pcibios_err_to_errno(err));
113*4882a593Smuzhiyun 		return pcibios_err_to_errno(err);
114*4882a593Smuzhiyun 	}
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	return 0;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun 
renesas_fw_verify(const void * fw_data,size_t length)119*4882a593Smuzhiyun static int renesas_fw_verify(const void *fw_data,
120*4882a593Smuzhiyun 			     size_t length)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	u16 fw_version_pointer;
123*4882a593Smuzhiyun 	u16 fw_version;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	/*
126*4882a593Smuzhiyun 	 * The Firmware's Data Format is describe in
127*4882a593Smuzhiyun 	 * "6.3 Data Format" R19UH0078EJ0500 Rev.5.00 page 124
128*4882a593Smuzhiyun 	 */
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	/*
131*4882a593Smuzhiyun 	 * The bootrom chips of the big brother have sizes up to 64k, let's
132*4882a593Smuzhiyun 	 * assume that's the biggest the firmware can get.
133*4882a593Smuzhiyun 	 */
134*4882a593Smuzhiyun 	if (length < 0x1000 || length >= 0x10000) {
135*4882a593Smuzhiyun 		pr_err("firmware is size %zd is not (4k - 64k).",
136*4882a593Smuzhiyun 			length);
137*4882a593Smuzhiyun 		return -EINVAL;
138*4882a593Smuzhiyun 	}
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	/* The First 2 bytes are fixed value (55aa). "LSB on Left" */
141*4882a593Smuzhiyun 	if (get_unaligned_le16(fw_data) != 0x55aa) {
142*4882a593Smuzhiyun 		pr_err("no valid firmware header found.");
143*4882a593Smuzhiyun 		return -EINVAL;
144*4882a593Smuzhiyun 	}
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	/* verify the firmware version position and print it. */
147*4882a593Smuzhiyun 	fw_version_pointer = get_unaligned_le16(fw_data + 4);
148*4882a593Smuzhiyun 	if (fw_version_pointer + 2 >= length) {
149*4882a593Smuzhiyun 		pr_err("fw ver pointer is outside of the firmware image");
150*4882a593Smuzhiyun 		return -EINVAL;
151*4882a593Smuzhiyun 	}
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	fw_version = get_unaligned_le16(fw_data + fw_version_pointer);
154*4882a593Smuzhiyun 	pr_err("got firmware version: %02x.", fw_version);
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	return 0;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun 
renesas_check_rom(struct pci_dev * pdev)159*4882a593Smuzhiyun static bool renesas_check_rom(struct pci_dev *pdev)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun 	u16 rom_status;
162*4882a593Smuzhiyun 	int retval;
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	/* Check if external ROM exists */
165*4882a593Smuzhiyun 	retval = pci_read_config_word(pdev, RENESAS_ROM_STATUS, &rom_status);
166*4882a593Smuzhiyun 	if (retval)
167*4882a593Smuzhiyun 		return false;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	rom_status &= RENESAS_ROM_STATUS_ROM_EXISTS;
170*4882a593Smuzhiyun 	if (rom_status) {
171*4882a593Smuzhiyun 		dev_dbg(&pdev->dev, "External ROM exists\n");
172*4882a593Smuzhiyun 		return true; /* External ROM exists */
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	return false;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun 
renesas_check_rom_state(struct pci_dev * pdev)178*4882a593Smuzhiyun static int renesas_check_rom_state(struct pci_dev *pdev)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun 	u16 rom_state;
181*4882a593Smuzhiyun 	u32 version;
182*4882a593Smuzhiyun 	int err;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	/* check FW version */
185*4882a593Smuzhiyun 	err = pci_read_config_dword(pdev, RENESAS_FW_VERSION, &version);
186*4882a593Smuzhiyun 	if (err)
187*4882a593Smuzhiyun 		return pcibios_err_to_errno(err);
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	version &= RENESAS_FW_VERSION_FIELD;
190*4882a593Smuzhiyun 	version = version >> RENESAS_FW_VERSION_OFFSET;
191*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "Found ROM version: %x\n", version);
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	/*
194*4882a593Smuzhiyun 	 * Test if ROM is present and loaded, if so we can skip everything
195*4882a593Smuzhiyun 	 */
196*4882a593Smuzhiyun 	err = pci_read_config_word(pdev, RENESAS_ROM_STATUS, &rom_state);
197*4882a593Smuzhiyun 	if (err)
198*4882a593Smuzhiyun 		return pcibios_err_to_errno(err);
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	if (rom_state & BIT(15)) {
201*4882a593Smuzhiyun 		/* ROM exists */
202*4882a593Smuzhiyun 		dev_dbg(&pdev->dev, "ROM exists\n");
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 		/* Check the "Result Code" Bits (6:4) and act accordingly */
205*4882a593Smuzhiyun 		switch (rom_state & RENESAS_ROM_STATUS_RESULT) {
206*4882a593Smuzhiyun 		case RENESAS_ROM_STATUS_SUCCESS:
207*4882a593Smuzhiyun 			return 0;
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 		case RENESAS_ROM_STATUS_NO_RESULT: /* No result yet */
210*4882a593Smuzhiyun 			dev_dbg(&pdev->dev, "Unknown ROM status ...\n");
211*4882a593Smuzhiyun 			return -ENOENT;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 		case RENESAS_ROM_STATUS_ERROR: /* Error State */
214*4882a593Smuzhiyun 		default: /* All other states are marked as "Reserved states" */
215*4882a593Smuzhiyun 			dev_err(&pdev->dev, "Invalid ROM..");
216*4882a593Smuzhiyun 			break;
217*4882a593Smuzhiyun 		}
218*4882a593Smuzhiyun 	}
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	return -EIO;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun 
renesas_fw_check_running(struct pci_dev * pdev)223*4882a593Smuzhiyun static int renesas_fw_check_running(struct pci_dev *pdev)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun 	u8 fw_state;
226*4882a593Smuzhiyun 	int err;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	/*
229*4882a593Smuzhiyun 	 * Test if the device is actually needing the firmware. As most
230*4882a593Smuzhiyun 	 * BIOSes will initialize the device for us. If the device is
231*4882a593Smuzhiyun 	 * initialized.
232*4882a593Smuzhiyun 	 */
233*4882a593Smuzhiyun 	err = pci_read_config_byte(pdev, RENESAS_FW_STATUS, &fw_state);
234*4882a593Smuzhiyun 	if (err)
235*4882a593Smuzhiyun 		return pcibios_err_to_errno(err);
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	/*
238*4882a593Smuzhiyun 	 * Check if "FW Download Lock" is locked. If it is and the FW is
239*4882a593Smuzhiyun 	 * ready we can simply continue. If the FW is not ready, we have
240*4882a593Smuzhiyun 	 * to give up.
241*4882a593Smuzhiyun 	 */
242*4882a593Smuzhiyun 	if (fw_state & RENESAS_FW_STATUS_LOCK) {
243*4882a593Smuzhiyun 		dev_dbg(&pdev->dev, "FW Download Lock is engaged.");
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 		if (fw_state & RENESAS_FW_STATUS_SUCCESS)
246*4882a593Smuzhiyun 			return 0;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 		dev_err(&pdev->dev,
249*4882a593Smuzhiyun 			"FW Download Lock is set and FW is not ready. Giving Up.");
250*4882a593Smuzhiyun 		return -EIO;
251*4882a593Smuzhiyun 	}
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	/*
254*4882a593Smuzhiyun 	 * Check if "FW Download Enable" is set. If someone (us?) tampered
255*4882a593Smuzhiyun 	 * with it and it can't be reset, we have to give up too... and
256*4882a593Smuzhiyun 	 * ask for a forgiveness and a reboot.
257*4882a593Smuzhiyun 	 */
258*4882a593Smuzhiyun 	if (fw_state & RENESAS_FW_STATUS_DOWNLOAD_ENABLE) {
259*4882a593Smuzhiyun 		dev_err(&pdev->dev,
260*4882a593Smuzhiyun 			"FW Download Enable is stale. Giving Up (poweroff/reboot needed).");
261*4882a593Smuzhiyun 		return -EIO;
262*4882a593Smuzhiyun 	}
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	/* Otherwise, Check the "Result Code" Bits (6:4) and act accordingly */
265*4882a593Smuzhiyun 	switch (fw_state & RENESAS_FW_STATUS_RESULT) {
266*4882a593Smuzhiyun 	case 0: /* No result yet */
267*4882a593Smuzhiyun 		dev_dbg(&pdev->dev, "FW is not ready/loaded yet.");
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 		/* tell the caller, that this device needs the firmware. */
270*4882a593Smuzhiyun 		return 1;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	case RENESAS_FW_STATUS_SUCCESS: /* Success, device should be working. */
273*4882a593Smuzhiyun 		dev_dbg(&pdev->dev, "FW is ready.");
274*4882a593Smuzhiyun 		return 0;
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	case RENESAS_FW_STATUS_ERROR: /* Error State */
277*4882a593Smuzhiyun 		dev_err(&pdev->dev,
278*4882a593Smuzhiyun 			"hardware is in an error state. Giving up (poweroff/reboot needed).");
279*4882a593Smuzhiyun 		return -ENODEV;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	default: /* All other states are marked as "Reserved states" */
282*4882a593Smuzhiyun 		dev_err(&pdev->dev,
283*4882a593Smuzhiyun 			"hardware is in an invalid state %lx. Giving up (poweroff/reboot needed).",
284*4882a593Smuzhiyun 			(fw_state & RENESAS_FW_STATUS_RESULT) >> 4);
285*4882a593Smuzhiyun 		return -EINVAL;
286*4882a593Smuzhiyun 	}
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun 
renesas_fw_download(struct pci_dev * pdev,const struct firmware * fw)289*4882a593Smuzhiyun static int renesas_fw_download(struct pci_dev *pdev,
290*4882a593Smuzhiyun 			       const struct firmware *fw)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun 	const u32 *fw_data = (const u32 *)fw->data;
293*4882a593Smuzhiyun 	size_t i;
294*4882a593Smuzhiyun 	int err;
295*4882a593Smuzhiyun 	u8 fw_status;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	/*
298*4882a593Smuzhiyun 	 * For more information and the big picture: please look at the
299*4882a593Smuzhiyun 	 * "Firmware Download Sequence" in "7.1 FW Download Interface"
300*4882a593Smuzhiyun 	 * of R19UH0078EJ0500 Rev.5.00 page 131
301*4882a593Smuzhiyun 	 */
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	/*
304*4882a593Smuzhiyun 	 * 0. Set "FW Download Enable" bit in the
305*4882a593Smuzhiyun 	 * "FW Download Control & Status Register" at 0xF4
306*4882a593Smuzhiyun 	 */
307*4882a593Smuzhiyun 	err = pci_write_config_byte(pdev, RENESAS_FW_STATUS,
308*4882a593Smuzhiyun 				    RENESAS_FW_STATUS_DOWNLOAD_ENABLE);
309*4882a593Smuzhiyun 	if (err)
310*4882a593Smuzhiyun 		return pcibios_err_to_errno(err);
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	/* 1 - 10 follow one step after the other. */
313*4882a593Smuzhiyun 	for (i = 0; i < fw->size / 4; i++) {
314*4882a593Smuzhiyun 		err = renesas_fw_download_image(pdev, fw_data, i, false);
315*4882a593Smuzhiyun 		if (err) {
316*4882a593Smuzhiyun 			dev_err(&pdev->dev,
317*4882a593Smuzhiyun 				"Firmware Download Step %zd failed at position %zd bytes with (%d).",
318*4882a593Smuzhiyun 				i, i * 4, err);
319*4882a593Smuzhiyun 			return err;
320*4882a593Smuzhiyun 		}
321*4882a593Smuzhiyun 	}
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	/*
324*4882a593Smuzhiyun 	 * This sequence continues until the last data is written to
325*4882a593Smuzhiyun 	 * "DATA0" or "DATA1". Naturally, we wait until "SET DATA0/1"
326*4882a593Smuzhiyun 	 * is cleared by the hardware beforehand.
327*4882a593Smuzhiyun 	 */
328*4882a593Smuzhiyun 	for (i = 0; i < RENESAS_RETRY; i++) {
329*4882a593Smuzhiyun 		err = pci_read_config_byte(pdev, RENESAS_FW_STATUS_MSB,
330*4882a593Smuzhiyun 					   &fw_status);
331*4882a593Smuzhiyun 		if (err)
332*4882a593Smuzhiyun 			return pcibios_err_to_errno(err);
333*4882a593Smuzhiyun 		if (!(fw_status & (BIT(0) | BIT(1))))
334*4882a593Smuzhiyun 			break;
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 		udelay(RENESAS_DELAY);
337*4882a593Smuzhiyun 	}
338*4882a593Smuzhiyun 	if (i == RENESAS_RETRY)
339*4882a593Smuzhiyun 		dev_warn(&pdev->dev, "Final Firmware Download step timed out.");
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	/*
342*4882a593Smuzhiyun 	 * 11. After finishing writing the last data of FW, the
343*4882a593Smuzhiyun 	 * System Software must clear "FW Download Enable"
344*4882a593Smuzhiyun 	 */
345*4882a593Smuzhiyun 	err = pci_write_config_byte(pdev, RENESAS_FW_STATUS, 0);
346*4882a593Smuzhiyun 	if (err)
347*4882a593Smuzhiyun 		return pcibios_err_to_errno(err);
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	/* 12. Read "Result Code" and confirm it is good. */
350*4882a593Smuzhiyun 	for (i = 0; i < RENESAS_RETRY; i++) {
351*4882a593Smuzhiyun 		err = pci_read_config_byte(pdev, RENESAS_FW_STATUS, &fw_status);
352*4882a593Smuzhiyun 		if (err)
353*4882a593Smuzhiyun 			return pcibios_err_to_errno(err);
354*4882a593Smuzhiyun 		if (fw_status & RENESAS_FW_STATUS_SUCCESS)
355*4882a593Smuzhiyun 			break;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 		udelay(RENESAS_DELAY);
358*4882a593Smuzhiyun 	}
359*4882a593Smuzhiyun 	if (i == RENESAS_RETRY) {
360*4882a593Smuzhiyun 		/* Timed out / Error - let's see if we can fix this */
361*4882a593Smuzhiyun 		err = renesas_fw_check_running(pdev);
362*4882a593Smuzhiyun 		switch (err) {
363*4882a593Smuzhiyun 		case 0: /*
364*4882a593Smuzhiyun 			 * we shouldn't end up here.
365*4882a593Smuzhiyun 			 * maybe it took a little bit longer.
366*4882a593Smuzhiyun 			 * But all should be well?
367*4882a593Smuzhiyun 			 */
368*4882a593Smuzhiyun 			break;
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 		case 1: /* (No result yet! */
371*4882a593Smuzhiyun 			dev_err(&pdev->dev, "FW Load timedout");
372*4882a593Smuzhiyun 			return -ETIMEDOUT;
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 		default:
375*4882a593Smuzhiyun 			return err;
376*4882a593Smuzhiyun 		}
377*4882a593Smuzhiyun 	}
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	return 0;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun 
renesas_rom_erase(struct pci_dev * pdev)382*4882a593Smuzhiyun static void renesas_rom_erase(struct pci_dev *pdev)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun 	int retval, i;
385*4882a593Smuzhiyun 	u8 status;
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "Performing ROM Erase...\n");
388*4882a593Smuzhiyun 	retval = pci_write_config_dword(pdev, RENESAS_DATA0,
389*4882a593Smuzhiyun 					RENESAS_ROM_ERASE_MAGIC);
390*4882a593Smuzhiyun 	if (retval) {
391*4882a593Smuzhiyun 		dev_err(&pdev->dev, "ROM erase, magic word write failed: %d\n",
392*4882a593Smuzhiyun 			pcibios_err_to_errno(retval));
393*4882a593Smuzhiyun 		return;
394*4882a593Smuzhiyun 	}
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 	retval = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status);
397*4882a593Smuzhiyun 	if (retval) {
398*4882a593Smuzhiyun 		dev_err(&pdev->dev, "ROM status read failed: %d\n",
399*4882a593Smuzhiyun 			pcibios_err_to_errno(retval));
400*4882a593Smuzhiyun 		return;
401*4882a593Smuzhiyun 	}
402*4882a593Smuzhiyun 	status |= RENESAS_ROM_STATUS_ERASE;
403*4882a593Smuzhiyun 	retval = pci_write_config_byte(pdev, RENESAS_ROM_STATUS, status);
404*4882a593Smuzhiyun 	if (retval) {
405*4882a593Smuzhiyun 		dev_err(&pdev->dev, "ROM erase set word write failed\n");
406*4882a593Smuzhiyun 		return;
407*4882a593Smuzhiyun 	}
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	/* sleep a bit while ROM is erased */
410*4882a593Smuzhiyun 	msleep(20);
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	for (i = 0; i < RENESAS_RETRY; i++) {
413*4882a593Smuzhiyun 		retval = pci_read_config_byte(pdev, RENESAS_ROM_STATUS,
414*4882a593Smuzhiyun 					      &status);
415*4882a593Smuzhiyun 		status &= RENESAS_ROM_STATUS_ERASE;
416*4882a593Smuzhiyun 		if (!status)
417*4882a593Smuzhiyun 			break;
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 		mdelay(RENESAS_DELAY);
420*4882a593Smuzhiyun 	}
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	if (i == RENESAS_RETRY)
423*4882a593Smuzhiyun 		dev_dbg(&pdev->dev, "Chip erase timedout: %x\n", status);
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "ROM Erase... Done success\n");
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun 
renesas_setup_rom(struct pci_dev * pdev,const struct firmware * fw)428*4882a593Smuzhiyun static bool renesas_setup_rom(struct pci_dev *pdev, const struct firmware *fw)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun 	const u32 *fw_data = (const u32 *)fw->data;
431*4882a593Smuzhiyun 	int err, i;
432*4882a593Smuzhiyun 	u8 status;
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	/* 2. Write magic word to Data0 */
435*4882a593Smuzhiyun 	err = pci_write_config_dword(pdev, RENESAS_DATA0,
436*4882a593Smuzhiyun 				     RENESAS_ROM_WRITE_MAGIC);
437*4882a593Smuzhiyun 	if (err)
438*4882a593Smuzhiyun 		return false;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	/* 3. Set External ROM access */
441*4882a593Smuzhiyun 	err = pci_write_config_byte(pdev, RENESAS_ROM_STATUS,
442*4882a593Smuzhiyun 				    RENESAS_ROM_STATUS_ACCESS);
443*4882a593Smuzhiyun 	if (err)
444*4882a593Smuzhiyun 		goto remove_bypass;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	/* 4. Check the result */
447*4882a593Smuzhiyun 	err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status);
448*4882a593Smuzhiyun 	if (err)
449*4882a593Smuzhiyun 		goto remove_bypass;
450*4882a593Smuzhiyun 	status &= GENMASK(6, 4);
451*4882a593Smuzhiyun 	if (status) {
452*4882a593Smuzhiyun 		dev_err(&pdev->dev,
453*4882a593Smuzhiyun 			"setting external rom failed: %x\n", status);
454*4882a593Smuzhiyun 		goto remove_bypass;
455*4882a593Smuzhiyun 	}
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	/* 5 to 16 Write FW to DATA0/1 while checking SetData0/1 */
458*4882a593Smuzhiyun 	for (i = 0; i < fw->size / 4; i++) {
459*4882a593Smuzhiyun 		err = renesas_fw_download_image(pdev, fw_data, i, true);
460*4882a593Smuzhiyun 		if (err) {
461*4882a593Smuzhiyun 			dev_err(&pdev->dev,
462*4882a593Smuzhiyun 				"ROM Download Step %d failed at position %d bytes with (%d)\n",
463*4882a593Smuzhiyun 				 i, i * 4, err);
464*4882a593Smuzhiyun 			goto remove_bypass;
465*4882a593Smuzhiyun 		}
466*4882a593Smuzhiyun 	}
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	/*
469*4882a593Smuzhiyun 	 * wait till DATA0/1 is cleared
470*4882a593Smuzhiyun 	 */
471*4882a593Smuzhiyun 	for (i = 0; i < RENESAS_RETRY; i++) {
472*4882a593Smuzhiyun 		err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS_MSB,
473*4882a593Smuzhiyun 					   &status);
474*4882a593Smuzhiyun 		if (err)
475*4882a593Smuzhiyun 			goto remove_bypass;
476*4882a593Smuzhiyun 		if (!(status & (BIT(0) | BIT(1))))
477*4882a593Smuzhiyun 			break;
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 		udelay(RENESAS_DELAY);
480*4882a593Smuzhiyun 	}
481*4882a593Smuzhiyun 	if (i == RENESAS_RETRY) {
482*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Final Firmware ROM Download step timed out\n");
483*4882a593Smuzhiyun 		goto remove_bypass;
484*4882a593Smuzhiyun 	}
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 	/* 17. Remove bypass */
487*4882a593Smuzhiyun 	err = pci_write_config_byte(pdev, RENESAS_ROM_STATUS, 0);
488*4882a593Smuzhiyun 	if (err)
489*4882a593Smuzhiyun 		return false;
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 	udelay(10);
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 	/* 18. check result */
494*4882a593Smuzhiyun 	for (i = 0; i < RENESAS_RETRY; i++) {
495*4882a593Smuzhiyun 		err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status);
496*4882a593Smuzhiyun 		if (err) {
497*4882a593Smuzhiyun 			dev_err(&pdev->dev, "Read ROM status failed:%d\n",
498*4882a593Smuzhiyun 				pcibios_err_to_errno(err));
499*4882a593Smuzhiyun 			return false;
500*4882a593Smuzhiyun 		}
501*4882a593Smuzhiyun 		status &= RENESAS_ROM_STATUS_RESULT;
502*4882a593Smuzhiyun 		if (status ==  RENESAS_ROM_STATUS_SUCCESS) {
503*4882a593Smuzhiyun 			dev_dbg(&pdev->dev, "Download ROM success\n");
504*4882a593Smuzhiyun 			break;
505*4882a593Smuzhiyun 		}
506*4882a593Smuzhiyun 		udelay(RENESAS_DELAY);
507*4882a593Smuzhiyun 	}
508*4882a593Smuzhiyun 	if (i == RENESAS_RETRY) { /* Timed out */
509*4882a593Smuzhiyun 		dev_err(&pdev->dev,
510*4882a593Smuzhiyun 			"Download to external ROM TO: %x\n", status);
511*4882a593Smuzhiyun 		return false;
512*4882a593Smuzhiyun 	}
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	dev_dbg(&pdev->dev, "Download to external ROM succeeded\n");
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	/* Last step set Reload */
517*4882a593Smuzhiyun 	err = pci_write_config_byte(pdev, RENESAS_ROM_STATUS,
518*4882a593Smuzhiyun 				    RENESAS_ROM_STATUS_RELOAD);
519*4882a593Smuzhiyun 	if (err) {
520*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Set ROM execute failed: %d\n",
521*4882a593Smuzhiyun 			pcibios_err_to_errno(err));
522*4882a593Smuzhiyun 		return false;
523*4882a593Smuzhiyun 	}
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	/*
526*4882a593Smuzhiyun 	 * wait till Reload is cleared
527*4882a593Smuzhiyun 	 */
528*4882a593Smuzhiyun 	for (i = 0; i < RENESAS_RETRY; i++) {
529*4882a593Smuzhiyun 		err = pci_read_config_byte(pdev, RENESAS_ROM_STATUS, &status);
530*4882a593Smuzhiyun 		if (err)
531*4882a593Smuzhiyun 			return false;
532*4882a593Smuzhiyun 		if (!(status & RENESAS_ROM_STATUS_RELOAD))
533*4882a593Smuzhiyun 			break;
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 		udelay(RENESAS_DELAY);
536*4882a593Smuzhiyun 	}
537*4882a593Smuzhiyun 	if (i == RENESAS_RETRY) {
538*4882a593Smuzhiyun 		dev_err(&pdev->dev, "ROM Exec timed out: %x\n", status);
539*4882a593Smuzhiyun 		return false;
540*4882a593Smuzhiyun 	}
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	return true;
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun remove_bypass:
545*4882a593Smuzhiyun 	pci_write_config_byte(pdev, RENESAS_ROM_STATUS, 0);
546*4882a593Smuzhiyun 	return false;
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun 
renesas_load_fw(struct pci_dev * pdev,const struct firmware * fw)549*4882a593Smuzhiyun static int renesas_load_fw(struct pci_dev *pdev, const struct firmware *fw)
550*4882a593Smuzhiyun {
551*4882a593Smuzhiyun 	int err = 0;
552*4882a593Smuzhiyun 	bool rom;
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun 	/* Check if the device has external ROM */
555*4882a593Smuzhiyun 	rom = renesas_check_rom(pdev);
556*4882a593Smuzhiyun 	if (rom) {
557*4882a593Smuzhiyun 		/* perform chip erase first */
558*4882a593Smuzhiyun 		renesas_rom_erase(pdev);
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun 		/* lets try loading fw on ROM first */
561*4882a593Smuzhiyun 		rom = renesas_setup_rom(pdev, fw);
562*4882a593Smuzhiyun 		if (!rom) {
563*4882a593Smuzhiyun 			dev_dbg(&pdev->dev,
564*4882a593Smuzhiyun 				"ROM load failed, falling back on FW load\n");
565*4882a593Smuzhiyun 		} else {
566*4882a593Smuzhiyun 			dev_dbg(&pdev->dev,
567*4882a593Smuzhiyun 				"ROM load success\n");
568*4882a593Smuzhiyun 			goto exit;
569*4882a593Smuzhiyun 		}
570*4882a593Smuzhiyun 	}
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	err = renesas_fw_download(pdev, fw);
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun exit:
575*4882a593Smuzhiyun 	if (err)
576*4882a593Smuzhiyun 		dev_err(&pdev->dev, "firmware failed to download (%d).", err);
577*4882a593Smuzhiyun 	return err;
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun 
renesas_xhci_check_request_fw(struct pci_dev * pdev,const struct pci_device_id * id)580*4882a593Smuzhiyun int renesas_xhci_check_request_fw(struct pci_dev *pdev,
581*4882a593Smuzhiyun 				  const struct pci_device_id *id)
582*4882a593Smuzhiyun {
583*4882a593Smuzhiyun 	struct xhci_driver_data *driver_data =
584*4882a593Smuzhiyun 			(struct xhci_driver_data *)id->driver_data;
585*4882a593Smuzhiyun 	const char *fw_name = driver_data->firmware;
586*4882a593Smuzhiyun 	const struct firmware *fw;
587*4882a593Smuzhiyun 	bool has_rom;
588*4882a593Smuzhiyun 	int err;
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	/* Check if device has ROM and loaded, if so skip everything */
591*4882a593Smuzhiyun 	has_rom = renesas_check_rom(pdev);
592*4882a593Smuzhiyun 	if (has_rom) {
593*4882a593Smuzhiyun 		err = renesas_check_rom_state(pdev);
594*4882a593Smuzhiyun 		if (!err)
595*4882a593Smuzhiyun 			return 0;
596*4882a593Smuzhiyun 		else if (err != -ENOENT)
597*4882a593Smuzhiyun 			has_rom = false;
598*4882a593Smuzhiyun 	}
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun 	err = renesas_fw_check_running(pdev);
601*4882a593Smuzhiyun 	/* Continue ahead, if the firmware is already running. */
602*4882a593Smuzhiyun 	if (err == 0)
603*4882a593Smuzhiyun 		return 0;
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	/* no firmware interface available */
606*4882a593Smuzhiyun 	if (err != 1)
607*4882a593Smuzhiyun 		return has_rom ? 0 : err;
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun 	pci_dev_get(pdev);
610*4882a593Smuzhiyun 	err = firmware_request_nowarn(&fw, fw_name, &pdev->dev);
611*4882a593Smuzhiyun 	pci_dev_put(pdev);
612*4882a593Smuzhiyun 	if (err) {
613*4882a593Smuzhiyun 		if (has_rom) {
614*4882a593Smuzhiyun 			dev_info(&pdev->dev, "failed to load firmware %s, fallback to ROM\n",
615*4882a593Smuzhiyun 				 fw_name);
616*4882a593Smuzhiyun 			return 0;
617*4882a593Smuzhiyun 		}
618*4882a593Smuzhiyun 		dev_err(&pdev->dev, "failed to load firmware %s: %d\n",
619*4882a593Smuzhiyun 			fw_name, err);
620*4882a593Smuzhiyun 		return err;
621*4882a593Smuzhiyun 	}
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun 	err = renesas_fw_verify(fw->data, fw->size);
624*4882a593Smuzhiyun 	if (err)
625*4882a593Smuzhiyun 		goto exit;
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	err = renesas_load_fw(pdev, fw);
628*4882a593Smuzhiyun exit:
629*4882a593Smuzhiyun 	release_firmware(fw);
630*4882a593Smuzhiyun 	return err;
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(renesas_xhci_check_request_fw);
633*4882a593Smuzhiyun 
renesas_xhci_pci_exit(struct pci_dev * dev)634*4882a593Smuzhiyun void renesas_xhci_pci_exit(struct pci_dev *dev)
635*4882a593Smuzhiyun {
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(renesas_xhci_pci_exit);
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
640