Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 247093
b: refs/heads/master
c: 5ea417a
h: refs/heads/master
i:
  247091: d15a89a
v: v3
  • Loading branch information
Shahar Levi authored and Luciano Coelho committed Apr 19, 2011
1 parent 5bd3423 commit a11822c
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bc765bf3b9a095b3e41c8cda80643901884c3dd4
refs/heads/master: 5ea417ae7749076ddaacb5b36487cae6ac920413
183 changes: 175 additions & 8 deletions trunk/drivers/net/wireless/wl12xx/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/

#include <linux/slab.h>
#include <linux/wl12xx.h>

#include "acx.h"
#include "reg.h"
Expand Down Expand Up @@ -520,24 +521,159 @@ static void wl1271_boot_hw_version(struct wl1271 *wl)
wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
}

/* uploads NVS and firmware */
int wl1271_load_firmware(struct wl1271 *wl)
/*
* WL128x has two clocks input - TCXO and FREF.
* TCXO is the main clock of the device, while FREF is used to sync
* between the GPS and the cellular modem.
* In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
* as the WLAN/BT main clock.
*/
static int wl128x_switch_fref(struct wl1271 *wl, bool *is_ref_clk)
{
int ret = 0;
u32 tmp, clk, pause;
u16 sys_clk_cfg_val;

/* if working on XTAL-only mode go directly to TCXO TO FREF SWITCH */
if ((wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL) ||
(wl->ref_clock == CONF_REF_CLK_26_M_XTAL))
return true;

/* Read clock source FREF or TCXO */
sys_clk_cfg_val = wl1271_top_reg_read(wl, SYS_CLK_CFG_REG);

if (sys_clk_cfg_val & PRCM_CM_EN_MUX_WLAN_FREF) {
/* if bit 3 is set - working with FREF clock */
wl1271_debug(DEBUG_BOOT, "working with FREF clock, skip"
" to FREF");

*is_ref_clk = true;
} else {
/* if bit 3 is clear - working with TCXO clock */
wl1271_debug(DEBUG_BOOT, "working with TCXO clock");

/* TCXO to FREF switch, check TXCO clock config */
if ((wl->tcxo_clock != WL12XX_TCXOCLOCK_16_368) &&
(wl->tcxo_clock != WL12XX_TCXOCLOCK_32_736)) {
/*
* not 16.368Mhz and not 32.736Mhz - skip to
* configure ELP stage
*/
wl1271_debug(DEBUG_BOOT, "NEW PLL ALGO:"
" TcxoRefClk=%d - not 16.368Mhz and not"
" 32.736Mhz - skip to configure ELP"
" stage", wl->tcxo_clock);

*is_ref_clk = false;
} else {
wl1271_debug(DEBUG_BOOT, "NEW PLL ALGO:"
"TcxoRefClk=%d - 16.368Mhz or 32.736Mhz"
" - TCXO to FREF switch",
wl->tcxo_clock);

return true;
}
}

return false;
}

static int wl128x_boot_clk(struct wl1271 *wl, bool *is_ref_clk)
{
if (wl128x_switch_fref(wl, is_ref_clk)) {
wl1271_debug(DEBUG_BOOT, "XTAL-only mode go directly to"
" TCXO TO FREF SWITCH");
/* TCXO to FREF switch - for PG2.0 */
wl1271_top_reg_write(wl, WL_SPARE_REG,
WL_SPARE_MASK_8526);

wl1271_top_reg_write(wl, SYS_CLK_CFG_REG,
WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);

*is_ref_clk = true;
mdelay(15);
}

/* Set bit 2 in spare register to avoid illegal access */
wl1271_top_reg_write(wl, WL_SPARE_REG, WL_SPARE_VAL);

/* working with TCXO clock */
if ((*is_ref_clk == false) &&
((wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8) ||
(wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6))) {
wl1271_debug(DEBUG_BOOT, "16_8_M or 33_6_M TCXO detected");

/* Manually Configure MCS PLL settings PG2.0 Only */
wl1271_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
wl1271_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG,
MCS_PLL_CONFIG_REG_VAL);
} else {
int pll_config;
u16 mcs_pll_config_val;

/*
* Configure MCS PLL settings to FREF Freq
* Set the values that determine the time elapse since the PLL's
* get their enable signal until the lock indication is set
*/
wl1271_top_reg_write(wl, PLL_LOCK_COUNTERS_REG,
PLL_LOCK_COUNTERS_COEX | PLL_LOCK_COUNTERS_MCS);

mcs_pll_config_val = wl1271_top_reg_read(wl,
MCS_PLL_CONFIG_REG);
/*
* Set the MCS PLL input frequency value according to the
* reference clock value detected/read
*/
if (*is_ref_clk == false) {
if ((wl->tcxo_clock == WL12XX_TCXOCLOCK_19_2) ||
(wl->tcxo_clock == WL12XX_TCXOCLOCK_38_4))
pll_config = 1;
else if ((wl->tcxo_clock == WL12XX_TCXOCLOCK_26)
||
(wl->tcxo_clock == WL12XX_TCXOCLOCK_52))
pll_config = 2;
else
return -EINVAL;
} else {
if ((wl->ref_clock == CONF_REF_CLK_19_2_E) ||
(wl->ref_clock == CONF_REF_CLK_38_4_E))
pll_config = 1;
else if ((wl->ref_clock == CONF_REF_CLK_26_E) ||
(wl->ref_clock == CONF_REF_CLK_52_E))
pll_config = 2;
else
return -EINVAL;
}

mcs_pll_config_val |= (pll_config << (MCS_SEL_IN_FREQ_SHIFT)) &
(MCS_SEL_IN_FREQ_MASK);
wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG,
mcs_pll_config_val);
}

