misc: mods: update MODS driver from Perforce

Change-Id: I5a024a62688fa6ec1f445628bbc618ae92db737d
Signed-off-by: Chris Dragan <kdragan@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2303203
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Chris Dragan
2020-02-26 04:32:58 -08:00
committed by Laxman Dewangan
parent a85680cbc5
commit 14ecbcb3d5
3 changed files with 138 additions and 127 deletions

View File

@@ -109,6 +109,9 @@ struct mods_client {
u32 access_token;
atomic_t num_allocs;
atomic_t num_pages;
#if defined(MODS_HAS_CONSOLE_LOCK)
atomic_t console_is_locked;
#endif
u8 client_id;
};
@@ -446,12 +449,15 @@ int esc_mods_virtual_to_phys(struct mods_client *client,
struct MODS_VIRTUAL_TO_PHYSICAL *p);
int esc_mods_phys_to_virtual(struct mods_client *client,
struct MODS_PHYSICAL_TO_VIRTUAL *p);
int esc_mods_memory_barrier(struct mods_client *client);
int esc_mods_dma_map_memory(struct mods_client *client,
struct MODS_DMA_MAP_MEMORY *p);
int esc_mods_dma_unmap_memory(struct mods_client *client,
struct MODS_DMA_MAP_MEMORY *p);
#ifdef CONFIG_ARM
int esc_mods_memory_barrier(struct mods_client *client);
#endif
#if defined(CONFIG_PPC64)
/* ppc64 */
int esc_mods_set_ppc_tce_bypass(struct mods_client *client,

View File

@@ -28,7 +28,6 @@
#include <linux/poll.h>
#include <linux/random.h>
#include <linux/sched.h>
#include <linux/screen_info.h>
#include <linux/uaccess.h>
#ifdef MODS_HAS_CONSOLE_LOCK
# include <linux/console.h>
@@ -38,6 +37,7 @@
# include <linux/vt_kern.h>
#endif
#ifdef CONFIG_X86
# include <linux/screen_info.h>
# include <asm/msr.h>
#endif
@@ -50,7 +50,7 @@ static unsigned int mods_krnl_poll(struct file *, poll_table *);
static int mods_krnl_mmap(struct file *, struct vm_area_struct *);
static long mods_krnl_ioctl(struct file *, unsigned int, unsigned long);
#ifdef MODS_HAS_SRIOV
#if defined(CONFIG_PCI) && defined(MODS_HAS_SRIOV)
static int mods_pci_sriov_configure(struct pci_dev *dev, int numvfs);
#endif
@@ -146,7 +146,7 @@ static int debug;
static int multi_instance = MODS_MULTI_INSTANCE_DEFAULT_VALUE;
static u32 access_token = MODS_ACCESS_TOKEN_NONE;
#ifdef MODS_HAS_SRIOV
#if defined(CONFIG_PCI) && defined(MODS_HAS_SRIOV)
static int mods_pci_sriov_configure(struct pci_dev *dev, int numvfs)
{
int totalvfs;
@@ -557,7 +557,11 @@ static void mods_disable_all_devices(struct mods_client *client)
#endif
}
#if defined(MODS_HAS_CONSOLE_LOCK)
static int mods_resume_console(struct mods_client *client);
#else
static inline int mods_resume_console(struct mods_client *client) { return 0; }
#endif
/*********************
* MAPPING FUNCTIONS *
@@ -1249,8 +1253,8 @@ static int mods_krnl_map_inner(struct mods_client *client,
return OK;
}
#if !defined(CONFIG_ARM) && !defined(CONFIG_ARM64) && !defined(CONFIG_PPC64)
static int mods_get_screen_info(struct MODS_SCREEN_INFO *p)
#if defined(CONFIG_X86)
static void mods_get_screen_info(struct MODS_SCREEN_INFO *p)
{
p->orig_video_mode = screen_info.orig_video_mode;
p->orig_video_is_vga = screen_info.orig_video_isVGA;
@@ -1260,7 +1264,6 @@ static int mods_get_screen_info(struct MODS_SCREEN_INFO *p)
p->lfb_base = screen_info.lfb_base;
p->lfb_size = screen_info.lfb_size;
p->lfb_linelength = screen_info.lfb_linelength;
return OK;
}
#endif
@@ -1282,30 +1285,24 @@ static int esc_mods_get_kernel_version(struct mods_client *client,
return OK;
}
#if defined(CONFIG_X86)
static int esc_mods_get_screen_info(struct mods_client *client,
struct MODS_SCREEN_INFO *p)
{
#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_PPC64)
return -EINVAL;
#else
int rc = mods_get_screen_info(p);
mods_get_screen_info(p);
#if defined(VIDEO_CAPABILITY_64BIT_BASE)
if (screen_info.ext_lfb_base)
return -EOVERFLOW;
#endif
return rc;
#endif
return OK;
}
static int esc_mods_get_screen_info_2(struct mods_client *client,
struct MODS_SCREEN_INFO_2 *p)
{
#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_PPC64)
return -EINVAL;
#else
int rc = mods_get_screen_info(&p->info);
mods_get_screen_info(&p->info);
#if defined(VIDEO_CAPABILITY_64BIT_BASE)
p->ext_lfb_base = screen_info.ext_lfb_base;
@@ -1313,28 +1310,35 @@ static int esc_mods_get_screen_info_2(struct mods_client *client,
p->ext_lfb_base = 0;
#endif
return rc;
#endif
return OK;
}
#endif
#if defined(MODS_HAS_CONSOLE_LOCK)
static atomic_t console_is_locked;
static int esc_mods_lock_console(struct mods_client *client)
{
#if defined(MODS_HAS_CONSOLE_LOCK)
if (atomic_cmpxchg(&console_is_locked, 0, 1)) {
cl_error("console is already locked\n");
return -EINVAL;
}
atomic_set(&client->console_is_locked, 1);
console_lock();
return OK;
#else
return -EINVAL;
#endif
}
static int esc_mods_unlock_console(struct mods_client *client)
{
#if defined(MODS_HAS_CONSOLE_LOCK)
if (!atomic_cmpxchg(&client->console_is_locked, 1, 0)) {
cl_error("console is not locked by this client\n");
return -EINVAL;
}
console_unlock();
atomic_set(&console_is_locked, 0);
return OK;
#else
return -EINVAL;
#endif
}
static int esc_mods_suspend_console(struct mods_client *client)
@@ -1343,7 +1347,13 @@ static int esc_mods_suspend_console(struct mods_client *client)
LOG_ENT();
#if defined(CONFIG_FB) && defined(MODS_HAS_CONSOLE_LOCK)
if (atomic_cmpxchg(&console_is_locked, 0, 1)) {
cl_error("cannot suspend console, console is locked\n");
LOG_EXT();
return -EINVAL;
}
#if defined(CONFIG_FB)
if (num_registered_fb) {
/* tell the os to block fb accesses */
int i = 0;
@@ -1360,7 +1370,7 @@ static int esc_mods_suspend_console(struct mods_client *client)
}
#endif
#if defined(MODS_HAS_CONSOLE_BINDING) && defined(MODS_HAS_CONSOLE_LOCK)
#if defined(MODS_HAS_CONSOLE_BINDING)
if (&vga_con == vc_cons[fg_console].d->vc_sw) {
/* if the current console is the vga console driver,
* have the dummy driver take over.
@@ -1372,6 +1382,8 @@ static int esc_mods_suspend_console(struct mods_client *client)
}
#endif
atomic_set(&console_is_locked, 0);
LOG_EXT();
return err;
@@ -1388,7 +1400,16 @@ static int mods_resume_console(struct mods_client *client)
LOG_ENT();
#if defined(CONFIG_FB) && defined(MODS_HAS_CONSOLE_LOCK)
if (atomic_cmpxchg(&client->console_is_locked, 1, 0)) {
cl_warn("console was not properly unlocked\n");
console_unlock();
} else if (atomic_cmpxchg(&console_is_locked, 0, 1)) {
cl_error("cannot resume console, console is locked\n");
LOG_EXT();
return -EINVAL;
}
#if defined(CONFIG_FB)
if (num_registered_fb) {
int i = 0;
@@ -1404,7 +1425,7 @@ static int mods_resume_console(struct mods_client *client)
}
#endif
#if defined(MODS_HAS_CONSOLE_BINDING) && defined(MODS_HAS_CONSOLE_LOCK)
#if defined(MODS_HAS_CONSOLE_BINDING)
if (&dummy_con == vc_cons[fg_console].d->vc_sw) {
/* try to unbind the dummy driver,
* the system driver should take over.
@@ -1415,11 +1436,13 @@ static int mods_resume_console(struct mods_client *client)
err = OK;
}
#endif
atomic_set(&console_is_locked, 0);
LOG_EXT();
return err;
}
#endif
static int esc_mods_acquire_access_token(struct mods_client *client,
struct MODS_ACCESS_TOKEN *ptoken)
@@ -1780,12 +1803,6 @@ static long mods_krnl_ioctl(struct file *fp,
MODS_PCI_BUS_ADD_DEVICES);
break;
case MODS_ESC_PCI_HOT_RESET:
MODS_IOCTL_NORETVAL(MODS_ESC_PCI_HOT_RESET,
esc_mods_pci_hot_reset,
MODS_PCI_HOT_RESET);
break;
case MODS_ESC_PCI_BUS_REMOVE_DEV:
MODS_IOCTL_NORETVAL(MODS_ESC_PCI_BUS_REMOVE_DEV,
esc_mods_pci_bus_remove_dev,
@@ -1920,6 +1937,12 @@ static long mods_krnl_ioctl(struct file *fp,
break;
#if defined(CONFIG_PPC64)
case MODS_ESC_PCI_HOT_RESET:
MODS_IOCTL_NORETVAL(MODS_ESC_PCI_HOT_RESET,
esc_mods_pci_hot_reset,
MODS_PCI_HOT_RESET);
break;
case MODS_ESC_SET_PPC_TCE_BYPASS:
MODS_IOCTL(MODS_ESC_SET_PPC_TCE_BYPASS,
esc_mods_set_ppc_tce_bypass,
@@ -1931,11 +1954,13 @@ static long mods_krnl_ioctl(struct file *fp,
esc_mods_get_ats_address_range,
MODS_GET_ATS_ADDRESS_RANGE);
break;
case MODS_ESC_SET_NVLINK_SYSMEM_TRAINED:
MODS_IOCTL(MODS_ESC_SET_NVLINK_SYSMEM_TRAINED,
esc_mods_set_nvlink_sysmem_trained,
MODS_SET_NVLINK_SYSMEM_TRAINED);
break;
case MODS_ESC_GET_NVLINK_LINE_RATE:
MODS_IOCTL(MODS_ESC_GET_NVLINK_LINE_RATE,
esc_mods_get_nvlink_line_rate,
@@ -2214,11 +2239,12 @@ static long mods_krnl_ioctl(struct file *fp,
break;
#endif
#endif
#ifdef CONFIG_ARM
case MODS_ESC_MEMORY_BARRIER:
MODS_IOCTL_VOID(MODS_ESC_MEMORY_BARRIER,
esc_mods_memory_barrier);
break;
#endif
#ifdef CONFIG_ARCH_TEGRA
case MODS_ESC_DMABUF_GET_PHYSICAL_ADDRESS:
MODS_IOCTL(MODS_ESC_DMABUF_GET_PHYSICAL_ADDRESS,
@@ -2248,6 +2274,8 @@ static long mods_krnl_ioctl(struct file *fp,
MODS_ADSP_RUN_APP_INFO);
break;
#endif
#ifdef CONFIG_X86
case MODS_ESC_GET_SCREEN_INFO:
MODS_IOCTL(MODS_ESC_GET_SCREEN_INFO,
esc_mods_get_screen_info, MODS_SCREEN_INFO);
@@ -2256,6 +2284,9 @@ static long mods_krnl_ioctl(struct file *fp,
MODS_IOCTL(MODS_ESC_GET_SCREEN_INFO_2,
esc_mods_get_screen_info_2, MODS_SCREEN_INFO_2);
break;
#endif
#if defined(MODS_HAS_CONSOLE_LOCK)
case MODS_ESC_LOCK_CONSOLE:
MODS_IOCTL_VOID(MODS_ESC_LOCK_CONSOLE,
esc_mods_lock_console);
@@ -2272,6 +2303,7 @@ static long mods_krnl_ioctl(struct file *fp,
MODS_IOCTL_VOID(MODS_ESC_RESUME_CONSOLE,
esc_mods_resume_console);
break;
#endif
#if defined(CONFIG_ARCH_TEGRA)
case MODS_ESC_TEGRA_PROD_IS_SUPPORTED:
@@ -2345,7 +2377,7 @@ static long mods_krnl_ioctl(struct file *fp,
esc_mods_query_irq_3, MODS_QUERY_IRQ_3);
break;
#ifdef MODS_HAS_SRIOV
#if defined(CONFIG_PCI) && defined(MODS_HAS_SRIOV)
case MODS_ESC_SET_NUM_VF:
MODS_IOCTL_NORETVAL(MODS_ESC_SET_NUM_VF,
esc_mods_set_num_vf, MODS_SET_NUM_VF);

View File

@@ -121,57 +121,30 @@ static void mods_dma_unmap_page(struct mods_client *client,
}
/* Unmap and delete the specified DMA mapping */
static int mods_dma_unmap_and_free(struct mods_client *client,
struct MODS_MEM_INFO *p_mem_info,
struct MODS_DMA_MAP *p_del_map)
static void dma_unmap_and_free(struct mods_client *client,
struct MODS_MEM_INFO *p_mem_info,
struct MODS_DMA_MAP *p_del_map)
{
int found = 0;
struct list_head *head = &p_mem_info->dma_map_list;
struct list_head *iter;
u32 i;
list_for_each(iter, head) {
struct MODS_DMA_MAP *p_dma_map = list_entry(iter,
struct MODS_DMA_MAP,
list);
for (i = 0; i < p_mem_info->num_chunks; i++)
mods_dma_unmap_page(client,
p_del_map->dev,
p_del_map->dev_addr[i],
p_mem_info->pages[i].order);
if (p_dma_map == p_del_map) {
list_del(iter);
found = 1;
break;
}
}
if (!found) {
cl_error("failed to unmap and free %p\n", p_del_map);
return -EINVAL;
}
/* Safeguard check, all mappings should have a
* non-null device
*/
if (p_del_map->dev) {
int i;
for (i = 0; i < p_mem_info->num_chunks; i++)
mods_dma_unmap_page(client,
p_del_map->dev,
p_del_map->dev_addr[i],
p_mem_info->pages[i].order);
pci_dev_put(p_del_map->dev);
}
pci_dev_put(p_del_map->dev);
kfree(p_del_map);
atomic_dec(&client->num_allocs);
return OK;
}
#endif
/* Unmap and delete all DMA mappings on the specified allocation */
int mods_dma_unmap_all(struct mods_client *client,
struct MODS_MEM_INFO *p_mem_info,
struct pci_dev *dev)
static int dma_unmap_all(struct mods_client *client,
struct MODS_MEM_INFO *p_mem_info,
struct pci_dev *dev)
{
#ifdef CONFIG_PCI
int err = OK;
@@ -185,10 +158,10 @@ int mods_dma_unmap_all(struct mods_client *client,
p_dma_map = list_entry(iter, struct MODS_DMA_MAP, list);
if (!dev || (p_dma_map->dev == dev)) {
err = mods_dma_unmap_and_free(client,
p_mem_info,
p_dma_map);
if (err || dev)
list_del(iter);
dma_unmap_and_free(client, p_mem_info, p_dma_map);
if (dev)
break;
}
}
@@ -200,6 +173,38 @@ int mods_dma_unmap_all(struct mods_client *client,
}
#ifdef CONFIG_PCI
static int pci_map_chunk(struct mods_client *client,
struct pci_dev *dev,
struct MODS_PHYS_CHUNK *chunk,
u64 *out_dev_addr)
{
u64 dev_addr = pci_map_page(dev,
chunk->p_page,
0,
PAGE_SIZE << chunk->order,
DMA_BIDIRECTIONAL);
int err = pci_dma_mapping_error(dev, dev_addr);
if (err) {
cl_error(
"failed to map 2^%u pages at 0x%llx to dev %04x:%02x:%02x.%x with dma mask 0x%llx\n",
chunk->order,
(unsigned long long)chunk->dma_addr,
pci_domain_nr(dev->bus),
dev->bus->number,
PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn),
(unsigned long long)dma_get_mask(&dev->dev));
return err;
}
*out_dev_addr = mods_compress_nvlink_addr(dev, dev_addr);
return OK;
}
/* DMA map all pages in an allocation */
static int mods_dma_map_pages(struct mods_client *client,
struct MODS_MEM_INFO *p_mem_info,
@@ -210,36 +215,20 @@ static int mods_dma_map_pages(struct mods_client *client,
for (i = 0; i < p_mem_info->num_chunks; i++) {
struct MODS_PHYS_CHUNK *chunk = &p_mem_info->pages[i];
u64 dev_addr;
u64 dev_addr;
dev_addr = pci_map_page(dev,
chunk->p_page,
0,
PAGE_SIZE << chunk->order,
DMA_BIDIRECTIONAL);
if (pci_dma_mapping_error(dev, dev_addr)) {
cl_error(
"failed to map 2^%u pages at 0x%llx to dev %04x:%02x:%02x.%x with dma mask 0x%llx\n",
chunk->order,
(unsigned long long)chunk->dma_addr,
pci_domain_nr(dev->bus),
dev->bus->number,
PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn),
(unsigned long long)dma_get_mask(&dev->dev));
int err = pci_map_chunk(client, dev, chunk, &dev_addr);
if (err) {
while (--i >= 0)
mods_dma_unmap_page(client,
dev,
p_dma_map->dev_addr[i],
chunk->order);
return -EINVAL;
return err;
}
dev_addr = mods_compress_nvlink_addr(dev, dev_addr);
p_dma_map->dev_addr[i] = dev_addr;
cl_debug(DEBUG_MEM_DETAILED,
@@ -293,26 +282,12 @@ static int mods_dma_map_default_page(struct mods_client *client,
struct MODS_PHYS_CHUNK *chunk,
struct pci_dev *dev)
{
u64 dev_addr = pci_map_page(dev,
chunk->p_page,
0,
PAGE_SIZE << chunk->order,
DMA_BIDIRECTIONAL);
u64 dev_addr;
int err = pci_map_chunk(client, dev, chunk, &dev_addr);
if (pci_dma_mapping_error(dev, dev_addr)) {
cl_error(
"failed to map 2^%u pages at 0x%llx to dev %04x:%02x:%02x.%x with dma mask 0x%llx\n",
chunk->order,
(unsigned long long)chunk->dma_addr,
pci_domain_nr(dev->bus),
dev->bus->number,
PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn),
(unsigned long long)dma_get_mask(&dev->dev));
return -EINVAL;
}
if (err)
return err;
dev_addr = mods_compress_nvlink_addr(dev, dev_addr);
chunk->dev_addr = dev_addr;
chunk->mapped = 1;
@@ -881,7 +856,7 @@ static int mods_unregister_and_free(struct mods_client *client,
mutex_unlock(&client->mtx);
mods_dma_unmap_all(client, p_mem_info, NULL);
dma_unmap_all(client, p_mem_info, NULL);
save_non_wb_chunks(client, p_mem_info);
mods_free_pages(client, p_mem_info);
pci_dev_put(p_mem_info->dev);
@@ -1959,16 +1934,14 @@ int esc_mods_phys_to_virtual(struct mods_client *client,
return -EINVAL;
}
#if defined(CONFIG_ARM)
int esc_mods_memory_barrier(struct mods_client *client)
{
#if defined(CONFIG_ARM)
/* Full memory barrier on ARMv7 */
wmb();
return OK;
#else
return -EINVAL;
#endif
}
#endif
#ifdef CONFIG_PCI
int esc_mods_dma_map_memory(struct mods_client *client,
@@ -2051,7 +2024,7 @@ int esc_mods_dma_unmap_memory(struct mods_client *client,
p->pci_device.device,
p->pci_device.function);
} else
err = mods_dma_unmap_all(client, p_mem_info, dev);
err = dma_unmap_all(client, p_mem_info, dev);
pci_dev_put(dev);
LOG_EXT();