/* * 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 #include #include #include #include #include /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ struct _hw_boot *hw_boot = (struct _hw_boot *) AVALANCHE_DEVICE_CONFIG_LATCH_BASE; struct EMIF_register_memory_map *hw_emif = (struct EMIF_register_memory_map *) AVALANCHE_EMIF_CONTROL_BASE; struct _usb_hw *hw_usb = (struct _usb_hw *) AVALANCHE_USB_SLAVE_BASE; struct _usbdma_hw *hw_usbdma = (struct _usbdma_hw *) AVALANCHE_USB_SLAVE_CONTROL_BASE; struct _hw_gpio *hw_gpio = (struct _hw_gpio *) AVALANCHE_GPIO_BASE; struct _hw_i2c *hw_i2c = (struct _hw_i2c *) AVALANCHE_I2C_BASE; struct _irq_hw *hw_irq = (struct _irq_hw *) AVALANCHE_INTC_BASE; union _hw_non_reset *hw_reset = (union _hw_non_reset *) AVALANCHE_RESET_CONTROL_BASE; struct _timer_hw *hw_timer0 = (struct _timer_hw *) AVALANCHE_TIMER0_BASE; struct _timer_hw *hw_timer1 = (struct _timer_hw *) AVALANCHE_TIMER1_BASE; struct _vlynq_registers *hw_vlynq0 = (struct _vlynq_registers *) AVALANCHE_LOW_VLYNQ_CONTROL_BASE; #if CONFIG_MIPS_OHIO == 0 struct _vlynq_registers *hw_vlynq1 = (struct _vlynq_registers *) AVALANCHE_HIGH_VLYNQ_CONTROL_BASE; #endif /*--- #if CONFIG_MIPS_OHIO == 0 ---*/ struct _hw_clock *hw_clock = (struct _hw_clock *) AVALANCHE_CLOCK_CONTROL_BASE; /*--- AVALANCHE_ADSL_SUB_SYS_MEM_BASE; ---*/ /*--- AVALANCHE_BROADBAND_INTERFACE__BASE; ---*/ /*--- AVALANCHE_ATM_SAR_BASE; ---*/ /*--- AVALANCHE_LOW_VLYNQ_MEM_MAP_BASE; ---*/ /*--- AVALANCHE_LOW_CPMAC_BASE; ---*/ /*--- AVALANCHE_WATCHDOG_TIMER_BASE; ---*/ /*--- AVALANCHE_UART0_REGS_BASE; ---*/ /*--- AVALANCHE_UART1_REGS_BASE; ---*/ /*--- AVALANCHE_MCDMA0_CTRL_BASE; ---*/ /*--- AVALANCHE_BIST_CONTROL_BASE; ---*/ /*--- AVALANCHE_MDIO_BASE; ---*/ /*--- AVALANCHE_FSER_BASE; ---*/ /*--- AVALANCHE_HIGH_CPMAC_BASE; ---*/ /*--- AVALANCHE_HIGH_VLYNQ_MEM_MAP_BASE; ---*/ /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #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) ---*/ extern SET_MDIX_ON_CHIP_FN_T p_set_mdix_on_chip_fn; #define AUTO_MDIX_ENABLE_PIN 30 #define MDIX_NORMAL_MODE 0 #define AUTO_MDIX_GPIO_PIN 28 #define MDIX_MODE 1 #define MDI_MODE 0 #define AUTO_MDIX_CNTL_MASK ( (1 << AUTO_MDIX_ENABLE_PIN) \ |(1 << AUTO_MDIX_GPIO_PIN)) /* We ignore MDIX_NORMAL_MODE as it is 0 and we get to set 0 from the below macros for the AUTO_MDIX_ENABLE_PIN. */ #define AUTO_MDIX_ON_WORD (MDIX_MODE << AUTO_MDIX_GPIO_PIN) #define AUTO_MDIX_OFF_WORD (MDI_MODE << AUTO_MDIX_GPIO_PIN) int sangam_set_mdix_on_chip(unsigned int base_addr, unsigned int operation) { if((!p_set_mdix_on_chip_fn) || (base_addr != AVALANCHE_LOW_CPMAC_BASE)) return (-1); if(operation) /* 0perating on bit 29 and 30. Writing 1 to bit 29 and 0 to bit 30. */ avalanche_gpio_out_value(AUTO_MDIX_ON_WORD, AUTO_MDIX_CNTL_MASK,0); else /* 0perating on bit 29 and 30. Writing 0 to bit 29 and 0 to bit 30. */ avalanche_gpio_out_value(AUTO_MDIX_OFF_WORD, AUTO_MDIX_CNTL_MASK,0); return (0); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int avalanche_need(enum _avalanche_need_ need) { static char *pHWRevision = NULL; static unsigned int HWRevision = 0; static char *AutoMDIX = NULL; if(pHWRevision == NULL || HWRevision == 0) { pHWRevision = prom_getenv("HWRevision"); prom_printf("HWRevision=\"%s\"\n", pHWRevision ? pHWRevision : ""); HWRevision = simple_strtol(pHWRevision , NULL, 0); } if(AutoMDIX == NULL) { AutoMDIX = prom_getenv("AutoMDIX"); prom_printf("AutoMDIX=\"%s\"\n", AutoMDIX ? AutoMDIX : ""); } if(HWRevision == 0) { return 0; } switch(need) { case avalanche_need_vlynq: switch(HWRevision) { case 60: /*--- Fritz Box SL WLAN Annex B ---*/ case 61: /*--- Fritz Box FON WLAN Annex B ---*/ case 65: /*--- Fritz Box SL WLAN Annex A ---*/ case 66: /*--- Fritz Box FON WLAN Annex A ---*/ case 76: /*--- Fritz Box FON 2 WLAN ---*/ case 77: /*--- Fritz Box FON 2 WLAN Annex A ---*/ case 79: /*--- Fritz Box WLAN 3070 ---*/ case 82: /*--- Fritz Box WLAN 3050 ---*/ case 85: /*--- Fritz Box WLAN 3030 ---*/ case 100: /*--- Fritz Box User ---*/ return 1; default: break; } break; case avalanche_need_auto_mdix: switch(HWRevision) { case 60: /*--- Fritz Box SL WLAN Annex B ---*/ case 61: /*--- Fritz Box FON WLAN Annex B ---*/ case 65: /*--- Fritz Box SL WLAN Annex A ---*/ case 66: /*--- Fritz Box FON WLAN Annex A ---*/ case 71: /*--- Fritz Box FON ATA ---*/ case 72: /*--- Fritz Box FON 2 ---*/ case 73: /*--- Fritz Box FON 2 AnnexA ---*/ case 74: /*--- Fritz Box 8MB ---*/ case 75: /*--- Fritz Box MVoIP ---*/ case 76: /*--- Fritz Box FON 2 WLAN ---*/ case 77: /*--- Fritz Box FON 2 WLAN AnnexA ---*/ case 78: /*--- Eumes 300IP ---*/ case 79: /*--- Fritz Box WLAN 3070 ---*/ /*--- case 80: ---*/ /*--- Fritz Box ---*/ case 81: /*--- Fritz Box 301 ---*/ case 82: /*--- Fritz Box WLAN 3050 ---*/ case 83: /*--- Fritz Box 2030 ---*/ case 84: /*--- Fritz Box 2070 ---*/ case 85: /*--- Fritz Box WLAN 3030 ---*/ /*--- case : ---*/ /*--- Fritz Box ---*/ case 100: /*--- Fritz Box USER ---*/ return 1; default: break; } if(AutoMDIX && (AutoMDIX[0] == 'y')) { return 1; } break; } return 0; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #if defined (CONFIG_MIPS_AVALANCHE_VLYNQ) void avalanche_soc_platform_init_vlynq(void) { if(avalanche_need(avalanche_need_vlynq)) { p_remote_vlynq_dev_reset_ctrl = remote_vlynq_dev_reset_ctrl; vlynq_dev_init(); } } #endif /*--- #if defined (CONFIG_MIPS_AVALANCHE_VLYNQ) ---*/ /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ void avalanche_soc_platform_init(void) { printk("Reset Status: "); switch (avalanche_get_sys_last_reset_status()) { case HARDWARE_RESET: printk("HW reset\n"); break; case WATCHDOG_RESET: printk("WD reset\n"); break; case SOFTWARE_RESET0: printk("SW reset 0\n"); break; case SOFTWARE_RESET1: printk("SW reset 1\n"); break; default: printk("unknown.\n"); } /* GPIO INIT */ avalanche_gpio_init(); avalanche_reset_ctrl(AVALANCHE_UART0_RESET_BIT, OUT_OF_RESET); avalanche_reset_ctrl(AVALANCHE_GPIO_RESET_BIT, OUT_OF_RESET); // avalanche_gpio_out_value(0xf3fc3ff0, 0xf3fc3ff0, 0); /* hack for now, to be cleaned up. */ *(unsigned int *)0xa861090c = 0xf3fc3ff0; // REG32_WRITE(TNETD73XX_GPIOENR, 0xf3fc3ff0); avalanche_reset_ctrl(AVALANCHE_LOW_EPHY_RESET_BIT,IN_RESET); //#if (!defined(CONFIG_MIPS_AR7WRD) && !defined(CONFIG_MIPS_AR7VWI)) #if (!defined(CONFIG_MIPS_AVALANCHE_MARVELL)) avalanche_reset_ctrl(AVALANCHE_LOW_EPHY_RESET_BIT,OUT_OF_RESET); #endif /* CLK CTRl INIT */ avalanche_clkc_init(AFECLK_FREQ, REFCLK_FREQ, OSC3_FREQ); /* initialize vbus frequency */ avalanche_set_vbus_freq(avalanche_clkc_get_freq(CLKC_VBUS)); /* This initialization is required to make the kernel work with ADAM2. */ { volatile unsigned long *reset_cntl = (volatile unsigned long *) AVALANCHE_RESET_CONTROL_BASE, *mdio_cntl = (volatile unsigned long *)((int)AVALANCHE_MDIO_BASE + 0x4); printk ("DEBUG: Bring MDIO out of reset.\n"); *reset_cntl |= (1 << AVALANCHE_MDIO_RESET_BIT) | (1 << AVALANCHE_LOW_CPMAC_RESET_BIT) | (1 << AVALANCHE_HIGH_CPMAC_RESET_BIT) | (1 << AVALANCHE_LOW_EPHY_RESET_BIT); *mdio_cntl = (1 << 30) | (avalanche_get_vbus_freq()/2200000); } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #if CONFIG_MIPS_OHIO == 1 p_set_mdix_on_chip_fn = &sangam_set_mdix_on_chip; avalanche_gpio_ctrl(AUTO_MDIX_ENABLE_PIN, GPIO_PIN, GPIO_OUTPUT_PIN); avalanche_gpio_ctrl(AUTO_MDIX_GPIO_PIN, GPIO_PIN, GPIO_OUTPUT_PIN); prom_printf("MDIX enabled.\n"); #else /*--- #if CONFIG_MIPS_OHIO == 1 ---*/ /* Takes care of the CVR bug in the Sangam Chip as well. */ if((*((volatile unsigned int*)AVALANCHE_CVR) == 0x570005) || (*((volatile unsigned int*)AVALANCHE_CVR) == 0x200005) || (*((volatile unsigned int*)AVALANCHE_CVR) == 0x210005) || (*((volatile unsigned int*)AVALANCHE_CVR) == 0x220005) || (*((volatile unsigned int*)AVALANCHE_CVR) == 0x230005)) { prom_printf("This SOC has MDIX cababilities on chip: "); if(avalanche_need(avalanche_need_auto_mdix)) { p_set_mdix_on_chip_fn = &sangam_set_mdix_on_chip; avalanche_gpio_ctrl(AUTO_MDIX_ENABLE_PIN, GPIO_PIN, GPIO_OUTPUT_PIN); avalanche_gpio_ctrl(AUTO_MDIX_GPIO_PIN, GPIO_PIN, GPIO_OUTPUT_PIN); prom_printf("MDIX enabled.\n"); } else { prom_printf("MDIX disabled.\n"); } } #endif /*--- #else ---*/ /*--- #if CONFIG_MIPS_OHIO == 1 ---*/ /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #if defined (CONFIG_MIPS_AVALANCHE_VLYNQ) avalanche_soc_platform_init_vlynq(); #endif }