linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)
@ 2014-02-01  3:16 Alexandre Courbot
  2014-02-01  3:16 ` [RFC 01/16] drm/nouveau: handle -EACCES runtime PM return code Alexandre Courbot
                   ` (19 more replies)
  0 siblings, 20 replies; 40+ 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

Hello everyone,

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


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [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
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 40+ 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

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] 40+ 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 03/16] drm/nouveau: add platform device probing function Alexandre Courbot
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 40+ 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] 40+ messages in thread

* [RFC 03/16] drm/nouveau: add platform device probing function
  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 04/16] drm/nouveau/fifo: support platform devices Alexandre Courbot
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 40+ 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 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@nvidia.com>
---
 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] 40+ messages in thread

* [RFC 04/16] drm/nouveau/fifo: support platform devices
  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 03/16] drm/nouveau: add platform device probing function Alexandre Courbot
@ 2014-02-01  3:16 ` Alexandre Courbot
  2014-02-01  3:16 ` [RFC 05/16] drm/nouveau/bar: " Alexandre Courbot
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 40+ 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 FIFO engine can also handle platform
devices.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
 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] 40+ 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
                   ` (3 preceding siblings ...)
  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 06/16] drm/nouveau/bar: only ioremap BAR3 if it exists Alexandre Courbot
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 40+ 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] 40+ 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
                   ` (4 preceding siblings ...)
  2014-02-01  3:16 ` [RFC 05/16] drm/nouveau/bar: " 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
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 40+ 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

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] 40+ 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
                   ` (5 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
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 40+ 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

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] 40+ 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
                   ` (6 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
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 40+ 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

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] 40+ 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
                   ` (7 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
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 40+ 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

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] 40+ 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
                   ` (8 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 11/16] drm/nouveau/fifo: allocate usermem as needed Alexandre Courbot
                   ` (9 subsequent siblings)
  19 siblings, 1 reply; 40+ 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

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] 40+ messages in thread

* [RFC 11/16] drm/nouveau/fifo: allocate usermem as needed
  2014-02-01  3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
                   ` (9 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-01  3:16 ` [RFC 12/16] drm/nouveau/fifo: add GK20A support Alexandre Courbot
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 40+ 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

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@nvidia.com>
---
 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] 40+ messages in thread

* [RFC 12/16] drm/nouveau/fifo: add GK20A support
  2014-02-01  3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
                   ` (10 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
  2014-02-04  9:15   ` Daniel Vetter
  2014-02-01  3:16 ` [RFC 13/16] drm/nouveau/ibus: " Alexandre Courbot
                   ` (7 subsequent siblings)
  19 siblings, 1 reply; 40+ 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

GK20A's FIFO is compatible with NVE0, but only features 128 channels and
1 runlist.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
 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] 40+ 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
                   ` (11 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  6:35   ` Ilia Mirkin
  2014-02-01  3:16 ` [RFC 14/16] drm/nouveau/fb: " Alexandre Courbot
                   ` (6 subsequent siblings)
  19 siblings, 1 reply; 40+ 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] 40+ 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
                   ` (12 preceding siblings ...)
  2014-02-01  3:16 ` [RFC 13/16] drm/nouveau/ibus: " Alexandre Courbot
@ 2014-02-01  3:16 ` Alexandre Courbot
  2014-02-01 13:40   ` Lucas Stach
  2014-02-01  3:16 ` [RFC 15/16] drm/nouveau: support GK20A in nouveau_accel_init() Alexandre Courbot
                   ` (5 subsequent siblings)
  19 siblings, 1 reply; 40+ 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 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] 40+ messages in thread

* [RFC 15/16] drm/nouveau: support GK20A in nouveau_accel_init()
  2014-02-01  3:16 [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Alexandre Courbot
                   ` (13 preceding siblings ...)
  2014-02-01  3:16 ` [RFC 14/16] drm/nouveau/fb: " Alexandre Courbot
@ 2014-02-01  3:16 ` Alexandre Courbot
  2014-02-01  3:16 ` [RFC 16/16] drm/nouveau: support for probing GK20A Alexandre Courbot
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 40+ 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

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@nvidia.com>
---
 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] 40+ 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
                   ` (14 preceding siblings ...)
  2014-02-01  3:16 ` [RFC 15/16] drm/nouveau: support GK20A in nouveau_accel_init() 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
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 40+ 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

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] 40+ messages in thread

