134 lines
3.3 KiB
C
134 lines
3.3 KiB
C
/*
|
|
* Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
|
|
*
|
|
* May be copied or modified under the terms of the GNU General Public
|
|
* License. See linux/COPYING for more information.
|
|
*
|
|
* This file handles programming up the Altera Flex10K that interfaces to
|
|
* the Galileo, and does the PS/2 keyboard and mouse
|
|
*
|
|
*/
|
|
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/smp.h>
|
|
#include <linux/smp_lock.h>
|
|
#include <linux/init.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/pci.h>
|
|
#include <linux/delay.h>
|
|
|
|
|
|
#include <asm/overdriver/gt64111.h>
|
|
#include <asm/overdrive/overdrive.h>
|
|
#include <asm/overdrive/fpga.h>
|
|
|
|
#define FPGA_NotConfigHigh() (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT
|
|
#define FPGA_NotConfigLow() (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK
|
|
|
|
/* I need to find out what (if any) the real delay factor here is */
|
|
/* The delay is definately not critical */
|
|
#define long_delay() {int i;for(i=0;i<10000;i++);}
|
|
#define short_delay() {int i;for(i=0;i<100;i++);}
|
|
|
|
static void __init program_overdrive_fpga(const unsigned char *fpgacode,
|
|
int size)
|
|
{
|
|
int timeout = 0;
|
|
int i, j;
|
|
unsigned char b;
|
|
static volatile unsigned char *FPGA_ControlReg =
|
|
(volatile unsigned char *) (OVERDRIVE_CTRL);
|
|
static volatile unsigned char *FPGA_ProgramReg =
|
|
(volatile unsigned char *) (FPGA_DCLK_ADDRESS);
|
|
|
|
printk("FPGA: Commencing FPGA Programming\n");
|
|
|
|
/* The PCI reset but MUST be low when programming the FPGA !!! */
|
|
b = (*FPGA_ControlReg) & RESET_PCI_MASK;
|
|
|
|
(*FPGA_ControlReg) = b;
|
|
|
|
/* Prepare FPGA to program */
|
|
|
|
FPGA_NotConfigHigh();
|
|
long_delay();
|
|
|
|
FPGA_NotConfigLow();
|
|
short_delay();
|
|
|
|
while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) {
|
|
printk("FPGA: Waiting for NotStatus to go Low ... \n");
|
|
}
|
|
|
|
FPGA_NotConfigHigh();
|
|
|
|
/* Wait for FPGA "ready to be programmed" signal */
|
|
printk("FPGA: Waiting for NotStatus to go high (FPGA ready)... \n");
|
|
|
|
for (timeout = 0;
|
|
(((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0)
|
|
&& (timeout < FPGA_TIMEOUT)); timeout++);
|
|
|
|
/* Check if timeout condition occured - i.e. an error */
|
|
|
|
if (timeout == FPGA_TIMEOUT) {
|
|
printk
|
|
("FPGA: Failed to program - Timeout waiting for notSTATUS to go high\n");
|
|
return;
|
|
}
|
|
|
|
printk("FPGA: Copying data to FPGA ... %d bytes\n", size);
|
|
|
|
/* Copy array to FPGA - bit at a time */
|
|
|
|
for (i = 0; i < size; i++) {
|
|
volatile unsigned w = 0;
|
|
|
|
for (j = 0; j < 8; j++) {
|
|
*FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01;
|
|
short_delay();
|
|
}
|
|
if ((i & 0x3ff) == 0) {
|
|
printk(".");
|
|
}
|
|
}
|
|
|
|
/* Waiting for CONFDONE to go high - means the program is complete */
|
|
|
|
for (timeout = 0;
|
|
(((*FPGA_ProgramReg & FPGA_CONFDONE) == 0)
|
|
&& (timeout < FPGA_TIMEOUT)); timeout++) {
|
|
|
|
*FPGA_ProgramReg = 0x0;
|
|
long_delay();
|
|
}
|
|
|
|
if (timeout == FPGA_TIMEOUT) {
|
|
printk
|
|
("FPGA: Failed to program - Timeout waiting for CONFDONE to go high\n");
|
|
return;
|
|
} else { /* Clock another 10 times - gets the device into a working state */
|
|
for (i = 0; i < 10; i++) {
|
|
*FPGA_ProgramReg = 0x0;
|
|
short_delay();
|
|
}
|
|
}
|
|
|
|
printk("FPGA: Programming complete\n");
|
|
}
|
|
|
|
|
|
static const unsigned char __init fpgacode[] = {
|
|
#include "./overdrive.ttf" /* Code from maxplus2 compiler */
|
|
, 0, 0
|
|
};
|
|
|
|
|
|
int __init init_overdrive_fpga(void)
|
|
{
|
|
program_overdrive_fpga(fpgacode, sizeof(fpgacode));
|
|
|
|
return 0;
|
|
}
|