wil6210: prevent deep sleep of 60G device in critical paths

In idle times 60G device can enter deep sleep and turn off
its XTAL clock.
Host access triggers the device power-up flow which will hold
the AHB during XTAL stabilization until device switches from
slow-clock to XTAL clock.
This behavior can stall the PCIe bus for some arbitrary period
of time.
In order to prevent this stall, host can vote for High Latency
Access Policy (HALP) before reading from PCIe bus.
This vote will wakeup the device from deep sleep and prevent
deep sleep until unvote is done.

Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
Maya Erez
2016-04-26 14:41:41 +03:00
committed by Kalle Valo
parent 54eaa8c69e
commit 349214c1e7
5 changed files with 194 additions and 32 deletions

View File

@@ -171,6 +171,8 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
int rsize;
uint i;
wil_halp_vote(wil);
wil_memcpy_fromio_32(&r, off, sizeof(r));
wil_mbox_ring_le2cpus(&r);
/*
@@ -236,6 +238,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
}
out:
seq_puts(s, "}\n");
wil_halp_unvote(wil);
}
static int wil_mbox_debugfs_show(struct seq_file *s, void *data)
@@ -500,9 +503,9 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
enum { max_count = 4096 };
struct debugfs_blob_wrapper *blob = file->private_data;
struct wil_blob_wrapper *wil_blob = file->private_data;
loff_t pos = *ppos;
size_t available = blob->size;
size_t available = wil_blob->blob.size;
void *buf;
size_t ret;
@@ -521,8 +524,9 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
if (!buf)
return -ENOMEM;
wil_memcpy_fromio_32(buf, (const volatile void __iomem *)blob->data +
pos, count);
wil_memcpy_fromio_halp_vote(wil_blob->wil, buf,
(const volatile void __iomem *)
wil_blob->blob.data + pos, count);
ret = copy_to_user(user_buf, buf, count);
kfree(buf);
@@ -545,9 +549,9 @@ static
struct dentry *wil_debugfs_create_ioblob(const char *name,
umode_t mode,
struct dentry *parent,
struct debugfs_blob_wrapper *blob)
struct wil_blob_wrapper *wil_blob)
{
return debugfs_create_file(name, mode, parent, blob, &fops_ioblob);
return debugfs_create_file(name, mode, parent, wil_blob, &fops_ioblob);
}
/*---reset---*/
@@ -1445,16 +1449,18 @@ static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
char name[32];
for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
struct debugfs_blob_wrapper *blob = &wil->blobs[i];
struct wil_blob_wrapper *wil_blob = &wil->blobs[i];
struct debugfs_blob_wrapper *blob = &wil_blob->blob;
const struct fw_map *map = &fw_mapping[i];
if (!map->name)
continue;
wil_blob->wil = wil;
blob->data = (void * __force)wil->csr + HOSTADDR(map->host);
blob->size = map->to - map->from;
snprintf(name, sizeof(name), "blob_%s", map->name);
wil_debugfs_create_ioblob(name, S_IRUGO, dbg, blob);
wil_debugfs_create_ioblob(name, S_IRUGO, dbg, wil_blob);
}
}