Skip to content

Commit

Permalink
Merge branch 'linux-4.1' of git://anongit.freedesktop.org/git/nouveau…
Browse files Browse the repository at this point in the history
…/linux-2.6 into drm-next

- gk20a iommu support
- gm107 graphics support without needing proprietary ucode
- various random fixes
- more gm20x bring-up, fifo/ce are ok, gr is mostly complete with the
exception of ctxsw ucode.. nvidia aren't playing nice yet so there's
not much more that can be done at this point...

I spent a lot of time trying to find a viable way of doing gr ctxsw
without signed firmware, but the "security" restrictions on the
fecs/gpccs falcons are excessive and go beyond what'd be necessary to
protect the host from malicious firmware.  This newer nvidia hw is
VERY open-source unfriendly.

I have some experimental host-based ctxsw work that could be a viable
(albeit unsatisfactory and slow) workaround in the meantime, but it
needs some more work and i'd like to get the 3d driver working
properly before i commit to pushing it.

* 'linux-4.1' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (40 commits)
  drm/nouveau/bios: fix fetching from acpi on certain systems
  drm/nouveau/gr/gm206: initial init+ctx code
  drm/nouveau/ce/gm206: enable support via gm204 code
  drm/nouveau/fifo/gm206: enable support via gm204 code
  drm/nouveau/gr/gm204: initial init+ctx code
  drm/nouveau: support for buffer moves via MaxwellDmaCopyA
  drm/nouveau/ce/gm204: initial support
  drm/nouveau: add support for gm20x fifo channels
  drm/nouveau/fifo/gm204: initial support
  drm/nouveau/gr/gk104-: prevent reading non-existent regs in intr handler
  drm/nouveau/gr/gm107: very slightly demagic part of attrib cb setup
  drm/nouveau/gr/gk104-: correct crop/zrop num_active_fbps setting
  drm/nouveau/gr/gf100-: add symbolic names for classes
  drm/nouveau/gr/gm107: support tpc "strand" ctxsw in gpccs ucode
  drm/nouveau/gr/gf100-: support mmio access with gpc offset from gpccs ucode
  drm/nouveau/gr: fix engine name, cosmetic search+replace mistake
  drm/nouveau/pmu/gk20a: add some missing statics
  drm/nouveau/platform: fix probe error path
  drm/nouveau/platform: release IOMMU's mm upon exit
  drm/nouveau/gr/gk104-gk20a: call pmu to disable any power-gating before ctor()
  ...
  • Loading branch information
Dave Airlie committed Apr 15, 2015
2 parents 1d2add2 + 4195f40 commit 665ae58
Show file tree
Hide file tree
Showing 75 changed files with 3,957 additions and 1,314 deletions.
10 changes: 10 additions & 0 deletions drivers/gpu/drm/nouveau/include/nvif/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
#define NV_DMA_TO_MEMORY 0x00000003
#define NV_DMA_IN_MEMORY 0x0000003d

#define FERMI_TWOD_A 0x0000902d

#define FERMI_MEMORY_TO_MEMORY_FORMAT_A 0x0000903d

#define KEPLER_INLINE_TO_MEMORY_A 0x0000a040
#define KEPLER_INLINE_TO_MEMORY_B 0x0000a140

#define NV04_DISP 0x00000046

#define NV03_CHANNEL_DMA 0x0000006b
Expand All @@ -25,6 +32,7 @@
#define G82_CHANNEL_GPFIFO 0x0000826f
#define FERMI_CHANNEL_GPFIFO 0x0000906f
#define KEPLER_CHANNEL_GPFIFO_A 0x0000a06f
#define MAXWELL_CHANNEL_GPFIFO_A 0x0000b06f

#define NV50_DISP 0x00005070
#define G82_DISP 0x00008270
Expand Down Expand Up @@ -84,6 +92,7 @@
#define KEPLER_C 0x0000a297

#define MAXWELL_A 0x0000b097
#define MAXWELL_B 0x0000b197

#define FERMI_COMPUTE_A 0x000090c0
#define FERMI_COMPUTE_B 0x000091c0
Expand All @@ -92,6 +101,7 @@
#define KEPLER_COMPUTE_B 0x0000a1c0

#define MAXWELL_COMPUTE_A 0x0000b0c0
#define MAXWELL_COMPUTE_B 0x0000b1c0


