1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#ifndef __KERNEL__
31# define __KERNEL__
32#endif
33
34#ifndef KBUILD_MODNAME
35# define KBUILD_MODNAME KBUILD_STR(mefirmware)
36#endif
37
38#include <linux/pci.h>
39#include <linux/delay.h>
40
41#include <linux/firmware.h>
42
43#include "meplx_reg.h"
44#include "medebug.h"
45
46#include "mefirmware.h"
47
48int me_xilinx_download(unsigned long register_base_control,
49 unsigned long register_base_data,
50 struct device *dev, const char *firmware_name)
51{
52 int err = ME_ERRNO_FIRMWARE;
53 uint32_t value = 0;
54 int idx = 0;
55
56 const struct firmware *fw;
57
58 PDEBUG("executed.\n");
59
60 if (!firmware_name) {
61 PERROR("Request for firmware failed. No name provided. \n");
62 return err;
63 }
64
65 PINFO("Request '%s' firmware.\n", firmware_name);
66 err = request_firmware(&fw, firmware_name, dev);
67
68 if (err) {
69 PERROR("Request for firmware failed.\n");
70 return err;
71 }
72
73
74 outl(PLX_INTCSR_LOCAL_INT2_POL, register_base_control + PLX_INTCSR);
75
76
77 value = inl(register_base_control + PLX_ICR);
78 value |= ME_FIRMWARE_CS_WRITE;
79 outl(value, register_base_control + PLX_ICR);
80
81
82 inl(register_base_data + ME_XILINX_CS1_REG);
83
84
85 udelay(20);
86
87
88 if (!
89 (inl(register_base_control + PLX_INTCSR) &
90 PLX_INTCSR_LOCAL_INT2_STATE)) {
91 PERROR("Can't init Xilinx.\n");
92 release_firmware(fw);
93 return -EIO;
94 }
95
96 value = inl(register_base_control + PLX_ICR);
97 value &= ~ME_FIRMWARE_CS_WRITE;
98 outl(value, register_base_control + PLX_ICR);
99
100
101 udelay(10);
102
103 for (idx = 0; idx < fw->size; idx++) {
104 outl(fw->data[idx], register_base_data);
105#ifdef ME6000_v2_4
106
107
108 if (inl(register_base_control + PLX_ICR) &
109 ME_FIRMWARE_BUSY_FLAG) {
110 PERROR("Xilinx is still busy (idx = %d)\n", idx);
111 release_firmware(fw);
112 return -EIO;
113 }
114#endif
115 }
116 PDEBUG("Download finished. %d bytes written to PLX.\n", idx);
117
118
119 if (inl(register_base_control + PLX_ICR) & ME_FIRMWARE_DONE_FLAG) {
120 PDEBUG("SUCCESS. Done flag is set.\n");
121 } else {
122 PERROR("FAILURE. DONE flag is not set.\n");
123 release_firmware(fw);
124 return -EIO;
125 }
126
127
128 value = inl(register_base_control + PLX_ICR);
129 value |= ME_FIRMWARE_CS_WRITE;
130 outl(value, register_base_control + PLX_ICR);
131
132 PDEBUG("Enable interrupts on the PCI interface.\n");
133 outl(ME_PLX_PCI_ACTIVATE, register_base_control + PLX_INTCSR);
134 release_firmware(fw);
135
136 return 0;
137}
138