| /* |
| * 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/config.h> |
| #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; |
| } |