* Re: [RFC 14/16] drm/nouveau/fb: add GK20A support
  2014-02-01  3:16 ` [RFC 14/16] drm/nouveau/fb: " Alexandre Courbot
@ 2014-02-01 13:40   ` Lucas Stach
  2014-02-01 23:28     ` Ilia Mirkin
  0 siblings, 1 reply; 40+ messages in thread
From: Lucas Stach @ 2014-02-01 13:40 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Ben Skeggs, nouveau, dri-devel, gnurou, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, Terje Bergstrom,
	Ken Adams

Am Samstag, den 01.02.2014, 12:16 +0900 schrieb Alexandre Courbot:
> 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.
> 
I don't know if Tegra124 is similar to 114 in this regard [hint: get the
TRM out :)], but if you go for a dedicated VRAM allocator, wouldn't it
make sense to take a chunk of the MMIO overlaid memory for this when
possible, rather than carving this out of CPU accessible mem?

> 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,
> +	},
> +};



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC 14/16] drm/nouveau/fb: add GK20A support
  2014-02-01 13:40   ` Lucas Stach
@ 2014-02-01 23:28     ` Ilia Mirkin
  2014-02-01 23:58       ` Lucas Stach
  0 siblings, 1 reply; 40+ messages in thread
From: Ilia Mirkin @ 2014-02-01 23:28 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Alexandre Courbot, Ben Skeggs, nouveau, dri-devel, gnurou,
	Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
	Terje Bergstrom, Ken Adams

On Sat, Feb 1, 2014 at 8:40 AM, Lucas Stach <dev@lynxeye.de> wrote:
> Am Samstag, den 01.02.2014, 12:16 +0900 schrieb Alexandre Courbot:
>> 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.
>>
> I don't know if Tegra124 is similar to 114 in this regard [hint: get the
> TRM out :)], but if you go for a dedicated VRAM allocator, wouldn't it
> make sense to take a chunk of the MMIO overlaid memory for this when
> possible, rather than carving this out of CPU accessible mem?

This is probably a stupid question... what do you need VRAM for
anyways? In _theory_ it's an abstraction to talk about memory that's
not accessible by the CPU. This is obviously not the case here, and
presumably the GPU can access all the memory in the system, so it can
be all treated as "GART" memory... AFAIK all accesses are behind the
in-GPU MMU, so contiguous physical memory isn't an issue either. In
practice, I suspect nouveau automatically sticks certain things into
vram (gpuobj's), but it should be feasible to make them optionally use
GART memory when VRAM is not available. I haven't really looked at the
details though, perhaps that's a major undertaking.

  -ilia

>
>> 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,
>> +     },
>> +};
>
>
> --
> 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] 40+ messages in thread

* Re: [RFC 14/16] drm/nouveau/fb: add GK20A support
  2014-02-01 23:28     ` Ilia Mirkin
@ 2014-02-01 23:58       ` Lucas Stach
  2014-02-02 13:43         ` Alexandre Courbot
  0 siblings, 1 reply; 40+ messages in thread
From: Lucas Stach @ 2014-02-01 23:58 UTC (permalink / raw)
  To: Ilia Mirkin
  Cc: Alexandre Courbot, Ben Skeggs, nouveau, dri-devel, gnurou,
	Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
	Terje Bergstrom, Ken Adams

Am Samstag, den 01.02.2014, 18:28 -0500 schrieb Ilia Mirkin:
> On Sat, Feb 1, 2014 at 8:40 AM, Lucas Stach <dev@lynxeye.de> wrote:
> > Am Samstag, den 01.02.2014, 12:16 +0900 schrieb Alexandre Courbot:
> >> 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.
> >>
> > I don't know if Tegra124 is similar to 114 in this regard [hint: get the
> > TRM out :)], but if you go for a dedicated VRAM allocator, wouldn't it
> > make sense to take a chunk of the MMIO overlaid memory for this when
> > possible, rather than carving this out of CPU accessible mem?
> 
> This is probably a stupid question... what do you need VRAM for
> anyways? In _theory_ it's an abstraction to talk about memory that's
> not accessible by the CPU. This is obviously not the case here, and
> presumably the GPU can access all the memory in the system, so it can
> be all treated as "GART" memory... AFAIK all accesses are behind the
> in-GPU MMU, so contiguous physical memory isn't an issue either. In
> practice, I suspect nouveau automatically sticks certain things into
> vram (gpuobj's), but it should be feasible to make them optionally use
> GART memory when VRAM is not available. I haven't really looked at the
> details though, perhaps that's a major undertaking.
> 
>   -ilia
> 
If it's similar to the Tegar114 there actually is memory that isn't
accessible from the CPU. About 2GB of the address space is overlaid with
MMIO for the devices, so in a 4GB system you potentially have 2GB of RAM
that's only visible for the devices.

But yes in general nouveau should just fall back to a GART placement if
VRAM isn't available.

> >
> >> 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,
> >> +     },
> >> +};
> >
> >
> > --
> > 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] 40+ messages in thread

* Re: [RFC 13/16] drm/nouveau/ibus: add GK20A support
  2014-02-01  3:16 ` [RFC 13/16] drm/nouveau/ibus: " Alexandre Courbot
