int wl1271_boot(struct wl1271 *wl) { int ret = 0; u32 tmp, clk, pause; if (REF_CLOCK == 0 || REF_CLOCK == 2) /* ref clk: 19.2/38.4 */ clk = 0x3; else if (REF_CLOCK == 1 || REF_CLOCK == 3) /* ref clk: 26/52 */ clk = 0x5; wl1271_reg_write32(wl, PLL_PARAMETERS, clk); pause = wl1271_reg_read32(wl, PLL_PARAMETERS); wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause); pause &= ~(WU_COUNTER_PAUSE_VAL); /* FIXME: This should probably be * WU_COUNTER_PAUSE_VAL instead of * 0x3ff (magic number ). How does * this work?! */ pause |= WU_COUNTER_PAUSE_VAL; wl1271_reg_write32(wl, WU_COUNTER_PAUSE, pause); /* Continue the ELP wake up sequence */ wl1271_reg_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); udelay(500); wl1271_set_partition(wl, part_table[PART_DRPW].mem.start, part_table[PART_DRPW].mem.size, part_table[PART_DRPW].reg.start, part_table[PART_DRPW].reg.size); /* Read-modify-write DRPW_SCRATCH_START register (see next state) to be used by DRPw FW. The RTRIM value will be added by the FW before taking DRPw out of reset */ wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START); clk = wl1271_reg_read32(wl, DRPW_SCRATCH_START); wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); /* 2 */ clk |= (REF_CLOCK << 1) << 4; wl1271_reg_write32(wl, DRPW_SCRATCH_START, clk); wl1271_set_partition(wl, part_table[PART_WORK].mem.start, part_table[PART_WORK].mem.size, part_table[PART_WORK].reg.start, part_table[PART_WORK].reg.size); /* Disable interrupts */ wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); ret = wl1271_boot_soft_reset(wl); if (ret < 0) goto out; /* 2. start processing NVS file */ ret = wl1271_boot_upload_nvs(wl); if (ret < 0) goto out; /* write firmware's last address (ie. it's length) to * ACX_EEPROMLESS_IND_REG */ wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG"); wl1271_reg_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG); tmp = wl1271_reg_read32(wl, CHIP_ID_B); wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); /* 6. read the EEPROM parameters */ tmp = wl1271_reg_read32(wl, SCR_PAD2); ret = wl1271_boot_write_irq_polarity(wl); if (ret < 0) goto out; /* FIXME: Need to check whether this is really what we want */ wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR); /* WL1271: The reference driver skips steps 7 to 10 (jumps directly * to upload_fw) */ ret = wl1271_boot_upload_firmware(wl); if (ret < 0) goto out; /* 10.5 start firmware */ ret = wl1271_boot_run_firmware(wl); if (ret < 0) goto out; /* set the wl1271 default filters */ wl->rx_config = WL1271_DEFAULT_RX_CONFIG; wl->rx_filter = WL1271_DEFAULT_RX_FILTER; wl1271_event_mbox_config(wl); out: return ret; }
/* uploads NVS and firmware */ int wl1271_load_firmware(struct wl1271 *wl) { int ret = 0; u32 tmp, clk; int selected_clock = -1; ret = wl12xx_init_pll_clock(wl, &selected_clock); if (ret < 0) goto out; ret = wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]); if (ret < 0) goto out; /* Read-modify-write DRPW_SCRATCH_START register (see next state) to be used by DRPw FW. The RTRIM value will be added by the FW before taking DRPw out of reset */ wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START); ret = wl1271_read32(wl, DRPW_SCRATCH_START, &clk); if (ret < 0) goto out; wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); if (wl->chip.id == CHIP_ID_1283_PG20) { clk |= ((selected_clock & 0x3) << 1) << 4; } else { clk |= (wl->ref_clock << 1) << 4; } ret = wl1271_write32(wl, DRPW_SCRATCH_START, clk); if (ret < 0) goto out; ret = wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]); if (ret < 0) goto out; /* Disable interrupts */ ret = wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); if (ret < 0) goto out; ret = wl1271_boot_soft_reset(wl); if (ret < 0) goto out; /* 2. start processing NVS file */ ret = wl1271_boot_upload_nvs(wl); if (ret < 0) goto out; /* write firmware's last address (ie. it's length) to * ACX_EEPROMLESS_IND_REG */ wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG"); ret = wl1271_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG); if (ret < 0) goto out; ret = wl1271_read32(wl, CHIP_ID_B, &tmp); if (ret < 0) goto out; wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); /* 6. read the EEPROM parameters */ ret = wl1271_read32(wl, SCR_PAD2, &tmp); if (ret < 0) goto out; /* WL1271: The reference driver skips steps 7 to 10 (jumps directly * to upload_fw) */ if (wl->chip.id == CHIP_ID_1283_PG20) { ret = wl1271_top_reg_write(wl, SDIO_IO_DS, wl->conf.hci_io_ds); if (ret < 0) goto out; } ret = wl1271_boot_upload_firmware(wl); if (ret < 0) goto out; /* update loaded fw type */ wl->fw_type = wl->saved_fw_type; out: return ret; }