Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.26-rc9 266 lines 7.2 kB view raw
1/**************************************************************************** 2 * Driver for Solarflare Solarstorm network controllers and boards 3 * Copyright 2007 Solarflare Communications Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published 7 * by the Free Software Foundation, incorporated herein by reference. 8 */ 9 10/***************************************************************************** 11 * Support for the SFE4001 NIC: driver code for the PCA9539 I/O expander that 12 * controls the PHY power rails, and for the MAX6647 temp. sensor used to check 13 * the PHY 14 */ 15#include <linux/delay.h> 16#include "efx.h" 17#include "phy.h" 18#include "boards.h" 19#include "falcon.h" 20#include "falcon_hwdefs.h" 21#include "mac.h" 22 23/************************************************************************** 24 * 25 * I2C IO Expander device 26 * 27 **************************************************************************/ 28#define PCA9539 0x74 29 30#define P0_IN 0x00 31#define P0_OUT 0x02 32#define P0_INVERT 0x04 33#define P0_CONFIG 0x06 34 35#define P0_EN_1V0X_LBN 0 36#define P0_EN_1V0X_WIDTH 1 37#define P0_EN_1V2_LBN 1 38#define P0_EN_1V2_WIDTH 1 39#define P0_EN_2V5_LBN 2 40#define P0_EN_2V5_WIDTH 1 41#define P0_EN_3V3X_LBN 3 42#define P0_EN_3V3X_WIDTH 1 43#define P0_EN_5V_LBN 4 44#define P0_EN_5V_WIDTH 1 45#define P0_SHORTEN_JTAG_LBN 5 46#define P0_SHORTEN_JTAG_WIDTH 1 47#define P0_X_TRST_LBN 6 48#define P0_X_TRST_WIDTH 1 49#define P0_DSP_RESET_LBN 7 50#define P0_DSP_RESET_WIDTH 1 51 52#define P1_IN 0x01 53#define P1_OUT 0x03 54#define P1_INVERT 0x05 55#define P1_CONFIG 0x07 56 57#define P1_AFE_PWD_LBN 0 58#define P1_AFE_PWD_WIDTH 1 59#define P1_DSP_PWD25_LBN 1 60#define P1_DSP_PWD25_WIDTH 1 61#define P1_RESERVED_LBN 2 62#define P1_RESERVED_WIDTH 2 63#define P1_SPARE_LBN 4 64#define P1_SPARE_WIDTH 4 65 66 67/************************************************************************** 68 * 69 * Temperature Sensor 70 * 71 **************************************************************************/ 72#define MAX6647 0x4e 73 74#define RLTS 0x00 75#define RLTE 0x01 76#define RSL 0x02 77#define RCL 0x03 78#define RCRA 0x04 79#define RLHN 0x05 80#define RLLI 0x06 81#define RRHI 0x07 82#define RRLS 0x08 83#define WCRW 0x0a 84#define WLHO 0x0b 85#define WRHA 0x0c 86#define WRLN 0x0e 87#define OSHT 0x0f 88#define REET 0x10 89#define RIET 0x11 90#define RWOE 0x19 91#define RWOI 0x20 92#define HYS 0x21 93#define QUEUE 0x22 94#define MFID 0xfe 95#define REVID 0xff 96 97/* Status bits */ 98#define MAX6647_BUSY (1 << 7) /* ADC is converting */ 99#define MAX6647_LHIGH (1 << 6) /* Local high temp. alarm */ 100#define MAX6647_LLOW (1 << 5) /* Local low temp. alarm */ 101#define MAX6647_RHIGH (1 << 4) /* Remote high temp. alarm */ 102#define MAX6647_RLOW (1 << 3) /* Remote low temp. alarm */ 103#define MAX6647_FAULT (1 << 2) /* DXN/DXP short/open circuit */ 104#define MAX6647_EOT (1 << 1) /* Remote junction overtemp. */ 105#define MAX6647_IOT (1 << 0) /* Local junction overtemp. */ 106 107static const u8 xgphy_max_temperature = 90; 108 109void sfe4001_poweroff(struct efx_nic *efx) 110{ 111 struct efx_i2c_interface *i2c = &efx->i2c; 112 113 u8 cfg, out, in; 114 115 EFX_INFO(efx, "%s\n", __func__); 116 117 /* Turn off all power rails */ 118 out = 0xff; 119 efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); 120 121 /* Disable port 1 outputs on IO expander */ 122 cfg = 0xff; 123 efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1); 124 125 /* Disable port 0 outputs on IO expander */ 126 cfg = 0xff; 127 efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1); 128 129 /* Clear any over-temperature alert */ 130 efx_i2c_read(i2c, MAX6647, RSL, &in, 1); 131} 132 133/* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected 134 * to the FLASH_CFG_1 input on the DSP. We must keep it high at power- 135 * up to allow writing the flash (done through MDIO from userland). 136 */ 137unsigned int sfe4001_phy_flash_cfg; 138module_param_named(phy_flash_cfg, sfe4001_phy_flash_cfg, uint, 0444); 139MODULE_PARM_DESC(phy_flash_cfg, 140 "Force PHY to enter flash configuration mode"); 141 142/* This board uses an I2C expander to provider power to the PHY, which needs to 143 * be turned on before the PHY can be used. 144 * Context: Process context, rtnl lock held 145 */ 146int sfe4001_poweron(struct efx_nic *efx) 147{ 148 struct efx_i2c_interface *i2c = &efx->i2c; 149 unsigned int count; 150 int rc; 151 u8 out, in, cfg; 152 efx_dword_t reg; 153 154 /* 10Xpress has fixed-function LED pins, so there is no board-specific 155 * blink code. */ 156 efx->board_info.blink = tenxpress_phy_blink; 157 158 /* Ensure that XGXS and XAUI SerDes are held in reset */ 159 EFX_POPULATE_DWORD_7(reg, XX_PWRDNA_EN, 1, 160 XX_PWRDNB_EN, 1, 161 XX_RSTPLLAB_EN, 1, 162 XX_RESETA_EN, 1, 163 XX_RESETB_EN, 1, 164 XX_RSTXGXSRX_EN, 1, 165 XX_RSTXGXSTX_EN, 1); 166 falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC); 167 udelay(10); 168 169 /* Set DSP over-temperature alert threshold */ 170 EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature); 171 rc = efx_i2c_write(i2c, MAX6647, WLHO, 172 &xgphy_max_temperature, 1); 173 if (rc) 174 goto fail1; 175 176 /* Read it back and verify */ 177 rc = efx_i2c_read(i2c, MAX6647, RLHN, &in, 1); 178 if (rc) 179 goto fail1; 180 if (in != xgphy_max_temperature) { 181 rc = -EFAULT; 182 goto fail1; 183 } 184 185 /* Clear any previous over-temperature alert */ 186 rc = efx_i2c_read(i2c, MAX6647, RSL, &in, 1); 187 if (rc) 188 goto fail1; 189 190 /* Enable port 0 and port 1 outputs on IO expander */ 191 cfg = 0x00; 192 rc = efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1); 193 if (rc) 194 goto fail1; 195 cfg = 0xff & ~(1 << P1_SPARE_LBN); 196 rc = efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1); 197 if (rc) 198 goto fail2; 199 200 /* Turn all power off then wait 1 sec. This ensures PHY is reset */ 201 out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) | 202 (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) | 203 (0 << P0_EN_1V0X_LBN)); 204 rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); 205 if (rc) 206 goto fail3; 207 208 schedule_timeout_uninterruptible(HZ); 209 count = 0; 210 do { 211 /* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */ 212 out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) | 213 (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) | 214 (1 << P0_X_TRST_LBN)); 215 if (sfe4001_phy_flash_cfg) 216 out |= 1 << P0_EN_3V3X_LBN; 217 218 rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); 219 if (rc) 220 goto fail3; 221 msleep(10); 222 223 /* Turn on 1V power rail */ 224 out &= ~(1 << P0_EN_1V0X_LBN); 225 rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); 226 if (rc) 227 goto fail3; 228 229 EFX_INFO(efx, "waiting for power (attempt %d)...\n", count); 230 231 schedule_timeout_uninterruptible(HZ); 232 233 /* Check DSP is powered */ 234 rc = efx_i2c_read(i2c, PCA9539, P1_IN, &in, 1); 235 if (rc) 236 goto fail3; 237 if (in & (1 << P1_AFE_PWD_LBN)) 238 goto done; 239 240 /* DSP doesn't look powered in flash config mode */ 241 if (sfe4001_phy_flash_cfg) 242 goto done; 243 } while (++count < 20); 244 245 EFX_INFO(efx, "timed out waiting for power\n"); 246 rc = -ETIMEDOUT; 247 goto fail3; 248 249done: 250 EFX_INFO(efx, "PHY is powered on\n"); 251 return 0; 252 253fail3: 254 /* Turn off all power rails */ 255 out = 0xff; 256 efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1); 257 /* Disable port 1 outputs on IO expander */ 258 out = 0xff; 259 efx_i2c_write(i2c, PCA9539, P1_CONFIG, &out, 1); 260fail2: 261 /* Disable port 0 outputs on IO expander */ 262 out = 0xff; 263 efx_i2c_write(i2c, PCA9539, P0_CONFIG, &out, 1); 264fail1: 265 return rc; 266}