@ 2014-02-02  6:35   ` Ilia Mirkin
  2014-02-02  9:38     ` Alexandre Courbot
  0 siblings, 1 reply; 40+ messages in thread
From: Ilia Mirkin @ 2014-02-02  6:35 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Ben Skeggs, nouveau, dri-devel, Terje Bergstrom, Ken Adams,
	Thierry Reding, Stephen Warren, Eric Brower, linux-tegra,
	linux-kernel, gnurou

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] 40+ messages in thread

* Re: [RFC 13/16] drm/nouveau/ibus: add GK20A support
  2014-02-02  6:35   ` Ilia Mirkin
@ 2014-02-02  9:38     ` Alexandre Courbot
  0 siblings, 0 replies; 40+ messages in thread
From: Alexandre Courbot @ 2014-02-02  9:38 UTC (permalink / raw)
  To: Ilia Mirkin
  Cc: Alexandre Courbot, Ben Skeggs, nouveau, dri-devel,
	Terje Bergstrom, Ken Adams, Thierry Reding, Stephen Warren,
	Eric Brower, linux-tegra, linux-kernel

On Sun, Feb 2, 2014 at 3:35 PM, Ilia Mirkin <imirkin@alum.mit.edu> wrote:
> 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)

Absolutely correct for both.

>> +
>> +       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?

Sounds more adequate indeed.

