diff options
author | Juli Mallett <jmallett@FreeBSD.org> | 2010-07-20 07:11:19 +0000 |
---|---|---|
committer | Juli Mallett <jmallett@FreeBSD.org> | 2010-07-20 07:11:19 +0000 |
commit | 1c305b501145f696d3597fb9b5b2091caaa6f67c (patch) | |
tree | 776ea14a76df76cd5ee4d9b63107c1e819c68914 /cvmx-thunder.c | |
download | src-1c305b501145f696d3597fb9b5b2091caaa6f67c.tar.gz src-1c305b501145f696d3597fb9b5b2091caaa6f67c.zip |
Initial import of Cavium Networks Octeon Simple Executive, SDK version 1.9.0.vendor/octeon-sdk/1.9.0
Notes
Notes:
svn path=/vendor-sys/octeon-sdk/dist/; revision=210284
svn path=/vendor-sys/octeon-sdk/1.9.0/; revision=210285; tag=vendor/octeon-sdk/1.9.0
Diffstat (limited to 'cvmx-thunder.c')
-rw-r--r-- | cvmx-thunder.c | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/cvmx-thunder.c b/cvmx-thunder.c new file mode 100644 index 000000000000..4bafa1d29b49 --- /dev/null +++ b/cvmx-thunder.c @@ -0,0 +1,328 @@ +/***********************license start*************** + * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights + * reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of Cavium Networks nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" + * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS + * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH + * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY + * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT + * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES + * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR + * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET + * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT + * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. + * + * + * For any questions regarding licensing please contact marketing@caviumnetworks.com + * + ***********************license end**************************************/ + + + + + + +/** + * @file + * + * Interface to the Thunder specific devices + * + * <hr>$Revision: 41586 $<hr> + * + */ + +#include "cvmx-config.h" +#include "cvmx.h" +#include "cvmx-sysinfo.h" +#include "cvmx-thunder.h" +#include "cvmx-gpio.h" +#include "cvmx-twsi.h" + + +static const int BYPASS_STATUS = 1<<5; /* GPIO 5 */ +static const int BYPASS_EN = 1<<6; /* GPIO 6 */ +static const int WDT_BP_CLR = 1<<7; /* GPIO 7 */ + +static const int RTC_CTL_ADDR = 0x7; +static const int RTC_CTL_BIT_EOSC = 0x80; +static const int RTC_CTL_BIT_WACE = 0x40; +static const int RTC_CTL_BIT_WD_ALM = 0x20; +static const int RTC_CTL_BIT_WDSTR = 0x8; +static const int RTC_CTL_BIT_AIE = 0x1; +static const int RTC_WD_ALM_CNT_BYTE0_ADDR = 0x4; + +#define CVMX_LAN_BYPASS_MSG(...) do {} while(0) + +/* + * Board-specifc RTC read + * Time is expressed in seconds from epoch (Jan 1 1970 at 00:00:00 UTC) + */ +uint32_t cvmx_rtc_ds1374_read(void) +{ + int retry; + uint8_t sec; + uint32_t time; + + for(retry=0; retry<2; retry++) + { + time = cvmx_twsi_read8(CVMX_RTC_DS1374_ADDR, 0x0); + time |= (cvmx_twsi_read8_cur_addr(CVMX_RTC_DS1374_ADDR) & 0xff) << 8; + time |= (cvmx_twsi_read8_cur_addr(CVMX_RTC_DS1374_ADDR) & 0xff) << 16; + time |= (cvmx_twsi_read8_cur_addr(CVMX_RTC_DS1374_ADDR) & 0xff) << 24; + + sec = cvmx_twsi_read8(CVMX_RTC_DS1374_ADDR, 0x0); + if (sec == (time & 0xff)) + break; /* Time did not roll-over, value is correct */ + } + + return time; +} + +/* + * Board-specific RTC write + * Time is expressed in seconds from epoch (Jan 1 1970 at 00:00:00 UTC) + */ +int cvmx_rtc_ds1374_write(uint32_t time) +{ + int rc; + int retry; + uint8_t sec; + + for(retry=0; retry<2; retry++) + { + rc = cvmx_twsi_write8(CVMX_RTC_DS1374_ADDR, 0x0, time & 0xff); + rc |= cvmx_twsi_write8(CVMX_RTC_DS1374_ADDR, 0x1, (time >> 8) & 0xff); + rc |= cvmx_twsi_write8(CVMX_RTC_DS1374_ADDR, 0x2, (time >> 16) & 0xff); + rc |= cvmx_twsi_write8(CVMX_RTC_DS1374_ADDR, 0x3, (time >> 24) & 0xff); + sec = cvmx_twsi_read8(CVMX_RTC_DS1374_ADDR, 0x0); + if (sec == (time & 0xff)) + break; /* Time did not roll-over, value is correct */ + } + + return (rc ? -1 : 0); +} + +int cvmx_rtc_ds1374_alarm_config(int WD, int WDSTR, int AIE) +{ + int val; + + val = cvmx_twsi_read8(CVMX_RTC_DS1374_ADDR,RTC_CTL_ADDR); + val = val & ~RTC_CTL_BIT_EOSC; /* Make sure that oscillator is running */ + WD?(val = val | RTC_CTL_BIT_WD_ALM):(val = val & ~RTC_CTL_BIT_WD_ALM); + WDSTR?(val = val | RTC_CTL_BIT_WDSTR):(val = val & ~RTC_CTL_BIT_WDSTR); + AIE?(val = val | RTC_CTL_BIT_AIE):(val = val & ~RTC_CTL_BIT_AIE); + cvmx_twsi_write8(CVMX_RTC_DS1374_ADDR,RTC_CTL_ADDR, val); + return 0; +} + +int cvmx_rtc_ds1374_alarm_set(int alarm_on) +{ + uint8_t val; + + if (alarm_on) + { + val = cvmx_twsi_read8(CVMX_RTC_DS1374_ADDR,RTC_CTL_ADDR); + cvmx_twsi_write8(CVMX_RTC_DS1374_ADDR,RTC_CTL_ADDR, val | RTC_CTL_BIT_WACE); + } + else + { + val = cvmx_twsi_read8(CVMX_RTC_DS1374_ADDR,RTC_CTL_ADDR); + cvmx_twsi_write8(CVMX_RTC_DS1374_ADDR,RTC_CTL_ADDR, val & ~RTC_CTL_BIT_WACE); + } + return 0; +} + + +int cvmx_rtc_ds1374_alarm_counter_set(uint32_t interval) +{ + int i; + int rc = 0; + + for(i=0;i<3;i++) + { + rc |= cvmx_twsi_write8(CVMX_RTC_DS1374_ADDR, RTC_WD_ALM_CNT_BYTE0_ADDR+i, interval & 0xFF); + interval >>= 8; + } + return rc; +} + +uint32_t cvmx_rtc_ds1374_alarm_counter_get(void) +{ + int i; + uint32_t interval = 0; + + for(i=0;i<3;i++) + { + interval |= ( cvmx_twsi_read8(CVMX_RTC_DS1374_ADDR,RTC_WD_ALM_CNT_BYTE0_ADDR+i) & 0xff) << (i*8); + } + return interval; +} + + +#ifdef CVMX_RTC_DEBUG + +void cvmx_rtc_ds1374_dump_state(void) +{ + int i = 0; + + cvmx_dprintf("RTC:\n"); + cvmx_dprintf("%d : %02X ", i, cvmx_twsi_read8(CVMX_RTC_DS1374_ADDR, 0x0)); + for(i=1; i<10; i++) + { + cvmx_dprintf("%02X ", cvmx_twsi_read8_cur_addr(CVMX_RTC_DS1374_ADDR)); + } + cvmx_dprintf("\n"); +} + +#endif /* CVMX_RTC_DEBUG */ + + +/* + * LAN bypass functionality + */ + +/* Private initialization function */ +static int cvmx_lan_bypass_init(void) +{ + const int CLR_PULSE = 100; /* Longer than 100 ns (on CPUs up to 1 GHz) */ + + //Clear GPIO 6 + cvmx_gpio_clear(BYPASS_EN); + + //Disable WDT + cvmx_rtc_ds1374_alarm_set(0); + + //GPIO(7) Send a low pulse + cvmx_gpio_clear(WDT_BP_CLR); + cvmx_wait(CLR_PULSE); + cvmx_gpio_set(WDT_BP_CLR); + return 0; +} + +/** + * Set LAN bypass mode. + * + * Supported modes are: + * - CVMX_LAN_BYPASS_OFF + * <br>LAN ports are connected ( port 0 <--> Octeon <--> port 1 ) + * + * - CVMX_LAN_BYPASS_GPIO + * <br>LAN bypass is controlled by software using cvmx_lan_bypass_force() function. + * When transitioning to this mode, default is LAN bypass enabled + * ( port 0 <--> port 1, -- Octeon ). + * + * - CVMX_LAN_BYPASS_WATCHDOG + * <br>LAN bypass is inactive as long as a watchdog is kept alive. + * The default expiration time is 1 second and the function to + * call periodically to prevent watchdog expiration is + * cvmx_lan_bypass_keep_alive(). + * + * @param mode LAN bypass mode + * + * @return Error code, or 0 in case of success + */ +int cvmx_lan_bypass_mode_set(cvmx_lan_bypass_mode_t mode) +{ + switch(mode) + { + case CVMX_LAN_BYPASS_GPIO: + /* make lan bypass enable */ + cvmx_lan_bypass_init(); + cvmx_gpio_set(BYPASS_EN); + CVMX_LAN_BYPASS_MSG("Enable LAN bypass by GPIO. \n"); + break; + + case CVMX_LAN_BYPASS_WATCHDOG: + /* make lan bypass enable */ + cvmx_lan_bypass_init(); + /* Set WDT parameters and turn it on */ + cvmx_rtc_ds1374_alarm_counter_set(0x1000); /* 4096 ticks = 1 sec */ + cvmx_rtc_ds1374_alarm_config(1,1,1); + cvmx_rtc_ds1374_alarm_set(1); + CVMX_LAN_BYPASS_MSG("Enable LAN bypass by WDT. \n"); + break; + + case CVMX_LAN_BYPASS_OFF: + /* make lan bypass disable */ + cvmx_lan_bypass_init(); + CVMX_LAN_BYPASS_MSG("Disable LAN bypass. \n"); + break; + + default: + CVMX_LAN_BYPASS_MSG("%s: LAN bypass mode %d not supported\n", __FUNCTION__, mode); + break; + } + return 0; +} + +/** + * Refresh watchdog timer. + * + * Call periodically (less than 1 second) to prevent triggering LAN bypass. + * The alternative cvmx_lan_bypass_keep_alive_ms() is provided for cases + * where a variable interval is required. + */ +void cvmx_lan_bypass_keep_alive(void) +{ + cvmx_rtc_ds1374_alarm_counter_set(0x1000); /* 4096 ticks = 1 second */ +} + +/** + * Refresh watchdog timer, setting a specific expiration interval. + * + * @param interval_ms Interval, in milliseconds, to next watchdog expiration. + */ +void cvmx_lan_bypass_keep_alive_ms(uint32_t interval_ms) +{ + cvmx_rtc_ds1374_alarm_counter_set((interval_ms * 0x1000) / 1000); +} + +/** + * Control LAN bypass via software. + * + * @param force_bypass Force LAN bypass to active (1) or inactive (0) + * + * @return Error code, or 0 in case of success + */ +int cvmx_lan_bypass_force(int force_bypass) +{ + if (force_bypass) + { + //Set GPIO 6 + cvmx_gpio_set(BYPASS_EN); + } + else + { + cvmx_lan_bypass_init(); + } + return 0; +} + +/** + * Return status of LAN bypass circuit. + * + * @return 1 if ports are in LAN bypass, or 0 if normally connected + */ +int cvmx_lan_bypass_is_active(void) +{ + return !!(cvmx_gpio_read() & BYPASS_STATUS); +} |