PageRenderTime 73ms CodeModel.GetById 4ms app.highlight 55ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/net/wireless/bcm4329/bcmsdstd.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 3127 lines | 2414 code | 482 blank | 231 comment | 507 complexity | 5aad232ff8803f66b7b0f3bea186897f MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

   1/*
   2 *  'Standard' SDIO HOST CONTROLLER driver
   3 *
   4 * Copyright (C) 1999-2010, Broadcom Corporation
   5 * 
   6 *      Unless you and Broadcom execute a separate written software license
   7 * agreement governing use of this software, this software is licensed to you
   8 * under the terms of the GNU General Public License version 2 (the "GPL"),
   9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
  10 * following added to such license:
  11 * 
  12 *      As a special exception, the copyright holders of this software give you
  13 * permission to link this software with independent modules, and to copy and
  14 * distribute the resulting executable under terms of your choice, provided that
  15 * you also meet, for each linked independent module, the terms and conditions of
  16 * the license of that module.  An independent module is a module which is not
  17 * derived from this software.  The special exception does not apply to any
  18 * modifications of the software.
  19 * 
  20 *      Notwithstanding the above, under no circumstances may you combine this
  21 * software in any way with any other Broadcom software provided under a license
  22 * other than the GPL, without Broadcom's express prior written consent.
  23 *
  24 * $Id: bcmsdstd.c,v 1.64.4.1.4.4.2.18 2010/08/17 17:00:48 Exp $
  25 */
  26
  27#include <typedefs.h>
  28
  29#include <bcmdevs.h>
  30#include <bcmendian.h>
  31#include <bcmutils.h>
  32#include <osl.h>
  33#include <siutils.h>
  34#include <sdio.h>	/* SDIO Device and Protocol Specs */
  35#include <sdioh.h>	/* SDIO Host Controller Specification */
  36#include <bcmsdbus.h>	/* bcmsdh to/from specific controller APIs */
  37#include <sdiovar.h>	/* ioctl/iovars */
  38#include <pcicfg.h>
  39
  40
  41#define SD_PAGE_BITS	12
  42#define SD_PAGE 	(1 << SD_PAGE_BITS)
  43
  44#include <bcmsdstd.h>
  45
  46/* Globals */
  47uint sd_msglevel = SDH_ERROR_VAL;
  48uint sd_hiok = TRUE;			/* Use hi-speed mode if available? */
  49uint sd_sdmode = SDIOH_MODE_SD4;	/* Use SD4 mode by default */
  50uint sd_f2_blocksize = 64;		/* Default blocksize */
  51
  52#ifdef BCMSDYIELD
  53bool sd_yieldcpu = TRUE;		/* Allow CPU yielding for buffer requests */
  54uint sd_minyield = 0;			/* Minimum xfer size to allow CPU yield */
  55bool sd_forcerb = FALSE;		/* Force sync readback in intrs_on/off */
  56#endif
  57
  58uint sd_divisor = 2;			/* Default 48MHz/2 = 24MHz */
  59
  60uint sd_power = 1;		/* Default to SD Slot powered ON */
  61uint sd_clock = 1;		/* Default to SD Clock turned ON */
  62uint sd_pci_slot = 0xFFFFffff; /* Used to force selection of a particular PCI slot */
  63uint8 sd_dma_mode = DMA_MODE_SDMA; /* Default to SDMA for now */
  64
  65uint sd_toctl = 7;
  66
  67static bool trap_errs = FALSE;
  68
  69static const char *dma_mode_description[] = { "PIO", "SDMA", "ADMA1", "32b ADMA2", "64b ADMA2" };
  70
  71/* Prototypes */
  72static bool sdstd_start_clock(sdioh_info_t *sd, uint16 divisor);
  73static bool sdstd_start_power(sdioh_info_t *sd);
  74static bool sdstd_bus_width(sdioh_info_t *sd, int width);
  75static int sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode);
  76static int sdstd_set_dma_mode(sdioh_info_t *sd, int8 dma_mode);
  77static int sdstd_card_enablefuncs(sdioh_info_t *sd);
  78static void sdstd_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count);
  79static int sdstd_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd, uint32 arg);
  80static int sdstd_card_regread(sdioh_info_t *sd, int func, uint32 regaddr,
  81                              int regsize, uint32 *data);
  82static int sdstd_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr,
  83                               int regsize, uint32 data);
  84static int sdstd_driver_init(sdioh_info_t *sd);
  85static bool sdstd_reset(sdioh_info_t *sd, bool host_reset, bool client_reset);
  86static int sdstd_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo,
  87                          uint32 addr, int nbytes, uint32 *data);
  88static int sdstd_abort(sdioh_info_t *sd, uint func);
  89static int sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg);
  90static int set_client_block_size(sdioh_info_t *sd, int func, int blocksize);
  91static void sd_map_dma(sdioh_info_t * sd);
  92static void sd_unmap_dma(sdioh_info_t * sd);
  93static void sd_clear_adma_dscr_buf(sdioh_info_t *sd);
  94static void sd_fill_dma_data_buf(sdioh_info_t *sd, uint8 data);
  95static void sd_create_adma_descriptor(sdioh_info_t *sd,
  96                                      uint32 index, uint32 addr_phys,
  97                                      uint16 length, uint16 flags);
  98static void sd_dump_adma_dscr(sdioh_info_t *sd);
  99static void sdstd_dumpregs(sdioh_info_t *sd);
 100
 101
 102/*
 103 * Private register access routines.
 104 */
 105
 106/* 16 bit PCI regs */
 107
 108extern uint16 sdstd_rreg16(sdioh_info_t *sd, uint reg);
 109uint16
 110sdstd_rreg16(sdioh_info_t *sd, uint reg)
 111{
 112
 113	volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
 114	sd_ctrl(("16: R Reg 0x%02x, Data 0x%x\n", reg, data));
 115	return data;
 116}
 117
 118extern void sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data);
 119void
 120sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data)
 121{
 122	*(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
 123	sd_ctrl(("16: W Reg 0x%02x, Data 0x%x\n", reg, data));
 124}
 125
 126static void
 127sdstd_or_reg16(sdioh_info_t *sd, uint reg, uint16 val)
 128{
 129	volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
 130	sd_ctrl(("16: OR Reg 0x%02x, Val 0x%x\n", reg, val));
 131	data |= val;
 132	*(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
 133
 134}
 135static void
 136sdstd_mod_reg16(sdioh_info_t *sd, uint reg, int16 mask, uint16 val)
 137{
 138
 139	volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
 140	sd_ctrl(("16: MOD Reg 0x%02x, Mask 0x%x, Val 0x%x\n", reg, mask, val));
 141	data &= ~mask;
 142	data |= (val & mask);
 143	*(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
 144}
 145
 146
 147/* 32 bit PCI regs */
 148static uint32
 149sdstd_rreg(sdioh_info_t *sd, uint reg)
 150{
 151	volatile uint32 data = *(volatile uint32 *)(sd->mem_space + reg);
 152	sd_ctrl(("32: R Reg 0x%02x, Data 0x%x\n", reg, data));
 153	return data;
 154}
 155static inline void
 156sdstd_wreg(sdioh_info_t *sd, uint reg, uint32 data)
 157{
 158	*(volatile uint32 *)(sd->mem_space + reg) = (uint32)data;
 159	sd_ctrl(("32: W Reg 0x%02x, Data 0x%x\n", reg, data));
 160
 161}
 162
 163/* 8 bit PCI regs */
 164static inline void
 165sdstd_wreg8(sdioh_info_t *sd, uint reg, uint8 data)
 166{
 167	*(volatile uint8 *)(sd->mem_space + reg) = (uint8)data;
 168	sd_ctrl(("08: W Reg 0x%02x, Data 0x%x\n", reg, data));
 169}
 170static uint8
 171sdstd_rreg8(sdioh_info_t *sd, uint reg)
 172{
 173	volatile uint8 data = *(volatile uint8 *)(sd->mem_space + reg);
 174	sd_ctrl(("08: R Reg 0x%02x, Data 0x%x\n", reg, data));
 175	return data;
 176}
 177
 178/*
 179 * Private work routines
 180 */
 181
 182sdioh_info_t *glob_sd;
 183
 184/*
 185 *  Public entry points & extern's
 186 */
 187extern sdioh_info_t *
 188sdioh_attach(osl_t *osh, void *bar0, uint irq)
 189{
 190	sdioh_info_t *sd;
 191
 192	sd_trace(("%s\n", __FUNCTION__));
 193	if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) {
 194		sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh)));
 195		return NULL;
 196	}
 197	bzero((char *)sd, sizeof(sdioh_info_t));
 198	glob_sd = sd;
 199	sd->osh = osh;
 200	if (sdstd_osinit(sd) != 0) {
 201		sd_err(("%s:sdstd_osinit() failed\n", __FUNCTION__));
 202		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
 203		return NULL;
 204	}
 205	sd->mem_space = (volatile char *)sdstd_reg_map(osh, (uintptr)bar0, SDIOH_REG_WINSZ);
 206	sd_init_dma(sd);
 207	sd->irq = irq;
 208	if (sd->mem_space == NULL) {
 209		sd_err(("%s:ioremap() failed\n", __FUNCTION__));
 210		sdstd_osfree(sd);
 211		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
 212		return NULL;
 213	}
 214	sd_info(("%s:sd->mem_space = %p\n", __FUNCTION__, sd->mem_space));
 215	sd->intr_handler = NULL;
 216	sd->intr_handler_arg = NULL;
 217	sd->intr_handler_valid = FALSE;
 218
 219	/* Set defaults */
 220	sd->sd_blockmode = TRUE;
 221	sd->use_client_ints = TRUE;
 222	sd->sd_dma_mode = sd_dma_mode;
 223
 224	if (!sd->sd_blockmode)
 225		sd->sd_dma_mode = DMA_MODE_NONE;
 226
 227	if (sdstd_driver_init(sd) != SUCCESS) {
 228		/* If host CPU was reset without resetting SD bus or
 229		   SD device, the device will still have its RCA but
 230		   driver no longer knows what it is (since driver has been restarted).
 231		   go through once to clear the RCA and a gain reassign it.
 232		 */
 233		sd_info(("driver_init failed - Reset RCA and try again\n"));
 234		if (sdstd_driver_init(sd) != SUCCESS) {
 235			sd_err(("%s:driver_init() failed()\n", __FUNCTION__));
 236			if (sd->mem_space) {
 237				sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ);
 238				sd->mem_space = NULL;
 239			}
 240			sdstd_osfree(sd);
 241			MFREE(sd->osh, sd, sizeof(sdioh_info_t));
 242			return (NULL);
 243		}
 244	}
 245
 246	OSL_DMADDRWIDTH(osh, 32);
 247
 248	/* Always map DMA buffers, so we can switch between DMA modes. */
 249	sd_map_dma(sd);
 250
 251	if (sdstd_register_irq(sd, irq) != SUCCESS) {
 252		sd_err(("%s: sdstd_register_irq() failed for irq = %d\n", __FUNCTION__, irq));
 253		sdstd_free_irq(sd->irq, sd);
 254		if (sd->mem_space) {
 255			sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ);
 256			sd->mem_space = NULL;
 257		}
 258
 259		sdstd_osfree(sd);
 260		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
 261		return (NULL);
 262	}
 263
 264	sd_trace(("%s: Done\n", __FUNCTION__));
 265	return sd;
 266}
 267
 268extern SDIOH_API_RC
 269sdioh_detach(osl_t *osh, sdioh_info_t *sd)
 270{
 271	sd_trace(("%s\n", __FUNCTION__));
 272	if (sd) {
 273		sd_unmap_dma(sd);
 274		sdstd_wreg16(sd, SD_IntrSignalEnable, 0);
 275		sd_trace(("%s: freeing irq %d\n", __FUNCTION__, sd->irq));
 276		sdstd_free_irq(sd->irq, sd);
 277		if (sd->card_init_done)
 278			sdstd_reset(sd, 1, 1);
 279		if (sd->mem_space) {
 280			sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ);
 281			sd->mem_space = NULL;
 282		}
 283
 284		sdstd_osfree(sd);
 285		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
 286	}
 287	return SDIOH_API_RC_SUCCESS;
 288}
 289
 290/* Configure callback to client when we receive client interrupt */
 291extern SDIOH_API_RC
 292sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
 293{
 294	sd_trace(("%s: Entering\n", __FUNCTION__));
 295	sd->intr_handler = fn;
 296	sd->intr_handler_arg = argh;
 297	sd->intr_handler_valid = TRUE;
 298	return SDIOH_API_RC_SUCCESS;
 299}
 300
 301extern SDIOH_API_RC
 302sdioh_interrupt_deregister(sdioh_info_t *sd)
 303{
 304	sd_trace(("%s: Entering\n", __FUNCTION__));
 305	sd->intr_handler_valid = FALSE;
 306	sd->intr_handler = NULL;
 307	sd->intr_handler_arg = NULL;
 308	return SDIOH_API_RC_SUCCESS;
 309}
 310
 311extern SDIOH_API_RC
 312sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff)
 313{
 314	sd_trace(("%s: Entering\n", __FUNCTION__));
 315	*onoff = sd->client_intr_enabled;
 316	return SDIOH_API_RC_SUCCESS;
 317}
 318
 319#if defined(DHD_DEBUG)
 320extern bool
 321sdioh_interrupt_pending(sdioh_info_t *sd)
 322{
 323	uint16 intrstatus;
 324	intrstatus = sdstd_rreg16(sd, SD_IntrStatus);
 325	return !!(intrstatus & CLIENT_INTR);
 326}
 327#endif
 328
 329uint
 330sdioh_query_iofnum(sdioh_info_t *sd)
 331{
 332	return sd->num_funcs;
 333}
 334
 335/* IOVar table */
 336enum {
 337	IOV_MSGLEVEL = 1,
 338	IOV_BLOCKMODE,
 339	IOV_BLOCKSIZE,
 340	IOV_DMA,
 341	IOV_USEINTS,
 342	IOV_NUMINTS,
 343	IOV_NUMLOCALINTS,
 344	IOV_HOSTREG,
 345	IOV_DEVREG,
 346	IOV_DIVISOR,
 347	IOV_SDMODE,
 348	IOV_HISPEED,
 349	IOV_HCIREGS,
 350	IOV_POWER,
 351	IOV_YIELDCPU,
 352	IOV_MINYIELD,
 353	IOV_FORCERB,
 354	IOV_CLOCK
 355};
 356
 357const bcm_iovar_t sdioh_iovars[] = {
 358	{"sd_msglevel",	IOV_MSGLEVEL, 	0,	IOVT_UINT32,	0 },
 359	{"sd_blockmode", IOV_BLOCKMODE,	0,	IOVT_BOOL,	0 },
 360	{"sd_blocksize", IOV_BLOCKSIZE, 0,	IOVT_UINT32,	0 }, /* ((fn << 16) | size) */
 361	{"sd_dma",	IOV_DMA,	0,	IOVT_UINT32,	0 },
 362#ifdef BCMSDYIELD
 363	{"sd_yieldcpu",	IOV_YIELDCPU,	0,	IOVT_BOOL,	0 },
 364	{"sd_minyield",	IOV_MINYIELD,	0,	IOVT_UINT32,	0 },
 365	{"sd_forcerb",	IOV_FORCERB,	0,	IOVT_BOOL,	0 },
 366#endif
 367	{"sd_ints",	IOV_USEINTS,	0,	IOVT_BOOL,	0 },
 368	{"sd_numints",	IOV_NUMINTS,	0,	IOVT_UINT32,	0 },
 369	{"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32,	0 },
 370	{"sd_hostreg",	IOV_HOSTREG,	0,	IOVT_BUFFER,	sizeof(sdreg_t) },
 371	{"sd_devreg",	IOV_DEVREG,	0,	IOVT_BUFFER,	sizeof(sdreg_t)	},
 372	{"sd_divisor",	IOV_DIVISOR,	0,	IOVT_UINT32,	0 },
 373	{"sd_power",	IOV_POWER,	0,	IOVT_UINT32,	0 },
 374	{"sd_clock",	IOV_CLOCK,	0,	IOVT_UINT32,	0 },
 375	{"sd_mode",	IOV_SDMODE,	0,	IOVT_UINT32,	100},
 376	{"sd_highspeed",	IOV_HISPEED,	0,	IOVT_UINT32,	0},
 377	{NULL, 0, 0, 0, 0 }
 378};
 379
 380int
 381sdioh_iovar_op(sdioh_info_t *si, const char *name,
 382               void *params, int plen, void *arg, int len, bool set)
 383{
 384	const bcm_iovar_t *vi = NULL;
 385	int bcmerror = 0;
 386	int val_size;
 387	int32 int_val = 0;
 388	bool bool_val;
 389	uint32 actionid;
 390
 391	ASSERT(name);
 392	ASSERT(len >= 0);
 393
 394	/* Get must have return space; Set does not take qualifiers */
 395	ASSERT(set || (arg && len));
 396	ASSERT(!set || (!params && !plen));
 397
 398	sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name));
 399
 400	if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) {
 401		bcmerror = BCME_UNSUPPORTED;
 402		goto exit;
 403	}
 404
 405	if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0)
 406		goto exit;
 407
 408	/* Set up params so get and set can share the convenience variables */
 409	if (params == NULL) {
 410		params = arg;
 411		plen = len;
 412	}
 413
 414	if (vi->type == IOVT_VOID)
 415		val_size = 0;
 416	else if (vi->type == IOVT_BUFFER)
 417		val_size = len;
 418	else
 419		val_size = sizeof(int);
 420
 421	if (plen >= (int)sizeof(int_val))
 422		bcopy(params, &int_val, sizeof(int_val));
 423
 424	bool_val = (int_val != 0) ? TRUE : FALSE;
 425
 426	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
 427	switch (actionid) {
 428	case IOV_GVAL(IOV_MSGLEVEL):
 429		int_val = (int32)sd_msglevel;
 430		bcopy(&int_val, arg, val_size);
 431		break;
 432
 433	case IOV_SVAL(IOV_MSGLEVEL):
 434		sd_msglevel = int_val;
 435		break;
 436
 437	case IOV_GVAL(IOV_BLOCKMODE):
 438		int_val = (int32)si->sd_blockmode;
 439		bcopy(&int_val, arg, val_size);
 440		break;
 441
 442	case IOV_SVAL(IOV_BLOCKMODE):
 443		si->sd_blockmode = (bool)int_val;
 444		/* Haven't figured out how to make non-block mode with DMA */
 445		if (!si->sd_blockmode)
 446			si->sd_dma_mode = DMA_MODE_NONE;
 447		break;
 448
 449#ifdef BCMSDYIELD
 450	case IOV_GVAL(IOV_YIELDCPU):
 451		int_val = sd_yieldcpu;
 452		bcopy(&int_val, arg, val_size);
 453		break;
 454
 455	case IOV_SVAL(IOV_YIELDCPU):
 456		sd_yieldcpu = (bool)int_val;
 457		break;
 458
 459	case IOV_GVAL(IOV_MINYIELD):
 460		int_val = sd_minyield;
 461		bcopy(&int_val, arg, val_size);
 462		break;
 463
 464	case IOV_SVAL(IOV_MINYIELD):
 465		sd_minyield = (bool)int_val;
 466		break;
 467
 468	case IOV_GVAL(IOV_FORCERB):
 469		int_val = sd_forcerb;
 470		bcopy(&int_val, arg, val_size);
 471		break;
 472
 473	case IOV_SVAL(IOV_FORCERB):
 474		sd_forcerb = (bool)int_val;
 475		break;
 476#endif /* BCMSDYIELD */
 477
 478	case IOV_GVAL(IOV_BLOCKSIZE):
 479		if ((uint32)int_val > si->num_funcs) {
 480			bcmerror = BCME_BADARG;
 481			break;
 482		}
 483		int_val = (int32)si->client_block_size[int_val];
 484		bcopy(&int_val, arg, val_size);
 485		break;
 486
 487	case IOV_SVAL(IOV_BLOCKSIZE):
 488	{
 489		uint func = ((uint32)int_val >> 16);
 490		uint blksize = (uint16)int_val;
 491		uint maxsize;
 492
 493		if (func > si->num_funcs) {
 494			bcmerror = BCME_BADARG;
 495			break;
 496		}
 497
 498		switch (func) {
 499		case 0: maxsize = 32; break;
 500		case 1: maxsize = BLOCK_SIZE_4318; break;
 501		case 2: maxsize = BLOCK_SIZE_4328; break;
 502		default: maxsize = 0;
 503		}
 504		if (blksize > maxsize) {
 505			bcmerror = BCME_BADARG;
 506			break;
 507		}
 508		if (!blksize) {
 509			blksize = maxsize;
 510		}
 511
 512		/* Now set it */
 513		sdstd_lock(si);
 514		bcmerror = set_client_block_size(si, func, blksize);
 515		sdstd_unlock(si);
 516		break;
 517	}
 518
 519	case IOV_GVAL(IOV_DMA):
 520		int_val = (int32)si->sd_dma_mode;
 521		bcopy(&int_val, arg, val_size);
 522		break;
 523
 524	case IOV_SVAL(IOV_DMA):
 525		si->sd_dma_mode = (char)int_val;
 526		sdstd_set_dma_mode(si, si->sd_dma_mode);
 527		break;
 528
 529	case IOV_GVAL(IOV_USEINTS):
 530		int_val = (int32)si->use_client_ints;
 531		bcopy(&int_val, arg, val_size);
 532		break;
 533
 534	case IOV_SVAL(IOV_USEINTS):
 535		si->use_client_ints = (bool)int_val;
 536		if (si->use_client_ints)
 537			si->intmask |= CLIENT_INTR;
 538		else
 539			si->intmask &= ~CLIENT_INTR;
 540		break;
 541
 542	case IOV_GVAL(IOV_DIVISOR):
 543		int_val = (uint32)sd_divisor;
 544		bcopy(&int_val, arg, val_size);
 545		break;
 546
 547	case IOV_SVAL(IOV_DIVISOR):
 548		sd_divisor = int_val;
 549		if (!sdstd_start_clock(si, (uint16)sd_divisor)) {
 550			sd_err(("set clock failed!\n"));
 551			bcmerror = BCME_ERROR;
 552		}
 553		break;
 554
 555	case IOV_GVAL(IOV_POWER):
 556		int_val = (uint32)sd_power;
 557		bcopy(&int_val, arg, val_size);
 558		break;
 559
 560	case IOV_SVAL(IOV_POWER):
 561		sd_power = int_val;
 562		if (sd_power == 1) {
 563			if (sdstd_driver_init(si) != SUCCESS) {
 564				sd_err(("set SD Slot power failed!\n"));
 565				bcmerror = BCME_ERROR;
 566			} else {
 567				sd_err(("SD Slot Powered ON.\n"));
 568			}
 569		} else {
 570			uint8 pwr = 0;
 571
 572			pwr = SFIELD(pwr, PWR_BUS_EN, 0);
 573			sdstd_wreg8(si, SD_PwrCntrl, pwr); /* Set Voltage level */
 574			sd_err(("SD Slot Powered OFF.\n"));
 575		}
 576		break;
 577
 578	case IOV_GVAL(IOV_CLOCK):
 579		int_val = (uint32)sd_clock;
 580		bcopy(&int_val, arg, val_size);
 581		break;
 582
 583	case IOV_SVAL(IOV_CLOCK):
 584		sd_clock = int_val;
 585		if (sd_clock == 1) {
 586			sd_info(("SD Clock turned ON.\n"));
 587			if (!sdstd_start_clock(si, (uint16)sd_divisor)) {
 588				sd_err(("sdstd_start_clock failed\n"));
 589				bcmerror = BCME_ERROR;
 590			}
 591		} else {
 592			/* turn off HC clock */
 593			sdstd_wreg16(si, SD_ClockCntrl,
 594			             sdstd_rreg16(si, SD_ClockCntrl) & ~((uint16)0x4));
 595
 596			sd_info(("SD Clock turned OFF.\n"));
 597		}
 598		break;
 599
 600	case IOV_GVAL(IOV_SDMODE):
 601		int_val = (uint32)sd_sdmode;
 602		bcopy(&int_val, arg, val_size);
 603		break;
 604
 605	case IOV_SVAL(IOV_SDMODE):
 606		sd_sdmode = int_val;
 607
 608		if (!sdstd_bus_width(si, sd_sdmode)) {
 609			sd_err(("sdstd_bus_width failed\n"));
 610			bcmerror = BCME_ERROR;
 611		}
 612		break;
 613
 614	case IOV_GVAL(IOV_HISPEED):
 615		int_val = (uint32)sd_hiok;
 616		bcopy(&int_val, arg, val_size);
 617		break;
 618
 619	case IOV_SVAL(IOV_HISPEED):
 620		sd_hiok = int_val;
 621		bcmerror = sdstd_set_highspeed_mode(si, (bool)sd_hiok);
 622		break;
 623
 624	case IOV_GVAL(IOV_NUMINTS):
 625		int_val = (int32)si->intrcount;
 626		bcopy(&int_val, arg, val_size);
 627		break;
 628
 629	case IOV_GVAL(IOV_NUMLOCALINTS):
 630		int_val = (int32)si->local_intrcount;
 631		bcopy(&int_val, arg, val_size);
 632		break;
 633
 634	case IOV_GVAL(IOV_HOSTREG):
 635	{
 636		sdreg_t *sd_ptr = (sdreg_t *)params;
 637
 638		if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
 639			sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
 640			bcmerror = BCME_BADARG;
 641			break;
 642		}
 643
 644		sd_trace(("%s: rreg%d at offset %d\n", __FUNCTION__,
 645		          (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
 646		          sd_ptr->offset));
 647		if (sd_ptr->offset & 1)
 648			int_val = sdstd_rreg8(si, sd_ptr->offset);
 649		else if (sd_ptr->offset & 2)
 650			int_val = sdstd_rreg16(si, sd_ptr->offset);
 651		else
 652			int_val = sdstd_rreg(si, sd_ptr->offset);
 653
 654		bcopy(&int_val, arg, sizeof(int_val));
 655		break;
 656	}
 657
 658	case IOV_SVAL(IOV_HOSTREG):
 659	{
 660		sdreg_t *sd_ptr = (sdreg_t *)params;
 661
 662		if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
 663			sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
 664			bcmerror = BCME_BADARG;
 665			break;
 666		}
 667
 668		sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value,
 669		          (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
 670		          sd_ptr->offset));
 671		if (sd_ptr->offset & 1)
 672			sdstd_wreg8(si, sd_ptr->offset, (uint8)sd_ptr->value);
 673		else if (sd_ptr->offset & 2)
 674			sdstd_wreg16(si, sd_ptr->offset, (uint16)sd_ptr->value);
 675		else
 676			sdstd_wreg(si, sd_ptr->offset, (uint32)sd_ptr->value);
 677
 678		break;
 679	}
 680
 681	case IOV_GVAL(IOV_DEVREG):
 682	{
 683		sdreg_t *sd_ptr = (sdreg_t *)params;
 684		uint8 data;
 685
 686		if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) {
 687			bcmerror = BCME_SDIO_ERROR;
 688			break;
 689		}
 690
 691		int_val = (int)data;
 692		bcopy(&int_val, arg, sizeof(int_val));
 693		break;
 694	}
 695
 696	case IOV_SVAL(IOV_DEVREG):
 697	{
 698		sdreg_t *sd_ptr = (sdreg_t *)params;
 699		uint8 data = (uint8)sd_ptr->value;
 700
 701		if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) {
 702			bcmerror = BCME_SDIO_ERROR;
 703			break;
 704		}
 705		break;
 706	}
 707
 708
 709	default:
 710		bcmerror = BCME_UNSUPPORTED;
 711		break;
 712	}
 713exit:
 714
 715	return bcmerror;
 716}
 717
 718extern SDIOH_API_RC
 719sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
 720{
 721	SDIOH_API_RC status;
 722	/* No lock needed since sdioh_request_byte does locking */
 723	status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data);
 724	return status;
 725}
 726
 727extern SDIOH_API_RC
 728sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
 729{
 730	/* No lock needed since sdioh_request_byte does locking */
 731	SDIOH_API_RC status;
 732	status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data);
 733	return status;
 734}
 735
 736extern SDIOH_API_RC
 737sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length)
 738{
 739	uint32 count;
 740	int offset;
 741	uint32 foo;
 742	uint8 *cis = cisd;
 743
 744	sd_trace(("%s: Func = %d\n", __FUNCTION__, func));
 745
 746	if (!sd->func_cis_ptr[func]) {
 747		bzero(cis, length);
 748		return SDIOH_API_RC_FAIL;
 749	}
 750
 751	sdstd_lock(sd);
 752	*cis = 0;
 753	for (count = 0; count < length; count++) {
 754		offset =  sd->func_cis_ptr[func] + count;
 755		if (sdstd_card_regread(sd, 0, offset, 1, &foo)) {
 756			sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__));
 757			sdstd_unlock(sd);
 758			return SDIOH_API_RC_FAIL;
 759		}
 760		*cis = (uint8)(foo & 0xff);
 761		cis++;
 762	}
 763	sdstd_unlock(sd);
 764	return SDIOH_API_RC_SUCCESS;
 765}
 766
 767extern SDIOH_API_RC
 768sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte)
 769{
 770	int status;
 771	uint32 cmd_arg;
 772	uint32 rsp5;
 773
 774	sdstd_lock(sd);
 775	cmd_arg = 0;
 776	cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func);
 777	cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr);
 778	cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, rw == SDIOH_READ ? 0 : 1);
 779	cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0);
 780	cmd_arg = SFIELD(cmd_arg, CMD52_DATA, rw == SDIOH_READ ? 0 : *byte);
 781
 782	if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg)) != SUCCESS) {
 783		sdstd_unlock(sd);
 784		return status;
 785	}
 786
 787	sdstd_cmd_getrsp(sd, &rsp5, 1);
 788	if (sdstd_rreg16 (sd, SD_ErrorIntrStatus) != 0) {
 789		sd_err(("%s: 1: ErrorintrStatus 0x%x\n",
 790		        __FUNCTION__, sdstd_rreg16(sd, SD_ErrorIntrStatus)));
 791	}
 792	if (GFIELD(rsp5, RSP5_FLAGS) != 0x10)
 793		sd_err(("%s: rsp5 flags is 0x%x\t %d\n",
 794		        __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func));
 795
 796	if (GFIELD(rsp5, RSP5_STUFF))
 797		sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n",
 798		        __FUNCTION__, GFIELD(rsp5, RSP5_STUFF)));
 799
 800	if (rw == SDIOH_READ)
 801		*byte = GFIELD(rsp5, RSP5_DATA);
 802
 803	sdstd_unlock(sd);
 804	return SDIOH_API_RC_SUCCESS;
 805}
 806
 807extern SDIOH_API_RC
 808sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr,
 809                   uint32 *word, uint nbytes)
 810{
 811	int status;
 812	bool swap = FALSE;
 813
 814	sdstd_lock(sd);
 815
 816	if (rw == SDIOH_READ) {
 817		status = sdstd_card_regread(sd, func, addr, nbytes, word);
 818		if (swap)
 819			*word = BCMSWAP32(*word);
 820	} else {
 821		if (swap)
 822			*word = BCMSWAP32(*word);
 823		status = sdstd_card_regwrite(sd, func, addr, nbytes, *word);
 824	}
 825
 826	sdstd_unlock(sd);
 827	return (status == SUCCESS ?  SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
 828}
 829
 830extern SDIOH_API_RC
 831sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func,
 832                     uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt)
 833{
 834	int len;
 835	int buflen = (int)buflen_u;
 836	bool fifo = (fix_inc == SDIOH_DATA_FIX);
 837	uint8 *localbuf = NULL, *tmpbuf = NULL;
 838	uint tmplen = 0;
 839	bool local_blockmode = sd->sd_blockmode;
 840
 841	sdstd_lock(sd);
 842
 843	ASSERT(reg_width == 4);
 844	ASSERT(buflen_u < (1 << 30));
 845	ASSERT(sd->client_block_size[func]);
 846
 847	sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n",
 848	         __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W',
 849	         buflen_u, sd->r_cnt, sd->t_cnt, pkt));
 850
 851	/* Break buffer down into blocksize chunks:
 852	 * Bytemode: 1 block at a time.
 853	 * Blockmode: Multiples of blocksizes at a time w/ max of SD_PAGE.
 854	 * Both: leftovers are handled last (will be sent via bytemode).
 855	 */
 856	while (buflen > 0) {
 857		if (local_blockmode) {
 858			/* Max xfer is Page size */
 859			len = MIN(SD_PAGE, buflen);
 860
 861			/* Round down to a block boundry */
 862			if (buflen > sd->client_block_size[func])
 863				len = (len/sd->client_block_size[func]) *
 864				        sd->client_block_size[func];
 865			if ((func == SDIO_FUNC_1) && ((len % 4) == 3) && (rw == SDIOH_WRITE)) {
 866				tmplen = len;
 867				sd_err(("%s: Rounding up buffer to mod4 length.\n", __FUNCTION__));
 868				len++;
 869				tmpbuf = buffer;
 870				if ((localbuf = (uint8 *)MALLOC(sd->osh, len)) == NULL) {
 871					sd_err(("out of memory, malloced %d bytes\n",
 872					        MALLOCED(sd->osh)));
 873					sdstd_unlock(sd);
 874					return SDIOH_API_RC_FAIL;
 875				}
 876				bcopy(buffer, localbuf, len);
 877				buffer = localbuf;
 878			}
 879		} else {
 880			/* Byte mode: One block at a time */
 881			len = MIN(sd->client_block_size[func], buflen);
 882		}
 883
 884		if (sdstd_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) {
 885			sdstd_unlock(sd);
 886			return SDIOH_API_RC_FAIL;
 887		}
 888
 889		if (local_blockmode) {
 890			if ((func == SDIO_FUNC_1) && ((tmplen % 4) == 3) && (rw == SDIOH_WRITE)) {
 891				if (localbuf)
 892					MFREE(sd->osh, localbuf, len);
 893				len--;
 894				buffer = tmpbuf;
 895				sd_err(("%s: Restoring back buffer ptr and len.\n", __FUNCTION__));
 896			}
 897		}
 898
 899		buffer += len;
 900		buflen -= len;
 901		if (!fifo)
 902			addr += len;
 903	}
 904	sdstd_unlock(sd);
 905	return SDIOH_API_RC_SUCCESS;
 906}
 907
 908static
 909int sdstd_abort(sdioh_info_t *sd, uint func)
 910{
 911	int err = 0;
 912	int retries;
 913
 914	uint16 cmd_reg;
 915	uint32 cmd_arg;
 916	uint32 rsp5;
 917	uint8 rflags;
 918
 919	uint16 int_reg = 0;
 920	uint16 plain_intstatus;
 921
 922	/* Argument is write to F0 (CCCR) IOAbort with function number */
 923	cmd_arg = 0;
 924	cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, SDIO_FUNC_0);
 925	cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, SDIOD_CCCR_IOABORT);
 926	cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SD_IO_OP_WRITE);
 927	cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0);
 928	cmd_arg = SFIELD(cmd_arg, CMD52_DATA, func);
 929
 930	/* Command is CMD52 write */
 931	cmd_reg = 0;
 932	cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48_BUSY);
 933	cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1);
 934	cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1);
 935	cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0);
 936	cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_ABORT);
 937	cmd_reg = SFIELD(cmd_reg, CMD_INDEX, SDIOH_CMD_52);
 938
 939	if (sd->sd_mode == SDIOH_MODE_SPI) {
 940		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0);
 941		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0);
 942	}
 943
 944	/* Wait for CMD_INHIBIT to go away as per spec section 3.6.1.1 */
 945	retries = RETRIES_SMALL;
 946	while (GFIELD(sdstd_rreg(sd, SD_PresentState), PRES_CMD_INHIBIT)) {
 947		if (retries == RETRIES_SMALL)
 948			sd_err(("%s: Waiting for Command Inhibit, state 0x%08x\n",
 949			        __FUNCTION__, sdstd_rreg(sd, SD_PresentState)));
 950		if (!--retries) {
 951			sd_err(("%s: Command Inhibit timeout, state 0x%08x\n",
 952			        __FUNCTION__, sdstd_rreg(sd, SD_PresentState)));
 953			if (trap_errs)
 954				ASSERT(0);
 955			err = BCME_SDIO_ERROR;
 956			goto done;
 957		}
 958	}
 959
 960	/* Clear errors from any previous commands */
 961	if ((plain_intstatus = sdstd_rreg16(sd, SD_ErrorIntrStatus)) != 0) {
 962		sd_err(("abort: clearing errstat 0x%04x\n", plain_intstatus));
 963		sdstd_wreg16(sd, SD_ErrorIntrStatus, plain_intstatus);
 964	}
 965	plain_intstatus = sdstd_rreg16(sd, SD_IntrStatus);
 966	if (plain_intstatus & ~(SFIELD(0, INTSTAT_CARD_INT, 1))) {
 967		sd_err(("abort: intstatus 0x%04x\n", plain_intstatus));
 968		if (GFIELD(plain_intstatus, INTSTAT_CMD_COMPLETE)) {
 969			sd_err(("SDSTD_ABORT: CMD COMPLETE SET BEFORE COMMAND GIVEN!!!\n"));
 970		}
 971		if (GFIELD(plain_intstatus, INTSTAT_CARD_REMOVAL)) {
 972			sd_err(("SDSTD_ABORT: INTSTAT_CARD_REMOVAL\n"));
 973			err = BCME_NODEVICE;
 974			goto done;
 975		}
 976	}
 977
 978	/* Issue the command */
 979	sdstd_wreg(sd, SD_Arg0, cmd_arg);
 980	sdstd_wreg16(sd, SD_Command, cmd_reg);
 981
 982	/* In interrupt mode return, expect later CMD_COMPLETE interrupt */
 983	if (!sd->polled_mode)
 984		return err;
 985
 986	/* Otherwise, wait for the command to complete */
 987	retries = RETRIES_LARGE;
 988	do {
 989		int_reg = sdstd_rreg16(sd, SD_IntrStatus);
 990	} while (--retries &&
 991	         (GFIELD(int_reg, INTSTAT_ERROR_INT) == 0) &&
 992	         (GFIELD(int_reg, INTSTAT_CMD_COMPLETE) == 0));
 993
 994	/* If command completion fails, do a cmd reset and note the error */
 995	if (!retries) {
 996		sd_err(("%s: CMD_COMPLETE timeout: intr 0x%04x err 0x%04x state 0x%08x\n",
 997		        __FUNCTION__, int_reg,
 998		        sdstd_rreg16(sd, SD_ErrorIntrStatus),
 999		        sdstd_rreg(sd, SD_PresentState)));
1000
1001		sdstd_wreg8(sd, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1));
1002		retries = RETRIES_LARGE;
1003		do {
1004			sd_trace(("%s: waiting for CMD line reset\n", __FUNCTION__));
1005		} while ((GFIELD(sdstd_rreg8(sd, SD_SoftwareReset),
1006		                 SW_RESET_CMD)) && retries--);
1007
1008		if (!retries) {
1009			sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__));
1010		}
1011
1012		if (trap_errs)
1013			ASSERT(0);
1014
1015		err = BCME_SDIO_ERROR;
1016	}
1017
1018	/* Clear Command Complete interrupt */
1019	int_reg = SFIELD(0, INTSTAT_CMD_COMPLETE, 1);
1020	sdstd_wreg16(sd, SD_IntrStatus, int_reg);
1021
1022	/* Check for Errors */
1023	if ((plain_intstatus = sdstd_rreg16 (sd, SD_ErrorIntrStatus)) != 0) {
1024		sd_err(("%s: ErrorintrStatus: 0x%x, "
1025		        "(intrstatus = 0x%x, present state 0x%x) clearing\n",
1026		        __FUNCTION__, plain_intstatus,
1027		        sdstd_rreg16(sd, SD_IntrStatus),
1028		        sdstd_rreg(sd, SD_PresentState)));
1029
1030		sdstd_wreg16(sd, SD_ErrorIntrStatus, plain_intstatus);
1031
1032		sdstd_wreg8(sd, SD_SoftwareReset, SFIELD(0, SW_RESET_DAT, 1));
1033		retries = RETRIES_LARGE;
1034		do {
1035			sd_trace(("%s: waiting for DAT line reset\n", __FUNCTION__));
1036		} while ((GFIELD(sdstd_rreg8(sd, SD_SoftwareReset),
1037		                 SW_RESET_DAT)) && retries--);
1038
1039		if (!retries) {
1040			sd_err(("%s: Timeout waiting for DAT line reset\n", __FUNCTION__));
1041		}
1042
1043		if (trap_errs)
1044			ASSERT(0);
1045
1046		/* ABORT is dataless, only cmd errs count */
1047		if (plain_intstatus & ERRINT_CMD_ERRS)
1048			err = BCME_SDIO_ERROR;
1049	}
1050
1051	/* If command failed don't bother looking at response */
1052	if (err)
1053		goto done;
1054
1055	/* Otherwise, check the response */
1056	sdstd_cmd_getrsp(sd, &rsp5, 1);
1057	rflags = GFIELD(rsp5, RSP5_FLAGS);
1058
1059	if (rflags & SD_RSP_R5_ERRBITS) {
1060		sd_err(("%s: R5 flags include errbits: 0x%02x\n", __FUNCTION__, rflags));
1061
1062		/* The CRC error flag applies to the previous command */
1063		if (rflags & (SD_RSP_R5_ERRBITS & ~SD_RSP_R5_COM_CRC_ERROR)) {
1064			err = BCME_SDIO_ERROR;
1065			goto done;
1066		}
1067	}
1068
1069	if (((rflags & (SD_RSP_R5_IO_CURRENTSTATE0 | SD_RSP_R5_IO_CURRENTSTATE1)) != 0x10) &&
1070	    ((rflags & (SD_RSP_R5_IO_CURRENTSTATE0 | SD_RSP_R5_IO_CURRENTSTATE1)) != 0x20)) {
1071		sd_err(("%s: R5 flags has bad state: 0x%02x\n", __FUNCTION__, rflags));
1072		err = BCME_SDIO_ERROR;
1073		goto done;
1074	}
1075
1076	if (GFIELD(rsp5, RSP5_STUFF)) {
1077		sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n",
1078		        __FUNCTION__, GFIELD(rsp5, RSP5_STUFF)));
1079		err = BCME_SDIO_ERROR;
1080		goto done;
1081	}
1082
1083done:
1084	if (err == BCME_NODEVICE)
1085		return err;
1086
1087	sdstd_wreg8(sd, SD_SoftwareReset,
1088	            SFIELD(SFIELD(0, SW_RESET_DAT, 1), SW_RESET_CMD, 1));
1089
1090	retries = RETRIES_LARGE;
1091	do {
1092		rflags = sdstd_rreg8(sd, SD_SoftwareReset);
1093		if (!GFIELD(rflags, SW_RESET_DAT) && !GFIELD(rflags, SW_RESET_CMD))
1094			break;
1095	} while (--retries);
1096
1097	if (!retries) {
1098		sd_err(("%s: Timeout waiting for DAT/CMD reset: 0x%02x\n",
1099		        __FUNCTION__, rflags));
1100		err = BCME_SDIO_ERROR;
1101	}
1102
1103	return err;
1104}
1105
1106extern int
1107sdioh_abort(sdioh_info_t *sd, uint fnum)
1108{
1109	int ret;
1110
1111	sdstd_lock(sd);
1112	ret = sdstd_abort(sd, fnum);
1113	sdstd_unlock(sd);
1114
1115	return ret;
1116}
1117
1118int
1119sdioh_start(sdioh_info_t *sd, int stage)
1120{
1121	return SUCCESS;
1122}
1123
1124int
1125sdioh_stop(sdioh_info_t *sd)
1126{
1127	return SUCCESS;
1128}
1129
1130static int
1131sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg)
1132{
1133	uint16 regval;
1134	uint retries;
1135	uint function = 0;
1136
1137	/* If no errors, we're done */
1138	if ((regval = sdstd_rreg16(sdioh_info, SD_ErrorIntrStatus)) == 0)
1139		return SUCCESS;
1140
1141	sd_info(("%s: ErrorIntrStatus 0x%04x (clearing), IntrStatus 0x%04x PresentState 0x%08x\n",
1142	        __FUNCTION__, regval, sdstd_rreg16(sdioh_info, SD_IntrStatus),
1143	        sdstd_rreg(sdioh_info, SD_PresentState)));
1144	sdstd_wreg16(sdioh_info, SD_ErrorIntrStatus, regval);
1145
1146	/* On command error, issue CMD reset */
1147	if (regval & ERRINT_CMD_ERRS) {
1148		sd_trace(("%s: issuing CMD reset\n", __FUNCTION__));
1149		sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1));
1150		for (retries = RETRIES_LARGE; retries; retries--)
1151			if (!(GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), SW_RESET_CMD)))
1152				break;
1153		if (!retries) {
1154			sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__));
1155		}
1156	}
1157
1158	/* On data error, issue DAT reset */
1159	if (regval & ERRINT_DATA_ERRS) {
1160		sd_trace(("%s: issuing DAT reset\n", __FUNCTION__));
1161		sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_DAT, 1));
1162		for (retries = RETRIES_LARGE; retries; retries--)
1163			if (!(GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), SW_RESET_DAT)))
1164				break;
1165		if (!retries) {
1166			sd_err(("%s: Timeout waiting for DAT line reset\n", __FUNCTION__));
1167		}
1168	}
1169
1170	/* For an IO command (CMD52 or CMD53) issue an abort to the appropriate function */
1171	if (cmd == SDIOH_CMD_53)
1172		function = GFIELD(arg, CMD53_FUNCTION);
1173	else if (cmd == SDIOH_CMD_52)
1174		function = GFIELD(arg, CMD52_FUNCTION);
1175	if (function) {
1176		sd_trace(("%s: requesting abort for function %d after cmd %d\n",
1177		          __FUNCTION__, function, cmd));
1178		sdstd_abort(sdioh_info, function);
1179	}
1180
1181	if (trap_errs)
1182		ASSERT(0);
1183
1184	return ERROR;
1185}
1186
1187
1188
1189/*
1190 * Private/Static work routines
1191 */
1192static bool
1193sdstd_reset(sdioh_info_t *sd, bool host_reset, bool client_reset)
1194{
1195	int retries = RETRIES_LARGE;
1196	uchar regval;
1197
1198	if (!sd)
1199		return TRUE;
1200
1201	sdstd_lock(sd);
1202	/* Reset client card */
1203	if (client_reset && (sd->adapter_slot != -1)) {
1204		if (sdstd_card_regwrite(sd, 0, SDIOD_CCCR_IOABORT, 1, 0x8) != SUCCESS)
1205			sd_err(("%s: Cannot write to card reg 0x%x\n",
1206			        __FUNCTION__, SDIOD_CCCR_IOABORT));
1207		else
1208			sd->card_rca = 0;
1209	}
1210
1211	/* Reset host controller */
1212	if (host_reset) {
1213		regval = SFIELD(0, SW_RESET_ALL, 1);
1214		sdstd_wreg8(sd, SD_SoftwareReset, regval);
1215		do {
1216			sd_trace(("%s: waiting for reset\n", __FUNCTION__));
1217		} while ((sdstd_rreg8(sd, SD_SoftwareReset) & regval) && retries--);
1218
1219		if (!retries) {
1220			sd_err(("%s: Timeout waiting for host reset\n", __FUNCTION__));
1221			sdstd_unlock(sd);
1222			return (FALSE);
1223		}
1224
1225		/* A reset should reset bus back to 1 bit mode */
1226		sd->sd_mode = SDIOH_MODE_SD1;
1227		sdstd_set_dma_mode(sd, sd->sd_dma_mode);
1228	}
1229	sdstd_unlock(sd);
1230	return TRUE;
1231}
1232
1233/* Disable device interrupt */
1234void
1235sdstd_devintr_off(sdioh_info_t *sd)
1236{
1237	sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints));
1238	if (sd->use_client_ints) {
1239		sd->intmask &= ~CLIENT_INTR;
1240		sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
1241		sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
1242	}
1243}
1244
1245/* Enable device interrupt */
1246void
1247sdstd_devintr_on(sdioh_info_t *sd)
1248{
1249	ASSERT(sd->lockcount == 0);
1250	sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints));
1251	if (sd->use_client_ints) {
1252		uint16 status = sdstd_rreg16(sd, SD_IntrStatusEnable);
1253		sdstd_wreg16(sd, SD_IntrStatusEnable, SFIELD(status, INTSTAT_CARD_INT, 0));
1254		sdstd_wreg16(sd, SD_IntrStatusEnable, status);
1255
1256		sd->intmask |= CLIENT_INTR;
1257		sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
1258		sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
1259	}
1260}
1261
1262#ifdef BCMSDYIELD
1263/* Enable/disable other interrupts */
1264void
1265sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err)
1266{
1267	if (err) {
1268		norm = SFIELD(norm, INTSTAT_ERROR_INT, 1);
1269		sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, err);
1270	}
1271
1272	sd->intmask |= norm;
1273	sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
1274	if (sd_forcerb)
1275		sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
1276}
1277
1278void
1279sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err)
1280{
1281	if (err) {
1282		norm = SFIELD(norm, INTSTAT_ERROR_INT, 1);
1283		sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, 0);
1284	}
1285
1286	sd->intmask &= ~norm;
1287	sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
1288	if (sd_forcerb)
1289		sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
1290}
1291#endif /* BCMSDYIELD */
1292
1293static int
1294sdstd_host_init(sdioh_info_t *sd)
1295{
1296	int 		num_slots, full_slot;
1297	uint8		reg8;
1298
1299	uint32		card_ins;
1300	int			slot, first_bar = 0;
1301	bool		detect_slots = FALSE;
1302	uint		bar;
1303
1304	/* Check for Arasan ID */
1305	if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_SI_IMAGE) {
1306		sd_info(("%s: Found Arasan Standard SDIO Host Controller\n", __FUNCTION__));
1307		sd->controller_type = SDIOH_TYPE_ARASAN_HDK;
1308		detect_slots = TRUE;
1309	} else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_BROADCOM) {
1310		sd_info(("%s: Found Broadcom 27xx Standard SDIO Host Controller\n", __FUNCTION__));
1311		sd->controller_type = SDIOH_TYPE_BCM27XX;
1312		detect_slots = FALSE;
1313	} else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_TI) {
1314		sd_info(("%s: Found TI PCIxx21 Standard SDIO Host Controller\n", __FUNCTION__));
1315		sd->controller_type = SDIOH_TYPE_TI_PCIXX21;
1316		detect_slots = TRUE;
1317	} else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_RICOH) {
1318		sd_info(("%s: Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter\n",
1319			__FUNCTION__));
1320		sd->controller_type = SDIOH_TYPE_RICOH_R5C822;
1321		detect_slots = TRUE;
1322	} else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_JMICRON) {
1323		sd_info(("%s: JMicron Standard SDIO Host Controller\n",
1324			__FUNCTION__));
1325		sd->controller_type = SDIOH_TYPE_JMICRON;
1326		detect_slots = TRUE;
1327	} else {
1328		return ERROR;
1329	}
1330
1331	/*
1332	 * Determine num of slots
1333	 * Search each slot
1334	 */
1335
1336	first_bar = OSL_PCI_READ_CONFIG(sd->osh, SD_SlotInfo, 4) & 0x7;
1337	num_slots = (OSL_PCI_READ_CONFIG(sd->osh, SD_SlotInfo, 4) & 0xff) >> 4;
1338	num_slots &= 7;
1339	num_slots++;   	/* map bits to num slots according to spec */
1340
1341	if (OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) ==
1342	    ((SDIOH_FPGA_ID << 16) | VENDOR_BROADCOM)) {
1343		sd_err(("%s: Found Broadcom Standard SDIO Host Controller FPGA\n", __FUNCTION__));
1344		/* Set BAR0 Window to SDIOSTH core */
1345		OSL_PCI_WRITE_CONFIG(sd->osh, PCI_BAR0_WIN, 4, 0x18001000);
1346
1347		/* Set defaults particular to this controller. */
1348		detect_slots = TRUE;
1349		num_slots = 1;
1350		first_bar = 0;
1351
1352		/* Controller supports ADMA2, so turn it on here. */
1353		sd->sd_dma_mode = DMA_MODE_ADMA2;
1354	}
1355
1356	/* Map in each slot on the board and query it to see if a
1357	 * card is inserted.  Use the first populated slot found.
1358	 */
1359	if (sd->mem_space) {
1360		sdstd_reg_unmap(sd->osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ);
1361		sd->mem_space = NULL;
1362	}
1363
1364	full_slot = -1;
1365
1366	for (slot = 0; slot < num_slots; slot++) {
1367		bar = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(slot + first_bar)), 4);
1368		sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh,
1369		                                               (uintptr)bar, SDIOH_REG_WINSZ);
1370
1371		sd->adapter_slot = -1;
1372
1373		if (detect_slots) {
1374			card_ins = GFIELD(sdstd_rreg(sd, SD_PresentState), PRES_CARD_PRESENT);
1375		} else {
1376			card_ins = TRUE;
1377		}
1378
1379		if (card_ins) {
1380			sd_info(("%s: SDIO slot %d: Full\n", __FUNCTION__, slot));
1381			if (full_slot < 0)
1382				full_slot = slot;
1383		} else {
1384			sd_info(("%s: SDIO slot %d: Empty\n", __FUNCTION__, slot));
1385		}
1386
1387		if (sd->mem_space) {
1388			sdstd_reg_unmap(sd->osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ);
1389			sd->mem_space = NULL;
1390		}
1391	}
1392
1393	if (full_slot < 0) {
1394		sd_err(("No slots on SDIO controller are populated\n"));
1395		return -1;
1396	}
1397
1398	bar = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4);
1399	sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh, (uintptr)bar, SDIOH_REG_WINSZ);
1400
1401	sd_err(("Using slot %d at BAR%d [0x%08x] mem_space 0x%p\n",
1402		full_slot,
1403		(full_slot + first_bar),
1404		OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4),
1405		sd->mem_space));
1406
1407
1408	sd->adapter_slot = full_slot;
1409
1410	sd->version = sdstd_rreg16(sd, SD_HostControllerVersion) & 0xFF;
1411	switch (sd->version) {
1412		case 0:
1413			sd_err(("Host Controller version 1.0, Vendor Revision: 0x%02x\n",
1414				sdstd_rreg16(sd, SD_HostControllerVersion) >> 8));
1415			break;
1416		case 1:
1417		case 2:
1418			sd_err(("Host Controller version 2.0, Vendor Revision: 0x%02x\n",
1419				sdstd_rreg16(sd, SD_HostControllerVersion) >> 8));
1420			break;
1421		default:
1422			sd_err(("%s: Host Controller version 0x%02x not supported.\n",
1423			    __FUNCTION__, sd->version));
1424			break;
1425	}
1426
1427	sd->caps = sdstd_rreg(sd, SD_Capabilities);	/* Cache this for later use */
1428	sd->curr_caps = sdstd_rreg(sd, SD_MaxCurCap);
1429
1430	sdstd_set_dma_mode(sd, sd->sd_dma_mode);
1431
1432
1433	sdstd_reset(sd, 1, 0);
1434
1435	/* Read SD4/SD1 mode */
1436	if ((reg8 = sdstd_rreg8(sd, SD_HostCntrl))) {
1437		if (reg8 & SD4_MODE) {
1438			sd_err(("%s: Host cntrlr already in 4 bit mode: 0x%x\n",
1439			        __FUNCTION__,  reg8));
1440		}
1441	}
1442
1443	/* Default power on mode is SD1 */
1444	sd->sd_mode = SDIOH_MODE_SD1;
1445	sd->polled_mode = TRUE;
1446	sd->host_init_done = TRUE;
1447	sd->card_init_done = FALSE;
1448	sd->adapter_slot = full_slot;
1449
1450	return (SUCCESS);
1451}
1452#define CMD5_RETRIES 200
1453static int
1454get_ocr(sdioh_info_t *sd, uint32 *cmd_arg, uint32 *cmd_rsp)
1455{
1456	int retries, status;
1457
1458	/* Get the Card's Operation Condition.  Occasionally the board
1459	 * takes a while to become ready
1460	 */
1461	retries = CMD5_RETRIES;
1462	do {
1463		*cmd_rsp = 0;
1464		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_5, *cmd_arg))
1465		    != SUCCESS) {
1466			sd_err(("%s: CMD5 failed\n", __FUNCTION__));
1467			return status;
1468		}
1469		sdstd_cmd_getrsp(sd, cmd_rsp, 1);
1470		if (!GFIELD(*cmd_rsp, RSP4_CARD_READY))
1471			sd_trace(("%s: Waiting for card to become ready\n", __FUNCTION__));
1472	} while ((!GFIELD(*cmd_rsp, RSP4_CARD_READY)) && --retries);
1473	if (!retries)
1474		return ERROR;
1475
1476	return (SUCCESS);
1477}
1478
1479static int
1480sdstd_client_init(sdioh_info_t *sd)
1481{
1482	uint32 cmd_arg, cmd_rsp;
1483	int status;
1484	uint8 fn_ints;
1485
1486
1487	sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot));
1488
1489	/* Clear any pending ints */
1490	sdstd_wreg16(sd, SD_IntrStatus, 0x1ff);
1491	sdstd_wreg16(sd, SD_ErrorIntrStatus, 0x0fff);
1492
1493	/* Enable both Normal and Error Status.  This does not enable
1494	 * interrupts, it only enables the status bits to
1495	 * become 'live'
1496	 */
1497	sdstd_wreg16(sd, SD_IntrStatusEnable, 0x1ff);
1498	sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, 0xffff);
1499
1500	sdstd_wreg16(sd, SD_IntrSignalEnable, 0);	  /* Disable ints for now. */
1501
1502	/* Start at ~400KHz clock rate for initialization */
1503	if (!sdstd_start_clock(sd, 128)) {
1504		sd_err(("sdstd_start_clock failed\n"));
1505		return ERROR;
1506	}
1507	if (!sdstd_start_power(sd)) {
1508		sd_err(("sdstd_start_power failed\n"));
1509		return ERROR;
1510	}
1511
1512	if (sd->num_funcs == 0) {
1513		sd_err(("%s: No IO funcs!\n", __FUNCTION__));
1514		return ERROR;
1515	}
1516
1517	/* In SPI mode, issue CMD0 first */
1518	if (sd->sd_mode == SDIOH_MODE_SPI) {
1519		cmd_arg = 0;
1520		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_0, cmd_arg))
1521		    != SUCCESS) {
1522			sd_err(("BCMSDIOH: cardinit: CMD0 failed!\n"));
1523			return status;
1524		}
1525	}
1526
1527	if (sd->sd_mode != SDIOH_MODE_SPI) {
1528		uint16 rsp6_status;
1529
1530		/* Card is operational. Ask it to send an RCA */
1531		cmd_arg = 0;
1532		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_3, cmd_arg))
1533		    != SUCCESS) {
1534			sd_err(("%s: CMD3 failed!\n", __FUNCTION__));
1535			return status;
1536		}
1537
1538		/* Verify the card status returned with the cmd response */
1539		sdstd_cmd_getrsp(sd, &cmd_rsp, 1);
1540		rsp6_status = GFIELD(cmd_rsp, RSP6_STATUS);
1541		if (GFIELD(rsp6_status, RSP6STAT_COM_CRC_ERROR) ||
1542		    GFIELD(rsp6_status, RSP6STAT_ILLEGAL_CMD) ||
1543		    GFIELD(rsp6_status, RSP6STAT_ERROR)) {
1544			sd_err(("%s: CMD3 response error. Response = 0x%x!\n",
1545			        __FUNCTION__, rsp6_status));
1546			return ERROR;
1547		}
1548
1549		/* Save the Card's RCA */
1550		sd->card_rca = GFIELD(cmd_rsp, RSP6_IO_RCA);
1551		sd_info(("RCA is 0x%x\n", sd->card_rca));
1552
1553		if (rsp6_status)
1554			sd_err(("raw status is 0x%x\n", rsp6_status));
1555
1556		/* Select the card */
1557		cmd_arg = SFIELD(0, CMD7_RCA, sd->card_rca);
1558		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_7, cmd_arg))
1559		    != SUCCESS) {
1560			sd_err(("%s: CMD7 failed!\n", __FUNCTION__));
1561			return status;
1562		}
1563		sdstd_cmd_getrsp(sd, &cmd_rsp, 1);
1564		if (cmd_rsp != SDIOH_CMD7_EXP_STATUS) {
1565			sd_err(("%s: CMD7 response error. Response = 0x%x!\n",
1566			        __FUNCTION__, cmd_rsp));
1567			return ERROR;
1568		}
1569	}
1570
1571	sdstd_card_enablefuncs(sd);
1572
1573	if (!sdstd_bus_width(sd, sd_sdmode)) {
1574		sd_err(("sdstd_bus_width failed\n"));
1575		return ERROR;
1576	}
1577
1578	set_client_block_size(sd, 1, BLOCK_SIZE_4318);
1579	fn_ints = INTR_CTL_FUNC1_EN;
1580
1581	if (sd->num_funcs >= 2) {
1582		set_client_block_size(sd, 2, sd_f2_blocksize /* BLOCK_SIZE_4328 */);
1583		fn_ints |= INTR_CTL_FUNC2_EN;
1584	}
1585
1586	/* Enable/Disable Client interrupts */
1587	/* Turn on here but disable at host controller? */
1588	if (sdstd_card_regwrite(sd, 0, SDIOD_CCCR_INTEN, 1,
1589	                        (fn_ints | INTR_CTL_MASTER_EN)) != SUCCESS) {
1590		sd_err(("%s: Could not enable ints in CCCR\n", __FUNCTION__));
1591		return ERROR;
1592	}
1593
1594	/* Switch to High-speed clocking mode if both host and device support it */
1595	sdstd_set_highspeed_mode(sd, (bool)sd_hiok);
1596
1597	/* After configuring for High-Speed mode, set the desired clock rate. */
1598	if (!sdstd_start_clock(sd, (uint16)sd_divisor)) {
1599		sd_err(("sdstd_start_clock failed\n"));
1600		return ERROR;
1601	}
1602
1603	sd->card_init_done = TRUE;
1604
1605	return SUCCESS;
1606}
1607
1608static int
1609sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode)
1610{
1611	uint32 regdata;
1612	int status;
1613	uint8 reg8;
1614
1615	reg8 = sdstd_rreg8(sd, SD_HostCntrl);
1616
1617
1618	if (HSMode == TRUE) {
1619		if (sd_hiok && (GFIELD(sd->caps, CAP_HIGHSPEED)) == 0) {
1620			sd_err(("Host Controller does not support hi-speed mode.\n"));
1621			return BCME_ERROR;
1622		}
1623
1624		sd_info(("Attempting to enable High-Speed mode.\n"));
1625
1626		if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
1627		                                 1, &regdata)) != SUCCESS) {
1628			return BCME_SDIO_ERROR;
1629		}
1630		if (regdata & SDIO_SPEED_SHS) {
1631			sd_info(("Device supports High-Speed mode.\n"));
1632
1633			regdata |= SDIO_SPEED_EHS;
1634
1635			sd_info(("Writing %08x to Card at %08x\n",
1636			         regdata, SDIOD_CCCR_SPEED_CONTROL));
1637			if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
1638			                                  1, regdata)) != BCME_OK) {
1639				return BCME_SDIO_ERROR;
1640			}
1641
1642			if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
1643			                                 1, &regdata)) != BCME_OK) {
1644				return BCME_SDIO_ERROR;
1645			}
1646
1647			sd_info(("Read %08x to Card at %08x\n", regdata, SDIOD_CCCR_SPEED_CONTROL));
1648
1649			reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 1);
1650
1651			sd_err(("High-speed clocking mode enabled.\n"));
1652		}
1653		else {
1654			sd_err(("Device does not support High-Speed Mode.\n"));
1655			reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 0);
1656		}
1657	} else {
1658		/* Force off device bit */
1659		if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
1660		                                 1, &regdata)) != BCME_OK) {
1661			return status;
1662		}
1663		if (regdata & SDIO_SPEED_EHS) {
1664			regdata &= ~SDIO_SPEED_EHS;
1665			if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
1666			                                  1, regdata)) != BCME_OK) {
1667				return status;
1668			}
1669		}
1670
1671		sd_err(("High-speed clocking mode disabled.\n"));
1672		reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 0);
1673	}
1674
1675	sdstd_wreg8(sd, SD_HostCntrl, reg8);
1676
1677	return BCME_OK;
1678}
1679
1680/* Select DMA Mode:
1681 * If dma_mode == DMA_MODE_AUTO, pick the "best" mode.
1682 * Otherwise, pick the selected mode if supported.
1683 * If not supported, use PIO mode.
1684 */
1685static int
1686sdstd_set_dma_mode(sdioh_info_t *sd, int8 dma_mode)
1687{
1688	uint8 reg8, dma_sel_bits = SDIOH_SDMA_MODE;
1689	int8 prev_dma_mode = sd->sd_dma_mode;
1690
1691	switch (prev_dma_mode) {
1692		case DMA_MODE_AUTO:
1693			sd_dma(("%s: Selecting best DMA mode supported by controller.\n",
1694			          __FUNCTION__));
1695			if (GFIELD(sd->caps, CAP_ADMA2)) {
1696				sd->sd_dma_mode = DMA_MODE_ADMA2;
1697				dma_sel_bits = SDIOH_ADMA2_MODE;
1698			} else if (GFIELD(sd->caps, CAP_ADMA1)) {
1699				sd->sd_dma_mode = DMA_MODE_ADMA1;
1700				dma_sel_bits = SDIOH_ADMA1_MODE;
1701			} else if (GFIELD(sd->caps, CAP_DMA)) {
1702				sd->sd_dma_mode = DMA_MODE_SDMA;
1703			} else {
1704				sd->sd_dma_mode = DMA_MODE_NONE;
1705			}
1706			break;
1707		case DMA_MODE_NONE:
1708			sd->sd_dma_mode = DMA_MODE_NONE;
1709			break;
1710		case DMA_MODE_SDMA:
1711			if (GFIELD(sd->caps, CAP_DMA)) {
1712				sd->sd_dma_mode = DMA_MODE_SDMA;
1713			} else {
1714				sd_err(("%s: SDMA not supported by controller.\n", __FUNCTION__));
1715				sd->sd_dma_mode = DMA_MODE_NONE;
1716			}
1717			break;
1718		case DMA_MODE_ADMA1:
1719			if (GFIELD(sd->caps, CAP_ADMA1)) {
1720				sd->sd_dma_mode = DMA_MODE_ADMA1;
1721				dma_sel_bits = SDIOH_ADMA1_MODE;
1722			} else {
1723				sd_err(("%s: ADMA1 not supported by controller.\n", __FUNCTION__));
1724				sd->sd_dma_mode = DMA_MODE_NONE;
1725			}
1726			break;
1727		case DMA_MODE_ADMA2:
1728			if (GFIELD(sd->caps, CAP_ADMA2)) {
1729				sd->sd_dma_mode = DMA_MODE_ADMA2;
1730				dma_sel_bits = SDIOH_ADMA2_MODE;
1731			} else {
1732				sd_err(("%s: ADMA2 not supported by controller.\n", __FUNCTION__));
1733				sd->sd_dma_mode = DMA_MODE_NONE;
1734			}
1735			break;
1736		case DMA_MODE_ADMA2_64:
1737			sd_err(("%s: 64b ADMA2 not supported by driver.\n", __FUNCTION__));
1738			sd->sd_dma_mode = DMA_MODE_NONE;
1739			break;
1740		default:
1741			sd_err(("%s: Unsupported DMA Mode %d requested.\n", __FUNCTION__,
1742			        prev_dma_mode));
1743			sd->sd_dma_mode = DMA_MODE_NONE;
1744			break;
1745	}
1746
1747	/* clear SysAddr, only used for SDMA */
1748	sdstd_wreg(sd, SD_SysAddr, 0);
1749
1750	sd_err(("%s: %s mode selected.\n", __FUNCTION__, dma_mode_description[sd->sd_dma_mode]));
1751
1752	reg8 = sdstd_rreg8(sd, SD_HostCntrl);
1753	reg8 = SFIELD(reg8, HOST_DMA_SEL, dma_sel_bits);
1754	sdstd_wreg8(sd, SD_HostCntrl, reg8);
1755	sd_dma(("%s: SD_HostCntrl=0x%02x\n", __FUNCTION__, reg8));
1756
1757	return BCME_OK;
1758}
1759
1760
1761bool
1762sdstd_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor)
1763{
1764	uint rc, count;
1765	uint16 divisor;
1766
1767	/* turn off HC clock */
1768	sdstd_wreg16(sd, SD_ClockCntrl,
1769	             sdstd_rreg16(sd, SD_ClockCntrl) & ~((uint16)0x4)); /*  Disable the HC clock */
1770
1771	/* Set divisor */
1772
1773	divisor = (new_sd_divisor >> 1) << 8;
1774
1775	sd_info(("Clock control is 0x%x\n", sdstd_rreg16(sd, SD_ClockCntrl)));
1776	sdstd_mod_reg16(sd, SD_ClockCntrl, 0xff00, divisor);
1777	sd_info(("%s: Using clock divisor of %d (regval 0x%04x)\n", __FUNCTION__,
1778	         new_sd_divisor, divisor));
1779
1780	sd_info(("Primary Clock Freq = %d MHz\n", GFIELD(sd->caps, CAP_TO_CLKFREQ)));
1781
1782	if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 50) {
1783		sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
1784		        ((50 % new_sd_divisor) ? (50000 / new_sd_divisor) : (50 / new_sd_divisor)),
1785		        ((50 % new_sd_divisor) ? "KHz" : "MHz")));
1786	} else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 48) {
1787		sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
1788		        ((48 % new_sd_divisor) ? (48000 / new_sd_divisor) : (48 / new_sd_divisor)),
1789		        ((48 % new_sd_divisor) ? "KHz" : "MHz")));
1790	} else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 33) {
1791		sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
1792		        ((33 % new_sd_divisor) ? (33000 / new_sd_divisor) : (33 / new_sd_divisor)),
1793		        ((33 % new_sd_divisor) ? "KHz" : "MHz")));
1794
1795	} else if (sd->controller_type == SDIOH_TYPE_BCM27XX) {
1796	} else {
1797		sd_err(("Need to determine divisor for %d MHz clocks\n",
1798		        GFIELD(sd->caps, CAP_TO_CLKFREQ)));
1799		sd_err(("Consult SD Host Controller Spec: Clock Control Register\n"));
1800		

Large files files are truncated, but you can click here to view the full file