Thanks,
Alex.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC 14/16] drm/nouveau/fb: add GK20A support
  2014-02-01 23:58       ` Lucas Stach
@ 2014-02-02 13:43         ` Alexandre Courbot
  2014-02-07 14:19           ` Alexandre Courbot
  0 siblings, 1 reply; 40+ messages in thread
From: Alexandre Courbot @ 2014-02-02 13:43 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Ilia Mirkin, Alexandre Courbot, Ben Skeggs, nouveau, dri-devel,
	Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
	Terje Bergstrom, Ken Adams

On Sun, Feb 2, 2014 at 8:58 AM, Lucas Stach <dev@lynxeye.de> wrote:
> Am Samstag, den 01.02.2014, 18:28 -0500 schrieb Ilia Mirkin:
>> On Sat, Feb 1, 2014 at 8:40 AM, Lucas Stach <dev@lynxeye.de> wrote:
>> > Am Samstag, den 01.02.2014, 12:16 +0900 schrieb Alexandre Courbot:
>> >> 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.
>> >>
>> > I don't know if Tegra124 is similar to 114 in this regard [hint: get the
>> > TRM out :)], but if you go for a dedicated VRAM allocator, wouldn't it
>> > make sense to take a chunk of the MMIO overlaid memory for this when
>> > possible, rather than carving this out of CPU accessible mem?
>>
>> This is probably a stupid question... what do you need VRAM for
>> anyways? In _theory_ it's an abstraction to talk about memory that's
>> not accessible by the CPU. This is obviously not the case here, and
>> presumably the GPU can access all the memory in the system, so it can
>> be all treated as "GART" memory... AFAIK all accesses are behind the
>> in-GPU MMU, so contiguous physical memory isn't an issue either. In
>> practice, I suspect nouveau automatically sticks certain things into
>> vram (gpuobj's), but it should be feasible to make them optionally use
>> GART memory when VRAM is not available. I haven't really looked at the
>> details though, perhaps that's a major undertaking.
>>
>>   -ilia
>>
> If it's similar to the Tegar114 there actually is memory that isn't
> accessible from the CPU. About 2GB of the address space is overlaid with
> MMIO for the devices, so in a 4GB system you potentially have 2GB of RAM
> that's only visible for the devices.
>
> But yes in general nouveau should just fall back to a GART placement if
> VRAM isn't available.

With the limited time I spent studying it, it seems to me that Nouveau
has a strong dependency on VRAM. For gpuobjects indeed (that one could
be workarounded with a new instmem driver I suppose), and also for
TTM: objects placed in TTM_PL_VRAM are handled by the VRAM manager,
which requires a nouveau_ram instance in the FB. Actually the FB also
seems to assume the presence of a dedicated video RAM.

So while I agree that getting rid of VRAM altogether would be the most
logical solution, I have not found a way to do so for the moment.

T124's GPU actually sees the same physical address space as the CPU,
so memory management should be simplified thanks to that (you could
enable the SMMU and make things more interesting/complex, but for now
it seems untimely to even consider doing so). Actually even the
concept of a GART is not needed here: all your memory management needs
could be fulfilled by getting pages with alloc_page() and arranging
them using the GMMU. No GART, no BAR (at least for the purpose of
mapping objects for CPU access), no PRAMIN.

I really wonder how that picture would fit within Nouveau, and it is
quite likely that there is an elegant solution to this problem already
that my lack of understanding of Nouveau prevents me from seeing.
That's why your thoughts on this matter would be greatly appreciated.

Thanks,
Alex.

^ permalink raw reply	[flat|nested] 40+ 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
                   ` (15 preceding siblings ...)
  2014-02-01  3:16 ` [RFC 16/16] drm/nouveau: support for probing GK20A Alexandre Courbot
@ 2014-02-02 19:10 ` Ilia Mirkin
  2014-02-03  2:44   ` Alexandre Courbot
  2014-02-03 11:25 ` David Herrmann
                   ` (2 subsequent siblings)
  19 siblings, 1 reply; 40+ messages in thread
From: Ilia Mirkin @ 2014-02-02 19:10 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, Terje Bergstrom,
	Ken Adams

Hi Alexandre,

On Fri, Jan 31, 2014 at 10:16 PM, Alexandre Courbot <acourbot@nvidia.com> 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] 40+ messages in thread

* Re: [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)
  2014-02-02 19:10 ` [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Ilia Mirkin
@ 2014-02-03  2:44   ` Alexandre Courbot
  2014-02-03  3:14     ` Ilia Mirkin
  0 siblings, 1 reply; 40+ messages in thread
From: Alexandre Courbot @ 2014-02-03  2:44 UTC (permalink / raw)
  To: Ilia Mirkin
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, Terje Bergstrom,
	Ken Adams

On 02/03/2014 04:10 AM, Ilia Mirkin wrote:
> Hi Alexandre,
>
> On Fri, Jan 31, 2014 at 10:16 PM, Alexandre Courbot <acourbot@nvidia.com> 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!

Thanks! ^_^v

One beginner question: is it appropriate to send kernel patches to the 
nouveau list in addition to dri-devel? The moderation messages I receive 
make me think that this list might rather be intended for general 
discussion.

>  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.]

We are still testing things at libdrm level, but are eventually 
interested in bringing up the existing open-source stack. Our guess (and 
hope) is that it will work nicely almost as-is, minus the fact that the 
display hardware is not handled by Nouveau and we only support render 
nodes (I have yet to look at what the state of render nodes in Mesa is).

For X, Thierry is IIUC working on the display driver, and at some point 
these efforts should join to connect tegradrm and Nouveau using PRIME. 
We are not quite there yet, and since we are working with limited 
resources it will likely require some time, but the fact we could bring 
up a (seemingly) working Nouveau kernel driver with so little code is 
encouraging.

