From 71d559c7a03a45f01e6da4b36cc8181057d4d8ed Mon Sep 17 00:00:00 2001 From: Ben Cahill Date: Thu, 16 Aug 2007 14:49:17 -0700 Subject: [PATCH 08/31] iwlwifi: add BSM_DRAM_INST_LOAD definition Add BSM_DRAM_INST_LOAD definition and document uCode load procedure. Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi --- drivers/net/wireless/iwl-base.c | 2 +- drivers/net/wireless/iwl-hw.h | 157 +++++++++++++++++++++++++++++++++------ 2 files changed, 135 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwl-base.c b/drivers/net/wireless/iwl-base.c index 78589b1..428ca60 100644 --- a/drivers/net/wireless/iwl-base.c +++ b/drivers/net/wireless/iwl-base.c @@ -6574,7 +6574,7 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv) /* Inst bytecount must be last to set up, bit 31 signals uCode * that all new ptr/size info is in place */ iwl_write_restricted_reg(priv, BSM_DRAM_INST_BYTECOUNT_REG, - priv->ucode_code.len | 0x80000000); + priv->ucode_code.len | BSM_DRAM_INST_LOAD); iwl_release_restricted_access(priv); diff --git a/drivers/net/wireless/iwl-hw.h b/drivers/net/wireless/iwl-hw.h index fe7cb94..3743cdb 100644 --- a/drivers/net/wireless/iwl-hw.h +++ b/drivers/net/wireless/iwl-hw.h @@ -64,18 +64,19 @@ #define __iwlwifi_hw_h__ /* - * This file defines hardware / uCode API constants, enums, - * and inline functions. + * This file defines hardware constants common to 3945 and 4965. * - * For common usage code where the implementation can be the same - * with the exception of a different value going into a constant - * those constants are defined in this file. + * Device-specific constants are defined in iwl-3945-hw.h and iwl-4965-hw.h, + * although this file contains a few definitions for which the .c + * implementation is the same for 3945 and 4965, except for the value of + * a constant. * - * NOTE: DO NOT PUT IMPLEMENTATION SPECIFIC DECLRATIONS HERE + * uCode API constants are defined in iwl-commands.h. * - * The iwl-*hw.h (and files they include) files should remain OS driver - * implementation independent, declaring only the hardware/uCode API + * NOTE: DO NOT PUT OS IMPLEMENTATION-SPECIFIC DECLARATIONS HERE * + * The iwl-*hw.h (and files they include) files should remain OS/driver + * implementation independent, declaring only the hardware interface. */ /* uCode queue management definitions */ @@ -83,6 +84,7 @@ #define IWL_CMD_FIFO_NUM 4 #define IWL_BACK_QUEUE_FIRST_ID 7 +/* Tx rates */ #define IWL_CCK_RATES 4 #define IWL_OFDM_RATES 8 @@ -94,9 +96,7 @@ #define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES) -/* - * Time constants - */ +/* Time constants */ #define SHORT_SLOT_TIME 9 #define LONG_SLOT_TIME 20 @@ -151,7 +151,115 @@ #define CSR_ANA_PLL_CFG (CSR_BASE+0x20c) #define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) -/* BSM (Bootstrap State Machine) */ +/** + * BSM (Bootstrap State Machine) + * + * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program + * in special SRAM that does not power down when the embedded control + * processor is sleeping (e.g. for periodic power-saving shutdowns of radio). + * + * When powering back up after sleeps (or during initial uCode load), the BSM + * internally loads the short bootstrap program from the special SRAM into the + * embedded processor's instruction SRAM, and starts the processor so it runs + * the bootstrap program. + * + * This bootstrap program loads (via PCI busmaster DMA) instructions and data + * images for a uCode program from host DRAM locations. The host driver + * indicates DRAM locations and sizes for instruction and data images via the + * four BSM_DRAM_* registers. Once the bootstrap program loads the new program, + * the new program starts automatically. + * + * The uCode used for open-source drivers includes two programs: + * + * 1) Initialization -- performs hardware calibration and sets up some + * internal data, then notifies host via "initialize alive" notification + * (struct iwl_init_alive_resp) that it has completed all of its work. + * After signal from host, it then loads and starts the runtime program. + * The initialization program must be used when initially setting up the + * NIC after loading the driver. + * + * 2) Runtime/Protocol -- performs all normal runtime operations. This + * notifies host via "alive" notification (struct iwl_alive_resp) that it + * is ready to be used. + * + * When initializing the NIC, the host driver does the following procedure: + * + * 1) Load bootstrap program (instructions only, no data image for bootstrap) + * into bootstrap memory. Use dword writes starting at BSM_SRAM_LOWER_BOUND + * + * 2) Point (via BSM_DRAM_*) to the "initialize" uCode data and instruction + * images in host DRAM. + * + * 3) Set up BSM to copy from BSM SRAM into uCode instruction SRAM when asked: + * BSM_WR_MEM_SRC_REG = 0 + * BSM_WR_MEM_DST_REG = RTC_INST_LOWER_BOUND + * BSM_WR_MEM_DWCOUNT_REG = # dwords in bootstrap instruction image + * + * 4) Load bootstrap into instruction SRAM: + * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START + * + * 5) Wait for load completion: + * Poll BSM_WR_CTRL_REG for BSM_WR_CTRL_REG_BIT_START = 0 + * + * 6) Enable future boot loads whenever NIC's power management triggers it: + * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START_EN + * + * 7) Start the NIC by removing all reset bits: + * CSR_RESET = 0 + * + * The bootstrap uCode (already in instruction SRAM) loads initialization + * uCode. Initialization uCode performs data initialization, sends + * "initialize alive" notification to host, and waits for a signal from + * host to load runtime code. + * + * 4) Point (via BSM_DRAM_*) to the "runtime" uCode data and instruction + * images in host DRAM. The last register loaded must be the instruction + * bytecount register ("1" in MSbit tells initialization uCode to load + * the runtime uCode): + * BSM_DRAM_INST_BYTECOUNT_REG = bytecount | BSM_DRAM_INST_LOAD + * + * 5) Wait for "alive" notification, then issue normal runtime commands. + * + * Data caching during power-downs: + * + * Just before the embedded controller powers down (e.g for automatic + * power-saving modes, or for RFKILL), uCode stores (via PCI busmaster DMA) + * a current snapshot of the embedded processor's data SRAM into host DRAM. + * This caches the data while the embedded processor's memory is powered down. + * Location and size are controlled by BSM_DRAM_DATA_* registers. + * + * NOTE: Instruction SRAM does not need to be saved, since that doesn't + * change during operation; the original image (from uCode distribution + * file) can be used for reload. + * + * When powering back up, the BSM loads the bootstrap program. Bootstrap looks + * at the BSM_DRAM_* registers, which now point to the runtime instruction + * image and the cached (modified) runtime data (*not* the initialization + * uCode). Bootstrap reloads these runtime images into SRAM, and restarts the + * uCode from where it left off before the power-down. + * + * NOTE: Initialization uCode does *not* run as part of the save/restore + * procedure. + * + * This save/restore method is mostly for autonomous power management during + * normal operation (result of POWER_TABLE_CMD). Platform suspend/resume and + * RFKILL should use complete restarts (with total re-initialization) of uCode, + * allowing total shutdown (including BSM memory). + * + * Note that, during normal operation, the host DRAM that held the initial + * startup data for the runtime code is now being used as a backup data cache + * for modified data! If you need to completely re-initialize the NIC, make + * sure that you use the runtime data image from the uCode distribution file, + * not the modified/saved runtime data. You may want to store a separate + * "clean" runtime data image in DRAM to avoid disk reads of distribution file. + */ + +/* BSM bit fields */ +#define BSM_WR_CTRL_REG_BIT_START (0x80000000) /* start boot load now */ +#define BSM_WR_CTRL_REG_BIT_START_EN (0x40000000) /* enable boot after pwrup*/ +#define BSM_DRAM_INST_LOAD (0x80000000) /* start program load now */ + +/* BSM addresses */ #define BSM_BASE (CSR_BASE + 0x3400) #define BSM_WR_CTRL_REG (BSM_BASE + 0x000) /* ctl and status */ @@ -160,19 +268,25 @@ #define BSM_WR_DWCOUNT_REG (BSM_BASE + 0x00C) /* bytes */ #define BSM_WR_STATUS_REG (BSM_BASE + 0x010) /* bit 0: 1 == done */ -/* pointers and size regs for bootstrap load and data SRAM save */ +/* + * Pointers and size regs for bootstrap load and data SRAM save/restore. + * NOTE: 3945 pointers use bits 31:0 of DRAM address. + * 4965 pointers use bits 35:4 of DRAM address. + */ #define BSM_DRAM_INST_PTR_REG (BSM_BASE + 0x090) #define BSM_DRAM_INST_BYTECOUNT_REG (BSM_BASE + 0x094) #define BSM_DRAM_DATA_PTR_REG (BSM_BASE + 0x098) #define BSM_DRAM_DATA_BYTECOUNT_REG (BSM_BASE + 0x09C) -/* BSM special memory, stays powered during power-save sleeps */ +/* + * BSM special memory, stays powered on during power-save sleeps. + * Read/write, address range from LOWER_BOUND to (LOWER_BOUND + SIZE -1) + */ #define BSM_SRAM_LOWER_BOUND (CSR_BASE + 0x3800) -#define BSM_SRAM_SIZE (1024) +#define BSM_SRAM_SIZE (1024) /* bytes */ -/* DBG MON */ -/* SCD */ +/* SCD (Scheduler) */ #define SCD_BASE (CSR_BASE + 0x2E00) #define SCD_MODE_REG (SCD_BASE + 0x000) @@ -183,7 +297,7 @@ #define SCD_SBYP_MODE_1_REG (SCD_BASE + 0x02C) #define SCD_SBYP_MODE_2_REG (SCD_BASE + 0x030) -/*=== HBUS (Host-side bus) ===*/ +/*=== HBUS (Host-side Bus) ===*/ #define HBUS_TARG_MEM_RADDR (HBUS_BASE+0x00c) #define HBUS_TARG_MEM_WADDR (HBUS_BASE+0x010) @@ -194,7 +308,8 @@ #define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c) #define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) #define HBUS_TARG_WRPTR (HBUS_BASE+0x060) -/*=== FH (data Flow handler) ===*/ + +/*=== FH (data Flow Handler) ===*/ #define FH_CBCC_TABLE (FH_BASE+0x140) #define FH_TFDB_TABLE (FH_BASE+0x180) @@ -347,10 +462,6 @@ #define APMG_PS_CTRL_REG_VAL_POWER_SRC_VMAIN (0x00000000) #define APMG_PS_CTRL_REG_VAL_POWER_SRC_VAUX (0x01000000) -/* BSM (bootstrap state machine) */ -#define BSM_WR_CTRL_REG_BIT_START (0x80000000) /* start boot load now */ -#define BSM_WR_CTRL_REG_BIT_START_EN (0x40000000) /* enable boot after pwrup*/ - /* DBM */ #define ALM_FH_SRVC_CHNL (6) -- 1.5.2