/*******************************************************************************
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ extern struct nvkm_oclass gf100_ce1_oclass;
extern struct nvkm_oclass gk104_ce0_oclass;
extern struct nvkm_oclass gk104_ce1_oclass;
extern struct nvkm_oclass gk104_ce2_oclass;
extern struct nvkm_oclass gm204_ce0_oclass;
extern struct nvkm_oclass gm204_ce1_oclass;
extern struct nvkm_oclass gm204_ce2_oclass;
#endif
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ extern struct nvkm_oclass *gf100_fifo_oclass;
extern struct nvkm_oclass *gk104_fifo_oclass;
extern struct nvkm_oclass *gk20a_fifo_oclass;
extern struct nvkm_oclass *gk208_fifo_oclass;
extern struct nvkm_oclass *gm204_fifo_oclass;

int nvkm_fifo_uevent_ctor(struct nvkm_object *, void *, u32,
struct nvkm_notify *);
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/nouveau/include/nvkm/engine/gr.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ nvkm_gr(void *obj)
}

#define nvkm_gr_create(p,e,c,y,d) \
nvkm_engine_create((p), (e), (c), (y), "PGR", "graphics", (d))
nvkm_engine_create((p), (e), (c), (y), "PGRAPH", "graphics", (d))
#define nvkm_gr_destroy(d) \
nvkm_engine_destroy(&(d)->base)
#define nvkm_gr_init(d) \
Expand Down Expand Up @@ -72,6 +72,8 @@ extern struct nvkm_oclass *gk110_gr_oclass;
extern struct nvkm_oclass *gk110b_gr_oclass;
extern struct nvkm_oclass *gk208_gr_oclass;
extern struct nvkm_oclass *gm107_gr_oclass;
extern struct nvkm_oclass *gm204_gr_oclass;
extern struct nvkm_oclass *gm206_gr_oclass;

#include <core/enum.h>

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ nvkm_instmem(void *obj)
extern struct nvkm_oclass *nv04_instmem_oclass;
extern struct nvkm_oclass *nv40_instmem_oclass;
extern struct nvkm_oclass *nv50_instmem_oclass;
extern struct nvkm_oclass *gk20a_instmem_oclass;
#endif
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extern struct nvkm_oclass *gt215_pmu_oclass;
extern struct nvkm_oclass *gf100_pmu_oclass;
extern struct nvkm_oclass *gf110_pmu_oclass;
extern struct nvkm_oclass *gk104_pmu_oclass;
extern struct nvkm_oclass *gk110_pmu_oclass;
extern struct nvkm_oclass *gk208_pmu_oclass;
extern struct nvkm_oclass *gk20a_pmu_oclass;

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_bo.c
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,8 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
struct ttm_mem_reg *, struct ttm_mem_reg *);
int (*init)(struct nouveau_channel *, u32 handle);
} _methods[] = {
{ "COPY", 4, 0xb0b5, nve0_bo_move_copy, nve0_bo_move_init },
{ "GRCE", 0, 0xb0b5, nve0_bo_move_copy, nvc0_bo_move_init },
{ "COPY", 4, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
{ "GRCE", 0, 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init },
{ "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_move_init },
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/nouveau/nouveau_chan.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ static int
nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
u32 handle, u32 engine, struct nouveau_channel **pchan)
{
static const u16 oclasses[] = { KEPLER_CHANNEL_GPFIFO_A,
static const u16 oclasses[] = { MAXWELL_CHANNEL_GPFIFO_A,
KEPLER_CHANNEL_GPFIFO_A,
FERMI_CHANNEL_GPFIFO,
G82_CHANNEL_GPFIFO,
NV50_CHANNEL_GPFIFO,
Expand Down
9 changes: 8 additions & 1 deletion drivers/gpu/drm/nouveau/nouveau_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -869,13 +869,20 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
struct drm_mode_create_dumb *args)
{
struct nouveau_bo *bo;
uint32_t domain;
int ret;

args->pitch = roundup(args->width * (args->bpp / 8), 256);
args->size = args->pitch * args->height;
args->size = roundup(args->size, PAGE_SIZE);

ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo);
/* Use VRAM if there is any ; otherwise fallback to system memory */
if (nouveau_drm(dev)->device.info.ram_size != 0)
domain = NOUVEAU_GEM_DOMAIN_VRAM;
else
domain = NOUVEAU_GEM_DOMAIN_GART;

