linux/drivers/staging/meilhaus/mefirmware.c
<<
>>
Prefs
   1/**
   2 * @file mefirmware.c
   3 *
   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 */
   9
  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 ***************************************************************************/
  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        // 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);
  75
  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);
  80
  81        // Init Xilinx with CS1
  82        inl(register_base_data + ME_XILINX_CS1_REG);
  83
  84        // Wait for init to complete
  85        udelay(20);
  86
  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;
  94        }
  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);
  99
 100        // Download Xilinx firmware
 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///     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;
 113                }
 114#endif //ME6000_v2_4
 115        }
 116        PDEBUG("Download finished. %d bytes written to PLX.\n", idx);
 117
 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;
 125        }
 126
 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);
 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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.