Thanks,
Alex.


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)
  2014-02-03  2:44   ` Alexandre Courbot
@ 2014-02-03  3:14     ` Ilia Mirkin
  2014-02-03  3:41       ` Ben Skeggs
  0 siblings, 1 reply; 40+ messages in thread
From: Ilia Mirkin @ 2014-02-03  3:14 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, Terje Bergstrom,
	Ken Adams

On Sun, Feb 2, 2014 at 9:44 PM, Alexandre Courbot <acourbot@nvidia.com> wrote:
> One beginner question: is it appropriate to send kernel patches to the
> nouveau list in addition to dri-devel? The moderation messages I receive
> make me think that this list might rather be intended for general
> discussion.

I usually do. The main thing is to make sure that they're To: Ben,
since he's the one who will be ultimately be picking them up. I think
that if you're not subscribed, all the lists.freedesktop.org lists
moderate you, but dri-devel is configured not to tell you about it.
Also I've been getting bounce messages from nouveau@ complaining of
too many cc's and so it's getting auto-moderated -- not sure who, if
anyone, is an admin of the nouveau list. Hopefully someone :)

  -ilia

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)
  2014-02-03  3:14     ` Ilia Mirkin
@ 2014-02-03  3:41       ` Ben Skeggs
  0 siblings, 0 replies; 40+ messages in thread
From: Ben Skeggs @ 2014-02-03  3:41 UTC (permalink / raw)
  To: Ilia Mirkin
  Cc: Alexandre Courbot, Alexandre Courbot, Eric Brower,
	Stephen Warren, nouveau, linux-kernel, dri-devel, Ben Skeggs,
	linux-tegra, Terje Bergstrom, Ken Adams

On Mon, Feb 3, 2014 at 1:14 PM, Ilia Mirkin <imirkin@alum.mit.edu> wrote:
> On Sun, Feb 2, 2014 at 9:44 PM, Alexandre Courbot <acourbot@nvidia.com> wrote:
>> One beginner question: is it appropriate to send kernel patches to the
>> nouveau list in addition to dri-devel? The moderation messages I receive
>> make me think that this list might rather be intended for general
>> discussion.
>
> I usually do. The main thing is to make sure that they're To: Ben,
> since he's the one who will be ultimately be picking them up. I think
> that if you're not subscribed, all the lists.freedesktop.org lists
> moderate you, but dri-devel is configured not to tell you about it.
> Also I've been getting bounce messages from nouveau@ complaining of
> too many cc's and so it's getting auto-moderated -- not sure who, if
> anyone, is an admin of the nouveau list. Hopefully someone :)
The Nouveau list seems the most appropriate.  There's not really any
need to explicitly CC me either, I do watch the list :)

>
>   -ilia
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 40+ 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
                   ` (16 preceding siblings ...)
  2014-02-02 19:10 ` [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Ilia Mirkin
@ 2014-02-03 11:25 ` David Herrmann
  2014-02-04  2:47   ` Alexandre Courbot
  2014-02-03 17:33 ` Daniel Vetter
  2014-02-04  3:53 ` Ben Skeggs
  19 siblings, 1 reply; 40+ messages in thread
From: David Herrmann @ 2014-02-03 11:25 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Ben Skeggs, nouveau, dri-devel, 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] 40+ 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
                   ` (17 preceding siblings ...)
  2014-02-03 11:25 ` David Herrmann
@ 2014-02-03 17:33 ` Daniel Vetter
  2014-02-04  3:53 ` Ben Skeggs
  19 siblings, 0 replies; 40+ 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, Eric Brower,
	Stephen Warren, Linux Kernel Mailing List, linux-tegra,
	Terje Bergstrom, Ken Adams

On Sat, Feb 1, 2014 at 4:16 AM, Alexandre Courbot <acourbot@nvidia.com> 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] 40+ messages in thread

* Re: [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)
  2014-02-03 11:25 ` David Herrmann
