Skip to content

Commit

Permalink
wl18xx: Yield issue Work Arond - part 2
Browse files Browse the repository at this point in the history
Add more steps to the sequence.

Bug description: Some PDSP Regs wake up value is such that OCP bridge is stuck, this happened randomly
WA: toggle BT and PHY reset till OCP is free, PDSP registers value is valid.
Sequence will be done in PG1 only.

Signed-off-by: Orit Brayer <orit@ti.com>
  • Loading branch information
OritB authored and ariknem committed Dec 5, 2011
1 parent 4526843 commit ecfeda9
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 6 deletions.
57 changes: 51 additions & 6 deletions drivers/net/wireless/wl12xx/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,12 @@ static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
},
[PART_PHY_PDSP_WA] = {
.mem = {
.start = 0x00953000,
.size = 0x00012000
.start = 0x00940100,
.size = 0x00000200
},
.reg = {
.start = 0x00000000,
.size = 0x00000000
.start = 0x00953000,
.size = 0x00012000
},
.mem2 = {
.start = 0x00000000,
Expand Down Expand Up @@ -998,12 +998,13 @@ static int wl127x_boot_clk(struct wl1271 *wl)
/* Summarizing yield issue:
Bug description: Some PDSP Regs wake up value is such that OCP bridge is stuck, this happened randomly
WA: toggle BT and PHY reset till OCP is free, PDSP registers value is valid */
static void wl18xx_pdsp_wa_sequence(struct wl1271 *wl)
static int wl18xx_pdsp_wa_sequence(struct wl1271 *wl)
{
int i;
u32 ocp_state;
u32 val;

/* PHY Reset */
for (i = 0; i < 10; i++) {

wl1271_set_partition(wl, &part_table[PART_PHY_PDSP_WA]);
Expand All @@ -1015,6 +1016,24 @@ static void wl18xx_pdsp_wa_sequence(struct wl1271 *wl)
goto toggle_pdsp_reset;
}

wl1271_set_partition(wl, &part_table[PART_TOP_PRCM_ELP_SOC]);
wl1271_top_reg_write(wl, 0xA021FE, 0x400); /* WL PHY off*/
wl1271_top_reg_write(wl, 0xA021FC, 0x400); /* PHY on */
wl1271_top_reg_write(wl, 0xA021FE, 0); /* remove override - turn off BT */
}

/* BT Reset */
for (i = 0; i < 10; i++) {

wl1271_set_partition(wl, &part_table[PART_PHY_PDSP_WA]);

ocp_state = wl1271_read32(wl, PHY_HRAM_RD_EN_PER_RAM);

/* Check OCP state */
if (ocp_state == 0x3F) {
goto toggle_pdsp_reset;
}

wl1271_set_partition(wl, &part_table[PART_TOP_PRCM_ELP_SOC]);
val = wl1271_top_reg_read(wl, PRCM_BT_PWR_RST);

Expand All @@ -1030,14 +1049,38 @@ static void wl18xx_pdsp_wa_sequence(struct wl1271 *wl)
}

wl1271_set_partition(wl, &part_table[PART_PHY_PDSP_WA]);
ocp_state = wl1271_read32(wl, PHY_HRAM_RD_EN_PER_RAM);

/* Check OCP state */
if (ocp_state != 0x3F) {
wl1271_error("F/PDSP OCP is not accessible - please reset device");
return -1;
}

toggle_pdsp_reset:
/* toggle PDSP reset*/
wl1271_write32(wl, PDSP_CONTROL_REG, 0x00000007);
wl1271_write32(wl, PDSP_CONTROL_REG, 0x00000000);
wl1271_write32(wl, PDSP_CONTROL_REG, 0x00000007);
wl1271_write32(wl, PDSP_CONTROL_REG, 0x00000000);

/* Validate PDSP Reset */
for (i = 0; i < 3; i++) {

wl1271_write32(wl, FDSP_RAM, 0xA5A5A5A5);
val = wl1271_read32(wl, FDSP_RAM);
if (val == 0xA5A5A5A5) {
goto out;
}
}

wl1271_error("Validate PDSP Reset failed - please reset device");
return -1;

out:
wl1271_set_partition(wl, &part_table[PART_BOOT]);

return 0;
}

/* uploads NVS and firmware */
Expand All @@ -1057,7 +1100,9 @@ int wl1271_load_firmware(struct wl1271 *wl)

/* PDSP work around sequence for Yield issue */
if (wl->chip.id == CHIP_ID_185x_PG10) {
wl18xx_pdsp_wa_sequence(wl);
ret = wl18xx_pdsp_wa_sequence(wl);
if (ret < 0)
goto out;
}
}
else if (wl->chip.id == CHIP_ID_1283_PG20) {
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/wl12xx/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ enum {
/* wl18xx PDSP work around sequence */
#define PHY_HRAM_RD_EN_PER_RAM (0x0095380C)
#define PDSP_CONTROL_REG (0x00964400)
#define FDSP_RAM (0x00940100)
#define PRCM_BT_PWR_RST (0xA0240A)

enum
Expand Down

0 comments on commit ecfeda9

Please sign in to comment.