added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / drivers / staging / meilhaus / mefirmware.c
blobc07d202e8cb51efe49c509295453d705691fe587
1 /**
2 * @file mefirmware.c
4 * @brief Implements the firmware handling.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 * @author Krzysztof Gantzke (k.gantzke@meilhaus.de)
8 */
10 /***************************************************************************
11 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de) *
12 * Copyright (C) 2007 by Krzysztof Gantzke k.gantzke@meilhaus.de *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 ***************************************************************************/
30 #ifndef __KERNEL__
31 # define __KERNEL__
32 #endif
34 #ifndef KBUILD_MODNAME
35 # define KBUILD_MODNAME KBUILD_STR(mefirmware)
36 #endif
38 #include <linux/pci.h>
39 #include <linux/delay.h>
41 #include <linux/firmware.h>
43 #include "meplx_reg.h"
44 #include "medebug.h"
46 #include "mefirmware.h"
48 int me_xilinx_download(unsigned long register_base_control,
49 unsigned long register_base_data,
50 struct device *dev, const char *firmware_name)
52 int err = ME_ERRNO_FIRMWARE;
53 uint32_t value = 0;
54 int idx = 0;
56 const struct firmware *fw;
58 PDEBUG("executed.\n");
60 if (!firmware_name) {
61 PERROR("Request for firmware failed. No name provided. \n");
62 return err;
65 PINFO("Request '%s' firmware.\n", firmware_name);
66 err = request_firmware(&fw, firmware_name, dev);
68 if (err) {
69 PERROR("Request for firmware failed.\n");
70 return err;
72 // Set PLX local interrupt 2 polarity to high.
73 // Interrupt is thrown by init pin of xilinx.
74 outl(PLX_INTCSR_LOCAL_INT2_POL, register_base_control + PLX_INTCSR);
76 // Set /CS and /WRITE of the Xilinx
77 value = inl(register_base_control + PLX_ICR);
78 value |= ME_FIRMWARE_CS_WRITE;
79 outl(value, register_base_control + PLX_ICR);
81 // Init Xilinx with CS1
82 inl(register_base_data + ME_XILINX_CS1_REG);
84 // Wait for init to complete
85 udelay(20);
87 // Checkl /INIT pin
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;
95 // Reset /CS and /WRITE of the Xilinx
96 value = inl(register_base_control + PLX_ICR);
97 value &= ~ME_FIRMWARE_CS_WRITE;
98 outl(value, register_base_control + PLX_ICR);
100 // Download Xilinx firmware
101 udelay(10);
103 for (idx = 0; idx < fw->size; idx++) {
104 outl(fw->data[idx], register_base_data);
105 #ifdef ME6000_v2_4
106 /// This checking only for board's version 2.4
107 // Check if BUSY flag is set (low = ready, high = busy)
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;
114 #endif //ME6000_v2_4
116 PDEBUG("Download finished. %d bytes written to PLX.\n", idx);
118 // If done flag is high download was successful
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;
127 // Set /CS and /WRITE
128 value = inl(register_base_control + PLX_ICR);
129 value |= ME_FIRMWARE_CS_WRITE;
130 outl(value, register_base_control + PLX_ICR);
132 PDEBUG("Enable interrupts on the PCI interface.\n");
133 outl(ME_PLX_PCI_ACTIVATE, register_base_control + PLX_INTCSR);
134 release_firmware(fw);
136 return 0;