@ 2014-02-04  2:47   ` Alexandre Courbot
  0 siblings, 0 replies; 40+ messages in thread
From: Alexandre Courbot @ 2014-02-04  2:47 UTC (permalink / raw)
  To: David Herrmann
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, Terje Bergstrom,
	Ken Adams

On 02/03/2014 08:25 PM, David Herrmann wrote:
> 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).

Actually my mention of /dev/dri/cardX was misleading. I was rather 
thinking about getting rid of the DRIVER_MODESET flag to correctly 
expose what the card provides, not only to user-space, but to DRM 
itself. The legacy node is ok as long as DRM itself correctly knows what 
the driver can and cannot do and fails gracefully if the user tries to 
set a mode.

DRIVER_MODESET is statically set in nouveau_drm.c, and the reason why I 
cannot get rid of it is because the driver (and its features) is 
registered with drm_pci_init() before the card is probed and its actual 
features known.

For platform devices, you could check the card features before 
registering it with drm_platform_init(), but then you have the issue 
that the driver instance is referenced by every probed card, and thus 
you cannot have cards with different capabilities.

So it seems like handling this would require the driver_features to move 
from drm_driver to drm_device, but that's quite a core change. As 
pointed out by you and Daniel, we can certainly live with the control 
and legacy nodes. Nonetheless I'd be curious to know how (and if) this 
case can be correctly handled.

Alex.


^ permalink raw reply	[flat|nested] 40+ 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
                   ` (18 preceding siblings ...)
  2014-02-03 17:33 ` Daniel Vetter
@ 2014-02-04  3:53 ` Ben Skeggs
  2014-02-04  8:44   ` Alexandre Courbot
  19 siblings, 1 reply; 40+ messages in thread
From: Ben Skeggs @ 2014-02-04  3:53 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, Terje Bergstrom,
	Ken Adams

On Sat, Feb 1, 2014 at 1:16 PM, Alexandre Courbot <acourbot@nvidia.com> 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@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 40+ 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
  2014-02-04  8:31     ` Alexandre Courbot
  0 siblings, 1 reply; 40+ messages in thread
From: Ben Skeggs @ 2014-02-04  3:54 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, 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] 40+ 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; 40+ messages in thread
From: Ben Skeggs @ 2014-02-04  3:55 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, 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] 40+ messages in thread

* Re: [RFC 07/16] drm/nouveau/bar/nvc0: support chips without BAR3
  2014-02-04  3:54   ` Ben Skeggs
@ 2014-02-04  8:31     ` Alexandre Courbot
  0 siblings, 0 replies; 40+ messages in thread
From: Alexandre Courbot @ 2014-02-04  8:31 UTC (permalink / raw)
  To: Ben Skeggs
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, Terje Bergstrom,
	Ken Adams

On 02/04/2014 12:54 PM, Ben Skeggs wrote:
> 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.

You're right, this test is not needed at all. Thanks.

^ permalink raw reply	[flat|nested] 40+ 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; 40+ messages in thread
From: Alexandre Courbot @ 2014-02-04  8:39 UTC (permalink / raw)
  To: Ben Skeggs
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, 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] 40+ messages in thread

* Re: [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)
  2014-02-04  3:53 ` Ben Skeggs
@ 2014-02-04  8:44   ` Alexandre Courbot
  0 siblings, 0 replies; 40+ messages in thread
From: Alexandre Courbot @ 2014-02-04  8:44 UTC (permalink / raw)
  To: Ben Skeggs
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, Terje Bergstrom,
	Ken Adams

On 02/04/2014 12:53 PM, Ben Skeggs wrote:
> On Sat, Feb 1, 2014 at 1:16 PM, Alexandre Courbot <acourbot@nvidia.com> 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.

Thanks for the review and the welcome. The first part (infrastructure 
changes to support platform devices) has not really been commented yet. 
If this means it is already in acceptable shape, I propose to re-submit 
it separately so it can be merged ahead of the rest. Let me know if you 
would like us to generalize the use of the bus abstraction functions 
throughout the driver.

For the actual GK20A support, what worries me the most is the memory 
model, and my very incomplete understanding of how Nouveau manages 
memory doesn't help here. I hope to get some more feedback about it and 
see if we can fit somewhere before attempting broader changes.

Thanks!
Alex.


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC 12/16] drm/nouveau/fifo: add GK20A support
  2014-02-01  3:16 ` [RFC 12/16] drm/nouveau/fifo: add GK20A support Alexandre Courbot
@ 2014-02-04  9:15   ` Daniel Vetter
  2014-02-05  1:21     ` Alexandre Courbot
  0 siblings, 1 reply; 40+ messages in thread
From: Daniel Vetter @ 2014-02-04  9:15 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Ben Skeggs, nouveau, dri-devel, gnurou, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, Terje Bergstrom,
	Ken Adams

On Sat, Feb 01, 2014 at 12:16:54PM +0900, Alexandre Courbot wrote:
> GK20A's FIFO is compatible with NVE0, but only features 128 channels and
> 1 runlist.
> 
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> ---
>  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.

Just stumbled over this lincense header: Generally drm is mit/gpl dual
lincensed. The important part for me is the drm core, but due to all the
refactoring we tend to do and code extraction from drivers those are
rather relevant imo, too. Was this just an oversight or are you still
working with your legap people on this?
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [RFC 12/16] drm/nouveau/fifo: add GK20A support
  2014-02-04  9:15   ` Daniel Vetter
