* [RFC 01/16] drm/nouveau: handle -EACCES runtime PM return code
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-01 3:16 ` [RFC 02/16] drm/nouveau: basic support for platform devices Alexandre Courbot
` (11 subsequent siblings)
12 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: gnurou, Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
Terje Bergstrom, Ken Adams
pm_runtime_get*() may return -EACCESS to indicate a device does not have
runtime PM enabled. This is the case when the nouveau.runpm parameter is
set to 0, and is not an error in that context. Handle this case without
failure.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/dispnv04/crtc.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_connector.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_drm.c | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index 0e3270c..1caef1f 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -1048,7 +1048,7 @@ nouveau_crtc_set_config(struct drm_mode_set *set)
/* get a pm reference here */
ret = pm_runtime_get_sync(dev->dev);
- if (ret < 0)
+ if (ret < 0 && ret != -EACCES)
return ret;
ret = drm_crtc_helper_set_config(set);
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 1674882..cddef54 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -255,7 +255,7 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
}
ret = pm_runtime_get_sync(connector->dev->dev);
- if (ret < 0)
+ if (ret < 0 && ret != -EACCES)
return conn_status;
i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 98a22e6..23299ca 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -670,7 +670,7 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
/* need to bring up power immediately if opening device */
ret = pm_runtime_get_sync(dev->dev);
- if (ret < 0)
+ if (ret < 0 && ret != -EACCES)
return ret;
get_task_comm(tmpname, current);
@@ -753,7 +753,7 @@ long nouveau_drm_ioctl(struct file *filp,
dev = file_priv->minor->dev;
ret = pm_runtime_get_sync(dev->dev);
- if (ret < 0)
+ if (ret < 0 && ret != -EACCES)
return ret;
ret = drm_ioctl(filp, cmd, arg);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* [RFC 02/16] drm/nouveau: basic support for platform devices
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
2014-02-01 3:16 ` [RFC 01/16] drm/nouveau: handle -EACCES runtime PM return code Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-01 3:16 ` [RFC 05/16] drm/nouveau/bar: support " Alexandre Courbot
` (10 subsequent siblings)
12 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: Terje Bergstrom, Ken Adams, Thierry Reding, Stephen Warren,
Eric Brower, linux-tegra, linux-kernel, gnurou, Alexandre Courbot
The T124 generation of Tegra GPUs uses the Kepler architecture and can
thus be driven by Nouveau. However, they are declared as platform
devices using the Device Tree, and Nouveau has a very strong dependency
on PCI. This patch makes Nouveau core able to handle platform devices as
well as PCI devices.
Commonly-used PCI functions include resource range query and page
mapping. These functions are abstracted so the correct bus type is used
to perform them. Some PCI-dependent code is also disabled when probing a
non-PCI device.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/core/engine/device/base.c | 58 +++++++++++++++++++++-
drivers/gpu/drm/nouveau/core/include/core/device.h | 27 ++++++++++
drivers/gpu/drm/nouveau/core/os.h | 1 +
drivers/gpu/drm/nouveau/nouveau_abi16.c | 13 ++++-
drivers/gpu/drm/nouveau/nouveau_bo.c | 22 ++++----
drivers/gpu/drm/nouveau/nouveau_display.c | 3 +-
drivers/gpu/drm/nouveau/nouveau_drm.c | 53 ++++++++++++++------
drivers/gpu/drm/nouveau/nouveau_sysfs.c | 8 +--
drivers/gpu/drm/nouveau/nouveau_ttm.c | 31 +++++++-----
9 files changed, 170 insertions(+), 46 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c
index dd01c6c..a6abb51 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c
@@ -131,8 +131,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
if (ret)
return ret;
- mmio_base = pci_resource_start(device->pdev, 0);
- mmio_size = pci_resource_len(device->pdev, 0);
+ mmio_base = nv_device_resource_start(device, 0);
+ mmio_size = nv_device_resource_len(device, 0);
/* translate api disable mask into internal mapping */
disable = args->debug0;
@@ -446,6 +446,60 @@ nouveau_device_dtor(struct nouveau_object *object)
nouveau_engine_destroy(&device->base);
}
+resource_size_t
+nv_device_resource_start(struct nouveau_device *device, unsigned int bar)
+{
+ if (nv_device_is_pci(device)) {
+ return pci_resource_start(device->pdev, bar);
+ } else {
+ struct resource *res;
+ res = platform_get_resource(device->platformdev,
+ IORESOURCE_MEM, bar);
+ if (!res)
+ return 0;
+ return res->start;
+ }
+}
+
+resource_size_t
+nv_device_resource_len(struct nouveau_device *device, unsigned int bar)
+{
+ if (nv_device_is_pci(device)) {
+ return pci_resource_len(device->pdev, bar);
+ } else {
+ struct resource *res;
+ res = platform_get_resource(device->platformdev,
+ IORESOURCE_MEM, bar);
+ if (!res)
+ return 0;
+ return resource_size(res);
+ }
+}
+
+dma_addr_t
+nv_device_map_page(struct nouveau_device *device, struct page *page) {
+ dma_addr_t ret;
+
+ if (nv_device_is_pci(device)) {
+ ret = pci_map_page(device->pdev, page, 0, PAGE_SIZE,
+ PCI_DMA_BIDIRECTIONAL);
+ if (pci_dma_mapping_error(device->pdev, ret))
+ ret = 0;
+ } else {
+ ret = page_to_phys(page);
+ }
+
+ return ret;
+}
+
+void
+nv_device_unmap_page(struct nouveau_device *device, dma_addr_t addr)
+{
+ if (nv_device_is_pci(device))
+ pci_unmap_page(device->pdev, addr, PAGE_SIZE,
+ PCI_DMA_BIDIRECTIONAL);
+}
+
static struct nouveau_oclass
nouveau_device_oclass = {
.handle = NV_ENGINE(DEVICE, 0x00),
diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h
index 7b8ea22..23f4a25 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/device.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/device.h
@@ -65,6 +65,7 @@ struct nouveau_device {
struct list_head head;
struct pci_dev *pdev;
+ struct platform_device *platformdev;
u64 handle;
const char *cfgopt;
@@ -140,4 +141,30 @@ nv_device_match(struct nouveau_object *object, u16 dev, u16 ven, u16 sub)
device->pdev->subsystem_device == sub;
}
+static inline bool
+nv_device_is_pci(struct nouveau_device *device)
+{
+ return device->pdev != NULL;
+}
+
+static inline struct device *
+nv_device_base(struct nouveau_device *device)
+{
+ return nv_device_is_pci(device) ? &device->pdev->dev :
+ &device->platformdev->dev;
+}
+
+resource_size_t
+nv_device_resource_start(struct nouveau_device *device, unsigned int bar);
+
+resource_size_t
+nv_device_resource_len(struct nouveau_device *device, unsigned int bar);
+
+dma_addr_t
+nv_device_map_page(struct nouveau_device *device, struct page *page);
+
+void
+nv_device_unmap_page(struct nouveau_device *device, dma_addr_t addr);
+
#endif
+
diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/core/os.h
index 191e739..90a6c90 100644
--- a/drivers/gpu/drm/nouveau/core/os.h
+++ b/drivers/gpu/drm/nouveau/core/os.h
@@ -5,6 +5,7 @@
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/pci.h>
+#include <linux/platform_device.h>
#include <linux/printk.h>
#include <linux/bitops.h>
#include <linux/firmware.h>
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index 900fae0..a28422b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -179,12 +179,21 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
getparam->value = device->chipset;
break;
case NOUVEAU_GETPARAM_PCI_VENDOR:
- getparam->value = dev->pdev->vendor;
+ if (nv_device_is_pci(device))
+ getparam->value = dev->pdev->vendor;
+ else
+ getparam->value = 0;
break;
case NOUVEAU_GETPARAM_PCI_DEVICE:
- getparam->value = dev->pdev->device;
+ if (nv_device_is_pci(device))
+ getparam->value = dev->pdev->device;
+ else
+ getparam->value = 0;
break;
case NOUVEAU_GETPARAM_BUS_TYPE:
+ if (!nv_device_is_pci(device))
+ getparam->value = 3;
+ else
if (drm_pci_device_is_agp(dev))
getparam->value = 0;
else
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 488686d..f8d43cf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1255,7 +1255,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
/* fallthrough, tiled memory */
case TTM_PL_VRAM:
mem->bus.offset = mem->start << PAGE_SHIFT;
- mem->bus.base = pci_resource_start(dev->pdev, 1);
+ mem->bus.base = nv_device_resource_start(nouveau_dev(dev), 1);
mem->bus.is_iomem = true;
if (nv_device(drm->device)->card_type >= NV_50) {
struct nouveau_bar *bar = nouveau_bar(drm->device);
@@ -1293,7 +1293,7 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct nouveau_device *device = nv_device(drm->device);
- u32 mappable = pci_resource_len(device->pdev, 1) >> PAGE_SHIFT;
+ u32 mappable = nv_device_resource_len(device, 1) >> PAGE_SHIFT;
int ret;
/* as long as the bo isn't in vram, and isn't tiled, we've got
@@ -1331,6 +1331,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
{
struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct nouveau_drm *drm;
+ struct nouveau_device *device;
struct drm_device *dev;
unsigned i;
int r;
@@ -1348,6 +1349,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
}
drm = nouveau_bdev(ttm->bdev);
+ device = nv_device(drm->device);
dev = drm->dev;
#if __OS_HAS_AGP
@@ -1368,13 +1370,12 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
}
for (i = 0; i < ttm->num_pages; i++) {
- ttm_dma->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i],
- 0, PAGE_SIZE,
- PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(dev->pdev, ttm_dma->dma_address[i])) {
+ ttm_dma->dma_address[i] = nv_device_map_page(device,
+ ttm->pages[i]);
+ if (ttm_dma->dma_address[i] == 0) {
while (--i) {
- pci_unmap_page(dev->pdev, ttm_dma->dma_address[i],
- PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+ nv_device_unmap_page(device,
+ ttm_dma->dma_address[i]);
ttm_dma->dma_address[i] = 0;
}
ttm_pool_unpopulate(ttm);
@@ -1389,6 +1390,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
{
struct ttm_dma_tt *ttm_dma = (void *)ttm;
struct nouveau_drm *drm;
+ struct nouveau_device *device;
struct drm_device *dev;
unsigned i;
bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
@@ -1397,6 +1399,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
return;
drm = nouveau_bdev(ttm->bdev);
+ device = nv_device(drm->device);
dev = drm->dev;
#if __OS_HAS_AGP
@@ -1415,8 +1418,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
for (i = 0; i < ttm->num_pages; i++) {
if (ttm_dma->dma_address[i]) {
- pci_unmap_page(dev->pdev, ttm_dma->dma_address[i],
- PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+ nv_device_unmap_page(device, ttm_dma->dma_address[i]);
}
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index b4262ad..bc39241 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -339,6 +339,7 @@ int
nouveau_display_create(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nouveau_dev(dev);
struct nouveau_display *disp;
int ret, gen;
@@ -379,7 +380,7 @@ nouveau_display_create(struct drm_device *dev)
}
dev->mode_config.funcs = &nouveau_mode_config_funcs;
- dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1);
+ dev->mode_config.fb_base = nv_device_resource_start(device, 1);
dev->mode_config.min_width = 0;
dev->mode_config.min_height = 0;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 23299ca..4cba4d8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -81,7 +81,7 @@ module_param_named(runpm, nouveau_runtime_pm, int, 0400);
static struct drm_driver driver;
static u64
-nouveau_name(struct pci_dev *pdev)
+nouveau_pci_name(struct pci_dev *pdev)
{
u64 name = (u64)pci_domain_nr(pdev->bus) << 32;
name |= pdev->bus->number << 16;
@@ -89,15 +89,30 @@ nouveau_name(struct pci_dev *pdev)
return name | PCI_FUNC(pdev->devfn);
}
+static u64
+nouveau_platform_name(struct platform_device *pdev)
+{
+ return pdev->id;
+}
+
+static u64
+nouveau_name(struct drm_device *dev)
+{
+ if (dev->pdev)
+ return nouveau_pci_name(dev->pdev);
+ else
+ return nouveau_platform_name(dev->platformdev);
+}
+
static int
-nouveau_cli_create(struct pci_dev *pdev, const char *name,
+nouveau_cli_create(u64 name, const char *sname,
int size, void **pcli)
{
struct nouveau_cli *cli;
int ret;
*pcli = NULL;
- ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config,
+ ret = nouveau_client_create_(sname, name, nouveau_config,
nouveau_debug, size, pcli);
cli = *pcli;
if (ret) {
@@ -281,8 +296,9 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
remove_conflicting_framebuffers(aper, "nouveaufb", boot);
kfree(aper);
- ret = nouveau_device_create(pdev, nouveau_name(pdev), pci_name(pdev),
- nouveau_config, nouveau_debug, &device);
+ ret = nouveau_device_create(pdev, nouveau_pci_name(pdev),
+ pci_name(pdev), nouveau_config,
+ nouveau_debug, &device);
if (ret)
return ret;
@@ -330,7 +346,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
struct nouveau_drm *drm;
int ret;
- ret = nouveau_cli_create(pdev, "DRM", sizeof(*drm), (void**)&drm);
+ ret = nouveau_cli_create(nouveau_name(dev), "DRM", sizeof(*drm),
+ (void **)&drm);
if (ret)
return ret;
@@ -340,12 +357,13 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
INIT_LIST_HEAD(&drm->clients);
spin_lock_init(&drm->tile.lock);
- nouveau_get_hdmi_dev(dev);
+ if (pdev)
+ nouveau_get_hdmi_dev(dev);
/* make sure AGP controller is in a consistent state before we
* (possibly) execute vbios init tables (see nouveau_agp.h)
*/
- if (drm_pci_device_is_agp(dev) && dev->agp) {
+ if (pdev && drm_pci_device_is_agp(dev) && dev->agp) {
/* dummy device object, doesn't init anything, but allows
* agp code access to registers
*/
@@ -384,8 +402,10 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
if (nv_device(drm->device)->chipset == 0xc1)
nv_mask(device, 0x00088080, 0x00000800, 0x00000000);
- nouveau_vga_init(drm);
- nouveau_agp_init(drm);
+ if (pdev) {
+ nouveau_vga_init(drm);
+ nouveau_agp_init(drm);
+ }
if (device->card_type >= NV_50) {
ret = nouveau_vm_new(nv_device(drm->device), 0, (1ULL << 40),
@@ -398,9 +418,11 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
if (ret)
goto fail_ttm;
- ret = nouveau_bios_init(dev);
- if (ret)
- goto fail_bios;
+ if (pdev) {
+ ret = nouveau_bios_init(dev);
+ if (ret)
+ goto fail_bios;
+ }
ret = nouveau_display_create(dev);
if (ret)
@@ -662,7 +684,6 @@ static int nouveau_pmops_thaw(struct device *dev)
static int
nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
{
- struct pci_dev *pdev = dev->pdev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_cli *cli;
char name[32], tmpname[TASK_COMM_LEN];
@@ -676,7 +697,9 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
get_task_comm(tmpname, current);
snprintf(name, sizeof(name), "%s[%d]", tmpname, pid_nr(fpriv->pid));
- ret = nouveau_cli_create(pdev, name, sizeof(*cli), (void **)&cli);
+ ret = nouveau_cli_create(nouveau_name(dev), name, sizeof(*cli),
+ (void **)&cli);
+
if (ret)
goto out_suspend;
diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
index 89201a1..75dda2b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
@@ -30,7 +30,7 @@
static inline struct drm_device *
drm_device(struct device *d)
{
- return pci_get_drvdata(to_pci_dev(d));
+ return dev_get_drvdata(d);
}
#define snappendf(p,r,f,a...) do { \
@@ -132,9 +132,10 @@ nouveau_sysfs_fini(struct drm_device *dev)
{
struct nouveau_sysfs *sysfs = nouveau_sysfs(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
if (sysfs->ctrl) {
- device_remove_file(&dev->pdev->dev, &dev_attr_pstate);
+ device_remove_file(nv_device_base(device), &dev_attr_pstate);
nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL);
}
@@ -146,6 +147,7 @@ int
nouveau_sysfs_init(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nouveau_device *device = nv_device(drm->device);
struct nouveau_sysfs *sysfs;
int ret;
@@ -156,7 +158,7 @@ nouveau_sysfs_init(struct drm_device *dev)
ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL,
NV_CONTROL_CLASS, NULL, 0, &sysfs->ctrl);
if (ret == 0)
- device_create_file(&dev->pdev->dev, &dev_attr_pstate);
+ device_create_file(nv_device_base(device), &dev_attr_pstate);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index d45d50d..9574f87 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -354,21 +354,26 @@ int
nouveau_ttm_init(struct nouveau_drm *drm)
{
struct drm_device *dev = drm->dev;
+ struct nouveau_device *device = nv_device(drm->device);
u32 bits;
int ret;
bits = nouveau_vmmgr(drm->device)->dma_bits;
- if ( drm->agp.stat == ENABLED ||
- !pci_dma_supported(dev->pdev, DMA_BIT_MASK(bits)))
- bits = 32;
-
- ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(bits));
- if (ret)
- return ret;
-
- ret = pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(bits));
- if (ret)
- pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32));
+ if (nv_device_is_pci(device)) {
+ if (drm->agp.stat == ENABLED ||
+ !pci_dma_supported(dev->pdev, DMA_BIT_MASK(bits)))
+ bits = 32;
+
+ ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(bits));
+ if (ret)
+ return ret;
+
+ ret = pci_set_consistent_dma_mask(dev->pdev,
+ DMA_BIT_MASK(bits));
+ if (ret)
+ pci_set_consistent_dma_mask(dev->pdev,
+ DMA_BIT_MASK(32));
+ }
ret = nouveau_ttm_global_init(drm);
if (ret)
@@ -394,8 +399,8 @@ nouveau_ttm_init(struct nouveau_drm *drm)
return ret;
}
- drm->ttm.mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 1),
- pci_resource_len(dev->pdev, 1));
+ drm->ttm.mtrr = arch_phys_wc_add(nv_device_resource_start(device, 1),
+ nv_device_resource_len(device, 1));
/* GART init */
if (drm->agp.stat != ENABLED) {
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* [RFC 05/16] drm/nouveau/bar: support platform devices
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
2014-02-01 3:16 ` [RFC 01/16] drm/nouveau: handle -EACCES runtime PM return code Alexandre Courbot
2014-02-01 3:16 ` [RFC 02/16] drm/nouveau: basic support for platform devices Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-01 3:16 ` [RFC 06/16] drm/nouveau/bar: only ioremap BAR3 if it exists Alexandre Courbot
` (9 subsequent siblings)
12 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: Terje Bergstrom, Ken Adams, Thierry Reding, Stephen Warren,
Eric Brower, linux-tegra, linux-kernel, gnurou, Alexandre Courbot
Remove PCI-dependent code so the BAR core can also handle platform
devices.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/core/subdev/bar/base.c | 4 ++--
drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c | 4 ++--
drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c | 15 +++++++--------
3 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
index 7098ddd..bdf5941 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
@@ -118,8 +118,8 @@ nouveau_bar_create_(struct nouveau_object *parent,
if (ret)
return ret;
- bar->iomem = ioremap(pci_resource_start(device->pdev, 3),
- pci_resource_len(device->pdev, 3));
+ bar->iomem = ioremap(nv_device_resource_start(device, 3),
+ nv_device_resource_len(device, 3));
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
index 090d594..baa2b62 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
@@ -139,7 +139,7 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
/* BAR3 */
start = 0x0100000000ULL;
- limit = start + pci_resource_len(device->pdev, 3);
+ limit = start + nv_device_resource_len(device, 3);
ret = nouveau_vm_new(device, start, limit, start, &vm);
if (ret)
@@ -173,7 +173,7 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
/* BAR1 */
start = 0x0000000000ULL;
- limit = start + pci_resource_len(device->pdev, 1);
+ limit = start + nv_device_resource_len(device, 1);
ret = nouveau_vm_new(device, start, limit--, start, &vm);
if (ret)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
index bac5e75..3f30db6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
@@ -84,7 +84,6 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_object **pobject)
{
struct nouveau_device *device = nv_device(parent);
- struct pci_dev *pdev = device->pdev;
struct nvc0_bar_priv *priv;
struct nouveau_gpuobj *mem;
struct nouveau_vm *vm;
@@ -107,14 +106,14 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- ret = nouveau_vm_new(device, 0, pci_resource_len(pdev, 3), 0, &vm);
+ ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 3), 0, &vm);
if (ret)
return ret;
atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
ret = nouveau_gpuobj_new(nv_object(priv), NULL,
- (pci_resource_len(pdev, 3) >> 12) * 8,
+ (nv_device_resource_len(device, 3) >> 12) * 8,
0x1000, NVOBJ_FLAG_ZERO_ALLOC,
&vm->pgt[0].obj[0]);
vm->pgt[0].refcount[0] = 1;
@@ -128,8 +127,8 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[0].pgd->addr));
nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[0].pgd->addr));
- nv_wo32(mem, 0x0208, lower_32_bits(pci_resource_len(pdev, 3) - 1));
- nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 3) - 1));
+ nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 3) - 1));
+ nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 3) - 1));
/* BAR1 */
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
@@ -143,7 +142,7 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- ret = nouveau_vm_new(device, 0, pci_resource_len(pdev, 1), 0, &vm);
+ ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 1), 0, &vm);
if (ret)
return ret;
@@ -156,8 +155,8 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[1].pgd->addr));
nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[1].pgd->addr));
- nv_wo32(mem, 0x0208, lower_32_bits(pci_resource_len(pdev, 1) - 1));
- nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 1) - 1));
+ nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 1) - 1));
+ nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 1) - 1));
priv->base.alloc = nouveau_bar_alloc;
priv->base.kmap = nvc0_bar_kmap;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* [RFC 06/16] drm/nouveau/bar: only ioremap BAR3 if it exists
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
` (2 preceding siblings ...)
2014-02-01 3:16 ` [RFC 05/16] drm/nouveau/bar: support " Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-01 3:16 ` [RFC 07/16] drm/nouveau/bar/nvc0: support chips without BAR3 Alexandre Courbot
` (8 subsequent siblings)
12 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: gnurou, Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
Terje Bergstrom, Ken Adams
Some chips that use system memory exclusively (e.g. GK20A) do not
expose 2 BAR regions. For them only BAR1 exists, and it should be used
for USERD mapping. Do not map BAR3 if its resource does not exist.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/core/subdev/bar/base.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
index bdf5941..d713eeb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
@@ -110,6 +110,7 @@ nouveau_bar_create_(struct nouveau_object *parent,
{
struct nouveau_device *device = nv_device(parent);
struct nouveau_bar *bar;
+ bool has_bar3 = nv_device_resource_len(device, 3) != 0;
int ret;
ret = nouveau_subdev_create_(parent, engine, oclass, 0, "BARCTL",
@@ -118,8 +119,10 @@ nouveau_bar_create_(struct nouveau_object *parent,
if (ret)
return ret;
- bar->iomem = ioremap(nv_device_resource_start(device, 3),
- nv_device_resource_len(device, 3));
+ if (has_bar3)
+ bar->iomem = ioremap(nv_device_resource_start(device, 3),
+ nv_device_resource_len(device, 3));
+
return 0;
}
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* [RFC 07/16] drm/nouveau/bar/nvc0: support chips without BAR3
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
` (3 preceding siblings ...)
2014-02-01 3:16 ` [RFC 06/16] drm/nouveau/bar: only ioremap BAR3 if it exists Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-04 3:54 ` Ben Skeggs
2014-02-01 3:16 ` [RFC 08/16] drm/nouveau/mc: support platform devices Alexandre Courbot
` (7 subsequent siblings)
12 siblings, 1 reply; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: gnurou, Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
Terje Bergstrom, Ken Adams
Adapt the NVC0 BAR driver to make it able to support chips that do not
expose a BAR3. When this happens, BAR1 is then used for USERD mapping
and the BAR alloc() functions is disabled, making GPU objects unable
to rely on BAR for data access and falling back to PRAMIN.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c | 115 +++++++++++++------------
1 file changed, 61 insertions(+), 54 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
index 3f30db6..c2bb0e5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
@@ -79,87 +79,88 @@ nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
}
static int
-nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+nvc0_bar_init_vm(struct nvc0_bar_priv *priv, int nr, int bar)
{
- struct nouveau_device *device = nv_device(parent);
- struct nvc0_bar_priv *priv;
+ struct nouveau_device *device = nv_device(&priv->base);
struct nouveau_gpuobj *mem;
struct nouveau_vm *vm;
+ resource_size_t bar_len;
int ret;
- ret = nouveau_bar_create(parent, engine, oclass, &priv);
- *pobject = nv_object(priv);
- if (ret)
- return ret;
-
- /* BAR3 */
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
- &priv->bar[0].mem);
- mem = priv->bar[0].mem;
+ &priv->bar[nr].mem);
+ mem = priv->bar[nr].mem;
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
- &priv->bar[0].pgd);
+ &priv->bar[nr].pgd);
if (ret)
return ret;
- ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 3), 0, &vm);
+ bar_len = nv_device_resource_len(device, bar);
+
+ ret = nouveau_vm_new(device, 0, bar_len, 0, &vm);
if (ret)
return ret;
atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
- ret = nouveau_gpuobj_new(nv_object(priv), NULL,
- (nv_device_resource_len(device, 3) >> 12) * 8,
- 0x1000, NVOBJ_FLAG_ZERO_ALLOC,
- &vm->pgt[0].obj[0]);
- vm->pgt[0].refcount[0] = 1;
- if (ret)
- return ret;
+ /*
+ * Bootstrap page table lookup.
+ */
+ if (bar == 3) {
+ ret = nouveau_gpuobj_new(nv_object(priv), NULL,
+ (bar_len >> 12) * 8, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC,
+ &vm->pgt[0].obj[0]);
+ vm->pgt[0].refcount[0] = 1;
+ if (ret)
+ return ret;
+ }
- ret = nouveau_vm_ref(vm, &priv->bar[0].vm, priv->bar[0].pgd);
+ ret = nouveau_vm_ref(vm, &priv->bar[nr].vm, priv->bar[nr].pgd);
nouveau_vm_ref(NULL, &vm, NULL);
if (ret)
return ret;
- nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[0].pgd->addr));
- nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[0].pgd->addr));
- nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 3) - 1));
- nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 3) - 1));
+ nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[nr].pgd->addr));
+ nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[nr].pgd->addr));
+ nv_wo32(mem, 0x0208, lower_32_bits(bar_len - 1));
+ nv_wo32(mem, 0x020c, upper_32_bits(bar_len - 1));
- /* BAR1 */
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
- &priv->bar[1].mem);
- mem = priv->bar[1].mem;
- if (ret)
- return ret;
+ return 0;
+}
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
- &priv->bar[1].pgd);
- if (ret)
- return ret;
+static int
+nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_device *device = nv_device(parent);
+ struct nvc0_bar_priv *priv;
+ bool has_bar3 = nv_device_resource_len(device, 3) != 0;
+ int ret;
- ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 1), 0, &vm);
+ ret = nouveau_bar_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
if (ret)
return ret;
- atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+ /* BAR3 */
+ if (has_bar3) {
+ ret = nvc0_bar_init_vm(priv, 0, 3);
+ if (ret)
+ return ret;
+ priv->base.alloc = nouveau_bar_alloc;
+ priv->base.kmap = nvc0_bar_kmap;
+ }
- ret = nouveau_vm_ref(vm, &priv->bar[1].vm, priv->bar[1].pgd);
- nouveau_vm_ref(NULL, &vm, NULL);
+ /* BAR1 */
+ ret = nvc0_bar_init_vm(priv, 1, 1);
if (ret)
return ret;
- nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[1].pgd->addr));
- nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[1].pgd->addr));
- nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 1) - 1));
- nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 1) - 1));
-
- priv->base.alloc = nouveau_bar_alloc;
- priv->base.kmap = nvc0_bar_kmap;
priv->base.umap = nvc0_bar_umap;
priv->base.unmap = nvc0_bar_unmap;
priv->base.flush = nv84_bar_flush;
@@ -176,12 +177,16 @@ nvc0_bar_dtor(struct nouveau_object *object)
nouveau_gpuobj_ref(NULL, &priv->bar[1].pgd);
nouveau_gpuobj_ref(NULL, &priv->bar[1].mem);
- if (priv->bar[0].vm) {
- nouveau_gpuobj_ref(NULL, &priv->bar[0].vm->pgt[0].obj[0]);
- nouveau_vm_ref(NULL, &priv->bar[0].vm, priv->bar[0].pgd);
+ if (priv->bar[0].mem) {
+ if (priv->bar[0].vm) {
+ nouveau_gpuobj_ref(NULL,
+ &priv->bar[0].vm->pgt[0].obj[0]);
+ nouveau_vm_ref(NULL, &priv->bar[0].vm,
+ priv->bar[0].pgd);
+ }
+ nouveau_gpuobj_ref(NULL, &priv->bar[0].pgd);
+ nouveau_gpuobj_ref(NULL, &priv->bar[0].mem);
}
- nouveau_gpuobj_ref(NULL, &priv->bar[0].pgd);
- nouveau_gpuobj_ref(NULL, &priv->bar[0].mem);
nouveau_bar_destroy(&priv->base);
}
@@ -201,7 +206,9 @@ nvc0_bar_init(struct nouveau_object *object)
nv_mask(priv, 0x100c80, 0x00000001, 0x00000000);
nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12);
- nv_wr32(priv, 0x001714, 0xc0000000 | priv->bar[0].mem->addr >> 12);
+ if (priv->bar[0].mem)
+ nv_wr32(priv, 0x001714,
+ 0xc0000000 | priv->bar[0].mem->addr >> 12);
return 0;
}
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [RFC 07/16] drm/nouveau/bar/nvc0: support chips without BAR3
2014-02-01 3:16 ` [RFC 07/16] drm/nouveau/bar/nvc0: support chips without BAR3 Alexandre Courbot
@ 2014-02-04 3:54 ` Ben Skeggs
[not found] ` <CACAvsv7BDDEOJ-C88PRWy7z21c1LMorb5r=f6atDJAWtTN=Luw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 41+ messages in thread
From: Ben Skeggs @ 2014-02-04 3:54 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Ben Skeggs, nouveau@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, Alexandre Courbot, Eric Brower,
Stephen Warren, linux-kernel@vger.kernel.org,
linux-tegra@vger.kernel.org, Terje Bergstrom, Ken Adams
On Sat, Feb 1, 2014 at 1:16 PM, Alexandre Courbot <acourbot@nvidia.com> wrote:
> Adapt the NVC0 BAR driver to make it able to support chips that do not
> expose a BAR3. When this happens, BAR1 is then used for USERD mapping
> and the BAR alloc() functions is disabled, making GPU objects unable
> to rely on BAR for data access and falling back to PRAMIN.
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> ---
> drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c | 115 +++++++++++++------------
> 1 file changed, 61 insertions(+), 54 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
> index 3f30db6..c2bb0e5 100644
> --- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
> +++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
> @@ -79,87 +79,88 @@ nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
> }
>
> static int
> -nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
> - struct nouveau_oclass *oclass, void *data, u32 size,
> - struct nouveau_object **pobject)
> +nvc0_bar_init_vm(struct nvc0_bar_priv *priv, int nr, int bar)
> {
> - struct nouveau_device *device = nv_device(parent);
> - struct nvc0_bar_priv *priv;
> + struct nouveau_device *device = nv_device(&priv->base);
> struct nouveau_gpuobj *mem;
> struct nouveau_vm *vm;
> + resource_size_t bar_len;
> int ret;
>
> - ret = nouveau_bar_create(parent, engine, oclass, &priv);
> - *pobject = nv_object(priv);
> - if (ret)
> - return ret;
> -
> - /* BAR3 */
> ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
> - &priv->bar[0].mem);
> - mem = priv->bar[0].mem;
> + &priv->bar[nr].mem);
> + mem = priv->bar[nr].mem;
> if (ret)
> return ret;
>
> ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
> - &priv->bar[0].pgd);
> + &priv->bar[nr].pgd);
> if (ret)
> return ret;
>
> - ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 3), 0, &vm);
> + bar_len = nv_device_resource_len(device, bar);
> +
> + ret = nouveau_vm_new(device, 0, bar_len, 0, &vm);
> if (ret)
> return ret;
>
> atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
>
> - ret = nouveau_gpuobj_new(nv_object(priv), NULL,
> - (nv_device_resource_len(device, 3) >> 12) * 8,
> - 0x1000, NVOBJ_FLAG_ZERO_ALLOC,
> - &vm->pgt[0].obj[0]);
> - vm->pgt[0].refcount[0] = 1;
> - if (ret)
> - return ret;
> + /*
> + * Bootstrap page table lookup.
> + */
> + if (bar == 3) {
> + ret = nouveau_gpuobj_new(nv_object(priv), NULL,
> + (bar_len >> 12) * 8, 0x1000,
> + NVOBJ_FLAG_ZERO_ALLOC,
> + &vm->pgt[0].obj[0]);
> + vm->pgt[0].refcount[0] = 1;
> + if (ret)
> + return ret;
> + }
>
> - ret = nouveau_vm_ref(vm, &priv->bar[0].vm, priv->bar[0].pgd);
> + ret = nouveau_vm_ref(vm, &priv->bar[nr].vm, priv->bar[nr].pgd);
> nouveau_vm_ref(NULL, &vm, NULL);
> if (ret)
> return ret;
>
> - nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[0].pgd->addr));
> - nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[0].pgd->addr));
> - nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 3) - 1));
> - nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 3) - 1));
> + nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[nr].pgd->addr));
> + nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[nr].pgd->addr));
> + nv_wo32(mem, 0x0208, lower_32_bits(bar_len - 1));
> + nv_wo32(mem, 0x020c, upper_32_bits(bar_len - 1));
>
> - /* BAR1 */
> - ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
> - &priv->bar[1].mem);
> - mem = priv->bar[1].mem;
> - if (ret)
> - return ret;
> + return 0;
> +}
>
> - ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
> - &priv->bar[1].pgd);
> - if (ret)
> - return ret;
> +static int
> +nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
> + struct nouveau_oclass *oclass, void *data, u32 size,
> + struct nouveau_object **pobject)
> +{
> + struct nouveau_device *device = nv_device(parent);
> + struct nvc0_bar_priv *priv;
> + bool has_bar3 = nv_device_resource_len(device, 3) != 0;
> + int ret;
>
> - ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 1), 0, &vm);
> + ret = nouveau_bar_create(parent, engine, oclass, &priv);
> + *pobject = nv_object(priv);
> if (ret)
> return ret;
>
> - atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
> + /* BAR3 */
> + if (has_bar3) {
> + ret = nvc0_bar_init_vm(priv, 0, 3);
> + if (ret)
> + return ret;
> + priv->base.alloc = nouveau_bar_alloc;
> + priv->base.kmap = nvc0_bar_kmap;
> + }
>
> - ret = nouveau_vm_ref(vm, &priv->bar[1].vm, priv->bar[1].pgd);
> - nouveau_vm_ref(NULL, &vm, NULL);
> + /* BAR1 */
> + ret = nvc0_bar_init_vm(priv, 1, 1);
> if (ret)
> return ret;
>
> - nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[1].pgd->addr));
> - nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[1].pgd->addr));
> - nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 1) - 1));
> - nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 1) - 1));
> -
> - priv->base.alloc = nouveau_bar_alloc;
> - priv->base.kmap = nvc0_bar_kmap;
> priv->base.umap = nvc0_bar_umap;
> priv->base.unmap = nvc0_bar_unmap;
> priv->base.flush = nv84_bar_flush;
> @@ -176,12 +177,16 @@ nvc0_bar_dtor(struct nouveau_object *object)
> nouveau_gpuobj_ref(NULL, &priv->bar[1].pgd);
> nouveau_gpuobj_ref(NULL, &priv->bar[1].mem);
>
> - if (priv->bar[0].vm) {
> - nouveau_gpuobj_ref(NULL, &priv->bar[0].vm->pgt[0].obj[0]);
> - nouveau_vm_ref(NULL, &priv->bar[0].vm, priv->bar[0].pgd);
> + if (priv->bar[0].mem) {
> + if (priv->bar[0].vm) {
> + nouveau_gpuobj_ref(NULL,
> + &priv->bar[0].vm->pgt[0].obj[0]);
> + nouveau_vm_ref(NULL, &priv->bar[0].vm,
> + priv->bar[0].pgd);
> + }
> + nouveau_gpuobj_ref(NULL, &priv->bar[0].pgd);
> + nouveau_gpuobj_ref(NULL, &priv->bar[0].mem);
> }
> - nouveau_gpuobj_ref(NULL, &priv->bar[0].pgd);
> - nouveau_gpuobj_ref(NULL, &priv->bar[0].mem);
Did the conditional on priv->bar[0].mem fix anything here? The ref()
functions called are designed to handle the NULL pointers already.
>
> nouveau_bar_destroy(&priv->base);
> }
> @@ -201,7 +206,9 @@ nvc0_bar_init(struct nouveau_object *object)
> nv_mask(priv, 0x100c80, 0x00000001, 0x00000000);
>
> nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12);
> - nv_wr32(priv, 0x001714, 0xc0000000 | priv->bar[0].mem->addr >> 12);
> + if (priv->bar[0].mem)
> + nv_wr32(priv, 0x001714,
> + 0xc0000000 | priv->bar[0].mem->addr >> 12);
> return 0;
> }
>
> --
> 1.8.5.3
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 41+ messages in thread
* [RFC 08/16] drm/nouveau/mc: support platform devices
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
` (4 preceding siblings ...)
2014-02-01 3:16 ` [RFC 07/16] drm/nouveau/bar/nvc0: support chips without BAR3 Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-01 3:16 ` [RFC 09/16] drm/nouveau/fb: " Alexandre Courbot
` (6 subsequent siblings)
12 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: gnurou, Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
Terje Bergstrom, Ken Adams
Use abstracted resource query functions, and obtain the IRQ from the
correct bus.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/core/include/subdev/mc.h | 1 +
drivers/gpu/drm/nouveau/core/subdev/mc/base.c | 43 +++++++++++++++---------
2 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
index adc88b7..7c551b5 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
@@ -12,6 +12,7 @@ struct nouveau_mc_intr {
struct nouveau_mc {
struct nouveau_subdev base;
bool use_msi;
+ unsigned int irq;
};
static inline struct nouveau_mc *
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
index b4b9943..081fd96 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
@@ -93,8 +93,8 @@ _nouveau_mc_dtor(struct nouveau_object *object)
{
struct nouveau_device *device = nv_device(object);
struct nouveau_mc *pmc = (void *)object;
- free_irq(device->pdev->irq, pmc);
- if (pmc->use_msi)
+ free_irq(pmc->irq, pmc);
+ if (nv_device_is_pci(device) && pmc->use_msi)
pci_disable_msi(device->pdev);
nouveau_subdev_destroy(&pmc->base);
}
@@ -114,22 +114,25 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- switch (device->pdev->device & 0x0ff0) {
- case 0x00f0:
- case 0x02e0:
- /* BR02? NFI how these would be handled yet exactly */
- break;
- default:
- switch (device->chipset) {
- case 0xaa: break; /* reported broken, nv also disable it */
- default:
- pmc->use_msi = true;
+ if (nv_device_is_pci(device))
+ switch (device->pdev->device & 0x0ff0) {
+ case 0x00f0:
+ case 0x02e0:
+ /* BR02? NFI how these would be handled yet exactly */
break;
+ default:
+ switch (device->chipset) {
+ case 0xaa:
+ /* reported broken, nv also disable it */
+ break;
+ default:
+ pmc->use_msi = true;
+ break;
}
}
pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI", pmc->use_msi);
- if (pmc->use_msi && oclass->msi_rearm) {
+ if (nv_device_is_pci(device) && pmc->use_msi && oclass->msi_rearm) {
pmc->use_msi = pci_enable_msi(device->pdev) == 0;
if (pmc->use_msi) {
nv_info(pmc, "MSI interrupts enabled\n");
@@ -139,8 +142,18 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
pmc->use_msi = false;
}
- ret = request_irq(device->pdev->irq, nouveau_mc_intr,
- IRQF_SHARED, "nouveau", pmc);
+ if (nv_device_is_pci(device)) {
+ pmc->irq = device->pdev->irq;
+ } else {
+ int irq = platform_get_irq_byname(device->platformdev, "stall");
+ if (irq < 0)
+ return irq;
+ pmc->irq = irq;
+ }
+
+ ret = request_irq(pmc->irq, nouveau_mc_intr, IRQF_SHARED, "nouveau",
+ pmc);
+
if (ret < 0)
return ret;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* [RFC 09/16] drm/nouveau/fb: support platform devices
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
` (5 preceding siblings ...)
2014-02-01 3:16 ` [RFC 08/16] drm/nouveau/mc: support platform devices Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-01 3:16 ` [RFC 10/16] drm/nouveau/timer: skip calibration on GK20A Alexandre Courbot
` (5 subsequent siblings)
12 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: gnurou, Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
Terje Bergstrom, Ken Adams
Use abstracted resource query functions to allow FB core to handle
both PCI and platform devices.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
index 45470e1..0670ae3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
@@ -70,8 +70,7 @@ nvc0_fb_dtor(struct nouveau_object *object)
struct nvc0_fb_priv *priv = (void *)object;
if (priv->r100c10_page) {
- pci_unmap_page(device->pdev, priv->r100c10, PAGE_SIZE,
- PCI_DMA_BIDIRECTIONAL);
+ nv_device_unmap_page(device, priv->r100c10);
__free_page(priv->r100c10_page);
}
@@ -94,10 +93,8 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (priv->r100c10_page) {
- priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page,
- 0, PAGE_SIZE,
- PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(device->pdev, priv->r100c10))
+ priv->r100c10 = nv_device_map_page(device, priv->r100c10_page);
+ if (!priv->r100c10)
return -EFAULT;
}
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* [RFC 10/16] drm/nouveau/timer: skip calibration on GK20A
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
` (6 preceding siblings ...)
2014-02-01 3:16 ` [RFC 09/16] drm/nouveau/fb: " Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-04 3:55 ` Ben Skeggs
2014-02-01 3:16 ` [RFC 13/16] drm/nouveau/ibus: add GK20A support Alexandre Courbot
` (4 subsequent siblings)
12 siblings, 1 reply; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: gnurou, Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
Terje Bergstrom, Ken Adams
GK20A's timer is directly attached to the system timer and cannot be
calibrated. Skip the calibration phase on that chip since the
corresponding registers do not exist.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
index c0bdd10..822fe0d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
@@ -185,6 +185,10 @@ nv04_timer_init(struct nouveau_object *object)
if (ret)
return ret;
+ /* gk20a does not have the calibration registers */
+ if (device->chipset == 0xea)
+ goto skip_clk_init;
+
/* aim for 31.25MHz, which gives us nanosecond timestamps */
d = 1000000 / 32;
@@ -235,20 +239,23 @@ nv04_timer_init(struct nouveau_object *object)
d >>= 1;
}
- /* restore the time before suspend */
- lo = priv->suspend_time;
- hi = (priv->suspend_time >> 32);
-
nv_debug(priv, "input frequency : %dHz\n", f);
nv_debug(priv, "input multiplier: %d\n", m);
nv_debug(priv, "numerator : 0x%08x\n", n);
nv_debug(priv, "denominator : 0x%08x\n", d);
nv_debug(priv, "timer frequency : %dHz\n", (f * m) * d / n);
- nv_debug(priv, "time low : 0x%08x\n", lo);
- nv_debug(priv, "time high : 0x%08x\n", hi);
nv_wr32(priv, NV04_PTIMER_NUMERATOR, n);
nv_wr32(priv, NV04_PTIMER_DENOMINATOR, d);
+
+skip_clk_init:
+ /* restore the time before suspend */
+ lo = priv->suspend_time;
+ hi = (priv->suspend_time >> 32);
+
+ nv_debug(priv, "time low : 0x%08x\n", lo);
+ nv_debug(priv, "time high : 0x%08x\n", hi);
+
nv_wr32(priv, NV04_PTIMER_INTR_0, 0xffffffff);
nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000);
nv_wr32(priv, NV04_PTIMER_TIME_1, hi);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [RFC 10/16] drm/nouveau/timer: skip calibration on GK20A
2014-02-01 3:16 ` [RFC 10/16] drm/nouveau/timer: skip calibration on GK20A Alexandre Courbot
@ 2014-02-04 3:55 ` Ben Skeggs
2014-02-04 8:39 ` Alexandre Courbot
0 siblings, 1 reply; 41+ messages in thread
From: Ben Skeggs @ 2014-02-04 3:55 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Ben Skeggs, nouveau@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, Alexandre Courbot, Eric Brower,
Stephen Warren, linux-kernel@vger.kernel.org,
linux-tegra@vger.kernel.org, Terje Bergstrom, Ken Adams
On Sat, Feb 1, 2014 at 1:16 PM, Alexandre Courbot <acourbot@nvidia.com> wrote:
> GK20A's timer is directly attached to the system timer and cannot be
> calibrated. Skip the calibration phase on that chip since the
> corresponding registers do not exist.
Just a curiosity: What timer resolution does the HW initialise at?
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> ---
> drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c | 19 +++++++++++++------
> 1 file changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
> index c0bdd10..822fe0d 100644
> --- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
> +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
> @@ -185,6 +185,10 @@ nv04_timer_init(struct nouveau_object *object)
> if (ret)
> return ret;
>
> + /* gk20a does not have the calibration registers */
> + if (device->chipset == 0xea)
> + goto skip_clk_init;
> +
> /* aim for 31.25MHz, which gives us nanosecond timestamps */
> d = 1000000 / 32;
>
> @@ -235,20 +239,23 @@ nv04_timer_init(struct nouveau_object *object)
> d >>= 1;
> }
>
> - /* restore the time before suspend */
> - lo = priv->suspend_time;
> - hi = (priv->suspend_time >> 32);
> -
> nv_debug(priv, "input frequency : %dHz\n", f);
> nv_debug(priv, "input multiplier: %d\n", m);
> nv_debug(priv, "numerator : 0x%08x\n", n);
> nv_debug(priv, "denominator : 0x%08x\n", d);
> nv_debug(priv, "timer frequency : %dHz\n", (f * m) * d / n);
> - nv_debug(priv, "time low : 0x%08x\n", lo);
> - nv_debug(priv, "time high : 0x%08x\n", hi);
>
> nv_wr32(priv, NV04_PTIMER_NUMERATOR, n);
> nv_wr32(priv, NV04_PTIMER_DENOMINATOR, d);
> +
> +skip_clk_init:
> + /* restore the time before suspend */
> + lo = priv->suspend_time;
> + hi = (priv->suspend_time >> 32);
> +
> + nv_debug(priv, "time low : 0x%08x\n", lo);
> + nv_debug(priv, "time high : 0x%08x\n", hi);
> +
> nv_wr32(priv, NV04_PTIMER_INTR_0, 0xffffffff);
> nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000);
> nv_wr32(priv, NV04_PTIMER_TIME_1, hi);
> --
> 1.8.5.3
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [RFC 10/16] drm/nouveau/timer: skip calibration on GK20A
2014-02-04 3:55 ` Ben Skeggs
@ 2014-02-04 8:39 ` Alexandre Courbot
2014-02-05 20:27 ` Stephen Warren
0 siblings, 1 reply; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-04 8:39 UTC (permalink / raw)
To: Ben Skeggs
Cc: Alexandre Courbot, Eric Brower, Stephen Warren,
nouveau@lists.freedesktop.org, linux-kernel@vger.kernel.org,
dri-devel@lists.freedesktop.org, Ben Skeggs,
linux-tegra@vger.kernel.org, Terje Bergstrom, Ken Adams
On 02/04/2014 12:55 PM, Ben Skeggs wrote:
> On Sat, Feb 1, 2014 at 1:16 PM, Alexandre Courbot <acourbot@nvidia.com> wrote:
>> GK20A's timer is directly attached to the system timer and cannot be
>> calibrated. Skip the calibration phase on that chip since the
>> corresponding registers do not exist.
> Just a curiosity: What timer resolution does the HW initialise at?
On T124 the timer input is the oscillator clock, which depending on the
device can run between 12 and 48Mhz (IIUC).
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [RFC 10/16] drm/nouveau/timer: skip calibration on GK20A
2014-02-04 8:39 ` Alexandre Courbot
@ 2014-02-05 20:27 ` Stephen Warren
0 siblings, 0 replies; 41+ messages in thread
From: Stephen Warren @ 2014-02-05 20:27 UTC (permalink / raw)
To: Alexandre Courbot, Ben Skeggs
Cc: Alexandre Courbot, Eric Brower, nouveau@lists.freedesktop.org,
linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
Ben Skeggs, linux-tegra@vger.kernel.org, Terje Bergstrom,
Ken Adams
On 02/04/2014 01:39 AM, Alexandre Courbot wrote:
> On 02/04/2014 12:55 PM, Ben Skeggs wrote:
>> On Sat, Feb 1, 2014 at 1:16 PM, Alexandre Courbot
>> <acourbot@nvidia.com> wrote:
>>> GK20A's timer is directly attached to the system timer and cannot be
>>> calibrated. Skip the calibration phase on that chip since the
>>> corresponding registers do not exist.
>> Just a curiosity: What timer resolution does the HW initialise at?
>
> On T124 the timer input is the oscillator clock, which depending on the
> device can run between 12 and 48Mhz (IIUC).
On the one Tegra124 board we support upstream, the crystal is 12MHz. I
believe this is a typical/common value; almost all the Tegra boards we
support upstream run at this rate.
^ permalink raw reply [flat|nested] 41+ messages in thread
* [RFC 13/16] drm/nouveau/ibus: add GK20A support
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
` (7 preceding siblings ...)
2014-02-01 3:16 ` [RFC 10/16] drm/nouveau/timer: skip calibration on GK20A Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-02 6:35 ` Ilia Mirkin
2014-02-01 3:16 ` [RFC 14/16] drm/nouveau/fb: " Alexandre Courbot
` (3 subsequent siblings)
12 siblings, 1 reply; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: Terje Bergstrom, Ken Adams, Thierry Reding, Stephen Warren,
Eric Brower, linux-tegra, linux-kernel, gnurou, Alexandre Courbot
Add support for initializing the priv ring of GK20A. This is done by the
BIOS on desktop GPUs, but needs to be done by hand on Tegra.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/Makefile | 1 +
drivers/gpu/drm/nouveau/core/include/subdev/ibus.h | 1 +
drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c | 108 +++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 6c4b76d..3548fcd 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -132,6 +132,7 @@ nouveau-y += core/subdev/i2c/nv94.o
nouveau-y += core/subdev/i2c/nvd0.o
nouveau-y += core/subdev/ibus/nvc0.o
nouveau-y += core/subdev/ibus/nve0.o
+nouveau-y += core/subdev/ibus/nvea.o
nouveau-y += core/subdev/instmem/base.o
nouveau-y += core/subdev/instmem/nv04.o
nouveau-y += core/subdev/instmem/nv40.o
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
index 88814f1..056a42f 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
@@ -30,5 +30,6 @@ nouveau_ibus(void *obj)
extern struct nouveau_oclass nvc0_ibus_oclass;
extern struct nouveau_oclass nve0_ibus_oclass;
+extern struct nouveau_oclass nvea_ibus_oclass;
#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c b/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c
new file mode 100644
index 0000000..0bcd281
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <subdev/ibus.h>
+
+struct nvea_ibus_priv {
+ struct nouveau_ibus base;
+};
+
+static void
+nvea_ibus_init_priv_ring(struct nvea_ibus_priv *priv)
+{
+ u32 data;
+
+ data = nv_rd32(priv, 0x137250);
+ data &= (~0x3f);
+ nv_wr32(priv, 0x137250, data);
+
+ nv_mask(priv, 0x000200, 0x20, 0);
+ udelay(20);
+ nv_mask(priv, 0x000200, 0x20, 0x20);
+
+ nv_wr32(priv, 0x12004c, 0x4);
+ nv_wr32(priv, 0x122204, 0x2);
+ nv_rd32(priv, 0x122204);
+}
+
+static void
+nvea_ibus_intr(struct nouveau_subdev *subdev)
+{
+ struct nvea_ibus_priv *priv = (void *)subdev;
+ u32 status0 = nv_rd32(priv, 0x120058);
+ s32 retry = 100;
+ u32 command;
+
+ if (status0 & 0x7) {
+ nv_debug(priv, "resetting priv ring\n");
+ nvea_ibus_init_priv_ring(priv);
+ }
+
+ /* Acknowledge interrupt */
+ command = nv_rd32(priv, 0x0012004c);
+ command |= 0x2;
+ nv_wr32(priv, 0x0012004c, command);
+
+ while (--retry >= 0) {
+ command = nv_rd32(priv, 0x12004c) & 0x3f;
+ if (command == 0)
+ break;
+ }
+
+ if (retry < 0)
+ nv_debug(priv, "timeout waiting for ringmaster ack\n");
+}
+
+static int
+nvea_ibus_init(struct nouveau_object *object)
+{
+ struct nvea_ibus_priv *priv = (void *)object;
+ int ret;
+
+ ret = _nouveau_ibus_init(object);
+ if (ret)
+ return ret;
+
+ nvea_ibus_init_priv_ring(priv);
+
+ return 0;
+}
+
+static int
+nvea_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 size,
+ struct nouveau_object **pobject)
+{
+ struct nvea_ibus_priv *priv;
+ int ret;
+
+ ret = nouveau_ibus_create(parent, engine, oclass, &priv);
+ *pobject = nv_object(priv);
+ if (ret)
+ return ret;
+
+ nv_subdev(priv)->intr = nvea_ibus_intr;
+ return 0;
+}
+
+struct nouveau_oclass
+nvea_ibus_oclass = {
+ .handle = NV_SUBDEV(IBUS, 0xea),
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvea_ibus_ctor,
+ .dtor = _nouveau_ibus_dtor,
+ .init = nvea_ibus_init,
+ .fini = _nouveau_ibus_fini,
+ },
+};
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [RFC 13/16] drm/nouveau/ibus: add GK20A support
2014-02-01 3:16 ` [RFC 13/16] drm/nouveau/ibus: add GK20A support Alexandre Courbot
@ 2014-02-02 6:35 ` Ilia Mirkin
[not found] ` <CAKb7Uvh7QTn1m0N6ynVxVup9VdA9y7fKJ66nwUDMiy6aHz+_Uw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
0 siblings, 1 reply; 41+ messages in thread
From: Ilia Mirkin @ 2014-02-02 6:35 UTC (permalink / raw)
To: Alexandre Courbot
Cc: gnurou, Terje Bergstrom, Stephen Warren,
nouveau@lists.freedesktop.org, linux-kernel@vger.kernel.org,
dri-devel@lists.freedesktop.org, Ben Skeggs, linux-tegra,
Eric Brower, Ken Adams
Some very trivial comments below:
On Fri, Jan 31, 2014 at 10:16 PM, Alexandre Courbot <acourbot@nvidia.com> wrote:
> Add support for initializing the priv ring of GK20A. This is done by the
> BIOS on desktop GPUs, but needs to be done by hand on Tegra.
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> ---
> drivers/gpu/drm/nouveau/Makefile | 1 +
> drivers/gpu/drm/nouveau/core/include/subdev/ibus.h | 1 +
> drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c | 108 +++++++++++++++++++++
> 3 files changed, 110 insertions(+)
> create mode 100644 drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c
>
> diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
> index 6c4b76d..3548fcd 100644
> --- a/drivers/gpu/drm/nouveau/Makefile
> +++ b/drivers/gpu/drm/nouveau/Makefile
> @@ -132,6 +132,7 @@ nouveau-y += core/subdev/i2c/nv94.o
> nouveau-y += core/subdev/i2c/nvd0.o
> nouveau-y += core/subdev/ibus/nvc0.o
> nouveau-y += core/subdev/ibus/nve0.o
> +nouveau-y += core/subdev/ibus/nvea.o
> nouveau-y += core/subdev/instmem/base.o
> nouveau-y += core/subdev/instmem/nv04.o
> nouveau-y += core/subdev/instmem/nv40.o
> diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
> index 88814f1..056a42f 100644
> --- a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
> +++ b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
> @@ -30,5 +30,6 @@ nouveau_ibus(void *obj)
>
> extern struct nouveau_oclass nvc0_ibus_oclass;
> extern struct nouveau_oclass nve0_ibus_oclass;
> +extern struct nouveau_oclass nvea_ibus_oclass;
>
> #endif
> diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c b/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c
> new file mode 100644
> index 0000000..0bcd281
> --- /dev/null
> +++ b/drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c
> @@ -0,0 +1,108 @@
> +/*
> + * Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + */
> +
> +#include <subdev/ibus.h>
> +
> +struct nvea_ibus_priv {
> + struct nouveau_ibus base;
> +};
> +
> +static void
> +nvea_ibus_init_priv_ring(struct nvea_ibus_priv *priv)
> +{
> + u32 data;
> +
> + data = nv_rd32(priv, 0x137250);
> + data &= (~0x3f);
> + nv_wr32(priv, 0x137250, data);
nv_mask(priv, 0x137250, 0x3f, 0) should do this, right?
> +
> + nv_mask(priv, 0x000200, 0x20, 0);
> + udelay(20);
> + nv_mask(priv, 0x000200, 0x20, 0x20);
> +
> + nv_wr32(priv, 0x12004c, 0x4);
> + nv_wr32(priv, 0x122204, 0x2);
> + nv_rd32(priv, 0x122204);
> +}
> +
> +static void
> +nvea_ibus_intr(struct nouveau_subdev *subdev)
> +{
> + struct nvea_ibus_priv *priv = (void *)subdev;
> + u32 status0 = nv_rd32(priv, 0x120058);
> + s32 retry = 100;
> + u32 command;
> +
> + if (status0 & 0x7) {
> + nv_debug(priv, "resetting priv ring\n");
> + nvea_ibus_init_priv_ring(priv);
> + }
> +
> + /* Acknowledge interrupt */
> + command = nv_rd32(priv, 0x0012004c);
> + command |= 0x2;
> + nv_wr32(priv, 0x0012004c, command);
nv_mask(priv, 0x12004c, 0x2, 0x2)
> +
> + while (--retry >= 0) {
> + command = nv_rd32(priv, 0x12004c) & 0x3f;
> + if (command == 0)
> + break;
> + }
> +
> + if (retry < 0)
> + nv_debug(priv, "timeout waiting for ringmaster ack\n");
this sounds kinda bad, no? perhaps a nv_warn?
> +}
> +
> +static int
> +nvea_ibus_init(struct nouveau_object *object)
> +{
> + struct nvea_ibus_priv *priv = (void *)object;
> + int ret;
> +
> + ret = _nouveau_ibus_init(object);
> + if (ret)
> + return ret;
> +
> + nvea_ibus_init_priv_ring(priv);
> +
> + return 0;
> +}
> +
> +static int
> +nvea_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
> + struct nouveau_oclass *oclass, void *data, u32 size,
> + struct nouveau_object **pobject)
> +{
> + struct nvea_ibus_priv *priv;
> + int ret;
> +
> + ret = nouveau_ibus_create(parent, engine, oclass, &priv);
> + *pobject = nv_object(priv);
> + if (ret)
> + return ret;
> +
> + nv_subdev(priv)->intr = nvea_ibus_intr;
> + return 0;
> +}
> +
> +struct nouveau_oclass
> +nvea_ibus_oclass = {
> + .handle = NV_SUBDEV(IBUS, 0xea),
> + .ofuncs = &(struct nouveau_ofuncs) {
> + .ctor = nvea_ibus_ctor,
> + .dtor = _nouveau_ibus_dtor,
> + .init = nvea_ibus_init,
> + .fini = _nouveau_ibus_fini,
> + },
> +};
> --
> 1.8.5.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 41+ messages in thread
* [RFC 14/16] drm/nouveau/fb: add GK20A support
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
` (8 preceding siblings ...)
2014-02-01 3:16 ` [RFC 13/16] drm/nouveau/ibus: add GK20A support Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
[not found] ` <1391224618-3794-15-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
[not found] ` <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
` (2 subsequent siblings)
12 siblings, 1 reply; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: gnurou, Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
Terje Bergstrom, Ken Adams
Add a clumsy-but-working FB support for GK20A. This chip only uses system
memory, so we allocate a big chunk using CMA and let the existing memory
managers work on it.
A better future design would be to allocate objects directly from system
memory without having to suffer from the limitations of a large,
contiguous pool.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/Makefile | 2 +
drivers/gpu/drm/nouveau/core/include/subdev/fb.h | 1 +
drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c | 28 ++++++++++
drivers/gpu/drm/nouveau/core/subdev/fb/priv.h | 1 +
drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c | 67 ++++++++++++++++++++++++
5 files changed, 99 insertions(+)
create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c
create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 3548fcd..d9fe3e6 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -100,6 +100,7 @@ nouveau-y += core/subdev/fb/nvaa.o
nouveau-y += core/subdev/fb/nvaf.o
nouveau-y += core/subdev/fb/nvc0.o
nouveau-y += core/subdev/fb/nve0.o
+nouveau-y += core/subdev/fb/nvea.o
nouveau-y += core/subdev/fb/ramnv04.o
nouveau-y += core/subdev/fb/ramnv10.o
nouveau-y += core/subdev/fb/ramnv1a.o
@@ -114,6 +115,7 @@ nouveau-y += core/subdev/fb/ramnva3.o
nouveau-y += core/subdev/fb/ramnvaa.o
nouveau-y += core/subdev/fb/ramnvc0.o
nouveau-y += core/subdev/fb/ramnve0.o
+nouveau-y += core/subdev/fb/ramnvea.o
nouveau-y += core/subdev/fb/sddr3.o
nouveau-y += core/subdev/fb/gddr5.o
nouveau-y += core/subdev/gpio/base.o
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
index d7ecafb..3905816 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
@@ -105,6 +105,7 @@ extern struct nouveau_oclass *nvaa_fb_oclass;
extern struct nouveau_oclass *nvaf_fb_oclass;
extern struct nouveau_oclass *nvc0_fb_oclass;
extern struct nouveau_oclass *nve0_fb_oclass;
+extern struct nouveau_oclass *nvea_fb_oclass;
#include <subdev/bios/ramcfg.h>
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c
new file mode 100644
index 0000000..5ff6029
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include "nvc0.h"
+
+struct nouveau_oclass *
+nvea_fb_oclass = &(struct nouveau_fb_impl) {
+ .base.handle = NV_SUBDEV(FB, 0xea),
+ .base.ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvc0_fb_ctor,
+ .dtor = nvc0_fb_dtor,
+ .init = nvc0_fb_init,
+ .fini = _nouveau_fb_fini,
+ },
+ .memtype = nvc0_fb_memtype_valid,
+ .ram = &nvea_ram_oclass,
+}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
index edaf95d..0b95a25 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
@@ -32,6 +32,7 @@ extern struct nouveau_oclass nva3_ram_oclass;
extern struct nouveau_oclass nvaa_ram_oclass;
extern struct nouveau_oclass nvc0_ram_oclass;
extern struct nouveau_oclass nve0_ram_oclass;
+extern struct nouveau_oclass nvea_ram_oclass;
int nouveau_sddr3_calc(struct nouveau_ram *ram);
int nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c
new file mode 100644
index 0000000..3038e08
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+/*
+ * TODO replace this CMA-requiring horror with a proper allocator for GPU
+ * objects in main memory. But for the moment it does the job and can reuse some
+ * of the nvc0 functions.
+ */
+
+#include "nvc0.h"
+
+#include <linux/dma-mapping.h>
+
+static int
+nvea_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+ struct nouveau_oclass *oclass, void *data, u32 datasize,
+ struct nouveau_object **pobject)
+{
+ struct nouveau_fb *pfb = nouveau_fb(parent);
+ struct nouveau_ram *ram;
+ void *vram;
+ dma_addr_t dma_handle;
+ int ret;
+
+ ret = nouveau_ram_create(parent, engine, oclass, &ram);
+ *pobject = nv_object(ram);
+ if (ret)
+ return ret;
+
+ ram->type = NV_MEM_TYPE_STOLEN;
+ /* Use a fixed size of 64MB for now */
+ ram->size = 0x4000000;
+ ram->stolen = (u64)0x00000000;
+ vram = dma_alloc_coherent(nv_device_base(nv_device(parent)), ram->size,
+ &dma_handle, GFP_KERNEL);
+ if (!vram)
+ return -ENOMEM;
+
+ ret = nouveau_mm_init(&pfb->vram, dma_handle >> 12, ram->size >> 12, 1);
+ if (ret)
+ return ret;
+
+ ram->get = nvc0_ram_get;
+ ram->put = nvc0_ram_put;
+ return 0;
+}
+
+struct nouveau_oclass
+nvea_ram_oclass = {
+ .ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nvea_ram_ctor,
+ .dtor = _nouveau_ram_dtor,
+ .init = _nouveau_ram_init,
+ .fini = _nouveau_ram_fini,
+ },
+};
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread[parent not found: <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>]
* [RFC 03/16] drm/nouveau: add platform device probing function
[not found] ` <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-01 3:16 ` [RFC 04/16] drm/nouveau/fifo: support platform devices Alexandre Courbot
` (6 subsequent siblings)
7 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Cc: Terje Bergstrom, Ken Adams, Thierry Reding, Stephen Warren,
Eric Brower, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gnurou-Re5JQEeQqe8AvxtiuMwx3w, Alexandre Courbot
Add a nouveau_drm_platform_probe() function that probes a Nouveau
platform device and registers it using drm_platform_init().
Signed-off-by: Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/gpu/drm/nouveau/core/engine/device/base.c | 34 ++++++++++++++++++++++
.../gpu/drm/nouveau/core/include/engine/device.h | 10 +++++++
drivers/gpu/drm/nouveau/nouveau_drm.c | 19 ++++++++++++
3 files changed, 63 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c
index a6abb51..ba6c2f2 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c
@@ -543,3 +543,37 @@ done:
mutex_unlock(&nv_devices_mutex);
return ret;
}
+
+int
+nouveau_device_platform_create_(struct platform_device *pdev, u64 name,
+ const char *sname, const char *cfg,
+ const char *dbg, int length, void **pobject)
+{
+ struct nouveau_device *device;
+ int ret = -EEXIST;
+
+ mutex_lock(&nv_devices_mutex);
+ list_for_each_entry(device, &nv_devices, head) {
+ if (device->handle == name)
+ goto done;
+ }
+
+ ret = nouveau_engine_create_(NULL, NULL, &nouveau_device_oclass, true,
+ "DEVICE", "device", length, pobject);
+ device = *pobject;
+ if (ret)
+ goto done;
+
+ device->platformdev = pdev;
+ device->handle = name;
+ device->cfgopt = cfg;
+ device->dbgopt = dbg;
+ device->name = sname;
+
+ nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE");
+ nv_engine(device)->sclass = nouveau_device_sclass;
+ list_add(&device->head, &nv_devices);
+done:
+ mutex_unlock(&nv_devices_mutex);
+ return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/device.h b/drivers/gpu/drm/nouveau/core/include/engine/device.h
index b3dd2c4..90056190 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/device.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/device.h
@@ -3,12 +3,22 @@
#include <core/device.h>
+struct platform_device;
+
#define nouveau_device_create(p,n,s,c,d,u) \
nouveau_device_create_((p), (n), (s), (c), (d), sizeof(**u), (void **)u)
int nouveau_device_create_(struct pci_dev *, u64 name, const char *sname,
const char *cfg, const char *dbg, int, void **);
+#define nouveau_device_platform_create(p,n,s,c,d,u) \
+ nouveau_device_platform_create_((p), (n), (s), (c), (d), sizeof(**u), \
+ (void **)u)
+
+int nouveau_device_platform_create_(struct platform_device *pdev, u64 name,
+ const char *sname, const char *cfg,
+ const char *dbg, int, void **);
+
int nv04_identify(struct nouveau_device *);
int nv10_identify(struct nouveau_device *);
int nv20_identify(struct nouveau_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 4cba4d8..8d55a50 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -986,6 +986,25 @@ nouveau_drm_pci_driver = {
.driver.pm = &nouveau_pm_ops,
};
+
+int nouveau_drm_platform_probe(struct platform_device *pdev)
+{
+ struct nouveau_device *device;
+ int ret;
+
+ ret = nouveau_device_platform_create(pdev, nouveau_platform_name(pdev),
+ dev_name(&pdev->dev), nouveau_config,
+ nouveau_debug, &device);
+
+ ret = drm_platform_init(&driver, pdev);
+ if (ret) {
+ nouveau_object_ref(NULL, (struct nouveau_object **)&device);
+ return ret;
+ }
+
+ return ret;
+}
+
static int __init
nouveau_drm_init(void)
{
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* [RFC 04/16] drm/nouveau/fifo: support platform devices
[not found] ` <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-02-01 3:16 ` [RFC 03/16] drm/nouveau: add platform device probing function Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-01 3:16 ` [RFC 11/16] drm/nouveau/fifo: allocate usermem as needed Alexandre Courbot
` (5 subsequent siblings)
7 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Cc: Terje Bergstrom, Ken Adams, Thierry Reding, Stephen Warren,
Eric Brower, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gnurou-Re5JQEeQqe8AvxtiuMwx3w, Alexandre Courbot
Remove PCI-dependent code so the FIFO engine can also handle platform
devices.
Signed-off-by: Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/gpu/drm/nouveau/core/engine/fifo/base.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
index d3ec436d9..6f9041c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
@@ -86,7 +86,7 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent,
}
/* map fifo control registers */
- chan->user = ioremap(pci_resource_start(device->pdev, bar) + addr +
+ chan->user = ioremap(nv_device_resource_start(device, bar) + addr +
(chan->chid * size), size);
if (!chan->user)
return -EFAULT;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* [RFC 11/16] drm/nouveau/fifo: allocate usermem as needed
[not found] ` <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-02-01 3:16 ` [RFC 03/16] drm/nouveau: add platform device probing function Alexandre Courbot
2014-02-01 3:16 ` [RFC 04/16] drm/nouveau/fifo: support platform devices Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-01 3:16 ` [RFC 12/16] drm/nouveau/fifo: add GK20A support Alexandre Courbot
` (4 subsequent siblings)
7 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Cc: Terje Bergstrom, Ken Adams, Thierry Reding, Stephen Warren,
Eric Brower, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gnurou-Re5JQEeQqe8AvxtiuMwx3w, Alexandre Courbot
Memory was always allocated for 4096 channels. Change this to allocate
what we actually need according to the number of channels we use.
Signed-off-by: Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
index 54c1b5b..dbc3ff6 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
@@ -852,8 +852,8 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;
}
- ret = nouveau_gpuobj_new(nv_object(priv), NULL, 4096 * 0x200, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
+ ret = nouveau_gpuobj_new(nv_object(priv), NULL, impl->channels * 0x200,
+ 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
if (ret)
return ret;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* [RFC 12/16] drm/nouveau/fifo: add GK20A support
[not found] ` <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
` (2 preceding siblings ...)
2014-02-01 3:16 ` [RFC 11/16] drm/nouveau/fifo: allocate usermem as needed Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
[not found] ` <1391224618-3794-13-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-02-01 3:16 ` [RFC 15/16] drm/nouveau: support GK20A in nouveau_accel_init() Alexandre Courbot
` (3 subsequent siblings)
7 siblings, 1 reply; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Cc: Terje Bergstrom, Ken Adams, Thierry Reding, Stephen Warren,
Eric Brower, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gnurou-Re5JQEeQqe8AvxtiuMwx3w, Alexandre Courbot
GK20A's FIFO is compatible with NVE0, but only features 128 channels and
1 runlist.
Signed-off-by: Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/gpu/drm/nouveau/Makefile | 1 +
drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h | 1 +
drivers/gpu/drm/nouveau/core/engine/fifo/nvea.c | 27 ++++++++++++++++++++++
drivers/gpu/drm/nouveau/core/include/engine/fifo.h | 1 +
4 files changed, 30 insertions(+)
create mode 100644 drivers/gpu/drm/nouveau/core/engine/fifo/nvea.c
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index e88145b..6c4b76d 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -236,6 +236,7 @@ nouveau-y += core/engine/fifo/nv50.o
nouveau-y += core/engine/fifo/nv84.o
nouveau-y += core/engine/fifo/nvc0.o
nouveau-y += core/engine/fifo/nve0.o
+nouveau-y += core/engine/fifo/nvea.o
nouveau-y += core/engine/fifo/nv108.o
nouveau-y += core/engine/graph/ctxnv40.o
nouveau-y += core/engine/graph/ctxnv50.o
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h
index 014344e..e96b32b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h
@@ -8,6 +8,7 @@ int nve0_fifo_ctor(struct nouveau_object *, struct nouveau_object *,
struct nouveau_object **);
void nve0_fifo_dtor(struct nouveau_object *);
int nve0_fifo_init(struct nouveau_object *);
+int nve0_fifo_fini(struct nouveau_object *, bool);
struct nve0_fifo_impl {
struct nouveau_oclass base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvea.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvea.c
new file mode 100644
index 0000000..16f8905
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvea.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include "nve0.h"
+
+struct nouveau_oclass *
+nvea_fifo_oclass = &(struct nve0_fifo_impl) {
+ .base.handle = NV_ENGINE(FIFO, 0xea),
+ .base.ofuncs = &(struct nouveau_ofuncs) {
+ .ctor = nve0_fifo_ctor,
+ .dtor = nve0_fifo_dtor,
+ .init = nve0_fifo_init,
+ .fini = nve0_fifo_fini,
+ },
+ .channels = 128,
+}.base;
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
index 26b6b2b..823356f 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
@@ -109,6 +109,7 @@ extern struct nouveau_oclass *nv50_fifo_oclass;
extern struct nouveau_oclass *nv84_fifo_oclass;
extern struct nouveau_oclass *nvc0_fifo_oclass;
extern struct nouveau_oclass *nve0_fifo_oclass;
+extern struct nouveau_oclass *nvea_fifo_oclass;
extern struct nouveau_oclass *nv108_fifo_oclass;
void nv04_fifo_intr(struct nouveau_subdev *);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* [RFC 15/16] drm/nouveau: support GK20A in nouveau_accel_init()
[not found] ` <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
` (3 preceding siblings ...)
2014-02-01 3:16 ` [RFC 12/16] drm/nouveau/fifo: add GK20A support Alexandre Courbot
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-02 19:10 ` [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Ilia Mirkin
` (2 subsequent siblings)
7 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
Cc: Terje Bergstrom, Ken Adams, Thierry Reding, Stephen Warren,
Eric Brower, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
gnurou-Re5JQEeQqe8AvxtiuMwx3w, Alexandre Courbot
GK20A does not embed a dedicated COPY engine and thus cannot allocate
the copy channel that nouveau_accel_init() attempts to create. It also
lacks any display hardware, so the creation of a software channel does
not apply neither.
Signed-off-by: Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
drivers/gpu/drm/nouveau/nouveau_drm.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 8d55a50..87bdf04 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -171,6 +171,11 @@ nouveau_accel_init(struct nouveau_drm *drm)
return;
}
+ if (device->chipset == 0xea) {
+ /* gk20a does not have CE0/CE1 */
+ arg0 = NVE0_CHANNEL_IND_ENGINE_GR;
+ arg1 = 1;
+ } else
if (device->card_type >= NV_E0) {
ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE,
NVDRM_CHAN + 1,
@@ -207,6 +212,10 @@ nouveau_accel_init(struct nouveau_drm *drm)
return;
}
+ /* Need to figure out how to handle sw for gk20a */
+ if (device->chipset == 0xea)
+ goto skip_sw_init;
+
ret = nouveau_object_new(nv_object(drm), NVDRM_CHAN, NVDRM_NVSW,
nouveau_abi16_swclass(drm), NULL, 0, &object);
if (ret == 0) {
@@ -233,6 +242,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
return;
}
+skip_sw_init:
if (device->card_type < NV_C0) {
ret = nouveau_gpuobj_new(drm->device, NULL, 32, 0, 0,
&drm->notify);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)
[not found] ` <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
` (4 preceding siblings ...)
2014-02-01 3:16 ` [RFC 15/16] drm/nouveau: support GK20A in nouveau_accel_init() Alexandre Courbot
@ 2014-02-02 19:10 ` Ilia Mirkin
[not found] ` <CAKb7Uvg4Bqy1tHetVZBe=aekFDbgrGygc-evnSXxsoGqgoTA8A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-02-03 17:33 ` Daniel Vetter
2014-02-04 3:53 ` Ben Skeggs
7 siblings, 1 reply; 41+ messages in thread
From: Ilia Mirkin @ 2014-02-02 19:10 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Ben Skeggs,
nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
Alexandre Courbot, Eric Brower, Stephen Warren,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, Terje Bergstrom, Ken Adams
Hi Alexandre,
On Fri, Jan 31, 2014 at 10:16 PM, Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> I guess my email address might surprise some of you, so let me anticipate some
> questions you might have. :P Yes, this work is endorsed by NVIDIA. Several other
> NVIDIAns (CC'd), including core GPU experts, have provided significant technical
> guidance and will continue their involvement. Special thanks go to Terje
> Bergstrom and Ken Adams for their invaluable GPU expertise, and Thierry Reding
> (at FOSDEM this weekend) for help with debugging and user-space testing.
>
> Let me also stress that although very exciting, this effort is still
> experimental, so I would like to make sure that nobody makes excessive
> expectations based on these few patches. The scope of this work is strictly
> limited to Tegra (although given the similarities desktop GPU support will
> certainly benefit from it indirectly), and we do not have any plan to work on
> user-space support. So do not uninstall that proprietary driver just yet. ;)
>
> With this being clarified, we are looking forward to getting your feedback and
> working with you guys to bring and improve Tegra K1 support into Nouveau! :)
I've sent a couple of fairly trivial comments, as you saw, and I
suspect that others with a better understanding of the guts will have
more substantial architectural feedback, esp after the weekend/FOSDEM.
However, since no one's said it already -- welcome to Nouveau!
From the looks of it, you could bring up a full open-source stack with
your patches (i.e. Xorg + nouveau DDX + mesa) and use PRIME to render
stuff (assuming the actual display hw has an X ddx). Although I
suspect that you're going to want to use your own drivers. Still a
little curious if you've tried the open-source stack and whether it
worked. [Not sure what the status is of render-node support is in
mesa, but perhaps it's enough to try running piglit tests, if you
can't get X going with the display HW.]
-ilia
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)
[not found] ` <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
` (5 preceding siblings ...)
2014-02-02 19:10 ` [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Ilia Mirkin
@ 2014-02-03 17:33 ` Daniel Vetter
2014-02-04 3:53 ` Ben Skeggs
7 siblings, 0 replies; 41+ messages in thread
From: Daniel Vetter @ 2014-02-03 17:33 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Ben Skeggs, Nouveau Dev, dri-devel, gnurou-Re5JQEeQqe8AvxtiuMwx3w,
Eric Brower, Stephen Warren, Linux Kernel Mailing List,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Terje Bergstrom, Ken Adams
On Sat, Feb 1, 2014 at 4:16 AM, Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Finally, support for probing GK20A is added in the last 2 patches. It should be
> noted that contrary to what Nouveau currently expects, GK20A does not embed any
> display hardware (that part being handled by tegradrm). So this driver should
> really be only used through DRM render-nodes and collaborate with the display
> driver using PRIME. I have not yet figured out how to turn GK20A's instantiation
> of Nouveau into a render-node only driver without breaking support for existing
> desktop GPUs, and consequently the driver spawns a /dev/dri/cardX node which we
> should try to get rid of.
tbh I wouldn't care about the lagecy dev nodes - we have hw platforms
on intel with similar setup (i.e. just rendering and no outputs) and
we don't bother to hide the legacy node. kms ioctl will still be
there, but as long as no encoder/connector/crtc/... gets set up by the
driver the only thing userspace can do is create framebuffers. Which
is rather harmless ;-)
And having legacy dev nodes around helps on older userspace (e.g.
X/Prime with dri2 which uses flink).
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 41+ messages in thread* Re: [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)
[not found] ` <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
` (6 preceding siblings ...)
2014-02-03 17:33 ` Daniel Vetter
@ 2014-02-04 3:53 ` Ben Skeggs
[not found] ` <CACAvsv4QFSL8u8hQFr-T_28n3icN_CwDsvLtrcPXx5nErD89wQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
7 siblings, 1 reply; 41+ messages in thread
From: Ben Skeggs @ 2014-02-04 3:53 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Ben Skeggs,
nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
Alexandre Courbot, Eric Brower, Stephen Warren,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Terje Bergstrom, Ken Adams
On Sat, Feb 1, 2014 at 1:16 PM, Alexandre Courbot <acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
> Hello everyone,
Hey Alex,
The series looks pretty good to me. I'll reply to the relevant
patches with any minor nit-picks on top of what's already been said by
others.
Thank you, and welcome to Nouveau :)
Ben.
>
> GK20A is the Kepler-based GPU used in the upcoming Tegra K1 chips. The following
> patches perform architectural changes to Nouveau that are necessary to support
> non-PCI GPUs and add initial support for GK20A. Although the support is still
> very basic and more user-space changes will be needed to make the full graphics
> stack run on top of it, we were able to successfully open channels and run
> simple pushbuffers with libdrm (more testing including rendering is in progress
> as we get more familiar with Nouveau's user-space interface).
>
> This work should be considered as a RFC and a proof-of-concept for driving
> future Tegra GPUs with Nouveau. Some design choices need to be discussed and
> quite a few inelegant shortcuts were purposely taken to minimize the size of
> this first set. Or said otherwise, apart from the changes that add support for
> non-PCI GPUs, remarkably little code needs to be added to get GK20A to a point
> where it is actually running. This is very encouraging, and it will be
> interesting to keep improving this support and see where this gets us.
>
> The first part of this series (patches 01/09) adds support for platform devices
> to Nouveau. Nouveau currently only supports PCI devices, and GK20A uses the
> platform bus and Device Tree. So the first step towards GK20A support is to
> abstract the PCI functions used by Nouveau (mainly resources range querying and
> page mapping functions) and add platform device probing functions. For most of
> the existing chips, platform device support does not make any sense, so only the
> subdev and engine drivers actually used by GK20A were updated to use these
> abstractions. If, for consistency reasons, it is deemed preferable to use them
> everywhere in the driver, we will do it in the next revision of this series.
>
> This part can be considered independently from the actual GK20A support, and I
> believe it would make sense to discuss what needs to be improved and drive it to
> merge separately, as the remainder of the series will likely require more work.
>
> The second part (10/14) updates existing subdev/engine drivers to support GK20A,
> and adds a very simple memory driver that simulates dedicated video memory by
> allocating a large system memory chunk at boot time. This is clearly sub-optimal
> and should not be merged, but allowed us to quickly bring GK20A up with Nouveau.
> Other drivers changes are fairly small, and are here to handle the difference in
> number of engines and units compared to desktop Kepler as well as to perform a
> few things usually done by the video BIOS (which Tegra does not feature).
>
> Finally, support for probing GK20A is added in the last 2 patches. It should be
> noted that contrary to what Nouveau currently expects, GK20A does not embed any
> display hardware (that part being handled by tegradrm). So this driver should
> really be only used through DRM render-nodes and collaborate with the display
> driver using PRIME. I have not yet figured out how to turn GK20A's instantiation
> of Nouveau into a render-node only driver without breaking support for existing
> desktop GPUs, and consequently the driver spawns a /dev/dri/cardX node which we
> should try to get rid of.
>
> I guess my email address might surprise some of you, so let me anticipate some
> questions you might have. :P Yes, this work is endorsed by NVIDIA. Several other
> NVIDIAns (CC'd), including core GPU experts, have provided significant technical
> guidance and will continue their involvement. Special thanks go to Terje
> Bergstrom and Ken Adams for their invaluable GPU expertise, and Thierry Reding
> (at FOSDEM this weekend) for help with debugging and user-space testing.
>
> Let me also stress that although very exciting, this effort is still
> experimental, so I would like to make sure that nobody makes excessive
> expectations based on these few patches. The scope of this work is strictly
> limited to Tegra (although given the similarities desktop GPU support will
> certainly benefit from it indirectly), and we do not have any plan to work on
> user-space support. So do not uninstall that proprietary driver just yet. ;)
>
> With this being clarified, we are looking forward to getting your feedback and
> working with you guys to bring and improve Tegra K1 support into Nouveau! :)
>
> Alexandre Courbot (16):
> drm/nouveau: handle -EACCES runtime PM return code
> drm/nouveau: basic support for platform devices
> drm/nouveau: add platform device probing function
> drm/nouveau/fifo: support platform devices
> drm/nouveau/bar: support platform devices
> drm/nouveau/bar: only ioremap BAR3 if it exists
> drm/nouveau/bar/nvc0: support chips without BAR3
> drm/nouveau/mc: support platform devices
> drm/nouveau/fb: support platform devices
> drm/nouveau/timer: skip calibration on GK20A
> drm/nouveau/fifo: allocate usermem as needed
> drm/nouveau/fifo: add GK20A support
> drm/nouveau/ibus: add GK20A support
> drm/nouveau/fb: add GK20A support
> drm/nouveau: support GK20A in nouveau_accel_init()
> drm/nouveau: support for probing GK20A
>
> drivers/gpu/drm/nouveau/Makefile | 4 +
> drivers/gpu/drm/nouveau/core/engine/device/base.c | 92 +++++++++++++++-
> drivers/gpu/drm/nouveau/core/engine/device/nve0.c | 20 ++++
> drivers/gpu/drm/nouveau/core/engine/fifo/base.c | 2 +-
> drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | 4 +-
> drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h | 1 +
> drivers/gpu/drm/nouveau/core/engine/fifo/nvea.c | 27 +++++
> drivers/gpu/drm/nouveau/core/include/core/device.h | 27 +++++
> .../gpu/drm/nouveau/core/include/engine/device.h | 10 ++
> drivers/gpu/drm/nouveau/core/include/engine/fifo.h | 1 +
> drivers/gpu/drm/nouveau/core/include/subdev/fb.h | 1 +
> drivers/gpu/drm/nouveau/core/include/subdev/ibus.h | 1 +
> drivers/gpu/drm/nouveau/core/include/subdev/mc.h | 1 +
> drivers/gpu/drm/nouveau/core/os.h | 1 +
> drivers/gpu/drm/nouveau/core/subdev/bar/base.c | 7 +-
> drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c | 4 +-
> drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c | 116 +++++++++++----------
> drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c | 9 +-
> drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c | 28 +++++
> drivers/gpu/drm/nouveau/core/subdev/fb/priv.h | 1 +
> drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c | 67 ++++++++++++
> drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c | 108 +++++++++++++++++++
> drivers/gpu/drm/nouveau/core/subdev/mc/base.c | 43 +++++---
> drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c | 19 ++--
> drivers/gpu/drm/nouveau/dispnv04/crtc.c | 2 +-
> drivers/gpu/drm/nouveau/nouveau_abi16.c | 13 ++-
> drivers/gpu/drm/nouveau/nouveau_bo.c | 22 ++--
> drivers/gpu/drm/nouveau/nouveau_connector.c | 2 +-
> drivers/gpu/drm/nouveau/nouveau_display.c | 3 +-
> drivers/gpu/drm/nouveau/nouveau_drm.c | 86 ++++++++++++---
> drivers/gpu/drm/nouveau/nouveau_sysfs.c | 8 +-
> drivers/gpu/drm/nouveau/nouveau_ttm.c | 31 +++---
> 32 files changed, 622 insertions(+), 139 deletions(-)
> create mode 100644 drivers/gpu/drm/nouveau/core/engine/fifo/nvea.c
> create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/nvea.c
> create mode 100644 drivers/gpu/drm/nouveau/core/subdev/fb/ramnvea.c
> create mode 100644 drivers/gpu/drm/nouveau/core/subdev/ibus/nvea.c
>
> --
> 1.8.5.3
>
> _______________________________________________
> dri-devel mailing list
> dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 41+ messages in thread
* [RFC 16/16] drm/nouveau: support for probing GK20A
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
` (10 preceding siblings ...)
[not found] ` <1391224618-3794-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2014-02-01 3:16 ` Alexandre Courbot
2014-02-03 11:25 ` [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) David Herrmann
12 siblings, 0 replies; 41+ messages in thread
From: Alexandre Courbot @ 2014-02-01 3:16 UTC (permalink / raw)
To: Ben Skeggs, nouveau, dri-devel
Cc: gnurou, Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
Terje Bergstrom, Ken Adams
Set the correct subdev/engine classes when GK20A (0xea) is probed.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nouveau/core/engine/device/nve0.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
index 987edbc..30d652e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
@@ -156,6 +156,26 @@ nve0_identify(struct nouveau_device *device)
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
break;
+ case 0xea:
+ device->cname = "GK20A";
+ device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
+ device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
+ device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
+ device->oclass[NVDEV_SUBDEV_FB ] = nvea_fb_oclass;
+ device->oclass[NVDEV_SUBDEV_IBUS ] = &nvea_ibus_oclass;
+ device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
+ device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
+ device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
+ device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
+ device->oclass[NVDEV_ENGINE_FIFO ] = nvea_fifo_oclass;
+ /* TODO will need an implementation for this at some point... */
+#if 0
+ device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
+#endif
+ device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass;
+ device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
+ device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
+ break;
case 0xf0:
device->cname = "GK110";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 41+ messages in thread* Re: [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)
2014-02-01 3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
` (11 preceding siblings ...)
2014-02-01 3:16 ` [RFC 16/16] drm/nouveau: support for probing GK20A Alexandre Courbot
@ 2014-02-03 11:25 ` David Herrmann
[not found] ` <CANq1E4R=DWp2WBWWBbLHE2FG9HWWP=bM4wvE8etoEr1PAp0+JA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
12 siblings, 1 reply; 41+ messages in thread
From: David Herrmann @ 2014-02-03 11:25 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Ben Skeggs, nouveau, dri-devel@lists.freedesktop.org,
Alexandre Courbot, Eric Brower, Stephen Warren, linux-kernel,
linux-tegra, Terje Bergstrom, Ken Adams
Hi
[..snip..]
> Finally, support for probing GK20A is added in the last 2 patches. It should be
> noted that contrary to what Nouveau currently expects, GK20A does not embed any
> display hardware (that part being handled by tegradrm). So this driver should
> really be only used through DRM render-nodes and collaborate with the display
> driver using PRIME. I have not yet figured out how to turn GK20A's instantiation
> of Nouveau into a render-node only driver without breaking support for existing
> desktop GPUs, and consequently the driver spawns a /dev/dri/cardX node which we
> should try to get rid of.
You cannot get rid of cardX currently. It is implied by DRIVER_MODESET
and that flag should actually be called NOT_A_LEGACY_DRIVER. So you
cannot remove it. I did try to replace DRIVER_MODESET by an inverted
DRIVER_LEGACY flag some time ago, but I thought it's not worth it.
Anyhow, you can easily add a new flag to make
drm_dev_register()/drm_dev_alloc() not create the drm_minor for
DRM_MINOR_LEGACY, which would prevent the card0 node from showing up.
But people started using the cardX interface as base interface so mesa
might not be able to open render-nodes if the related card-node is not
available (which is a bug in their code, so no reason to support that
by not adding stand-alone render-nodes).
Long story short: If you want to do it properly, just add a flag to
DRM core that prevents DRM_MINOR_LEGACY from showing up. If you just
want it to work, simply keep a dummy card0.
Thanks
David
^ permalink raw reply [flat|nested] 41+ messages in thread