ret = nouveau_gem_new(dev, args->size, 0, domain, 0, 0, &bo);
if (ret)
return ret;

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nouveau_drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
break;
case FERMI_CHANNEL_GPFIFO:
case KEPLER_CHANNEL_GPFIFO_A:
case MAXWELL_CHANNEL_GPFIFO_A:
ret = nvc0_fence_create(drm);
break;
default:
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/nouveau/nouveau_drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

#define DRIVER_MAJOR 1
#define DRIVER_MINOR 2
#define DRIVER_PATCHLEVEL 1
#define DRIVER_PATCHLEVEL 2

/*
* 1.1.1:
Expand All @@ -28,6 +28,8 @@
* - fermi,kepler,maxwell zbc
* 1.2.1:
* - allow concurrent access to bo's mapped read/write.
* 1.2.2:
* - add NOUVEAU_GEM_DOMAIN_COHERENT flag
*/

#include <nvif/client.h>
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ nouveau_gem_new(struct drm_device *dev, int size, int align, uint32_t domain,
if (!flags || domain & NOUVEAU_GEM_DOMAIN_CPU)
flags |= TTM_PL_FLAG_SYSTEM;

if (domain & NOUVEAU_GEM_DOMAIN_COHERENT)
flags |= TTM_PL_FLAG_UNCACHED;

ret = nouveau_bo_new(dev, size, align, flags, tile_mode,
tile_flags, NULL, NULL, pnvbo);
if (ret)
Expand Down
79 changes: 76 additions & 3 deletions drivers/gpu/drm/nouveau/nouveau_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/of.h>
#include <linux/reset.h>
#include <linux/regulator/consumer.h>
#include <linux/iommu.h>
#include <soc/tegra/fuse.h>
#include <soc/tegra/pmc.h>

Expand Down Expand Up @@ -91,6 +92,72 @@ static int nouveau_platform_power_down(struct nouveau_platform_gpu *gpu)
return 0;
}

static void nouveau_platform_probe_iommu(struct device *dev,
struct nouveau_platform_gpu *gpu)
{
int err;
unsigned long pgsize_bitmap;

mutex_init(&gpu->iommu.mutex);

if (iommu_present(&platform_bus_type)) {
gpu->iommu.domain = iommu_domain_alloc(&platform_bus_type);
if (IS_ERR(gpu->iommu.domain))
goto error;

/*
* A IOMMU is only usable if it supports page sizes smaller
* or equal to the system's PAGE_SIZE, with a preference if
* both are equal.
*/
pgsize_bitmap = gpu->iommu.domain->ops->pgsize_bitmap;
if (pgsize_bitmap & PAGE_SIZE) {
gpu->iommu.pgshift = PAGE_SHIFT;
} else {
gpu->iommu.pgshift = fls(pgsize_bitmap & ~PAGE_MASK);
if (gpu->iommu.pgshift == 0) {
dev_warn(dev, "unsupported IOMMU page size\n");
goto free_domain;
}
gpu->iommu.pgshift -= 1;
}

err = iommu_attach_device(gpu->iommu.domain, dev);
if (err)
goto free_domain;

err = nvkm_mm_init(&gpu->iommu._mm, 0,
(1ULL << 40) >> gpu->iommu.pgshift, 1);
if (err)
goto detach_device;

gpu->iommu.mm = &gpu->iommu._mm;
}

return;

detach_device:
iommu_detach_device(gpu->iommu.domain, dev);

free_domain:
iommu_domain_free(gpu->iommu.domain);

error:
gpu->iommu.domain = NULL;
gpu->iommu.pgshift = 0;
dev_err(dev, "cannot initialize IOMMU MM\n");
}

static void nouveau_platform_remove_iommu(struct device *dev,
struct nouveau_platform_gpu *gpu)
{
if (gpu->iommu.domain) {
nvkm_mm_fini(&gpu->iommu._mm);
iommu_detach_device(gpu->iommu.domain, dev);
iommu_domain_free(gpu->iommu.domain);
}
}