@ 2014-02-05  1:21     ` Alexandre Courbot
  0 siblings, 0 replies; 40+ messages in thread
From: Alexandre Courbot @ 2014-02-05  1:21 UTC (permalink / raw)
  To: Ben Skeggs, nouveau, dri-devel, gnurou, Eric Brower,
	Stephen Warren, linux-kernel, linux-tegra, Terje Bergstrom,
	Ken Adams

Hi Daniel,

On 02/04/2014 06:15 PM, Daniel Vetter wrote:
> On Sat, Feb 01, 2014 at 12:16:54PM +0900, Alexandre Courbot wrote:
>> GK20A's FIFO is compatible with NVE0, but only features 128 channels and
>> 1 runlist.
>>
>> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
>> ---
>>   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.
>
> Just stumbled over this lincense header: Generally drm is mit/gpl dual
> lincensed. The important part for me is the drm core, but due to all the
> refactoring we tend to do and code extraction from drivers those are
> rather relevant imo, too. Was this just an oversight or are you still
> working with your legap people on this?

Thanks for pointing this out. This was an oversight on my part indeed. 
The following revisions will use the correct MIT copyright header.

In case someone wants to contribute significant fixes to this patchset, 
please be aware that MIT is the license that will apply from now on.

Thanks,
Alex.


^ permalink raw reply	[flat|nested] 40+ 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; 40+ messages in thread
From: Stephen Warren @ 2014-02-05 20:27 UTC (permalink / raw)
  To: Alexandre Courbot, Ben Skeggs
  Cc: Ben Skeggs, nouveau, dri-devel, Alexandre Courbot, Eric Brower,
	linux-kernel, linux-tegra, 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] 40+ messages in thread

* Re: [RFC 14/16] drm/nouveau/fb: add GK20A support
  2014-02-02 13:43         ` Alexandre Courbot
