powerpc/powernv/vas: Define vas_init() and vas_exit()

Implement vas_init() and vas_exit() functions for a new VAS module.
This VAS module is essentially a library for other device drivers
and kernel users of the NX coprocessors like NX-842 and NX-GZIP.
In the future this will be extended to add support for user space
to access the NX coprocessors.

VAS is currently only supported with 64K page size.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
Sukadev Bhattiprolu 2017-08-28 23:23:33 -07:00 committed by Michael Ellerman
parent b6622a339e
commit 4dea2d1a92
7 changed files with 217 additions and 0 deletions

View File

@ -0,0 +1,22 @@
* IBM Powerpc Virtual Accelerator Switchboard (VAS)
VAS is a hardware mechanism that allows kernel subsystems and user processes
to directly submit compression and other requests to Nest accelerators (NX)
or other coprocessors functions.
Required properties:
- compatible : should be "ibm,vas".
- ibm,vas-id : A unique identifier for each instance of VAS in the system
- reg : Should contain 4 pairs of 64-bit fields specifying the Hypervisor
window context start and length, OS/User window context start and length,
"Paste address" start and length, "Paste window id" start bit and number
of bits)
Example:
vas@6019100000000 {
compatible = "ibm,vas", "ibm,power9-vas";
reg = <0x6019100000000 0x2000000 0x6019000000000 0x100000000 0x8000000000000 0x100000000 0x20 0x10>;
name = "vas";
ibm,vas-id = <0x1>;
};

View File

@ -6429,6 +6429,14 @@ L: netdev@vger.kernel.org
S: Supported S: Supported
F: drivers/net/ethernet/ibm/ibmvnic.* F: drivers/net/ethernet/ibm/ibmvnic.*
IBM Power Virtual Accelerator Switchboard
M: Sukadev Bhattiprolu
L: linuxppc-dev@lists.ozlabs.org
S: Supported
F: arch/powerpc/platforms/powernv/vas*
F: arch/powerpc/include/asm/vas.h
F: arch/powerpc/include/uapi/asm/vas.h
IBM Power Virtual Ethernet Device Driver IBM Power Virtual Ethernet Device Driver
M: Thomas Falcon <tlfalcon@linux.vnet.ibm.com> M: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org

View File

@ -38,3 +38,17 @@ config PPC_MEMTRACE
help help
Enabling this option allows for the removal of memory (RAM) Enabling this option allows for the removal of memory (RAM)
from the kernel mappings to be used for hardware tracing. from the kernel mappings to be used for hardware tracing.
config PPC_VAS
bool "IBM Virtual Accelerator Switchboard (VAS)"
depends on PPC_POWERNV && PPC_64K_PAGES
default y
help
This enables support for IBM Virtual Accelerator Switchboard (VAS).
VAS allows accelerators in co-processors like NX-GZIP and NX-842
to be accessible to kernel subsystems and user processes.
VAS adapters are found in POWER9 based systems.
If unsure, say N.

View File

@ -14,3 +14,4 @@ obj-$(CONFIG_TRACEPOINTS) += opal-tracepoints.o
obj-$(CONFIG_OPAL_PRD) += opal-prd.o obj-$(CONFIG_OPAL_PRD) += opal-prd.o
obj-$(CONFIG_PERF_EVENTS) += opal-imc.o obj-$(CONFIG_PERF_EVENTS) += opal-imc.o
obj-$(CONFIG_PPC_MEMTRACE) += memtrace.o obj-$(CONFIG_PPC_MEMTRACE) += memtrace.o
obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o

View File

@ -0,0 +1,19 @@
/*
* Copyright 2016-17 IBM Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/types.h>
#include <linux/mutex.h>
#include "vas.h"
/* stub for now */
int vas_win_close(struct vas_window *window)
{
return -1;
}

View File

@ -0,0 +1,151 @@
/*
* Copyright 2016-17 IBM Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#define pr_fmt(fmt) "vas: " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include "vas.h"
static DEFINE_MUTEX(vas_mutex);
static LIST_HEAD(vas_instances);
static int init_vas_instance(struct platform_device *pdev)
{
int rc, vasid;
struct resource *res;
struct vas_instance *vinst;
struct device_node *dn = pdev->dev.of_node;
rc = of_property_read_u32(dn, "ibm,vas-id", &vasid);
if (rc) {
pr_err("No ibm,vas-id property for %s?\n", pdev->name);
return -ENODEV;
}
if (pdev->num_resources != 4) {
pr_err("Unexpected DT configuration for [%s, %d]\n",
pdev->name, vasid);
return -ENODEV;
}
vinst = kzalloc(sizeof(*vinst), GFP_KERNEL);
if (!vinst)
return -ENOMEM;
INIT_LIST_HEAD(&vinst->node);
ida_init(&vinst->ida);
mutex_init(&vinst->mutex);
vinst->vas_id = vasid;
vinst->pdev = pdev;
res = &pdev->resource[0];
vinst->hvwc_bar_start = res->start;
res = &pdev->resource[1];
vinst->uwc_bar_start = res->start;
res = &pdev->resource[2];
vinst->paste_base_addr = res->start;
res = &pdev->resource[3];
if (res->end > 62) {
pr_err("Bad 'paste_win_id_shift' in DT, %llx\n", res->end);
goto free_vinst;
}
vinst->paste_win_id_shift = 63 - res->end;
pr_devel("Initialized instance [%s, %d], paste_base 0x%llx, "
"paste_win_id_shift 0x%llx\n", pdev->name, vasid,
vinst->paste_base_addr, vinst->paste_win_id_shift);
mutex_lock(&vas_mutex);
list_add(&vinst->node, &vas_instances);
mutex_unlock(&vas_mutex);
dev_set_drvdata(&pdev->dev, vinst);
return 0;
free_vinst:
kfree(vinst);
return -ENODEV;
}
/*
* Although this is read/used multiple times, it is written to only
* during initialization.
*/
struct vas_instance *find_vas_instance(int vasid)
{
struct list_head *ent;
struct vas_instance *vinst;
mutex_lock(&vas_mutex);
list_for_each(ent, &vas_instances) {
vinst = list_entry(ent, struct vas_instance, node);
if (vinst->vas_id == vasid) {
mutex_unlock(&vas_mutex);
return vinst;
}
}
mutex_unlock(&vas_mutex);
pr_devel("Instance %d not found\n", vasid);
return NULL;
}
static int vas_probe(struct platform_device *pdev)
{
return init_vas_instance(pdev);
}
static const struct of_device_id powernv_vas_match[] = {
{ .compatible = "ibm,vas",},
{},
};
static struct platform_driver vas_driver = {
.driver = {
.name = "vas",
.of_match_table = powernv_vas_match,
},
.probe = vas_probe,
};
static int __init vas_init(void)
{
int found = 0;
struct device_node *dn;
platform_driver_register(&vas_driver);
for_each_compatible_node(dn, NULL, "ibm,vas") {
of_platform_device_create(dn, NULL, NULL);
found++;
}
if (!found)
return -ENODEV;
pr_devel("Found %d instances\n", found);
return 0;
}
device_initcall(vas_init);

View File

@ -379,4 +379,6 @@ struct vas_winctx {
enum vas_notify_after_count notify_after_count; enum vas_notify_after_count notify_after_count;
}; };
extern struct vas_instance *find_vas_instance(int vasid);
#endif /* _VAS_H */ #endif /* _VAS_H */