static int nouveau_platform_probe(struct platform_device *pdev)
{
struct nouveau_platform_gpu *gpu;
Expand Down Expand Up @@ -118,6 +185,8 @@ static int nouveau_platform_probe(struct platform_device *pdev)
if (IS_ERR(gpu->clk_pwr))
return PTR_ERR(gpu->clk_pwr);

nouveau_platform_probe_iommu(&pdev->dev, gpu);

err = nouveau_platform_power_up(gpu);
if (err)
return err;
Expand All @@ -140,10 +209,9 @@ static int nouveau_platform_probe(struct platform_device *pdev)
err_unref:
drm_dev_unref(drm);

return 0;

power_down:
nouveau_platform_power_down(gpu);
nouveau_platform_remove_iommu(&pdev->dev, gpu);

return err;
}
Expand All @@ -154,10 +222,15 @@ static int nouveau_platform_remove(struct platform_device *pdev)
struct nouveau_drm *drm = nouveau_drm(drm_dev);
struct nvkm_device *device = nvxx_device(&drm->device);
struct nouveau_platform_gpu *gpu = nv_device_to_platform(device)->gpu;
int err;

nouveau_drm_device_remove(drm_dev);

return nouveau_platform_power_down(gpu);
err = nouveau_platform_power_down(gpu);

nouveau_platform_remove_iommu(&pdev->dev, gpu);

return err;
}

#if IS_ENABLED(CONFIG_OF)
Expand Down
18 changes: 18 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
#define __NOUVEAU_PLATFORM_H__

#include "core/device.h"
#include "core/mm.h"

struct reset_control;
struct clk;
struct regulator;
struct iommu_domain;
struct platform_driver;

struct nouveau_platform_gpu {
Expand All @@ -36,6 +38,22 @@ struct nouveau_platform_gpu {
struct clk *clk_pwr;

struct regulator *vdd;

struct {
/*
* Protects accesses to mm from subsystems
*/
struct mutex mutex;

struct nvkm_mm _mm;
/*
* Just points to _mm. We need this to avoid embedding
* struct nvkm_mm in os.h
*/
struct nvkm_mm *mm;
struct iommu_domain *domain;
unsigned long pgshift;
} iommu;
};

struct nouveau_platform_device {
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/nouveau/nouveau_ttm.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
u32 size_nc = 0;
int ret;

if (drm->device.info.ram_size == 0)
return -ENOMEM;

if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG)
size_nc = 1 << nvbo->page_shift;

Expand Down
14 changes: 11 additions & 3 deletions drivers/gpu/drm/nouveau/nv84_fence.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ nv84_fence_create(struct nouveau_drm *drm)
{
struct nvkm_fifo *pfifo = nvxx_fifo(&drm->device);
struct nv84_fence_priv *priv;
u32 domain;
int ret;

priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL);
Expand All @@ -231,10 +232,17 @@ nv84_fence_create(struct nouveau_drm *drm)
priv->base.context_base = fence_context_alloc(priv->base.contexts);
priv->base.uevent = true;

ret = nouveau_bo_new(drm->dev, 16 * priv->base.contexts, 0,
TTM_PL_FLAG_VRAM, 0, 0, NULL, NULL, &priv->bo);
/* Use VRAM if there is any ; otherwise fallback to system memory */
domain = drm->device.info.ram_size != 0 ? TTM_PL_FLAG_VRAM :
/*
* fences created in sysmem must be non-cached or we
* will lose CPU/GPU coherency!
*/
TTM_PL_FLAG_TT | TTM_PL_FLAG_UNCACHED;
ret = nouveau_bo_new(drm->dev, 16 * priv->base.contexts, 0, domain, 0,
0, NULL, NULL, &priv->bo);
if (ret == 0) {
ret = nouveau_bo_pin(priv->bo, TTM_PL_FLAG_VRAM, false);
ret = nouveau_bo_pin(priv->bo, domain, false);
if (ret == 0) {
ret = nouveau_bo_map(priv->bo);
if (ret)
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/nvkm/engine/ce/Kbuild
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
nvkm-y += nvkm/engine/ce/gt215.o
nvkm-y += nvkm/engine/ce/gf100.o
nvkm-y += nvkm/engine/ce/gk104.o
nvkm-y += nvkm/engine/ce/gm204.o
Loading

0 comments on commit 665ae58

Please sign in to comment.