@ 2014-02-07 14:19           ` Alexandre Courbot
  0 siblings, 0 replies; 40+ messages in thread
From: Alexandre Courbot @ 2014-02-07 14:19 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Ilia Mirkin, Alexandre Courbot, Ben Skeggs, nouveau, dri-devel,
	Eric Brower, Stephen Warren, linux-kernel, linux-tegra,
	Terje Bergstrom, Ken Adams

On Sun, Feb 2, 2014 at 10:43 PM, Alexandre Courbot <gnurou@gmail.com> wrote:
> On Sun, Feb 2, 2014 at 8:58 AM, Lucas Stach <dev@lynxeye.de> wrote:
>> Am Samstag, den 01.02.2014, 18:28 -0500 schrieb Ilia Mirkin:
>>> On Sat, Feb 1, 2014 at 8:40 AM, Lucas Stach <dev@lynxeye.de> wrote:
>>> > Am Samstag, den 01.02.2014, 12:16 +0900 schrieb Alexandre Courbot:
>>> >> 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.
>>> >>
>>> > I don't know if Tegra124 is similar to 114 in this regard [hint: get the
>>> > TRM out :)], but if you go for a dedicated VRAM allocator, wouldn't it
>>> > make sense to take a chunk of the MMIO overlaid memory for this when
>>> > possible, rather than carving this out of CPU accessible mem?
>>>
>>> This is probably a stupid question... what do you need VRAM for
>>> anyways? In _theory_ it's an abstraction to talk about memory that's
>>> not accessible by the CPU. This is obviously not the case here, and
>>> presumably the GPU can access all the memory in the system, so it can
>>> be all treated as "GART" memory... AFAIK all accesses are behind the
>>> in-GPU MMU, so contiguous physical memory isn't an issue either. In
>>> practice, I suspect nouveau automatically sticks certain things into
>>> vram (gpuobj's), but it should be feasible to make them optionally use
>>> GART memory when VRAM is not available. I haven't really looked at the
>>> details though, perhaps that's a major undertaking.
>>>
>>>   -ilia
>>>
>> If it's similar to the Tegar114 there actually is memory that isn't
>> accessible from the CPU. About 2GB of the address space is overlaid with
>> MMIO for the devices, so in a 4GB system you potentially have 2GB of RAM
>> that's only visible for the devices.
>>
>> But yes in general nouveau should just fall back to a GART placement if
>> VRAM isn't available.
>
> With the limited time I spent studying it, it seems to me that Nouveau
> has a strong dependency on VRAM. For gpuobjects indeed (that one could
> be workarounded with a new instmem driver I suppose), and also for
> TTM: objects placed in TTM_PL_VRAM are handled by the VRAM manager,
> which requires a nouveau_ram instance in the FB. Actually the FB also
> seems to assume the presence of a dedicated video RAM.
>
> So while I agree that getting rid of VRAM altogether would be the most
> logical solution, I have not found a way to do so for the moment.
>
> T124's GPU actually sees the same physical address space as the CPU,
> so memory management should be simplified thanks to that (you could
> enable the SMMU and make things more interesting/complex, but for now
> it seems untimely to even consider doing so). Actually even the
> concept of a GART is not needed here: all your memory management needs
> could be fulfilled by getting pages with alloc_page() and arranging
> them using the GMMU. No GART, no BAR (at least for the purpose of
> mapping objects for CPU access), no PRAMIN.

So, looking at the code more closely I noticed the nouveau_ram::get()
operation was only used by instmem (to allocate GPU objects) and TTM
(for BOs in VRAM).

I quickly wrote a custom instmem that allocates objects individually
with dma_alloc_coherent() (and manually builds a nouveau_mem instance
so they can be mapped into the BAR) and disabled nouveau_vram_manager
for TTM, making TTM_PL_VRAM BOs use the GART manager. And oooh, it
seems to work! :) I can remove that horrible CMA allocation and only
keep the nouveau_ram instance as a dummy object providing 0MB of
memory.

I think this should be a viable solution, BOs never need to be
contiguous thanks to the gMMU, and dma_alloc_coherent() returns
contiguous memory for instobjs (not sure if *all* instobjs need to be
contiguous in physical memory - page tables sure do - , but AFAICT we
never allocate crazy-big instobjs).

Any flaw/possible improvement with this design?

Alex.

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2014-02-07 14:20 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [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 ` [RFC 05/16] drm/nouveau/bar: " Alexandre Courbot
2014-02-01  3:16 ` [RFC 06/16] drm/nouveau/bar: only ioremap BAR3 if it exists Alexandre Courbot
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
2014-02-04  8:31     ` Alexandre Courbot
2014-02-01  3:16 ` [RFC 08/16] drm/nouveau/mc: support platform devices Alexandre Courbot
2014-02-01  3:16 ` [RFC 09/16] drm/nouveau/fb: " Alexandre Courbot
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
2014-02-05 20:27       ` Stephen Warren
2014-02-01  3:16 ` [RFC 11/16] drm/nouveau/fifo: allocate usermem as needed Alexandre Courbot
2014-02-01  3:16 ` [RFC 12/16] drm/nouveau/fifo: add GK20A support Alexandre Courbot
2014-02-04  9:15   ` Daniel Vetter
2014-02-05  1:21     ` Alexandre Courbot
2014-02-01  3:16 ` [RFC 13/16] drm/nouveau/ibus: " Alexandre Courbot
2014-02-02  6:35   ` Ilia Mirkin
2014-02-02  9:38     ` Alexandre Courbot
2014-02-01  3:16 ` [RFC 14/16] drm/nouveau/fb: " Alexandre Courbot
2014-02-01 13:40   ` Lucas Stach
2014-02-01 23:28     ` Ilia Mirkin
2014-02-01 23:58       ` Lucas Stach
2014-02-02 13:43         ` Alexandre Courbot
2014-02-07 14:19           ` Alexandre Courbot
2014-02-01  3:16 ` [RFC 15/16] drm/nouveau: support GK20A in nouveau_accel_init() Alexandre Courbot
2014-02-01  3:16 ` [RFC 16/16] drm/nouveau: support for probing GK20A Alexandre Courbot
2014-02-02 19:10 ` [RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1) Ilia Mirkin
2014-02-03  2:44   ` Alexandre Courbot
2014-02-03  3:14     ` Ilia Mirkin
2014-02-03  3:41       ` Ben Skeggs
2014-02-03 11:25 ` David Herrmann
2014-02-04  2:47   ` Alexandre Courbot
2014-02-03 17:33 ` Daniel Vetter
2014-02-04  3:53 ` Ben Skeggs
2014-02-04  8:44   ` Alexandre Courbot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).