return 0;
}

static int wl127x_boot_clk(struct wl1271 *wl)
{
u32 pause;
u32 clk;

wl1271_boot_hw_version(wl);

if (wl->ref_clock == 0 || wl->ref_clock == 2 || wl->ref_clock == 4)
if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
wl->ref_clock == CONF_REF_CLK_38_4_E ||
wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
/* ref clk: 19.2/38.4/38.4-XTAL */
clk = 0x3;
else if (wl->ref_clock == 1 || wl->ref_clock == 3)
else if (wl->ref_clock == CONF_REF_CLK_26_E ||
wl->ref_clock == CONF_REF_CLK_52_E)
/* ref clk: 26/52 */
clk = 0x5;
else
return -EINVAL;

if (wl->ref_clock != 0) {
if (wl->ref_clock != CONF_REF_CLK_19_2_E) {
u16 val;
/* Set clock type (open drain) */
val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
Expand Down Expand Up @@ -567,6 +703,26 @@ int wl1271_load_firmware(struct wl1271 *wl)
pause |= WU_COUNTER_PAUSE_VAL;
wl1271_write32(wl, WU_COUNTER_PAUSE, pause);

return 0;
}

/* uploads NVS and firmware */
int wl1271_load_firmware(struct wl1271 *wl)
{
int ret = 0;
u32 tmp, clk;
bool is_ref_clk = false;

if (wl->chip.id == CHIP_ID_1283_PG20) {
ret = wl128x_boot_clk(wl, &is_ref_clk);
if (ret < 0)
goto out;
} else {
ret = wl127x_boot_clk(wl);
if (ret < 0)
goto out;
}

/* Continue the ELP wake up sequence */
wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
udelay(500);
Expand All @@ -582,7 +738,15 @@ int wl1271_load_firmware(struct wl1271 *wl)

wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);

clk |= (wl->ref_clock << 1) << 4;
if (wl->chip.id == CHIP_ID_1283_PG20) {
if (is_ref_clk == false)
clk |= ((wl->tcxo_clock & 0x3) << 1) << 4;
else
clk |= ((wl->ref_clock & 0x3) << 1) << 4;
} else {
clk |= (wl->ref_clock << 1) << 4;
}

wl1271_write32(wl, DRPW_SCRATCH_START, clk);

wl1271_set_partition(wl, &part_table[PART_WORK]);
Expand Down Expand Up @@ -615,6 +779,9 @@ int wl1271_load_firmware(struct wl1271 *wl)
/* WL1271: The reference driver skips steps 7 to 10 (jumps directly
* to upload_fw) */

if (wl->chip.id == CHIP_ID_1283_PG20)
wl1271_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);

ret = wl1271_boot_upload_firmware(wl);
if (ret < 0)
goto out;
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/wl12xx/sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,

wl->irq = wlan_data->irq;
wl->ref_clock = wlan_data->board_ref_clock;
wl->tcxo_clock = wlan_data->board_tcxo_clock;

ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/wl12xx/sdio_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,

wl->irq = wlan_data->irq;
wl->ref_clock = wlan_data->board_ref_clock;
wl->tcxo_clock = wlan_data->board_tcxo_clock;

sdio_set_drvdata(func, wl_test);

Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/wl12xx/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)
}

wl->ref_clock = pdata->board_ref_clock;
wl->tcxo_clock = pdata->board_tcxo_clock;

wl->irq = spi->irq;
if (wl->irq < 0) {
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/wl12xx/wl12xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ struct wl1271 {
u8 ba_rx_bitmap;

u32 block_size;
int tcxo_clock;

/*
* AP-mode - links indexed by HLID. The global and broadcast links
Expand Down

0 comments on commit a11822c

Please sign in to comment.