Quantcast

[RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)

classic Classic list List threaded Threaded
40 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 00/16] drm/nouveau: initial support for GK20A (Tegra K1)

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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 01/16] drm/nouveau: handle -EACCES runtime PM return code

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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 02/16] drm/nouveau: basic support for platform devices

Alexandre Courbot
In reply to this post by 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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 03/16] drm/nouveau: add platform device probing function

Alexandre Courbot
In reply to this post by 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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 04/16] drm/nouveau/fifo: support platform devices

Alexandre Courbot
In reply to this post by Alexandre Courbot
Remove PCI-dependent code so the FIFO engine can also handle platform
devices.

Signed-off-by: Alexandre Courbot <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 05/16] drm/nouveau/bar: support platform devices

Alexandre Courbot
In reply to this post by Alexandre Courbot
Remove PCI-dependent code so the BAR core can also handle platform
devices.

Signed-off-by: Alexandre Courbot <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 06/16] drm/nouveau/bar: only ioremap BAR3 if it exists

Alexandre Courbot
In reply to this post by 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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 07/16] drm/nouveau/bar/nvc0: support chips without BAR3

Alexandre Courbot
In reply to this post by 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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 08/16] drm/nouveau/mc: support platform devices

Alexandre Courbot
In reply to this post by Alexandre Courbot
Use abstracted resource query functions, and obtain the IRQ from the
correct bus.

Signed-off-by: Alexandre Courbot <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 09/16] drm/nouveau/fb: support platform devices

Alexandre Courbot
In reply to this post by Alexandre Courbot
Use abstracted resource query functions to allow FB core to handle
both PCI and platform devices.

Signed-off-by: Alexandre Courbot <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 10/16] drm/nouveau/timer: skip calibration on GK20A

Alexandre Courbot
In reply to this post by 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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 11/16] drm/nouveau/fifo: allocate usermem as needed

Alexandre Courbot
In reply to this post by 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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 12/16] drm/nouveau/fifo: add GK20A support

Alexandre Courbot
In reply to this post by Alexandre Courbot
GK20A's FIFO is compatible with NVE0, but only features 128 channels and
1 runlist.

Signed-off-by: Alexandre Courbot <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 13/16] drm/nouveau/ibus: add GK20A support

Alexandre Courbot
In reply to this post by 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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 14/16] drm/nouveau/fb: add GK20A support

Alexandre Courbot
In reply to this post by 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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 15/16] drm/nouveau: support GK20A in nouveau_accel_init()

Alexandre Courbot
In reply to this post by 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 <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[RFC 16/16] drm/nouveau: support for probing GK20A

Alexandre Courbot
In reply to this post by Alexandre Courbot
Set the correct subdev/engine classes when GK20A (0xea) is probed.

Signed-off-by: Alexandre Courbot <[hidden email]>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [RFC 14/16] drm/nouveau/fb: add GK20A support

Lucas Stach
In reply to this post by Alexandre Courbot
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 <[hidden email]>
> ---
>  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 [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [RFC 14/16] drm/nouveau/fb: add GK20A support

Ilia Mirkin-2
On Sat, Feb 1, 2014 at 8:40 AM, Lucas Stach <[hidden email]> 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 <[hidden email]>
>> ---
>>  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 [hidden email]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [RFC 14/16] drm/nouveau/fb: add GK20A support

Lucas Stach
Am Samstag, den 01.02.2014, 18:28 -0500 schrieb Ilia Mirkin:

> On Sat, Feb 1, 2014 at 8:40 AM, Lucas Stach <[hidden email]> 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 <[hidden email]>
> >> ---
> >>  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 [hidden email]
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [hidden email]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
12
Loading...