Skip to content

Commit

Permalink
wlcore/wl12xx: implement chip-specific partition tables
Browse files Browse the repository at this point in the history
Add partition tables to wlcore, move and reorganize partition setting
functions.  Move wl12xx partition table to use the wlcore partition
table instead.

Signed-off-by: Luciano Coelho <coelho@ti.com>
  • Loading branch information
Luciano Coelho committed Apr 12, 2012
1 parent c31be25 commit 25a43d7
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 139 deletions.
62 changes: 62 additions & 0 deletions drivers/net/wireless/ti/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,70 @@
#include "../wlcore/wlcore.h"
#include "../wlcore/debug.h"

#include "../wlcore/reg.h"

static struct wlcore_ops wl12xx_ops = {
};

static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
[PART_DOWN] = {
.mem = {
.start = 0x00000000,
.size = 0x000177c0
},
.reg = {
.start = REGISTERS_BASE,
.size = 0x00008800
},
.mem2 = {
.start = 0x00000000,
.size = 0x00000000
},
.mem3 = {
.start = 0x00000000,
.size = 0x00000000
},
},

[PART_WORK] = {
.mem = {
.start = 0x00040000,
.size = 0x00014fc0
},
.reg = {
.start = REGISTERS_BASE,
.size = 0x0000a000
},
.mem2 = {
.start = 0x003004f8,
.size = 0x00000004
},
.mem3 = {
.start = 0x00040404,
.size = 0x00000000
},
},

[PART_DRPW] = {
.mem = {
.start = 0x00040000,
.size = 0x00014fc0
},
.reg = {
.start = DRPW_BASE,
.size = 0x00006000
},
.mem2 = {
.start = 0x00000000,
.size = 0x00000000
},
.mem3 = {
.start = 0x00000000,
.size = 0x00000000
}
}
};

static int __devinit wl12xx_probe(struct platform_device *pdev)
{
struct wl1271 *wl;
Expand All @@ -43,6 +104,7 @@ static int __devinit wl12xx_probe(struct platform_device *pdev)

wl = hw->priv;
wl->ops = &wl12xx_ops;
wl->ptable = wl12xx_ptable;

return wlcore_probe(wl, pdev);
}
Expand Down
20 changes: 10 additions & 10 deletions drivers/net/wireless/ti/wlcore/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ static void wl1271_boot_fw_version(struct wl1271 *wl)
static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
size_t fw_data_len, u32 dest)
{
struct wl1271_partition_set partition;
struct wlcore_partition_set partition;
int addr, chunk_num, partition_limit;
u8 *p, *chunk;

Expand All @@ -130,23 +130,23 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
return -ENOMEM;
}

memcpy(&partition, &wl12xx_part_table[PART_DOWN], sizeof(partition));
memcpy(&partition, &wl->ptable[PART_DOWN], sizeof(partition));
partition.mem.start = dest;
wl1271_set_partition(wl, &partition);
wlcore_set_partition(wl, &partition);

/* 10.1 set partition limit and chunk num */
chunk_num = 0;
partition_limit = wl12xx_part_table[PART_DOWN].mem.size;
partition_limit = wl->ptable[PART_DOWN].mem.size;

while (chunk_num < fw_data_len / CHUNK_SIZE) {
/* 10.2 update partition, if needed */
addr = dest + (chunk_num + 2) * CHUNK_SIZE;
if (addr > partition_limit) {
addr = dest + chunk_num * CHUNK_SIZE;
partition_limit = chunk_num * CHUNK_SIZE +
wl12xx_part_table[PART_DOWN].mem.size;
wl->ptable[PART_DOWN].mem.size;
partition.mem.start = addr;
wl1271_set_partition(wl, &partition);
wlcore_set_partition(wl, &partition);
}

/* 10.3 upload the chunk */
Expand Down Expand Up @@ -332,7 +332,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
nvs_len -= nvs_ptr - (u8 *)wl->nvs;

/* Now we must set the partition correctly */
wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
wlcore_set_partition(wl, &wl->ptable[PART_WORK]);

/* Copy the NVS tables to a new block to ensure alignment */
nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
Expand Down Expand Up @@ -441,7 +441,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);

/* set the working partition to its "running" mode offset */
wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
wlcore_set_partition(wl, &wl->ptable[PART_WORK]);

wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
wl->cmd_box_addr, wl->event_box_addr);
Expand Down Expand Up @@ -702,7 +702,7 @@ int wl1271_load_firmware(struct wl1271 *wl)
wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
udelay(500);

wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]);
wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);

/* 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
Expand All @@ -721,7 +721,7 @@ int wl1271_load_firmware(struct wl1271 *wl)

wl1271_write32(wl, DRPW_SCRATCH_START, clk);

wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
wlcore_set_partition(wl, &wl->ptable[PART_WORK]);

/* Disable interrupts */
wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ti/wlcore/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ enum {
DEBUG_ADHOC = BIT(16),
DEBUG_AP = BIT(17),
DEBUG_PROBE = BIT(18),
DEBUG_IO = BIT(19),
DEBUG_MASTER = (DEBUG_ADHOC | DEBUG_AP),
DEBUG_ALL = ~0,
};
Expand Down
126 changes: 55 additions & 71 deletions drivers/net/wireless/ti/wlcore/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,65 +45,6 @@
#define OCP_STATUS_REQ_FAILED 0x20000
#define OCP_STATUS_RESP_ERROR 0x30000

struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN] = {
[PART_DOWN] = {
.mem = {
.start = 0x00000000,
.size = 0x000177c0
},
.reg = {
.start = REGISTERS_BASE,
.size = 0x00008800
},
.mem2 = {
.start = 0x00000000,
.size = 0x00000000
},
.mem3 = {
.start = 0x00000000,
.size = 0x00000000
},
},

[PART_WORK] = {
.mem = {
.start = 0x00040000,
.size = 0x00014fc0
},
.reg = {
.start = REGISTERS_BASE,
.size = 0x0000a000
},
.mem2 = {
.start = 0x003004f8,
.size = 0x00000004
},
.mem3 = {
.start = 0x00040404,
.size = 0x00000000
},
},

[PART_DRPW] = {
.mem = {
.start = 0x00040000,
.size = 0x00014fc0
},
.reg = {
.start = DRPW_BASE,
.size = 0x00006000
},
.mem2 = {
.start = 0x00000000,
.size = 0x00000000
},
.mem3 = {
.start = 0x00000000,
.size = 0x00000000
}
}
};

bool wl1271_set_block_size(struct wl1271 *wl)
{
if (wl->if_ops->set_block_size) {
Expand All @@ -124,7 +65,41 @@ void wl1271_enable_interrupts(struct wl1271 *wl)
enable_irq(wl->irq);
}

/* Set the SPI partitions to access the chip addresses
int wlcore_translate_addr(struct wl1271 *wl, int addr)
{
struct wlcore_partition_set *part = &wl->curr_part;

/*
* To translate, first check to which window of addresses the
* particular address belongs. Then subtract the starting address
* of that window from the address. Then, add offset of the
* translated region.
*
* The translated regions occur next to each other in physical device
* memory, so just add the sizes of the preceding address regions to
* get the offset to the new region.
*/
if ((addr >= part->mem.start) &&
(addr < part->mem.start + part->mem.size))
return addr - part->mem.start;
else if ((addr >= part->reg.start) &&
(addr < part->reg.start + part->reg.size))
return addr - part->reg.start + part->mem.size;
else if ((addr >= part->mem2.start) &&
(addr < part->mem2.start + part->mem2.size))
return addr - part->mem2.start + part->mem.size +
part->reg.size;
else if ((addr >= part->mem3.start) &&
(addr < part->mem3.start + part->mem3.size))
return addr - part->mem3.start + part->mem.size +
part->reg.size + part->mem2.size;

WARN(1, "HW address 0x%x out of range", addr);
return 0;
}
EXPORT_SYMBOL_GPL(wlcore_translate_addr);

/* Set the partitions to access the chip addresses
*
* To simplify driver code, a fixed (virtual) memory map is defined for
* register and memory addresses. Because in the chipset, in different stages
Expand Down Expand Up @@ -158,33 +133,43 @@ void wl1271_enable_interrupts(struct wl1271 *wl)
* | |
*
*/
int wl1271_set_partition(struct wl1271 *wl,
struct wl1271_partition_set *p)
void wlcore_set_partition(struct wl1271 *wl,
const struct wlcore_partition_set *p)
{
/* copy partition info */
memcpy(&wl->part, p, sizeof(*p));
memcpy(&wl->curr_part, p, sizeof(*p));

wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
wl1271_debug(DEBUG_IO, "mem_start %08X mem_size %08X",
p->mem.start, p->mem.size);
wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
wl1271_debug(DEBUG_IO, "reg_start %08X reg_size %08X",
p->reg.start, p->reg.size);
wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X",
wl1271_debug(DEBUG_IO, "mem2_start %08X mem2_size %08X",
p->mem2.start, p->mem2.size);
wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X",
wl1271_debug(DEBUG_IO, "mem3_start %08X mem3_size %08X",
p->mem3.start, p->mem3.size);

/* write partition info to the chipset */
wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);
wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);
wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
/*
* We don't need the size of the last partition, as it is
* automatically calculated based on the total memory size and
* the sizes of the previous partitions.
*/
wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
}
EXPORT_SYMBOL_GPL(wlcore_set_partition);

return 0;
void wlcore_select_partition(struct wl1271 *wl, u8 part)
{
wl1271_debug(DEBUG_IO, "setting partition %d", part);

wlcore_set_partition(wl, &wl->ptable[part]);
}
EXPORT_SYMBOL_GPL(wl1271_set_partition);
EXPORT_SYMBOL_GPL(wlcore_select_partition);

void wl1271_io_reset(struct wl1271 *wl)
{
Expand Down Expand Up @@ -241,4 +226,3 @@ u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
return 0xffff;
}
}

Loading

0 comments on commit 25a43d7

Please sign in to comment.