/* * Jeff Harrell, jharrell@ti.com * Copyright (C) 2001 Texas Instruments, Inc. All rights reserved. * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * Texas Instruments Sangam specific setup. */ #include #include #include #include #include /*--- #include ---*/ /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #if defined (CONFIG_MIPS_AVALANCHE_VLYNQ) || defined (CONFIG_MIPS_AVALANCHE_VLYNQ_MODULE) extern REMOTE_VLYNQ_DEV_RESET_CTRL_FN p_remote_vlynq_dev_reset_ctrl; #endif /*--- #if defined (CONFIG_MIPS_AVALANCHE_VLYNQ) || defined (CONFIG_MIPS_AVALANCHE_VLYNQ_MODULE) ---*/ #include /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ extern int vlynq_device_type0; extern int vlynq_device_type1; extern int reset_hack; extern int vlynq_dev_init(void); /*****************************************************************************\ ***************************************************************************** \*****************************************************************************/ /*------------------------------------------------------------------------------------------*\ This function is board specific and should be ported for each board. \*------------------------------------------------------------------------------------------*/ int remote_vlynq_dev_reset_ctrl(unsigned int module_reset_bit, AVALANCHE_RESET_CTRL_T reset_ctrl) { if(module_reset_bit >= 32) return 1; printk("remote_vlynq_dev_reset_ctrl(%u, %s)\n", module_reset_bit, OUT_OF_RESET == reset_ctrl ? "OUT_OF_RESET" : IN_RESET == reset_ctrl ? "IN_RESET" : "unknown_RESET"); switch(module_reset_bit) { case 0: if(OUT_OF_RESET == reset_ctrl) { if(reset_hack) return 2; vlynq_delay(20000); printk("Un-resetting the remote device.\n"); if(vlynq_dev_init()) { printk("ERROR: Un-resetting the remote device. failed\n"); printk("ERROR: remote_vlynq_dev_reset_ctrl: failed\n"); return 3; } printk("Re-initialized the VLYNQ.\n"); printk("Read the data. %x.\n", *(unsigned int*)0xa4000004); reset_hack = 2; } else if(IN_RESET == reset_ctrl) { *(unsigned long*) AVALANCHE_GPIO_DATA_OUT &= ~(1<<6); vlynq_delay(20000); printk("Resetting the remote device.\n"); reset_hack = 0; } else ; break; default: break; } printk("remote_vlynq_dev_reset_ctrl: done\n"); return 0; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #define SYS_VLYNQ_LOCAL_INTERRUPT_VECTOR 30 /* MSB - 1 bit */ #define SYS_VLYNQ_REMOTE_INTERRUPT_VECTOR 31 /* MSB bit */ #define SYS_VLYNQ_OPTIONS 0x7F; /* all options*/ /* These defines are board specific */ #define VLYNQ0_REMOTE_WINDOW1_OFFSET (0x0C000000) #define VLYNQ0_REMOTE_WINDOW1_SIZE (0x00030000) /* 0x10500 */ #define VLYNQ1_REMOTE_WINDOW1_OFFSET (0x0C010000) #define VLYNQ1_REMOTE_WINDOW1_SIZE (0x00000500) /*------------------------------------------------------------------------------------------*\ * Defines for Config = 0, Port = 0 \*------------------------------------------------------------------------------------------*/ #define VLYNQ_ACX111_MEM_OFFSET 0xC0000000 /* Physical address of ACX111 memory */ #define VLYNQ_ACX111_MEM_SIZE 0x00040000 /* Total size of the ACX111 memory */ #define VLYNQ_ACX111_REG_OFFSET 0xF0000000 /* PHYS_ADDR of ACX111 control registers */ #define VLYNQ_ACX111_REG_SIZE 0x00022000 /* Size of ACX111 registers area, MAC+PHY */ #include "vlynq_init.h" /*------------------------------------------------------------------------------------------*\ * for debugging \*------------------------------------------------------------------------------------------*/ struct _vlynq_registers *VLYNQ0_local = (struct _vlynq_registers *)0xa8611800; struct _vlynq_registers *VLYNQ0_remote = (struct _vlynq_registers *)0xa4000000; struct _vlynq_registers *VLYNQ1_local = (struct _vlynq_registers *)0xa8611C00; struct _vlynq_registers *VLYNQ1_remote = (struct _vlynq_registers *)0xac000000; extern VLYNQ_DEV vlynqDevice0, vlynqDevice1; int vlynq_init_status[CONFIG_MIPS_AVALANCHE_VLYNQ_PORTS] = {0, 0}; static int reset_hack = 1; /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int vlynq_config_dev_init(unsigned int device_index, unsigned int config_index) { VLYNQ_DEV *V = device_index == 0 ? &vlynqDevice0 : &vlynqDevice1; struct _vlynq_dev_config *C = device_index == 0 ? &vlynq_dev_config0[config_index] : NULL; if((V == NULL) || (C == NULL)) { printk ("[vlynq_config_dev_init] invallif config device=%u.config=%u\n", device_index, config_index); return 1; } int ret; printk("vlynq_config_dev_init: reset device per GPIO Pin\n"); *(unsigned long*) AVALANCHE_GPIO_ENBL |= (1<<6); vlynq_delay(20000); *(unsigned long*) AVALANCHE_GPIO_DIR &= ~(1<<6); vlynq_delay(20000); *(unsigned long*) AVALANCHE_GPIO_DATA_OUT&= ~(1<<6); vlynq_delay(50000); *(unsigned long*) AVALANCHE_GPIO_DATA_OUT|= (1<<6); vlynq_delay(50000); printk("vlynq_config_dev_init: setup Registers\n"); V->dev_idx = C->dev_idx; V->module_base = C->module_base; V->clk_source = C->clk_source; V->clk_div = C->clk_div; V->state = C->state; V->local_mem = C->local_mem; if(V->local_mem.RxSize[0] == 0) { char * memsize_str = prom_getenv("memsize"); V->local_mem.RxSize[0] = simple_strtol(memsize_str, NULL, 0); printk("set local_mem.RxSize to 0x%x\n", V->local_mem.RxSize[0]); } V->remote_mem = C->remote_mem; V->local_irq = C->local_irq; V->remote_irq = C->remote_irq; if(reset_hack != 1) printk("About to re-init the VLYNQ.\n"); /*--------------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------------*/ if((ret = vlynq_init(V, VLYNQ_INIT_PERFORM_ALL)) == 0) { int cnt, i; /* Suraj added the following to keep the 1130 going. */ switch(C->name) { /*------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------*/ case ti_vlynq_wlan: vlynq_interrupt_vector_set( V, 0 /* intr vector line running into 1130 vlynq */, 0 /* intr mapped onto the interrupt register on remote vlynq and this vlynq */, VLYNQ_REMOTE_DVC, 0 /* polarity active high */, 0 /* interrupt Level triggered */); /* System wide interrupt is 80 for 1130, please note. */ vlynq_init_status[device_index] = 1; reset_hack = 2; printk("vlynq_config_dev_init: success\n"); return 0; /*------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------*/ case ti_vlynq_usb: vlynq_init_status[device_index] = 1; cnt = sizeof (vecmap) / sizeof (vecmap[0]); for (i = 0; i < cnt; i++) { vlynq_interrupt_vector_set ( &vlynqDevice0, vecmap[i].int_vector, vecmap[i].map_vector, vecmap[i].dev, vecmap[i].pol, vecmap[i].type ); if (vecmap[i].int_enable) { vlynq_interrupt_enable (&vlynqDevice0, vecmap[i].dev, vecmap[i].map_vector); } else { vlynq_interrupt_disable (&vlynqDevice0, vecmap[i].dev, vecmap[i].map_vector); } } printk("vlynq_config_dev_init: success\n"); return 0; /*--- success ---*/ } } if(ret) /*--- prom_printf( ---*/ printk( "VLYNQ INIT FAILED: %s\n", ret == VLYNQ_INVALID_ARG ? "VLYNQ_INVALID_ARG" : ret == VLYNQ_INVALID_DRV_STATE ? "VLYNQ_INVALID_DRV_STATE" : ret == VLYNQ_INT_CONFIG_ERR ? "VLYNQ_INT_CONFIG_ERR" : ret == VLYNQ_LINK_DOWN ? "VLYNQ_LINK_DOWN" : ret == VLYNQ_MEMALLOC_FAIL ? "VLYNQ_MEMALLOC_FAIL" : ret == VLYNQ_SUCCESS ? "VLYNQ_SUCCESS" : "VLYNQ_unknown"); if(reset_hack == 1) { /*--- prom_printf("VLYNQ INIT FAILED: Please try cold reboot. \n"); ---*/ printk("VLYNQ INIT FAILED: Please try cold reboot. \n"); } else { printk("Failed to initialize the VLYNQ interface at insmod.\n"); } return 1; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int vlynq_dev_init(void) { volatile unsigned int *reset_base = (unsigned int *) AVALANCHE_RESET_CONTROL_BASE; if(vlynq_device_type0) { *reset_base &= ~((1 << AVALANCHE_LOW_VLYNQ_RESET_BIT)); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT)); */ vlynq_delay(20000); /* Bring vlynq out of reset if not already done */ *reset_base |= (1 << AVALANCHE_LOW_VLYNQ_RESET_BIT); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT); */ vlynq_delay(20000); /* Allowing sufficient time to VLYNQ to settle down.*/ if(vlynq_config_dev_init(0, vlynq_device_type0 - 1)) { return 1; } } if(vlynq_device_type1) { *reset_base &= ~((1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT)); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT)); */ vlynq_delay(20000); /* Bring vlynq out of reset if not already done */ *reset_base |= (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT); /* | (1 << AVALANCHE_HIGH_VLYNQ_RESET_BIT); */ vlynq_delay(20000); /* Allowing sufficient time to VLYNQ to settle down.*/ if(vlynq_config_dev_init(1, vlynq_device_type1 - 1)) { return 1; } } printk (KERN_INFO "vlynq init done\n"); return 0; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void vlynq_set_function_pointers(void) { extern VLYNQ_DEV vlynqDevice0; extern VLYNQ_DEV vlynqDevice1; p_vlynq_interrupt_vector_set = (p_vlynq_interrupt_vector_set_t)vlynq_interrupt_vector_set; p_vlynq_interrupt_vector_cntl = (p_vlynq_interrupt_vector_cntl_t)vlynq_interrupt_vector_cntl; p_vlynq_interrupt_get_count = (p_vlynq_interrupt_get_count_t)vlynq_interrupt_get_count; p_vlynq_install_isr = (p_vlynq_install_isr_t)vlynq_install_isr; p_vlynq_uninstall_isr = (p_vlynq_uninstall_isr_t)vlynq_uninstall_isr; p_vlynq_root_isr = (p_vlynq_root_isr_t)vlynq_root_isr; p_vlynq_delay = (p_vlynq_delay_t)vlynq_delay; p_vlynq_interrupt_vector_map = (p_vlynq_interrupt_vector_map_t)vlynq_interrupt_vector_map; p_vlynq_interrupt_set_polarity = (p_vlynq_interrupt_set_polarity_t)vlynq_interrupt_set_polarity; p_vlynq_interrupt_get_polarity = (p_vlynq_interrupt_get_polarity_t)vlynq_interrupt_get_polarity; p_vlynq_interrupt_set_type = (p_vlynq_interrupt_set_type_t)vlynq_interrupt_set_type; p_vlynq_interrupt_get_type = (p_vlynq_interrupt_get_type_t)vlynq_interrupt_get_type; p_vlynq_interrupt_enable = (p_vlynq_interrupt_enable_t)vlynq_interrupt_enable; p_vlynq_interrupt_disable = (p_vlynq_interrupt_disable_t)vlynq_interrupt_disable; p_remote_vlynq_dev_reset_ctrl = remote_vlynq_dev_reset_ctrl; p_vlynqDevice0 = &vlynqDevice0; p_vlynqDevice1 = &vlynqDevice1; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void vlynq_clear_function_pointers(void) { extern VLYNQ_DEV vlynqDevice0; extern VLYNQ_DEV vlynqDevice1; p_vlynq_interrupt_vector_set = NULL; p_vlynq_interrupt_vector_cntl = NULL; p_vlynq_interrupt_get_count = NULL; p_vlynq_install_isr = NULL; p_vlynq_uninstall_isr = NULL; p_vlynq_root_isr = NULL; p_vlynq_delay = NULL; p_vlynq_interrupt_vector_map = NULL; p_vlynq_interrupt_set_polarity = NULL; p_vlynq_interrupt_get_polarity = NULL; p_vlynq_interrupt_set_type = NULL; p_vlynq_interrupt_get_type = NULL; p_vlynq_interrupt_enable = NULL; p_vlynq_interrupt_disable = NULL; p_remote_vlynq_dev_reset_ctrl = NULL; p_vlynqDevice0 = NULL; p_vlynqDevice1 = NULL; }