aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-11-03 00:42:59 -0500
committerDave Airlie <airlied@redhat.com>2015-11-03 00:42:59 -0500
commit1c431cb4615334fb81c0d1c0ede21aa4354c1187 (patch)
tree00ae8990f0b97e5842c11c73ec7a91505ffbcf54 /drivers/gpu
parentb4590047966ba35a626f947c3fee2c4ed7081685 (diff)
parent79ef5dca5e5cd5a33662d64c927c1b9786d4edee (diff)
Merge branch 'linux-4.4' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
- Vast improvements to gk20a instmem handling. - Improved PGOB detection + GK107 support. - Compatibility between old/new interfaces added, final missing piece to finally enabling userspace to start using them. - Kepler GDDR5 PLL stability improvements - Support for non-GPIO (PWM) voltage controllers - G8x/GT2xx memory clock improvements - Misc other fixes * 'linux-4.4' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (45 commits) drm/nouveau: bump patchlevel to indicate availability of abi16/nvif interop drm/nouveau/abi16: implement limited interoperability with usif/nvif drm/nouveau/abi16: introduce locked variant of nouveau_abi16_get() drm/nouveau/abi16: remove unused argument from nouveau_abi16_get() drm/nouveau/pci: enable c800 magic for Medion Erazer X7827 drm/nouveau/pci: enable c800 magic for Lenovo Y510P drm/nouveau/pll/gk104: fix PLL instability due to bad configuration with gddr5 drm/nouveau/clk/g84: Enable reclocking for GDDR3 G94-G200 drm/nouveau/bus/hwsq: Implement VBLANK waiting heuristic drm/nouveau/fb/ramnv50: Script changes for G94 and up drm/nouveau/fb/ramnv50: Deal with cards without timing entries drm/nouveau/fb/ramnv50: Voltage GPIOs drm/nouveau/fb/ramgt215: Restructure r111100 calculation for DDR2 drm/nouveau/fb/ramgt215: Change FBVDD/Q when BIOS asks for it drm/nouveau/fb/ramgt215: Transform GPIO ramfuc method from FBVREF-specific to generic drm/nouveau/bios/rammap: Identify DLLoff for >= GF100 drm/nouveau/pci: Handle 5-bit and 8-bit tag field drm/nouveau/disp,pm: constify nvkm_object_func structures drm/nouveau/gr: add FERMI_COMPUTE_B class to GF110+ drm/nouveau/gr: document mp error 0x10 ...
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/include/nvif/os.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h13
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h2
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h2
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h15
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h4
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h5
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h10
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c84
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.c30
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c15
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.h14
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c13
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_platform.c19
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sysfs.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.c31
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_usif.c15
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/base.c83
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv04.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/pmu.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c32
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c141
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c123
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c121
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c51
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/priv.h7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c371
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c32
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gk104.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c64
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c39
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c (renamed from drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv50.c)14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c119
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/priv.h6
73 files changed, 1312 insertions, 373 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvif/os.h b/drivers/gpu/drm/nouveau/include/nvif/os.h
index 3accc99d8e0b..9fcab67c8557 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/os.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/os.h
@@ -27,6 +27,7 @@
27#include <linux/agp_backend.h> 27#include <linux/agp_backend.h>
28#include <linux/reset.h> 28#include <linux/reset.h>
29#include <linux/iommu.h> 29#include <linux/iommu.h>
30#include <linux/of_device.h>
30 31
31#include <asm/unaligned.h> 32#include <asm/unaligned.h>
32 33
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
index 5aa2480da25f..16641cec18a2 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
@@ -4,6 +4,7 @@
4#include <core/mm.h> 4#include <core/mm.h>
5 5
6struct nvkm_device_tegra { 6struct nvkm_device_tegra {
7 const struct nvkm_device_tegra_func *func;
7 struct nvkm_device device; 8 struct nvkm_device device;
8 struct platform_device *pdev; 9 struct platform_device *pdev;
9 int irq; 10 int irq;
@@ -28,7 +29,17 @@ struct nvkm_device_tegra {
28 int gpu_speedo; 29 int gpu_speedo;
29}; 30};
30 31
31int nvkm_device_tegra_new(struct platform_device *, 32struct nvkm_device_tegra_func {
33 /*
34 * If an IOMMU is used, indicates which address bit will trigger a
35 * IOMMU translation when set (when this bit is not set, IOMMU is
36 * bypassed). A value of 0 means an IOMMU is never used.
37 */
38 u8 iommu_bit;
39};
40
41int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *,
42 struct platform_device *,
32 const char *cfg, const char *dbg, 43 const char *cfg, const char *dbg,
33 bool detect, bool mmio, u64 subdev_mask, 44 bool detect, bool mmio, u64 subdev_mask,
34 struct nvkm_device **); 45 struct nvkm_device **);
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
index 33be260ddd38..a47d46dda704 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/gpio.h
@@ -15,6 +15,7 @@ enum dcb_gpio_func_name {
15 DCB_GPIO_VID5 = 0x74, 15 DCB_GPIO_VID5 = 0x74,
16 DCB_GPIO_VID6 = 0x75, 16 DCB_GPIO_VID6 = 0x75,
17 DCB_GPIO_VID7 = 0x76, 17 DCB_GPIO_VID7 = 0x76,
18 DCB_GPIO_VID_PWM = 0x81,
18}; 19};
19 20
20#define DCB_GPIO_LOG_DIR 0x02 21#define DCB_GPIO_LOG_DIR 0x02
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h
index d606875c125a..3a643df6de04 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/pmu.h
@@ -4,8 +4,6 @@ struct nvbios_pmuT {
4}; 4};
5 5
6u32 nvbios_pmuTe(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); 6u32 nvbios_pmuTe(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
7u32 nvbios_pmuTp(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
8 struct nvbios_pmuT *);
9 7
10struct nvbios_pmuE { 8struct nvbios_pmuE {
11 u8 type; 9 u8 type;
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
index 3a9abd38aca8..dca6c060a24f 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/ramcfg.h
@@ -39,6 +39,7 @@ struct nvbios_ramcfg {
39 unsigned ramcfg_timing; 39 unsigned ramcfg_timing;
40 unsigned ramcfg_DLLoff; 40 unsigned ramcfg_DLLoff;
41 unsigned ramcfg_RON; 41 unsigned ramcfg_RON;
42 unsigned ramcfg_FBVDDQ;
42 union { 43 union {
43 struct { 44 struct {
44 unsigned ramcfg_00_03_01:1; 45 unsigned ramcfg_00_03_01:1;
@@ -78,7 +79,6 @@ struct nvbios_ramcfg {
78 unsigned ramcfg_11_01_04:1; 79 unsigned ramcfg_11_01_04:1;
79 unsigned ramcfg_11_01_08:1; 80 unsigned ramcfg_11_01_08:1;
80 unsigned ramcfg_11_01_10:1; 81 unsigned ramcfg_11_01_10:1;
81 unsigned ramcfg_11_01_20:1;
82 unsigned ramcfg_11_01_40:1; 82 unsigned ramcfg_11_01_40:1;
83 unsigned ramcfg_11_01_80:1; 83 unsigned ramcfg_11_01_80:1;
84 unsigned ramcfg_11_02_03:2; 84 unsigned ramcfg_11_02_03:2;
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h
index eb2de4b85bbd..b0df610cec2b 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/volt.h
@@ -1,11 +1,24 @@
1#ifndef __NVBIOS_VOLT_H__ 1#ifndef __NVBIOS_VOLT_H__
2#define __NVBIOS_VOLT_H__ 2#define __NVBIOS_VOLT_H__
3
4enum nvbios_volt_type {
5 NVBIOS_VOLT_GPIO = 0,
6 NVBIOS_VOLT_PWM,
7};
8
3struct nvbios_volt { 9struct nvbios_volt {
4 u8 vidmask; 10 enum nvbios_volt_type type;
5 u32 min; 11 u32 min;
6 u32 max; 12 u32 max;
7 u32 base; 13 u32 base;
14
15 /* GPIO mode */
16 u8 vidmask;
8 s16 step; 17 s16 step;
18
19 /* PWM mode */
20 u32 pwm_freq;
21 u32 pwm_range;
9}; 22};
10 23
11u16 nvbios_volt_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); 24u16 nvbios_volt_table(struct nvkm_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
index 6a04d9c07944..33a057c334f2 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bus.h
@@ -14,6 +14,7 @@ int nvkm_hwsq_fini(struct nvkm_hwsq **, bool exec);
14void nvkm_hwsq_wr32(struct nvkm_hwsq *, u32 addr, u32 data); 14void nvkm_hwsq_wr32(struct nvkm_hwsq *, u32 addr, u32 data);
15void nvkm_hwsq_setf(struct nvkm_hwsq *, u8 flag, int data); 15void nvkm_hwsq_setf(struct nvkm_hwsq *, u8 flag, int data);
16void nvkm_hwsq_wait(struct nvkm_hwsq *, u8 flag, u8 data); 16void nvkm_hwsq_wait(struct nvkm_hwsq *, u8 flag, u8 data);
17void nvkm_hwsq_wait_vblank(struct nvkm_hwsq *);
17void nvkm_hwsq_nsec(struct nvkm_hwsq *, u32 nsec); 18void nvkm_hwsq_nsec(struct nvkm_hwsq *, u32 nsec);
18 19
19int nv04_bus_new(struct nvkm_device *, int, struct nvkm_bus **); 20int nv04_bus_new(struct nvkm_device *, int, struct nvkm_bus **);
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h
index 9d512cd5a0a7..c4dcd2680fe1 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ibus.h
@@ -3,6 +3,7 @@
3#include <core/subdev.h> 3#include <core/subdev.h>
4 4
5int gf100_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **); 5int gf100_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
6int gf117_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
6int gk104_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **); 7int gk104_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
7int gk20a_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **); 8int gk20a_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
8#endif 9#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h
index c773b5e958b4..3d4dbbf9aab3 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h
@@ -30,7 +30,11 @@ void nvkm_ltc_tags_clear(struct nvkm_ltc *, u32 first, u32 count);
30int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]); 30int nvkm_ltc_zbc_color_get(struct nvkm_ltc *, int index, const u32[4]);
31int nvkm_ltc_zbc_depth_get(struct nvkm_ltc *, int index, const u32); 31int nvkm_ltc_zbc_depth_get(struct nvkm_ltc *, int index, const u32);
32 32
33void nvkm_ltc_invalidate(struct nvkm_ltc *);
34void nvkm_ltc_flush(struct nvkm_ltc *);
35
33int gf100_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); 36int gf100_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
34int gk104_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); 37int gk104_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
38int gk20a_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
35int gm107_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); 39int gm107_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
36#endif 40#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h
index 5b3c054f3b55..fee0a97c44c5 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h
@@ -24,11 +24,14 @@ struct nvkm_pci {
24u32 nvkm_pci_rd32(struct nvkm_pci *, u16 addr); 24u32 nvkm_pci_rd32(struct nvkm_pci *, u16 addr);
25void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data); 25void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data);
26void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data); 26void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data);
27u32 nvkm_pci_mask(struct nvkm_pci *, u16 addr, u32 mask, u32 value);
27void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow); 28void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow);
28 29
29int nv04_pci_new(struct nvkm_device *, int, struct nvkm_pci **); 30int nv04_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
30int nv40_pci_new(struct nvkm_device *, int, struct nvkm_pci **); 31int nv40_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
32int nv46_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
31int nv4c_pci_new(struct nvkm_device *, int, struct nvkm_pci **); 33int nv4c_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
32int nv50_pci_new(struct nvkm_device *, int, struct nvkm_pci **); 34int g84_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
35int g94_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
33int gf100_pci_new(struct nvkm_device *, int, struct nvkm_pci **); 36int gf100_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
34#endif 37#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h
index 62ed0880b0e1..82d3e28918fd 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h
@@ -59,6 +59,16 @@ void nvkm_timer_alarm_cancel(struct nvkm_timer *, struct nvkm_alarm *);
59#define nvkm_usec(d,u,cond...) nvkm_nsec((d), (u) * 1000, ##cond) 59#define nvkm_usec(d,u,cond...) nvkm_nsec((d), (u) * 1000, ##cond)
60#define nvkm_msec(d,m,cond...) nvkm_usec((d), (m) * 1000, ##cond) 60#define nvkm_msec(d,m,cond...) nvkm_usec((d), (m) * 1000, ##cond)
61 61
62#define nvkm_wait_nsec(d,n,addr,mask,data) \
63 nvkm_nsec(d, n, \
64 if ((nvkm_rd32(d, (addr)) & (mask)) == (data)) \
65 break; \
66 )
67#define nvkm_wait_usec(d,u,addr,mask,data) \
68 nvkm_wait_nsec((d), (u) * 1000, (addr), (mask), (data))
69#define nvkm_wait_msec(d,m,addr,mask,data) \
70 nvkm_wait_usec((d), (m) * 1000, (addr), (mask), (data))
71
62int nv04_timer_new(struct nvkm_device *, int, struct nvkm_timer **); 72int nv04_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
63int nv40_timer_new(struct nvkm_device *, int, struct nvkm_timer **); 73int nv40_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
64int nv41_timer_new(struct nvkm_device *, int, struct nvkm_timer **); 74int nv41_timer_new(struct nvkm_device *, int, struct nvkm_timer **);
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h
index 5c8a3f1196de..b458d046dba7 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/volt.h
@@ -18,5 +18,6 @@ int nvkm_volt_get(struct nvkm_volt *);
18int nvkm_volt_set_id(struct nvkm_volt *, u8 id, int condition); 18int nvkm_volt_set_id(struct nvkm_volt *, u8 id, int condition);
19 19
20int nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **); 20int nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
21int gk104_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
21int gk20a_volt_new(struct nvkm_device *, int, struct nvkm_volt **); 22int gk20a_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
22#endif 23#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index d336c2247d6a..7f50cf5f929e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -25,6 +25,7 @@
25#include <nvif/driver.h> 25#include <nvif/driver.h>
26#include <nvif/ioctl.h> 26#include <nvif/ioctl.h>
27#include <nvif/class.h> 27#include <nvif/class.h>
28#include <nvif/unpack.h>
28 29
29#include "nouveau_drm.h" 30#include "nouveau_drm.h"
30#include "nouveau_dma.h" 31#include "nouveau_dma.h"
@@ -32,11 +33,10 @@
32#include "nouveau_chan.h" 33#include "nouveau_chan.h"
33#include "nouveau_abi16.h" 34#include "nouveau_abi16.h"
34 35
35struct nouveau_abi16 * 36static struct nouveau_abi16 *
36nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev) 37nouveau_abi16(struct drm_file *file_priv)
37{ 38{
38 struct nouveau_cli *cli = nouveau_cli(file_priv); 39 struct nouveau_cli *cli = nouveau_cli(file_priv);
39 mutex_lock(&cli->mutex);
40 if (!cli->abi16) { 40 if (!cli->abi16) {
41 struct nouveau_abi16 *abi16; 41 struct nouveau_abi16 *abi16;
42 cli->abi16 = abi16 = kzalloc(sizeof(*abi16), GFP_KERNEL); 42 cli->abi16 = abi16 = kzalloc(sizeof(*abi16), GFP_KERNEL);
@@ -51,8 +51,7 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev)
51 * device (ie. the one that belongs to the fd it 51 * device (ie. the one that belongs to the fd it
52 * opened) 52 * opened)
53 */ 53 */
54 if (nvif_device_init(&cli->base.object, 54 if (nvif_device_init(&cli->base.object, 0, NV_DEVICE,
55 NOUVEAU_ABI16_DEVICE, NV_DEVICE,
56 &args, sizeof(args), 55 &args, sizeof(args),
57 &abi16->device) == 0) 56 &abi16->device) == 0)
58 return cli->abi16; 57 return cli->abi16;
@@ -60,12 +59,21 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev)
60 kfree(cli->abi16); 59 kfree(cli->abi16);
61 cli->abi16 = NULL; 60 cli->abi16 = NULL;
62 } 61 }
63
64 mutex_unlock(&cli->mutex);
65 } 62 }
66 return cli->abi16; 63 return cli->abi16;
67} 64}
68 65
66struct nouveau_abi16 *
67nouveau_abi16_get(struct drm_file *file_priv)
68{
69 struct nouveau_cli *cli = nouveau_cli(file_priv);
70 mutex_lock(&cli->mutex);
71 if (nouveau_abi16(file_priv))
72 return cli->abi16;
73 mutex_unlock(&cli->mutex);
74 return NULL;
75}
76
69int 77int
70nouveau_abi16_put(struct nouveau_abi16 *abi16, int ret) 78nouveau_abi16_put(struct nouveau_abi16 *abi16, int ret)
71{ 79{
@@ -133,7 +141,6 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
133 141
134 /* destroy channel object, all children will be killed too */ 142 /* destroy channel object, all children will be killed too */
135 if (chan->chan) { 143 if (chan->chan) {
136 abi16->handles &= ~(1ULL << (chan->chan->user.handle & 0xffff));
137 nouveau_channel_idle(chan->chan); 144 nouveau_channel_idle(chan->chan);
138 nouveau_channel_del(&chan->chan); 145 nouveau_channel_del(&chan->chan);
139 } 146 }
@@ -238,7 +245,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
238 struct drm_nouveau_channel_alloc *init = data; 245 struct drm_nouveau_channel_alloc *init = data;
239 struct nouveau_cli *cli = nouveau_cli(file_priv); 246 struct nouveau_cli *cli = nouveau_cli(file_priv);
240 struct nouveau_drm *drm = nouveau_drm(dev); 247 struct nouveau_drm *drm = nouveau_drm(dev);
241 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); 248 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
242 struct nouveau_abi16_chan *chan; 249 struct nouveau_abi16_chan *chan;
243 struct nvif_device *device; 250 struct nvif_device *device;
244 int ret; 251 int ret;
@@ -268,26 +275,21 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
268 return nouveau_abi16_put(abi16, -EINVAL); 275 return nouveau_abi16_put(abi16, -EINVAL);
269 276
270 /* allocate "abi16 channel" data and make up a handle for it */ 277 /* allocate "abi16 channel" data and make up a handle for it */
271 init->channel = __ffs64(~abi16->handles);
272 if (~abi16->handles == 0)
273 return nouveau_abi16_put(abi16, -ENOSPC);
274
275 chan = kzalloc(sizeof(*chan), GFP_KERNEL); 278 chan = kzalloc(sizeof(*chan), GFP_KERNEL);
276 if (!chan) 279 if (!chan)
277 return nouveau_abi16_put(abi16, -ENOMEM); 280 return nouveau_abi16_put(abi16, -ENOMEM);
278 281
279 INIT_LIST_HEAD(&chan->notifiers); 282 INIT_LIST_HEAD(&chan->notifiers);
280 list_add(&chan->head, &abi16->channels); 283 list_add(&chan->head, &abi16->channels);
281 abi16->handles |= (1ULL << init->channel);
282 284
283 /* create channel object and initialise dma and fence management */ 285 /* create channel object and initialise dma and fence management */
284 ret = nouveau_channel_new(drm, device, 286 ret = nouveau_channel_new(drm, device, init->fb_ctxdma_handle,
285 NOUVEAU_ABI16_CHAN(init->channel),
286 init->fb_ctxdma_handle,
287 init->tt_ctxdma_handle, &chan->chan); 287 init->tt_ctxdma_handle, &chan->chan);
288 if (ret) 288 if (ret)
289 goto done; 289 goto done;
290 290
291 init->channel = chan->chan->chid;
292
291 if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) 293 if (device->info.family >= NV_DEVICE_INFO_V0_TESLA)
292 init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM | 294 init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM |
293 NOUVEAU_GEM_DOMAIN_GART; 295 NOUVEAU_GEM_DOMAIN_GART;
@@ -338,7 +340,7 @@ nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel)
338 struct nouveau_abi16_chan *chan; 340 struct nouveau_abi16_chan *chan;
339 341
340 list_for_each_entry(chan, &abi16->channels, head) { 342 list_for_each_entry(chan, &abi16->channels, head) {
341 if (chan->chan->user.handle == NOUVEAU_ABI16_CHAN(channel)) 343 if (chan->chan->chid == channel)
342 return chan; 344 return chan;
343 } 345 }
344 346
@@ -346,10 +348,48 @@ nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel)
346} 348}
347 349
348int 350int
351nouveau_abi16_usif(struct drm_file *file_priv, void *data, u32 size)
352{
353 union {
354 struct nvif_ioctl_v0 v0;
355 } *args = data;
356 struct nouveau_abi16_chan *chan;
357 struct nouveau_abi16 *abi16;
358 int ret;
359
360 if (nvif_unpack(args->v0, 0, 0, true)) {
361 switch (args->v0.type) {
362 case NVIF_IOCTL_V0_NEW:
363 case NVIF_IOCTL_V0_MTHD:
364 case NVIF_IOCTL_V0_SCLASS:
365 break;
366 default:
367 return -EACCES;
368 }
369 } else
370 return ret;
371
372 if (!(abi16 = nouveau_abi16(file_priv)))
373 return -ENOMEM;
374
375 if (args->v0.token != ~0ULL) {
376 if (!(chan = nouveau_abi16_chan(abi16, args->v0.token)))
377 return -EINVAL;
378 args->v0.object = nvif_handle(&chan->chan->user);
379 args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
380 return 0;
381 }
382
383 args->v0.object = nvif_handle(&abi16->device.object);
384 args->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
385 return 0;
386}
387
388int
349nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS) 389nouveau_abi16_ioctl_channel_free(ABI16_IOCTL_ARGS)
350{ 390{
351 struct drm_nouveau_channel_free *req = data; 391 struct drm_nouveau_channel_free *req = data;
352 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); 392 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
353 struct nouveau_abi16_chan *chan; 393 struct nouveau_abi16_chan *chan;
354 394
355 if (unlikely(!abi16)) 395 if (unlikely(!abi16))
@@ -366,7 +406,7 @@ int
366nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) 406nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
367{ 407{
368 struct drm_nouveau_grobj_alloc *init = data; 408 struct drm_nouveau_grobj_alloc *init = data;
369 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); 409 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
370 struct nouveau_abi16_chan *chan; 410 struct nouveau_abi16_chan *chan;
371 struct nouveau_abi16_ntfy *ntfy; 411 struct nouveau_abi16_ntfy *ntfy;
372 struct nvif_client *client; 412 struct nvif_client *client;
@@ -459,7 +499,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
459{ 499{
460 struct drm_nouveau_notifierobj_alloc *info = data; 500 struct drm_nouveau_notifierobj_alloc *info = data;
461 struct nouveau_drm *drm = nouveau_drm(dev); 501 struct nouveau_drm *drm = nouveau_drm(dev);
462 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); 502 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
463 struct nouveau_abi16_chan *chan; 503 struct nouveau_abi16_chan *chan;
464 struct nouveau_abi16_ntfy *ntfy; 504 struct nouveau_abi16_ntfy *ntfy;
465 struct nvif_device *device = &abi16->device; 505 struct nvif_device *device = &abi16->device;
@@ -531,7 +571,7 @@ int
531nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS) 571nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
532{ 572{
533 struct drm_nouveau_gpuobj_free *fini = data; 573 struct drm_nouveau_gpuobj_free *fini = data;
534 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); 574 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
535 struct nouveau_abi16_chan *chan; 575 struct nouveau_abi16_chan *chan;
536 struct nouveau_abi16_ntfy *ntfy; 576 struct nouveau_abi16_ntfy *ntfy;
537 int ret = -ENOENT; 577 int ret = -ENOENT;
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.h b/drivers/gpu/drm/nouveau/nouveau_abi16.h
index 6584557afa40..841cc556fad8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.h
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.h
@@ -33,11 +33,11 @@ struct nouveau_abi16 {
33 u64 handles; 33 u64 handles;
34}; 34};
35 35
36struct nouveau_drm; 36struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *);
37struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *, struct drm_device *);
38int nouveau_abi16_put(struct nouveau_abi16 *, int); 37int nouveau_abi16_put(struct nouveau_abi16 *, int);
39void nouveau_abi16_fini(struct nouveau_abi16 *); 38void nouveau_abi16_fini(struct nouveau_abi16 *);
40s32 nouveau_abi16_swclass(struct nouveau_drm *); 39s32 nouveau_abi16_swclass(struct nouveau_drm *);
40int nouveau_abi16_usif(struct drm_file *, void *data, u32 size);
41 41
42#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1) 42#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
43#define NOUVEAU_GEM_DOMAIN_GART (1 << 2) 43#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
index ff5e59db49db..1860f389f21f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.c
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -55,10 +55,8 @@ nouveau_channel_idle(struct nouveau_channel *chan)
55 } 55 }
56 56
57 if (ret) { 57 if (ret) {
58 NV_PRINTK(err, cli, "failed to idle channel " 58 NV_PRINTK(err, cli, "failed to idle channel %d [%s]\n",
59 "0x%08x [%s]\n", 59 chan->chid, nvxx_client(&cli->base)->name);
60 chan->user.handle,
61 nvxx_client(&cli->base)->name);
62 return ret; 60 return ret;
63 } 61 }
64 } 62 }
@@ -89,7 +87,7 @@ nouveau_channel_del(struct nouveau_channel **pchan)
89 87
90static int 88static int
91nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, 89nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
92 u32 handle, u32 size, struct nouveau_channel **pchan) 90 u32 size, struct nouveau_channel **pchan)
93{ 91{
94 struct nouveau_cli *cli = (void *)device->object.client; 92 struct nouveau_cli *cli = (void *)device->object.client;
95 struct nvkm_mmu *mmu = nvxx_mmu(device); 93 struct nvkm_mmu *mmu = nvxx_mmu(device);
@@ -174,8 +172,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
174 } 172 }
175 } 173 }
176 174
177 ret = nvif_object_init(&device->object, NVDRM_PUSH | 175 ret = nvif_object_init(&device->object, 0, NV_DMA_FROM_MEMORY,
178 (handle & 0xffff), NV_DMA_FROM_MEMORY,
179 &args, sizeof(args), &chan->push.ctxdma); 176 &args, sizeof(args), &chan->push.ctxdma);
180 if (ret) { 177 if (ret) {
181 nouveau_channel_del(pchan); 178 nouveau_channel_del(pchan);
@@ -187,7 +184,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
187 184
188static int 185static int
189nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, 186nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
190 u32 handle, u32 engine, struct nouveau_channel **pchan) 187 u32 engine, struct nouveau_channel **pchan)
191{ 188{
192 static const u16 oclasses[] = { MAXWELL_CHANNEL_GPFIFO_A, 189 static const u16 oclasses[] = { MAXWELL_CHANNEL_GPFIFO_A,
193 KEPLER_CHANNEL_GPFIFO_A, 190 KEPLER_CHANNEL_GPFIFO_A,
@@ -206,7 +203,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
206 int ret; 203 int ret;
207 204
208 /* allocate dma push buffer */ 205 /* allocate dma push buffer */
209 ret = nouveau_channel_prep(drm, device, handle, 0x12000, &chan); 206 ret = nouveau_channel_prep(drm, device, 0x12000, &chan);
210 *pchan = chan; 207 *pchan = chan;
211 if (ret) 208 if (ret)
212 return ret; 209 return ret;
@@ -236,7 +233,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
236 size = sizeof(args.nv50); 233 size = sizeof(args.nv50);
237 } 234 }
238 235
239 ret = nvif_object_init(&device->object, handle, *oclass++, 236 ret = nvif_object_init(&device->object, 0, *oclass++,
240 &args, size, &chan->user); 237 &args, size, &chan->user);
241 if (ret == 0) { 238 if (ret == 0) {
242 if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A) 239 if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A)
@@ -256,7 +253,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
256 253
257static int 254static int
258nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device, 255nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device,
259 u32 handle, struct nouveau_channel **pchan) 256 struct nouveau_channel **pchan)
260{ 257{
261 static const u16 oclasses[] = { NV40_CHANNEL_DMA, 258 static const u16 oclasses[] = { NV40_CHANNEL_DMA,
262 NV17_CHANNEL_DMA, 259 NV17_CHANNEL_DMA,
@@ -269,7 +266,7 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device,
269 int ret; 266 int ret;
270 267
271 /* allocate dma push buffer */ 268 /* allocate dma push buffer */
272 ret = nouveau_channel_prep(drm, device, handle, 0x10000, &chan); 269 ret = nouveau_channel_prep(drm, device, 0x10000, &chan);
273 *pchan = chan; 270 *pchan = chan;
274 if (ret) 271 if (ret)
275 return ret; 272 return ret;
@@ -280,7 +277,7 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device,
280 args.offset = chan->push.vma.offset; 277 args.offset = chan->push.vma.offset;
281 278
282 do { 279 do {
283 ret = nvif_object_init(&device->object, handle, *oclass++, 280 ret = nvif_object_init(&device->object, 0, *oclass++,
284 &args, sizeof(args), &chan->user); 281 &args, sizeof(args), &chan->user);
285 if (ret == 0) { 282 if (ret == 0) {
286 chan->chid = args.chid; 283 chan->chid = args.chid;
@@ -401,8 +398,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
401 398
402int 399int
403nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, 400nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
404 u32 handle, u32 arg0, u32 arg1, 401 u32 arg0, u32 arg1, struct nouveau_channel **pchan)
405 struct nouveau_channel **pchan)
406{ 402{
407 struct nouveau_cli *cli = (void *)device->object.client; 403 struct nouveau_cli *cli = (void *)device->object.client;
408 bool super; 404 bool super;
@@ -412,10 +408,10 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
412 super = cli->base.super; 408 super = cli->base.super;
413 cli->base.super = true; 409 cli->base.super = true;
414 410
415 ret = nouveau_channel_ind(drm, device, handle, arg0, pchan); 411 ret = nouveau_channel_ind(drm, device, arg0, pchan);
416 if (ret) { 412 if (ret) {
417 NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret); 413 NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret);
418 ret = nouveau_channel_dma(drm, device, handle, pchan); 414 ret = nouveau_channel_dma(drm, device, pchan);
419 if (ret) { 415 if (ret) {
420 NV_PRINTK(dbg, cli, "dma channel create, %d\n", ret); 416 NV_PRINTK(dbg, cli, "dma channel create, %d\n", ret);
421 goto done; 417 goto done;
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h
index 2ed32414cb69..48062c94f36d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.h
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.h
@@ -42,8 +42,7 @@ struct nouveau_channel {
42 42
43 43
44int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, 44int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *,
45 u32 handle, u32 arg0, u32 arg1, 45 u32 arg0, u32 arg1, struct nouveau_channel **);
46 struct nouveau_channel **);
47void nouveau_channel_del(struct nouveau_channel **); 46void nouveau_channel_del(struct nouveau_channel **);
48int nouveau_channel_idle(struct nouveau_channel *); 47int nouveau_channel_idle(struct nouveau_channel *);
49 48
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 614b32e6381c..db6bc6760545 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -509,9 +509,8 @@ nouveau_display_create(struct drm_device *dev)
509 int i; 509 int i;
510 510
511 for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) { 511 for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) {
512 ret = nvif_object_init(&drm->device.object, 512 ret = nvif_object_init(&drm->device.object, 0,
513 NVDRM_DISPLAY, oclass[i], 513 oclass[i], NULL, 0, &disp->disp);
514 NULL, 0, &disp->disp);
515 } 514 }
516 515
517 if (ret == 0) { 516 if (ret == 0) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 45ba67819199..1d3ee5179ab8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -208,7 +208,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
208 } 208 }
209 209
210 if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { 210 if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
211 ret = nouveau_channel_new(drm, &drm->device, NVDRM_CHAN + 1, 211 ret = nouveau_channel_new(drm, &drm->device,
212 KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0| 212 KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0|
213 KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1, 213 KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1,
214 0, &drm->cechan); 214 0, &drm->cechan);
@@ -221,7 +221,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
221 if (device->info.chipset >= 0xa3 && 221 if (device->info.chipset >= 0xa3 &&
222 device->info.chipset != 0xaa && 222 device->info.chipset != 0xaa &&
223 device->info.chipset != 0xac) { 223 device->info.chipset != 0xac) {
224 ret = nouveau_channel_new(drm, &drm->device, NVDRM_CHAN + 1, 224 ret = nouveau_channel_new(drm, &drm->device,
225 NvDmaFB, NvDmaTT, &drm->cechan); 225 NvDmaFB, NvDmaTT, &drm->cechan);
226 if (ret) 226 if (ret)
227 NV_ERROR(drm, "failed to create ce channel, %d\n", ret); 227 NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
@@ -233,8 +233,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
233 arg1 = NvDmaTT; 233 arg1 = NvDmaTT;
234 } 234 }
235 235
236 ret = nouveau_channel_new(drm, &drm->device, NVDRM_CHAN, arg0, arg1, 236 ret = nouveau_channel_new(drm, &drm->device, arg0, arg1, &drm->channel);
237 &drm->channel);
238 if (ret) { 237 if (ret) {
239 NV_ERROR(drm, "failed to create kernel channel, %d\n", ret); 238 NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
240 nouveau_accel_fini(drm); 239 nouveau_accel_fini(drm);
@@ -403,8 +402,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
403 402
404 nouveau_get_hdmi_dev(drm); 403 nouveau_get_hdmi_dev(drm);
405 404
406 ret = nvif_device_init(&drm->client.base.object, 405 ret = nvif_device_init(&drm->client.base.object, 0, NV_DEVICE,
407 NVDRM_DEVICE, NV_DEVICE,
408 &(struct nv_device_v0) { 406 &(struct nv_device_v0) {
409 .device = ~0, 407 .device = ~0,
410 }, sizeof(struct nv_device_v0), 408 }, sizeof(struct nv_device_v0),
@@ -1030,13 +1028,14 @@ nouveau_drm_pci_driver = {
1030}; 1028};
1031 1029
1032struct drm_device * 1030struct drm_device *
1033nouveau_platform_device_create(struct platform_device *pdev, 1031nouveau_platform_device_create(const struct nvkm_device_tegra_func *func,
1032 struct platform_device *pdev,
1034 struct nvkm_device **pdevice) 1033 struct nvkm_device **pdevice)
1035{ 1034{
1036 struct drm_device *drm; 1035 struct drm_device *drm;
1037 int err; 1036 int err;
1038 1037
1039 err = nvkm_device_tegra_new(pdev, nouveau_config, nouveau_debug, 1038 err = nvkm_device_tegra_new(func, pdev, nouveau_config, nouveau_debug,
1040 true, true, ~0ULL, pdevice); 1039 true, true, ~0ULL, pdevice);
1041 if (err) 1040 if (err)
1042 goto err_free; 1041 goto err_free;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
index 3c902c24a8dd..3050042e6c6d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.h
@@ -10,7 +10,7 @@
10 10
11#define DRIVER_MAJOR 1 11#define DRIVER_MAJOR 1
12#define DRIVER_MINOR 3 12#define DRIVER_MINOR 3
13#define DRIVER_PATCHLEVEL 0 13#define DRIVER_PATCHLEVEL 1
14 14
15/* 15/*
16 * 1.1.1: 16 * 1.1.1:
@@ -33,6 +33,8 @@
33 * 1.3.0: 33 * 1.3.0:
34 * - NVIF ABI modified, safe because only (current) users are test 34 * - NVIF ABI modified, safe because only (current) users are test
35 * programs that get directly linked with NVKM. 35 * programs that get directly linked with NVKM.
36 * 1.3.1:
37 * - implemented limited ABI16/NVIF interop
36 */ 38 */
37 39
38#include <nvif/client.h> 40#include <nvif/client.h>
@@ -74,11 +76,6 @@ enum nouveau_drm_notify_route {
74}; 76};
75 77
76enum nouveau_drm_handle { 78enum nouveau_drm_handle {
77 NVDRM_CLIENT = 0xffffffff,
78 NVDRM_DEVICE = 0xdddddddd,
79 NVDRM_CONTROL = 0xdddddddc,
80 NVDRM_DISPLAY = 0xd1500000,
81 NVDRM_PUSH = 0xbbbb0000, /* |= client chid */
82 NVDRM_CHAN = 0xcccc0000, /* |= client chid */ 79 NVDRM_CHAN = 0xcccc0000, /* |= client chid */
83 NVDRM_NVSW = 0x55550000, 80 NVDRM_NVSW = 0x55550000,
84}; 81};
@@ -183,8 +180,11 @@ nouveau_drm(struct drm_device *dev)
183int nouveau_pmops_suspend(struct device *); 180int nouveau_pmops_suspend(struct device *);
184int nouveau_pmops_resume(struct device *); 181int nouveau_pmops_resume(struct device *);
185 182
183#include <nvkm/core/tegra.h>
184
186struct drm_device * 185struct drm_device *
187nouveau_platform_device_create(struct platform_device *, struct nvkm_device **); 186nouveau_platform_device_create(const struct nvkm_device_tegra_func *,
187 struct platform_device *, struct nvkm_device **);
188void nouveau_drm_device_remove(struct drm_device *dev); 188void nouveau_drm_device_remove(struct drm_device *dev);
189 189
190#define NV_PRINTK(l,c,f,a...) do { \ 190#define NV_PRINTK(l,c,f,a...) do { \
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 2c9981512d27..a0865c49ec83 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -84,8 +84,10 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
84 } 84 }
85 85
86 ret = pm_runtime_get_sync(dev); 86 ret = pm_runtime_get_sync(dev);
87 if (ret < 0 && ret != -EACCES) 87 if (ret < 0 && ret != -EACCES) {
88 kfree(vma);
88 goto out; 89 goto out;
90 }
89 91
90 ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); 92 ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
91 if (ret) 93 if (ret)
@@ -227,11 +229,12 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
227 struct nouveau_bo *nvbo = nouveau_gem_object(gem); 229 struct nouveau_bo *nvbo = nouveau_gem_object(gem);
228 struct nvkm_vma *vma; 230 struct nvkm_vma *vma;
229 231
230 if (nvbo->bo.mem.mem_type == TTM_PL_TT) 232 if (is_power_of_2(nvbo->valid_domains))
233 rep->domain = nvbo->valid_domains;
234 else if (nvbo->bo.mem.mem_type == TTM_PL_TT)
231 rep->domain = NOUVEAU_GEM_DOMAIN_GART; 235 rep->domain = NOUVEAU_GEM_DOMAIN_GART;
232 else 236 else
233 rep->domain = NOUVEAU_GEM_DOMAIN_VRAM; 237 rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
234
235 rep->offset = nvbo->bo.offset; 238 rep->offset = nvbo->bo.offset;
236 if (cli->vm) { 239 if (cli->vm) {
237 vma = nouveau_bo_vma_find(nvbo, cli->vm); 240 vma = nouveau_bo_vma_find(nvbo, cli->vm);
@@ -665,7 +668,7 @@ int
665nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, 668nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
666 struct drm_file *file_priv) 669 struct drm_file *file_priv)
667{ 670{
668 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); 671 struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
669 struct nouveau_cli *cli = nouveau_cli(file_priv); 672 struct nouveau_cli *cli = nouveau_cli(file_priv);
670 struct nouveau_abi16_chan *temp; 673 struct nouveau_abi16_chan *temp;
671 struct nouveau_drm *drm = nouveau_drm(dev); 674 struct nouveau_drm *drm = nouveau_drm(dev);
@@ -681,7 +684,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
681 return -ENOMEM; 684 return -ENOMEM;
682 685
683 list_for_each_entry(temp, &abi16->channels, head) { 686 list_for_each_entry(temp, &abi16->channels, head) {
684 if (temp->chan->user.handle == (NVDRM_CHAN | req->channel)) { 687 if (temp->chan->chid == req->channel) {
685 chan = temp->chan; 688 chan = temp->chan;
686 break; 689 break;
687 } 690 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c
index 3eb665453165..60e32c4e4e49 100644
--- a/drivers/gpu/drm/nouveau/nouveau_platform.c
+++ b/drivers/gpu/drm/nouveau/nouveau_platform.c
@@ -23,11 +23,14 @@
23 23
24static int nouveau_platform_probe(struct platform_device *pdev) 24static int nouveau_platform_probe(struct platform_device *pdev)
25{ 25{
26 const struct nvkm_device_tegra_func *func;
26 struct nvkm_device *device; 27 struct nvkm_device *device;
27 struct drm_device *drm; 28 struct drm_device *drm;
28 int ret; 29 int ret;
29 30
30 drm = nouveau_platform_device_create(pdev, &device); 31 func = of_device_get_match_data(&pdev->dev);
32
33 drm = nouveau_platform_device_create(func, pdev, &device);
31 if (IS_ERR(drm)) 34 if (IS_ERR(drm))
32 return PTR_ERR(drm); 35 return PTR_ERR(drm);
33 36
@@ -48,9 +51,19 @@ static int nouveau_platform_remove(struct platform_device *pdev)
48} 51}
49 52
50#if IS_ENABLED(CONFIG_OF) 53#if IS_ENABLED(CONFIG_OF)
54static const struct nvkm_device_tegra_func gk20a_platform_data = {
55 .iommu_bit = 34,
56};
57
51static const struct of_device_id nouveau_platform_match[] = { 58static const struct of_device_id nouveau_platform_match[] = {
52 { .compatible = "nvidia,gk20a" }, 59 {
53 { .compatible = "nvidia,gm20b" }, 60 .compatible = "nvidia,gk20a",
61 .data = &gk20a_platform_data,
62 },
63 {
64 .compatible = "nvidia,gm20b",
65 .data = &gk20a_platform_data,
66 },
54 { } 67 { }
55}; 68};
56 69
diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
index d12a5faee047..5dac3546c1b8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
@@ -188,9 +188,8 @@ nouveau_sysfs_init(struct drm_device *dev)
188 if (!sysfs) 188 if (!sysfs)
189 return -ENOMEM; 189 return -ENOMEM;
190 190
191 ret = nvif_object_init(&device->object, NVDRM_CONTROL, 191 ret = nvif_object_init(&device->object, 0, NVIF_IOCTL_NEW_V0_CONTROL,
192 NVIF_IOCTL_NEW_V0_CONTROL, NULL, 0, 192 NULL, 0, &sysfs->ctrl);
193 &sysfs->ctrl);
194 if (ret == 0) 193 if (ret == 0)
195 device_create_file(nvxx_device(device)->dev, &dev_attr_pstate); 194 device_create_file(nvxx_device(device)->dev, &dev_attr_pstate);
196 195
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 3f0fb55cb473..3f713c1b5dc1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -29,6 +29,9 @@
29#include "nouveau_gem.h" 29#include "nouveau_gem.h"
30 30
31#include "drm_legacy.h" 31#include "drm_legacy.h"
32
33#include <core/tegra.h>
34
32static int 35static int
33nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) 36nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
34{ 37{
@@ -338,7 +341,7 @@ nouveau_ttm_init(struct nouveau_drm *drm)
338 struct nvkm_device *device = nvxx_device(&drm->device); 341 struct nvkm_device *device = nvxx_device(&drm->device);
339 struct nvkm_pci *pci = device->pci; 342 struct nvkm_pci *pci = device->pci;
340 struct drm_device *dev = drm->dev; 343 struct drm_device *dev = drm->dev;
341 u32 bits; 344 u8 bits;
342 int ret; 345 int ret;
343 346
344 if (pci && pci->agp.bridge) { 347 if (pci && pci->agp.bridge) {
@@ -351,20 +354,28 @@ nouveau_ttm_init(struct nouveau_drm *drm)
351 bits = nvxx_mmu(&drm->device)->dma_bits; 354 bits = nvxx_mmu(&drm->device)->dma_bits;
352 if (nvxx_device(&drm->device)->func->pci) { 355 if (nvxx_device(&drm->device)->func->pci) {
353 if (drm->agp.bridge || 356 if (drm->agp.bridge ||
354 !pci_dma_supported(dev->pdev, DMA_BIT_MASK(bits))) 357 !dma_supported(dev->dev, DMA_BIT_MASK(bits)))
355 bits = 32; 358 bits = 32;
359 } else if (device->func->tegra) {
360 struct nvkm_device_tegra *tegra = device->func->tegra(device);
356 361
357 ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(bits)); 362 /*
358 if (ret) 363 * If the platform can use a IOMMU, then the addressable DMA
359 return ret; 364 * space is constrained by the IOMMU bit
365 */
366 if (tegra->func->iommu_bit)
367 bits = min(bits, tegra->func->iommu_bit);
360 368
361 ret = pci_set_consistent_dma_mask(dev->pdev,
362 DMA_BIT_MASK(bits));
363 if (ret)
364 pci_set_consistent_dma_mask(dev->pdev,
365 DMA_BIT_MASK(32));
366 } 369 }
367 370
371 ret = dma_set_mask(dev->dev, DMA_BIT_MASK(bits));
372 if (ret)
373 return ret;
374
375 ret = dma_set_coherent_mask(dev->dev, DMA_BIT_MASK(bits));
376 if (ret)
377 dma_set_coherent_mask(dev->dev, DMA_BIT_MASK(32));
378
368 ret = nouveau_ttm_global_init(drm); 379 ret = nouveau_ttm_global_init(drm);
369 if (ret) 380 if (ret)
370 return ret; 381 return ret;
diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c
index cb1182d7e80e..89dc4ce63490 100644
--- a/drivers/gpu/drm/nouveau/nouveau_usif.c
+++ b/drivers/gpu/drm/nouveau/nouveau_usif.c
@@ -24,6 +24,7 @@
24 24
25#include "nouveau_drm.h" 25#include "nouveau_drm.h"
26#include "nouveau_usif.h" 26#include "nouveau_usif.h"
27#include "nouveau_abi16.h"
27 28
28#include <nvif/notify.h> 29#include <nvif/notify.h>
29#include <nvif/unpack.h> 30#include <nvif/unpack.h>
@@ -316,11 +317,21 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
316 } else 317 } else
317 goto done; 318 goto done;
318 319
320 /* USIF slightly abuses some return-only ioctl members in order
321 * to provide interoperability with the older ABI16 objects
322 */
319 mutex_lock(&cli->mutex); 323 mutex_lock(&cli->mutex);
324 if (argv->v0.route) {
325 if (ret = -EINVAL, argv->v0.route == 0xff)
326 ret = nouveau_abi16_usif(filp, argv, argc);
327 if (ret) {
328 mutex_unlock(&cli->mutex);
329 goto done;
330 }
331 }
332
320 switch (argv->v0.type) { 333 switch (argv->v0.type) {
321 case NVIF_IOCTL_V0_NEW: 334 case NVIF_IOCTL_V0_NEW:
322 /* ... except if we're creating children */
323 argv->v0.owner = NVIF_IOCTL_V0_OWNER_ANY;
324 ret = usif_object_new(filp, data, size, argv, argc); 335 ret = usif_object_new(filp, data, size, argv, argc);
325 break; 336 break;
326 case NVIF_IOCTL_V0_NTFY_NEW: 337 case NVIF_IOCTL_V0_NTFY_NEW:
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 4ae87aed4505..c053c50b346a 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -68,7 +68,6 @@ nv50_chan_create(struct nvif_device *device, struct nvif_object *disp,
68 const s32 *oclass, u8 head, void *data, u32 size, 68 const s32 *oclass, u8 head, void *data, u32 size,
69 struct nv50_chan *chan) 69 struct nv50_chan *chan)
70{ 70{
71 const u32 handle = (oclass[0] << 16) | head;
72 struct nvif_sclass *sclass; 71 struct nvif_sclass *sclass;
73 int ret, i, n; 72 int ret, i, n;
74 73
@@ -81,7 +80,7 @@ nv50_chan_create(struct nvif_device *device, struct nvif_object *disp,
81 while (oclass[0]) { 80 while (oclass[0]) {
82 for (i = 0; i < n; i++) { 81 for (i = 0; i < n; i++) {
83 if (sclass[i].oclass == oclass[0]) { 82 if (sclass[i].oclass == oclass[0]) {
84 ret = nvif_object_init(disp, handle, oclass[0], 83 ret = nvif_object_init(disp, 0, oclass[0],
85 data, size, &chan->user); 84 data, size, &chan->user);
86 if (ret == 0) 85 if (ret == 0)
87 nvif_object_map(&chan->user); 86 nvif_object_map(&chan->user);
@@ -231,8 +230,8 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
231 if (!dmac->ptr) 230 if (!dmac->ptr)
232 return -ENOMEM; 231 return -ENOMEM;
233 232
234 ret = nvif_object_init(&device->object, 0xd0000000, 233 ret = nvif_object_init(&device->object, 0, NV_DMA_FROM_MEMORY,
235 NV_DMA_FROM_MEMORY, &(struct nv_dma_v0) { 234 &(struct nv_dma_v0) {
236 .target = NV_DMA_V0_TARGET_PCI_US, 235 .target = NV_DMA_V0_TARGET_PCI_US,
237 .access = NV_DMA_V0_ACCESS_RD, 236 .access = NV_DMA_V0_ACCESS_RD,
238 .start = dmac->handle + 0x0000, 237 .start = dmac->handle + 0x0000,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index 94a906b8cb88..bbc9824af6e0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -637,7 +637,7 @@ nv46_chipset = {
637 .imem = nv40_instmem_new, 637 .imem = nv40_instmem_new,
638 .mc = nv44_mc_new, 638 .mc = nv44_mc_new,
639 .mmu = nv44_mmu_new, 639 .mmu = nv44_mmu_new,
640 .pci = nv4c_pci_new, 640 .pci = nv46_pci_new,
641 .therm = nv40_therm_new, 641 .therm = nv40_therm_new,
642 .timer = nv41_timer_new, 642 .timer = nv41_timer_new,
643 .volt = nv40_volt_new, 643 .volt = nv40_volt_new,
@@ -822,7 +822,7 @@ nv50_chipset = {
822 .mc = nv50_mc_new, 822 .mc = nv50_mc_new,
823 .mmu = nv50_mmu_new, 823 .mmu = nv50_mmu_new,
824 .mxm = nv50_mxm_new, 824 .mxm = nv50_mxm_new,
825 .pci = nv50_pci_new, 825 .pci = nv46_pci_new,
826 .therm = nv50_therm_new, 826 .therm = nv50_therm_new,
827 .timer = nv41_timer_new, 827 .timer = nv41_timer_new,
828 .volt = nv40_volt_new, 828 .volt = nv40_volt_new,
@@ -929,7 +929,7 @@ nv84_chipset = {
929 .mc = nv50_mc_new, 929 .mc = nv50_mc_new,
930 .mmu = nv50_mmu_new, 930 .mmu = nv50_mmu_new,
931 .mxm = nv50_mxm_new, 931 .mxm = nv50_mxm_new,
932 .pci = nv50_pci_new, 932 .pci = g84_pci_new,
933 .therm = g84_therm_new, 933 .therm = g84_therm_new,
934 .timer = nv41_timer_new, 934 .timer = nv41_timer_new,
935 .volt = nv40_volt_new, 935 .volt = nv40_volt_new,
@@ -961,7 +961,7 @@ nv86_chipset = {
961 .mc = nv50_mc_new, 961 .mc = nv50_mc_new,
962 .mmu = nv50_mmu_new, 962 .mmu = nv50_mmu_new,
963 .mxm = nv50_mxm_new, 963 .mxm = nv50_mxm_new,
964 .pci = nv50_pci_new, 964 .pci = g84_pci_new,
965 .therm = g84_therm_new, 965 .therm = g84_therm_new,
966 .timer = nv41_timer_new, 966 .timer = nv41_timer_new,
967 .volt = nv40_volt_new, 967 .volt = nv40_volt_new,
@@ -993,7 +993,7 @@ nv92_chipset = {
993 .mc = nv50_mc_new, 993 .mc = nv50_mc_new,
994 .mmu = nv50_mmu_new, 994 .mmu = nv50_mmu_new,
995 .mxm = nv50_mxm_new, 995 .mxm = nv50_mxm_new,
996 .pci = nv50_pci_new, 996 .pci = g84_pci_new,
997 .therm = g84_therm_new, 997 .therm = g84_therm_new,
998 .timer = nv41_timer_new, 998 .timer = nv41_timer_new,
999 .volt = nv40_volt_new, 999 .volt = nv40_volt_new,
@@ -1025,7 +1025,7 @@ nv94_chipset = {
1025 .mc = nv50_mc_new, 1025 .mc = nv50_mc_new,
1026 .mmu = nv50_mmu_new, 1026 .mmu = nv50_mmu_new,
1027 .mxm = nv50_mxm_new, 1027 .mxm = nv50_mxm_new,
1028 .pci = nv40_pci_new, 1028 .pci = g94_pci_new,
1029 .therm = g84_therm_new, 1029 .therm = g84_therm_new,
1030 .timer = nv41_timer_new, 1030 .timer = nv41_timer_new,
1031 .volt = nv40_volt_new, 1031 .volt = nv40_volt_new,
@@ -1057,7 +1057,7 @@ nv96_chipset = {
1057 .mc = nv50_mc_new, 1057 .mc = nv50_mc_new,
1058 .mmu = nv50_mmu_new, 1058 .mmu = nv50_mmu_new,
1059 .mxm = nv50_mxm_new, 1059 .mxm = nv50_mxm_new,
1060 .pci = nv40_pci_new, 1060 .pci = g94_pci_new,
1061 .therm = g84_therm_new, 1061 .therm = g84_therm_new,
1062 .timer = nv41_timer_new, 1062 .timer = nv41_timer_new,
1063 .volt = nv40_volt_new, 1063 .volt = nv40_volt_new,
@@ -1089,7 +1089,7 @@ nv98_chipset = {
1089 .mc = g98_mc_new, 1089 .mc = g98_mc_new,
1090 .mmu = nv50_mmu_new, 1090 .mmu = nv50_mmu_new,
1091 .mxm = nv50_mxm_new, 1091 .mxm = nv50_mxm_new,
1092 .pci = nv40_pci_new, 1092 .pci = g94_pci_new,
1093 .therm = g84_therm_new, 1093 .therm = g84_therm_new,
1094 .timer = nv41_timer_new, 1094 .timer = nv41_timer_new,
1095 .volt = nv40_volt_new, 1095 .volt = nv40_volt_new,
@@ -1121,7 +1121,7 @@ nva0_chipset = {
1121 .mc = g98_mc_new, 1121 .mc = g98_mc_new,
1122 .mmu = nv50_mmu_new, 1122 .mmu = nv50_mmu_new,
1123 .mxm = nv50_mxm_new, 1123 .mxm = nv50_mxm_new,
1124 .pci = nv40_pci_new, 1124 .pci = g94_pci_new,
1125 .therm = g84_therm_new, 1125 .therm = g84_therm_new,
1126 .timer = nv41_timer_new, 1126 .timer = nv41_timer_new,
1127 .volt = nv40_volt_new, 1127 .volt = nv40_volt_new,
@@ -1153,7 +1153,7 @@ nva3_chipset = {
1153 .mc = g98_mc_new, 1153 .mc = g98_mc_new,
1154 .mmu = nv50_mmu_new, 1154 .mmu = nv50_mmu_new,
1155 .mxm = nv50_mxm_new, 1155 .mxm = nv50_mxm_new,
1156 .pci = nv40_pci_new, 1156 .pci = g94_pci_new,
1157 .pmu = gt215_pmu_new, 1157 .pmu = gt215_pmu_new,
1158 .therm = gt215_therm_new, 1158 .therm = gt215_therm_new,
1159 .timer = nv41_timer_new, 1159 .timer = nv41_timer_new,
@@ -1187,7 +1187,7 @@ nva5_chipset = {
1187 .mc = g98_mc_new, 1187 .mc = g98_mc_new,
1188 .mmu = nv50_mmu_new, 1188 .mmu = nv50_mmu_new,
1189 .mxm = nv50_mxm_new, 1189 .mxm = nv50_mxm_new,
1190 .pci = nv40_pci_new, 1190 .pci = g94_pci_new,
1191 .pmu = gt215_pmu_new, 1191 .pmu = gt215_pmu_new,
1192 .therm = gt215_therm_new, 1192 .therm = gt215_therm_new,
1193 .timer = nv41_timer_new, 1193 .timer = nv41_timer_new,
@@ -1220,7 +1220,7 @@ nva8_chipset = {
1220 .mc = g98_mc_new, 1220 .mc = g98_mc_new,
1221 .mmu = nv50_mmu_new, 1221 .mmu = nv50_mmu_new,
1222 .mxm = nv50_mxm_new, 1222 .mxm = nv50_mxm_new,
1223 .pci = nv40_pci_new, 1223 .pci = g94_pci_new,
1224 .pmu = gt215_pmu_new, 1224 .pmu = gt215_pmu_new,
1225 .therm = gt215_therm_new, 1225 .therm = gt215_therm_new,
1226 .timer = nv41_timer_new, 1226 .timer = nv41_timer_new,
@@ -1253,7 +1253,7 @@ nvaa_chipset = {
1253 .mc = g98_mc_new, 1253 .mc = g98_mc_new,
1254 .mmu = nv50_mmu_new, 1254 .mmu = nv50_mmu_new,
1255 .mxm = nv50_mxm_new, 1255 .mxm = nv50_mxm_new,
1256 .pci = nv40_pci_new, 1256 .pci = g94_pci_new,
1257 .therm = g84_therm_new, 1257 .therm = g84_therm_new,
1258 .timer = nv41_timer_new, 1258 .timer = nv41_timer_new,
1259 .volt = nv40_volt_new, 1259 .volt = nv40_volt_new,
@@ -1285,7 +1285,7 @@ nvac_chipset = {
1285 .mc = g98_mc_new, 1285 .mc = g98_mc_new,
1286 .mmu = nv50_mmu_new, 1286 .mmu = nv50_mmu_new,
1287 .mxm = nv50_mxm_new, 1287 .mxm = nv50_mxm_new,
1288 .pci = nv40_pci_new, 1288 .pci = g94_pci_new,
1289 .therm = g84_therm_new, 1289 .therm = g84_therm_new,
1290 .timer = nv41_timer_new, 1290 .timer = nv41_timer_new,
1291 .volt = nv40_volt_new, 1291 .volt = nv40_volt_new,
@@ -1317,7 +1317,7 @@ nvaf_chipset = {
1317 .mc = g98_mc_new, 1317 .mc = g98_mc_new,
1318 .mmu = nv50_mmu_new, 1318 .mmu = nv50_mmu_new,
1319 .mxm = nv50_mxm_new, 1319 .mxm = nv50_mxm_new,
1320 .pci = nv40_pci_new, 1320 .pci = g94_pci_new,
1321 .pmu = gt215_pmu_new, 1321 .pmu = gt215_pmu_new,
1322 .therm = gt215_therm_new, 1322 .therm = gt215_therm_new,
1323 .timer = nv41_timer_new, 1323 .timer = nv41_timer_new,
@@ -1388,7 +1388,7 @@ nvc1_chipset = {
1388 .mc = gf100_mc_new, 1388 .mc = gf100_mc_new,
1389 .mmu = gf100_mmu_new, 1389 .mmu = gf100_mmu_new,
1390 .mxm = nv50_mxm_new, 1390 .mxm = nv50_mxm_new,
1391 .pci = nv40_pci_new, 1391 .pci = g94_pci_new,
1392 .pmu = gf100_pmu_new, 1392 .pmu = gf100_pmu_new,
1393 .therm = gt215_therm_new, 1393 .therm = gt215_therm_new,
1394 .timer = nv41_timer_new, 1394 .timer = nv41_timer_new,
@@ -1423,7 +1423,7 @@ nvc3_chipset = {
1423 .mc = gf100_mc_new, 1423 .mc = gf100_mc_new,
1424 .mmu = gf100_mmu_new, 1424 .mmu = gf100_mmu_new,
1425 .mxm = nv50_mxm_new, 1425 .mxm = nv50_mxm_new,
1426 .pci = nv40_pci_new, 1426 .pci = g94_pci_new,
1427 .pmu = gf100_pmu_new, 1427 .pmu = gf100_pmu_new,
1428 .therm = gt215_therm_new, 1428 .therm = gt215_therm_new,
1429 .timer = nv41_timer_new, 1429 .timer = nv41_timer_new,
@@ -1566,7 +1566,7 @@ nvcf_chipset = {
1566 .mc = gf100_mc_new, 1566 .mc = gf100_mc_new,
1567 .mmu = gf100_mmu_new, 1567 .mmu = gf100_mmu_new,
1568 .mxm = nv50_mxm_new, 1568 .mxm = nv50_mxm_new,
1569 .pci = nv40_pci_new, 1569 .pci = g94_pci_new,
1570 .pmu = gf100_pmu_new, 1570 .pmu = gf100_pmu_new,
1571 .therm = gt215_therm_new, 1571 .therm = gt215_therm_new,
1572 .timer = nv41_timer_new, 1572 .timer = nv41_timer_new,
@@ -1595,13 +1595,13 @@ nvd7_chipset = {
1595 .fuse = gf100_fuse_new, 1595 .fuse = gf100_fuse_new,
1596 .gpio = gf119_gpio_new, 1596 .gpio = gf119_gpio_new,
1597 .i2c = gf117_i2c_new, 1597 .i2c = gf117_i2c_new,
1598 .ibus = gf100_ibus_new, 1598 .ibus = gf117_ibus_new,
1599 .imem = nv50_instmem_new, 1599 .imem = nv50_instmem_new,
1600 .ltc = gf100_ltc_new, 1600 .ltc = gf100_ltc_new,
1601 .mc = gf100_mc_new, 1601 .mc = gf100_mc_new,
1602 .mmu = gf100_mmu_new, 1602 .mmu = gf100_mmu_new,
1603 .mxm = nv50_mxm_new, 1603 .mxm = nv50_mxm_new,
1604 .pci = nv40_pci_new, 1604 .pci = g94_pci_new,
1605 .therm = gf119_therm_new, 1605 .therm = gf119_therm_new,
1606 .timer = nv41_timer_new, 1606 .timer = nv41_timer_new,
1607 .ce[0] = gf100_ce_new, 1607 .ce[0] = gf100_ce_new,
@@ -1628,13 +1628,13 @@ nvd9_chipset = {
1628 .fuse = gf100_fuse_new, 1628 .fuse = gf100_fuse_new,
1629 .gpio = gf119_gpio_new, 1629 .gpio = gf119_gpio_new,
1630 .i2c = gf119_i2c_new, 1630 .i2c = gf119_i2c_new,
1631 .ibus = gf100_ibus_new, 1631 .ibus = gf117_ibus_new,
1632 .imem = nv50_instmem_new, 1632 .imem = nv50_instmem_new,
1633 .ltc = gf100_ltc_new, 1633 .ltc = gf100_ltc_new,
1634 .mc = gf100_mc_new, 1634 .mc = gf100_mc_new,
1635 .mmu = gf100_mmu_new, 1635 .mmu = gf100_mmu_new,
1636 .mxm = nv50_mxm_new, 1636 .mxm = nv50_mxm_new,
1637 .pci = nv40_pci_new, 1637 .pci = g94_pci_new,
1638 .pmu = gf119_pmu_new, 1638 .pmu = gf119_pmu_new,
1639 .therm = gf119_therm_new, 1639 .therm = gf119_therm_new,
1640 .timer = nv41_timer_new, 1640 .timer = nv41_timer_new,
@@ -1669,11 +1669,11 @@ nve4_chipset = {
1669 .mc = gf100_mc_new, 1669 .mc = gf100_mc_new,
1670 .mmu = gf100_mmu_new, 1670 .mmu = gf100_mmu_new,
1671 .mxm = nv50_mxm_new, 1671 .mxm = nv50_mxm_new,
1672 .pci = nv40_pci_new, 1672 .pci = g94_pci_new,
1673 .pmu = gk104_pmu_new, 1673 .pmu = gk104_pmu_new,
1674 .therm = gf119_therm_new, 1674 .therm = gf119_therm_new,
1675 .timer = nv41_timer_new, 1675 .timer = nv41_timer_new,
1676 .volt = nv40_volt_new, 1676 .volt = gk104_volt_new,
1677 .ce[0] = gk104_ce_new, 1677 .ce[0] = gk104_ce_new,
1678 .ce[1] = gk104_ce_new, 1678 .ce[1] = gk104_ce_new,
1679 .ce[2] = gk104_ce_new, 1679 .ce[2] = gk104_ce_new,
@@ -1706,11 +1706,11 @@ nve6_chipset = {
1706 .mc = gf100_mc_new, 1706 .mc = gf100_mc_new,
1707 .mmu = gf100_mmu_new, 1707 .mmu = gf100_mmu_new,
1708 .mxm = nv50_mxm_new, 1708 .mxm = nv50_mxm_new,
1709 .pci = nv40_pci_new, 1709 .pci = g94_pci_new,
1710 .pmu = gk104_pmu_new, 1710 .pmu = gk104_pmu_new,
1711 .therm = gf119_therm_new, 1711 .therm = gf119_therm_new,
1712 .timer = nv41_timer_new, 1712 .timer = nv41_timer_new,
1713 .volt = nv40_volt_new, 1713 .volt = gk104_volt_new,
1714 .ce[0] = gk104_ce_new, 1714 .ce[0] = gk104_ce_new,
1715 .ce[1] = gk104_ce_new, 1715 .ce[1] = gk104_ce_new,
1716 .ce[2] = gk104_ce_new, 1716 .ce[2] = gk104_ce_new,
@@ -1743,11 +1743,11 @@ nve7_chipset = {
1743 .mc = gf100_mc_new, 1743 .mc = gf100_mc_new,
1744 .mmu = gf100_mmu_new, 1744 .mmu = gf100_mmu_new,
1745 .mxm = nv50_mxm_new, 1745 .mxm = nv50_mxm_new,
1746 .pci = nv40_pci_new, 1746 .pci = g94_pci_new,
1747 .pmu = gf119_pmu_new, 1747 .pmu = gk104_pmu_new,
1748 .therm = gf119_therm_new, 1748 .therm = gf119_therm_new,
1749 .timer = nv41_timer_new, 1749 .timer = nv41_timer_new,
1750 .volt = nv40_volt_new, 1750 .volt = gk104_volt_new,
1751 .ce[0] = gk104_ce_new, 1751 .ce[0] = gk104_ce_new,
1752 .ce[1] = gk104_ce_new, 1752 .ce[1] = gk104_ce_new,
1753 .ce[2] = gk104_ce_new, 1753 .ce[2] = gk104_ce_new,
@@ -1804,11 +1804,11 @@ nvf0_chipset = {
1804 .mc = gf100_mc_new, 1804 .mc = gf100_mc_new,
1805 .mmu = gf100_mmu_new, 1805 .mmu = gf100_mmu_new,
1806 .mxm = nv50_mxm_new, 1806 .mxm = nv50_mxm_new,
1807 .pci = nv40_pci_new, 1807 .pci = g94_pci_new,
1808 .pmu = gk110_pmu_new, 1808 .pmu = gk110_pmu_new,
1809 .therm = gf119_therm_new, 1809 .therm = gf119_therm_new,
1810 .timer = nv41_timer_new, 1810 .timer = nv41_timer_new,
1811 .volt = nv40_volt_new, 1811 .volt = gk104_volt_new,
1812 .ce[0] = gk104_ce_new, 1812 .ce[0] = gk104_ce_new,
1813 .ce[1] = gk104_ce_new, 1813 .ce[1] = gk104_ce_new,
1814 .ce[2] = gk104_ce_new, 1814 .ce[2] = gk104_ce_new,
@@ -1840,11 +1840,11 @@ nvf1_chipset = {
1840 .mc = gf100_mc_new, 1840 .mc = gf100_mc_new,
1841 .mmu = gf100_mmu_new, 1841 .mmu = gf100_mmu_new,
1842 .mxm = nv50_mxm_new, 1842 .mxm = nv50_mxm_new,
1843 .pci = nv40_pci_new, 1843 .pci = g94_pci_new,
1844 .pmu = gk110_pmu_new, 1844 .pmu = gk110_pmu_new,
1845 .therm = gf119_therm_new, 1845 .therm = gf119_therm_new,
1846 .timer = nv41_timer_new, 1846 .timer = nv41_timer_new,
1847 .volt = nv40_volt_new, 1847 .volt = gk104_volt_new,
1848 .ce[0] = gk104_ce_new, 1848 .ce[0] = gk104_ce_new,
1849 .ce[1] = gk104_ce_new, 1849 .ce[1] = gk104_ce_new,
1850 .ce[2] = gk104_ce_new, 1850 .ce[2] = gk104_ce_new,
@@ -1876,11 +1876,11 @@ nv106_chipset = {
1876 .mc = gk20a_mc_new, 1876 .mc = gk20a_mc_new,
1877 .mmu = gf100_mmu_new, 1877 .mmu = gf100_mmu_new,
1878 .mxm = nv50_mxm_new, 1878 .mxm = nv50_mxm_new,
1879 .pci = nv40_pci_new, 1879 .pci = g94_pci_new,
1880 .pmu = gk208_pmu_new, 1880 .pmu = gk208_pmu_new,
1881 .therm = gf119_therm_new, 1881 .therm = gf119_therm_new,
1882 .timer = nv41_timer_new, 1882 .timer = nv41_timer_new,
1883 .volt = nv40_volt_new, 1883 .volt = gk104_volt_new,
1884 .ce[0] = gk104_ce_new, 1884 .ce[0] = gk104_ce_new,
1885 .ce[1] = gk104_ce_new, 1885 .ce[1] = gk104_ce_new,
1886 .ce[2] = gk104_ce_new, 1886 .ce[2] = gk104_ce_new,
@@ -1912,11 +1912,11 @@ nv108_chipset = {
1912 .mc = gk20a_mc_new, 1912 .mc = gk20a_mc_new,
1913 .mmu = gf100_mmu_new, 1913 .mmu = gf100_mmu_new,
1914 .mxm = nv50_mxm_new, 1914 .mxm = nv50_mxm_new,
1915 .pci = nv40_pci_new, 1915 .pci = g94_pci_new,
1916 .pmu = gk208_pmu_new, 1916 .pmu = gk208_pmu_new,
1917 .therm = gf119_therm_new, 1917 .therm = gf119_therm_new,
1918 .timer = nv41_timer_new, 1918 .timer = nv41_timer_new,
1919 .volt = nv40_volt_new, 1919 .volt = gk104_volt_new,
1920 .ce[0] = gk104_ce_new, 1920 .ce[0] = gk104_ce_new,
1921 .ce[1] = gk104_ce_new, 1921 .ce[1] = gk104_ce_new,
1922 .ce[2] = gk104_ce_new, 1922 .ce[2] = gk104_ce_new,
@@ -1948,10 +1948,11 @@ nv117_chipset = {
1948 .mc = gk20a_mc_new, 1948 .mc = gk20a_mc_new,
1949 .mmu = gf100_mmu_new, 1949 .mmu = gf100_mmu_new,
1950 .mxm = nv50_mxm_new, 1950 .mxm = nv50_mxm_new,
1951 .pci = nv40_pci_new, 1951 .pci = g94_pci_new,
1952 .pmu = gm107_pmu_new, 1952 .pmu = gm107_pmu_new,
1953 .therm = gm107_therm_new, 1953 .therm = gm107_therm_new,
1954 .timer = gk20a_timer_new, 1954 .timer = gk20a_timer_new,
1955 .volt = gk104_volt_new,
1955 .ce[0] = gk104_ce_new, 1956 .ce[0] = gk104_ce_new,
1956 .ce[2] = gk104_ce_new, 1957 .ce[2] = gk104_ce_new,
1957 .disp = gm107_disp_new, 1958 .disp = gm107_disp_new,
@@ -1978,9 +1979,10 @@ nv124_chipset = {
1978 .mc = gk20a_mc_new, 1979 .mc = gk20a_mc_new,
1979 .mmu = gf100_mmu_new, 1980 .mmu = gf100_mmu_new,
1980 .mxm = nv50_mxm_new, 1981 .mxm = nv50_mxm_new,
1981 .pci = nv40_pci_new, 1982 .pci = g94_pci_new,
1982 .pmu = gm107_pmu_new, 1983 .pmu = gm107_pmu_new,
1983 .timer = gk20a_timer_new, 1984 .timer = gk20a_timer_new,
1985 .volt = gk104_volt_new,
1984 .ce[0] = gm204_ce_new, 1986 .ce[0] = gm204_ce_new,
1985 .ce[1] = gm204_ce_new, 1987 .ce[1] = gm204_ce_new,
1986 .ce[2] = gm204_ce_new, 1988 .ce[2] = gm204_ce_new,
@@ -2008,9 +2010,10 @@ nv126_chipset = {
2008 .mc = gk20a_mc_new, 2010 .mc = gk20a_mc_new,
2009 .mmu = gf100_mmu_new, 2011 .mmu = gf100_mmu_new,
2010 .mxm = nv50_mxm_new, 2012 .mxm = nv50_mxm_new,
2011 .pci = nv40_pci_new, 2013 .pci = g94_pci_new,
2012 .pmu = gm107_pmu_new, 2014 .pmu = gm107_pmu_new,
2013 .timer = gk20a_timer_new, 2015 .timer = gk20a_timer_new,
2016 .volt = gk104_volt_new,
2014 .ce[0] = gm204_ce_new, 2017 .ce[0] = gm204_ce_new,
2015 .ce[1] = gm204_ce_new, 2018 .ce[1] = gm204_ce_new,
2016 .ce[2] = gm204_ce_new, 2019 .ce[2] = gm204_ce_new,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
index e8eb14e438f4..e3c783d0e2ab 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
@@ -259,6 +259,12 @@ nvkm_device_pci_10de_0df4[] = {
259}; 259};
260 260
261static const struct nvkm_device_pci_vendor 261static const struct nvkm_device_pci_vendor
262nvkm_device_pci_10de_0fcd[] = {
263 { 0x17aa, 0x3801, NULL, { .War00C800_0 = true } }, /* Lenovo Y510P */
264 {}
265};
266
267static const struct nvkm_device_pci_vendor
262nvkm_device_pci_10de_0fd2[] = { 268nvkm_device_pci_10de_0fd2[] = {
263 { 0x1028, 0x0595, "GeForce GT 640M LE" }, 269 { 0x1028, 0x0595, "GeForce GT 640M LE" },
264 { 0x1028, 0x05b2, "GeForce GT 640M LE" }, 270 { 0x1028, 0x05b2, "GeForce GT 640M LE" },
@@ -678,6 +684,7 @@ nvkm_device_pci_10de_1189[] = {
678static const struct nvkm_device_pci_vendor 684static const struct nvkm_device_pci_vendor
679nvkm_device_pci_10de_1199[] = { 685nvkm_device_pci_10de_1199[] = {
680 { 0x1458, 0xd001, "GeForce GTX 760" }, 686 { 0x1458, 0xd001, "GeForce GTX 760" },
687 { 0x1462, 0x1106, "GeForce GTX 780M", { .War00C800_0 = true } }, /* Medion Erazer X7827 */
681 {} 688 {}
682}; 689};
683 690
@@ -1349,7 +1356,7 @@ nvkm_device_pci_10de[] = {
1349 { 0x0fc6, "GeForce GTX 650" }, 1356 { 0x0fc6, "GeForce GTX 650" },
1350 { 0x0fc8, "GeForce GT 740" }, 1357 { 0x0fc8, "GeForce GT 740" },
1351 { 0x0fc9, "GeForce GT 730" }, 1358 { 0x0fc9, "GeForce GT 730" },
1352 { 0x0fcd, "GeForce GT 755M" }, 1359 { 0x0fcd, "GeForce GT 755M", nvkm_device_pci_10de_0fcd },
1353 { 0x0fce, "GeForce GT 640M LE" }, 1360 { 0x0fce, "GeForce GT 640M LE" },
1354 { 0x0fd1, "GeForce GT 650M" }, 1361 { 0x0fd1, "GeForce GT 650M" },
1355 { 0x0fd2, "GeForce GT 640M", nvkm_device_pci_10de_0fd2 }, 1362 { 0x0fd2, "GeForce GT 640M", nvkm_device_pci_10de_0fd2 },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
index da57c8a60608..7f8a42721eb2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
@@ -85,6 +85,9 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
85 unsigned long pgsize_bitmap; 85 unsigned long pgsize_bitmap;
86 int ret; 86 int ret;
87 87
88 if (!tdev->func->iommu_bit)
89 return;
90
88 mutex_init(&tdev->iommu.mutex); 91 mutex_init(&tdev->iommu.mutex);
89 92
90 if (iommu_present(&platform_bus_type)) { 93 if (iommu_present(&platform_bus_type)) {
@@ -114,7 +117,8 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
114 goto free_domain; 117 goto free_domain;
115 118
116 ret = nvkm_mm_init(&tdev->iommu.mm, 0, 119 ret = nvkm_mm_init(&tdev->iommu.mm, 0,
117 (1ULL << 40) >> tdev->iommu.pgshift, 1); 120 (1ULL << tdev->func->iommu_bit) >>
121 tdev->iommu.pgshift, 1);
118 if (ret) 122 if (ret)
119 goto detach_device; 123 goto detach_device;
120 } 124 }
@@ -237,7 +241,8 @@ nvkm_device_tegra_func = {
237}; 241};
238 242
239int 243int
240nvkm_device_tegra_new(struct platform_device *pdev, 244nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
245 struct platform_device *pdev,
241 const char *cfg, const char *dbg, 246 const char *cfg, const char *dbg,
242 bool detect, bool mmio, u64 subdev_mask, 247 bool detect, bool mmio, u64 subdev_mask,
243 struct nvkm_device **pdevice) 248 struct nvkm_device **pdevice)
@@ -248,6 +253,7 @@ nvkm_device_tegra_new(struct platform_device *pdev,
248 if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL))) 253 if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL)))
249 return -ENOMEM; 254 return -ENOMEM;
250 *pdevice = &tdev->device; 255 *pdevice = &tdev->device;
256 tdev->func = func;
251 tdev->pdev = pdev; 257 tdev->pdev = pdev;
252 tdev->irq = -1; 258 tdev->irq = -1;
253 259
@@ -285,7 +291,8 @@ nvkm_device_tegra_new(struct platform_device *pdev,
285} 291}
286#else 292#else
287int 293int
288nvkm_device_tegra_new(struct platform_device *pdev, 294nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
295 struct platform_device *pdev,
289 const char *cfg, const char *dbg, 296 const char *cfg, const char *dbg,
290 bool detect, bool mmio, u64 subdev_mask, 297 bool detect, bool mmio, u64 subdev_mask,
291 struct nvkm_device **pdevice) 298 struct nvkm_device **pdevice)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv04.c
index 62d3fb66d0ec..2be846374d39 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv04.c
@@ -109,7 +109,7 @@ nv04_disp_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
109 return -EINVAL; 109 return -EINVAL;
110} 110}
111 111
112static struct nvkm_object_func 112static const struct nvkm_object_func
113nv04_disp_root = { 113nv04_disp_root = {
114 .mthd = nv04_disp_mthd, 114 .mthd = nv04_disp_mthd,
115 .ntfy = nvkm_disp_ntfy, 115 .ntfy = nvkm_disp_ntfy,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
index f1358a564e3e..dda7a7d224c9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -882,6 +882,7 @@ static const struct nvkm_enum gf100_mp_warp_error[] = {
882 { 0x0d, "GPR_OUT_OF_BOUNDS" }, 882 { 0x0d, "GPR_OUT_OF_BOUNDS" },
883 { 0x0e, "MEM_OUT_OF_BOUNDS" }, 883 { 0x0e, "MEM_OUT_OF_BOUNDS" },
884 { 0x0f, "UNALIGNED_MEM_ACCESS" }, 884 { 0x0f, "UNALIGNED_MEM_ACCESS" },
885 { 0x10, "INVALID_ADDR_SPACE" },
885 { 0x11, "INVALID_PARAM" }, 886 { 0x11, "INVALID_PARAM" },
886 {} 887 {}
887}; 888};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c
index d13187409d68..d081ee41fc14 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c
@@ -98,6 +98,7 @@ gf110_gr = {
98 { -1, -1, FERMI_B, &gf100_fermi }, 98 { -1, -1, FERMI_B, &gf100_fermi },
99 { -1, -1, FERMI_C, &gf100_fermi }, 99 { -1, -1, FERMI_C, &gf100_fermi },
100 { -1, -1, FERMI_COMPUTE_A }, 100 { -1, -1, FERMI_COMPUTE_A },
101 { -1, -1, FERMI_COMPUTE_B },
101 {} 102 {}
102 } 103 }
103}; 104};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c
index 28483d8bf3d2..d8e8af4d3b30 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c
@@ -135,6 +135,7 @@ gf117_gr = {
135 { -1, -1, FERMI_B, &gf100_fermi }, 135 { -1, -1, FERMI_B, &gf100_fermi },
136 { -1, -1, FERMI_C, &gf100_fermi }, 136 { -1, -1, FERMI_C, &gf100_fermi },
137 { -1, -1, FERMI_COMPUTE_A }, 137 { -1, -1, FERMI_COMPUTE_A },
138 { -1, -1, FERMI_COMPUTE_B },
138 {} 139 {}
139 } 140 }
140}; 141};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c
index 9811a72e0313..01faf9a73774 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c
@@ -189,6 +189,7 @@ gf119_gr = {
189 { -1, -1, FERMI_B, &gf100_fermi }, 189 { -1, -1, FERMI_B, &gf100_fermi },
190 { -1, -1, FERMI_C, &gf100_fermi }, 190 { -1, -1, FERMI_C, &gf100_fermi },
191 { -1, -1, FERMI_COMPUTE_A }, 191 { -1, -1, FERMI_COMPUTE_A },
192 { -1, -1, FERMI_COMPUTE_B },
192 {} 193 {}
193 } 194 }
194}; 195};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
index 0db9be202c42..2721592d3031 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
@@ -633,7 +633,7 @@ nvkm_perfmon_dtor(struct nvkm_object *object)
633 return perfmon; 633 return perfmon;
634} 634}
635 635
636static struct nvkm_object_func 636static const struct nvkm_object_func
637nvkm_perfmon = { 637nvkm_perfmon = {
638 .dtor = nvkm_perfmon_dtor, 638 .dtor = nvkm_perfmon_dtor,
639 .mthd = nvkm_perfmon_mthd, 639 .mthd = nvkm_perfmon_mthd,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pmu.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pmu.c
index 441ec451b788..c268e5afe852 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pmu.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pmu.c
@@ -62,19 +62,6 @@ nvbios_pmuTe(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
62} 62}
63 63
64u32 64u32
65nvbios_pmuTp(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
66 struct nvbios_pmuT *info)
67{
68 u32 data = nvbios_pmuTe(bios, ver, hdr, cnt, len);
69 memset(info, 0x00, sizeof(*info));
70 switch (!!data * *ver) {
71 default:
72 break;
73 }
74 return data;
75}
76
77u32
78nvbios_pmuEe(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr) 65nvbios_pmuEe(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr)
79{ 66{
80 u8 cnt, len; 67 u8 cnt, len;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
index f0e1fc74a52e..d0ae7454764e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/rammap.c
@@ -171,6 +171,7 @@ nvbios_rammapSp_from_perf(struct nvkm_bios *bios, u32 data, u8 size, int idx,
171 p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x03) & 0x04) >> 2; 171 p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x03) & 0x04) >> 2;
172 p->ramcfg_00_03_08 = (nvbios_rd08(bios, data + 0x03) & 0x08) >> 3; 172 p->ramcfg_00_03_08 = (nvbios_rd08(bios, data + 0x03) & 0x08) >> 3;
173 p->ramcfg_RON = (nvbios_rd08(bios, data + 0x03) & 0x10) >> 3; 173 p->ramcfg_RON = (nvbios_rd08(bios, data + 0x03) & 0x10) >> 3;
174 p->ramcfg_FBVDDQ = (nvbios_rd08(bios, data + 0x03) & 0x80) >> 7;
174 p->ramcfg_00_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1; 175 p->ramcfg_00_04_02 = (nvbios_rd08(bios, data + 0x04) & 0x02) >> 1;
175 p->ramcfg_00_04_04 = (nvbios_rd08(bios, data + 0x04) & 0x04) >> 2; 176 p->ramcfg_00_04_04 = (nvbios_rd08(bios, data + 0x04) & 0x04) >> 2;
176 p->ramcfg_00_04_20 = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5; 177 p->ramcfg_00_04_20 = (nvbios_rd08(bios, data + 0x04) & 0x20) >> 5;
@@ -205,6 +206,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
205 p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6; 206 p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x02) & 0x40) >> 6;
206 p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0; 207 p->ramcfg_10_03_0f = (nvbios_rd08(bios, data + 0x03) & 0x0f) >> 0;
207 p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 0; 208 p->ramcfg_10_04_01 = (nvbios_rd08(bios, data + 0x04) & 0x01) >> 0;
209 p->ramcfg_FBVDDQ = (nvbios_rd08(bios, data + 0x04) & 0x08) >> 3;
208 p->ramcfg_10_05 = (nvbios_rd08(bios, data + 0x05) & 0xff) >> 0; 210 p->ramcfg_10_05 = (nvbios_rd08(bios, data + 0x05) & 0xff) >> 0;
209 p->ramcfg_10_06 = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0; 211 p->ramcfg_10_06 = (nvbios_rd08(bios, data + 0x06) & 0xff) >> 0;
210 p->ramcfg_10_07 = (nvbios_rd08(bios, data + 0x07) & 0xff) >> 0; 212 p->ramcfg_10_07 = (nvbios_rd08(bios, data + 0x07) & 0xff) >> 0;
@@ -219,7 +221,7 @@ nvbios_rammapSp(struct nvkm_bios *bios, u32 data,
219 p->ramcfg_11_01_04 = (nvbios_rd08(bios, data + 0x01) & 0x04) >> 2; 221 p->ramcfg_11_01_04 = (nvbios_rd08(bios, data + 0x01) & 0x04) >> 2;
220 p->ramcfg_11_01_08 = (nvbios_rd08(bios, data + 0x01) & 0x08) >> 3; 222 p->ramcfg_11_01_08 = (nvbios_rd08(bios, data + 0x01) & 0x08) >> 3;
221 p->ramcfg_11_01_10 = (nvbios_rd08(bios, data + 0x01) & 0x10) >> 4; 223 p->ramcfg_11_01_10 = (nvbios_rd08(bios, data + 0x01) & 0x10) >> 4;
222 p->ramcfg_11_01_20 = (nvbios_rd08(bios, data + 0x01) & 0x20) >> 5; 224 p->ramcfg_DLLoff = (nvbios_rd08(bios, data + 0x01) & 0x20) >> 5;
223 p->ramcfg_11_01_40 = (nvbios_rd08(bios, data + 0x01) & 0x40) >> 6; 225 p->ramcfg_11_01_40 = (nvbios_rd08(bios, data + 0x01) & 0x40) >> 6;
224 p->ramcfg_11_01_80 = (nvbios_rd08(bios, data + 0x01) & 0x80) >> 7; 226 p->ramcfg_11_01_80 = (nvbios_rd08(bios, data + 0x01) & 0x80) >> 7;
225 p->ramcfg_11_02_03 = (nvbios_rd08(bios, data + 0x02) & 0x03) >> 0; 227 p->ramcfg_11_02_03 = (nvbios_rd08(bios, data + 0x02) & 0x03) >> 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c
index 615804c3887b..6e0a33648be9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c
@@ -73,15 +73,19 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
73 memset(info, 0x00, sizeof(*info)); 73 memset(info, 0x00, sizeof(*info));
74 switch (!!volt * *ver) { 74 switch (!!volt * *ver) {
75 case 0x12: 75 case 0x12:
76 info->type = NVBIOS_VOLT_GPIO;
76 info->vidmask = nvbios_rd08(bios, volt + 0x04); 77 info->vidmask = nvbios_rd08(bios, volt + 0x04);
77 break; 78 break;
78 case 0x20: 79 case 0x20:
80 info->type = NVBIOS_VOLT_GPIO;
79 info->vidmask = nvbios_rd08(bios, volt + 0x05); 81 info->vidmask = nvbios_rd08(bios, volt + 0x05);
80 break; 82 break;
81 case 0x30: 83 case 0x30:
84 info->type = NVBIOS_VOLT_GPIO;
82 info->vidmask = nvbios_rd08(bios, volt + 0x04); 85 info->vidmask = nvbios_rd08(bios, volt + 0x04);
83 break; 86 break;
84 case 0x40: 87 case 0x40:
88 info->type = NVBIOS_VOLT_GPIO;
85 info->base = nvbios_rd32(bios, volt + 0x04); 89 info->base = nvbios_rd32(bios, volt + 0x04);
86 info->step = nvbios_rd16(bios, volt + 0x08); 90 info->step = nvbios_rd16(bios, volt + 0x08);
87 info->vidmask = nvbios_rd08(bios, volt + 0x0b); 91 info->vidmask = nvbios_rd08(bios, volt + 0x0b);
@@ -90,11 +94,20 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
90 info->max = info->base; 94 info->max = info->base;
91 break; 95 break;
92 case 0x50: 96 case 0x50:
93 info->vidmask = nvbios_rd08(bios, volt + 0x06);
94 info->min = nvbios_rd32(bios, volt + 0x0a); 97 info->min = nvbios_rd32(bios, volt + 0x0a);
95 info->max = nvbios_rd32(bios, volt + 0x0e); 98 info->max = nvbios_rd32(bios, volt + 0x0e);
96 info->base = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff; 99 info->base = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff;
97 info->step = nvbios_rd16(bios, volt + 0x16); 100
101 /* offset 4 seems to be a flag byte */
102 if (nvbios_rd32(bios, volt + 0x4) & 1) {
103 info->type = NVBIOS_VOLT_PWM;
104 info->pwm_freq = nvbios_rd32(bios, volt + 0x5) / 1000;
105 info->pwm_range = nvbios_rd32(bios, volt + 0x16);
106 } else {
107 info->type = NVBIOS_VOLT_GPIO;
108 info->vidmask = nvbios_rd08(bios, volt + 0x06);
109 info->step = nvbios_rd16(bios, volt + 0x16);
110 }
98 break; 111 break;
99 } 112 }
100 return volt; 113 return volt;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c
index 79f1cf513b36..2a5668938f2f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c
@@ -132,6 +132,38 @@ nvkm_hwsq_wait(struct nvkm_hwsq *hwsq, u8 flag, u8 data)
132} 132}
133 133
134void 134void
135nvkm_hwsq_wait_vblank(struct nvkm_hwsq *hwsq)
136{
137 struct nvkm_subdev *subdev = hwsq->subdev;
138 struct nvkm_device *device = subdev->device;
139 u32 heads, x, y, px = 0;
140 int i, head_sync;
141
142 heads = nvkm_rd32(device, 0x610050);
143 for (i = 0; i < 2; i++) {
144 /* Heuristic: sync to head with biggest resolution */
145 if (heads & (2 << (i << 3))) {
146 x = nvkm_rd32(device, 0x610b40 + (0x540 * i));
147 y = (x & 0xffff0000) >> 16;
148 x &= 0x0000ffff;
149 if ((x * y) > px) {
150 px = (x * y);
151 head_sync = i;
152 }
153 }
154 }
155
156 if (px == 0) {
157 nvkm_debug(subdev, "WAIT VBLANK !NO ACTIVE HEAD\n");
158 return;
159 }
160
161 nvkm_debug(subdev, "WAIT VBLANK HEAD%d\n", head_sync);
162 nvkm_hwsq_wait(hwsq, head_sync ? 0x3 : 0x1, 0x0);
163 nvkm_hwsq_wait(hwsq, head_sync ? 0x3 : 0x1, 0x1);
164}
165
166void
135nvkm_hwsq_nsec(struct nvkm_hwsq *hwsq, u32 nsec) 167nvkm_hwsq_nsec(struct nvkm_hwsq *hwsq, u32 nsec)
136{ 168{
137 u8 shift = 0, usec = nsec / 1000; 169 u8 shift = 0, usec = nsec / 1000;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h
index 8117ec5a1468..54ec3b131dfd 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.h
@@ -134,6 +134,12 @@ hwsq_wait(struct hwsq *ram, u8 flag, u8 data)
134} 134}
135 135
136static inline void 136static inline void
137hwsq_wait_vblank(struct hwsq *ram)
138{
139 nvkm_hwsq_wait_vblank(ram->hwsq);
140}
141
142static inline void
137hwsq_nsec(struct hwsq *ram, u32 nsec) 143hwsq_nsec(struct hwsq *ram, u32 nsec)
138{ 144{
139 nvkm_hwsq_nsec(ram->hwsq, nsec); 145 nvkm_hwsq_nsec(ram->hwsq, nsec);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c
index 347da9ee20f5..f97e3ec196bb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/g84.c
@@ -44,5 +44,5 @@ int
44g84_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk) 44g84_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
45{ 45{
46 return nv50_clk_new_(&g84_clk, device, index, 46 return nv50_clk_new_(&g84_clk, device, index,
47 (device->chipset == 0xa0), pclk); 47 (device->chipset >= 0x94), pclk);
48} 48}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
index 79b523aa52aa..60ece0a8a2e1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr3.c
@@ -63,7 +63,7 @@ ramgddr3_wr_lo[] = {
63 { 5, 2 }, { 7, 4 }, { 8, 5 }, { 9, 6 }, { 10, 7 }, 63 { 5, 2 }, { 7, 4 }, { 8, 5 }, { 9, 6 }, { 10, 7 },
64 { 11, 0 }, { 13 , 1 }, 64 { 11, 0 }, { 13 , 1 },
65 /* the below are mentioned in some, but not all, gddr3 docs */ 65 /* the below are mentioned in some, but not all, gddr3 docs */
66 { 4, 1 }, { 6, 3 }, { 12, 1 }, 66 { 4, 0 }, { 6, 3 }, { 12, 1 },
67 { -1 } 67 { -1 }
68}; 68};
69 69
@@ -87,15 +87,17 @@ nvkm_gddr3_calc(struct nvkm_ram *ram)
87 WR = (ram->next->bios.timing[2] & 0x007f0000) >> 16; 87 WR = (ram->next->bios.timing[2] & 0x007f0000) >> 16;
88 /* XXX: Get these values from the VBIOS instead */ 88 /* XXX: Get these values from the VBIOS instead */
89 DLL = !(ram->mr[1] & 0x1); 89 DLL = !(ram->mr[1] & 0x1);
90 ODT = (ram->mr[1] & 0x004) >> 2 |
91 (ram->mr[1] & 0x040) >> 5 |
92 (ram->mr[1] & 0x200) >> 7;
93 RON = !(ram->mr[1] & 0x300) >> 8; 90 RON = !(ram->mr[1] & 0x300) >> 8;
94 break; 91 break;
95 default: 92 default:
96 return -ENOSYS; 93 return -ENOSYS;
97 } 94 }
98 95
96 if (ram->next->bios.timing_ver == 0x20 ||
97 ram->next->bios.ramcfg_timing == 0xff) {
98 ODT = (ram->mr[1] & 0xc) >> 2;
99 }
100
99 hi = ram->mr[2] & 0x1; 101 hi = ram->mr[2] & 0x1;
100 CL = ramxlat(hi ? ramgddr3_cl_hi : ramgddr3_cl_lo, CL); 102 CL = ramxlat(hi ? ramgddr3_cl_hi : ramgddr3_cl_lo, CL);
101 WR = ramxlat(ramgddr3_wr_lo, WR); 103 WR = ramxlat(ramgddr3_wr_lo, WR);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
index 24f83b09e6a1..2cc074d3901a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gddr5.c
@@ -38,11 +38,12 @@ nvkm_gddr5_calc(struct nvkm_ram *ram, bool nuts)
38 int WL, CL, WR, at[2], dt, ds; 38 int WL, CL, WR, at[2], dt, ds;
39 int rq = ram->freq < 1000000; /* XXX */ 39 int rq = ram->freq < 1000000; /* XXX */
40 40
41 xd = !ram->next->bios.ramcfg_DLLoff;
42
41 switch (ram->next->bios.ramcfg_ver) { 43 switch (ram->next->bios.ramcfg_ver) {
42 case 0x11: 44 case 0x11:
43 pd = ram->next->bios.ramcfg_11_01_80; 45 pd = ram->next->bios.ramcfg_11_01_80;
44 lf = ram->next->bios.ramcfg_11_01_40; 46 lf = ram->next->bios.ramcfg_11_01_40;
45 xd = !ram->next->bios.ramcfg_11_01_20;
46 vh = ram->next->bios.ramcfg_11_02_10; 47 vh = ram->next->bios.ramcfg_11_02_10;
47 vr = ram->next->bios.ramcfg_11_02_04; 48 vr = ram->next->bios.ramcfg_11_02_04;
48 vo = ram->next->bios.ramcfg_11_06; 49 vo = ram->next->bios.ramcfg_11_06;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
index 989355622aac..9df45030ff9f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c
@@ -673,6 +673,25 @@ gk104_ram_calc_gddr5(struct gk104_ram *ram, u32 freq)
673 * DDR3 673 * DDR3
674 ******************************************************************************/ 674 ******************************************************************************/
675 675
676static void
677nvkm_sddr3_dll_reset(struct gk104_ramfuc *fuc)
678{
679 ram_nuke(fuc, mr[0]);
680 ram_mask(fuc, mr[0], 0x100, 0x100);
681 ram_mask(fuc, mr[0], 0x100, 0x000);
682}
683
684static void
685nvkm_sddr3_dll_disable(struct gk104_ramfuc *fuc)
686{
687 u32 mr1_old = ram_rd32(fuc, mr[1]);
688
689 if (!(mr1_old & 0x1)) {
690 ram_mask(fuc, mr[1], 0x1, 0x1);
691 ram_nsec(fuc, 1000);
692 }
693}
694
676static int 695static int
677gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq) 696gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
678{ 697{
@@ -702,6 +721,10 @@ gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
702 ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000); 721 ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000);
703 722
704 ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */ 723 ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */
724
725 if (next->bios.ramcfg_DLLoff)
726 nvkm_sddr3_dll_disable(fuc);
727
705 ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */ 728 ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */
706 ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */ 729 ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */
707 ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000); 730 ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000);
@@ -879,17 +902,20 @@ gk104_ram_calc_sddr3(struct gk104_ram *ram, u32 freq)
879 ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */ 902 ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */
880 ram_nsec(fuc, 1000); 903 ram_nsec(fuc, 1000);
881 904
882 ram_nuke(fuc, mr[0]); 905 if (!next->bios.ramcfg_DLLoff) {
883 ram_mask(fuc, mr[0], 0x100, 0x100); 906 ram_mask(fuc, mr[1], 0x1, 0x0);
884 ram_mask(fuc, mr[0], 0x100, 0x000); 907 nvkm_sddr3_dll_reset(fuc);
908 }
885 909
886 ram_mask(fuc, mr[2], 0xfff, ram->base.mr[2]); 910 ram_mask(fuc, mr[2], 0x00000fff, ram->base.mr[2]);
911 ram_mask(fuc, mr[1], 0xffffffff, ram->base.mr[1]);
887 ram_wr32(fuc, mr[0], ram->base.mr[0]); 912 ram_wr32(fuc, mr[0], ram->base.mr[0]);
888 ram_nsec(fuc, 1000); 913 ram_nsec(fuc, 1000);
889 914
890 ram_nuke(fuc, mr[0]); 915 if (!next->bios.ramcfg_DLLoff) {
891 ram_mask(fuc, mr[0], 0x100, 0x100); 916 nvkm_sddr3_dll_reset(fuc);
892 ram_mask(fuc, mr[0], 0x100, 0x000); 917 ram_nsec(fuc, 1000);
918 }
893 919
894 if (vc == 0 && ram_have(fuc, gpio2E)) { 920 if (vc == 0 && ram_have(fuc, gpio2E)) {
895 u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]); 921 u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]);
@@ -945,6 +971,67 @@ gk104_ram_calc_data(struct gk104_ram *ram, u32 khz, struct nvkm_ram_data *data)
945} 971}
946 972
947static int 973static int
974gk104_calc_pll_output(int fN, int M, int N, int P, int clk)
975{
976 return ((clk * N) + (((u16)(fN + 4096) * clk) >> 13)) / (M * P);
977}
978
979static int
980gk104_pll_calc_hiclk(int target_khz, int crystal,
981 int *N1, int *fN1, int *M1, int *P1,
982 int *N2, int *M2, int *P2)
983{
984 int best_clk = 0, best_err = target_khz, p_ref, n_ref;
985 bool upper = false;
986
987 *M1 = 1;
988 /* M has to be 1, otherwise it gets unstable */
989 *M2 = 1;
990 /* can be 1 or 2, sticking with 1 for simplicity */
991 *P2 = 1;
992
993 for (p_ref = 0x7; p_ref >= 0x5; --p_ref) {
994 for (n_ref = 0x25; n_ref <= 0x2b; ++n_ref) {
995 int cur_N, cur_clk, cur_err;
996
997 cur_clk = gk104_calc_pll_output(0, 1, n_ref, p_ref, crystal);
998 cur_N = target_khz / cur_clk;
999 cur_err = target_khz
1000 - gk104_calc_pll_output(0xf000, 1, cur_N, 1, cur_clk);
1001
1002 /* we found a better combination */
1003 if (cur_err < best_err) {
1004 best_err = cur_err;
1005 best_clk = cur_clk;
1006 *N2 = cur_N;
1007 *N1 = n_ref;
1008 *P1 = p_ref;
1009 upper = false;
1010 }
1011
1012 cur_N += 1;
1013 cur_err = gk104_calc_pll_output(0xf000, 1, cur_N, 1, cur_clk)
1014 - target_khz;
1015 if (cur_err < best_err) {
1016 best_err = cur_err;
1017 best_clk = cur_clk;
1018 *N2 = cur_N;
1019 *N1 = n_ref;
1020 *P1 = p_ref;
1021 upper = true;
1022 }
1023 }
1024 }
1025
1026 /* adjust fN to get closer to the target clock */
1027 *fN1 = (u16)((((best_err / *N2 * *P2) * (*P1 * *M1)) << 13) / crystal);
1028 if (upper)
1029 *fN1 = (u16)(1 - *fN1);
1030
1031 return gk104_calc_pll_output(*fN1, 1, *N1, *P1, crystal);
1032}
1033
1034static int
948gk104_ram_calc_xits(struct gk104_ram *ram, struct nvkm_ram_data *next) 1035gk104_ram_calc_xits(struct gk104_ram *ram, struct nvkm_ram_data *next)
949{ 1036{
950 struct gk104_ramfuc *fuc = &ram->fuc; 1037 struct gk104_ramfuc *fuc = &ram->fuc;
@@ -968,31 +1055,24 @@ gk104_ram_calc_xits(struct gk104_ram *ram, struct nvkm_ram_data *next)
968 * kepler boards, no idea how/why they're chosen. 1055 * kepler boards, no idea how/why they're chosen.
969 */ 1056 */
970 refclk = next->freq; 1057 refclk = next->freq;
971 if (ram->mode == 2)
972 refclk = fuc->mempll.refclk;
973
974 /* calculate refpll coefficients */
975 ret = gt215_pll_calc(subdev, &fuc->refpll, refclk, &ram->N1,
976 &ram->fN1, &ram->M1, &ram->P1);
977 fuc->mempll.refclk = ret;
978 if (ret <= 0) {
979 nvkm_error(subdev, "unable to calc refpll\n");
980 return -EINVAL;
981 }
982
983 /* calculate mempll coefficients, if we're using it */
984 if (ram->mode == 2) { 1058 if (ram->mode == 2) {
985 /* post-divider doesn't work... the reg takes the values but 1059 ret = gk104_pll_calc_hiclk(next->freq, subdev->device->crystal,
986 * appears to completely ignore it. there *is* a bit at 1060 &ram->N1, &ram->fN1, &ram->M1, &ram->P1,
987 * bit 28 that appears to divide the clock by 2 if set. 1061 &ram->N2, &ram->M2, &ram->P2);
988 */ 1062 fuc->mempll.refclk = ret;
989 fuc->mempll.min_p = 1; 1063 if (ret <= 0) {
990 fuc->mempll.max_p = 2; 1064 nvkm_error(subdev, "unable to calc plls\n");
991 1065 return -EINVAL;
992 ret = gt215_pll_calc(subdev, &fuc->mempll, next->freq, 1066 }
993 &ram->N2, NULL, &ram->M2, &ram->P2); 1067 nvkm_debug(subdev, "sucessfully calced PLLs for clock %i kHz"
1068 " (refclock: %i kHz)\n", next->freq, ret);
1069 } else {
1070 /* calculate refpll coefficients */
1071 ret = gt215_pll_calc(subdev, &fuc->refpll, refclk, &ram->N1,
1072 &ram->fN1, &ram->M1, &ram->P1);
1073 fuc->mempll.refclk = ret;
994 if (ret <= 0) { 1074 if (ret <= 0) {
995 nvkm_error(subdev, "unable to calc mempll\n"); 1075 nvkm_error(subdev, "unable to calc refpll\n");
996 return -EINVAL; 1076 return -EINVAL;
997 } 1077 }
998 } 1078 }
@@ -1600,6 +1680,7 @@ gk104_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
1600 break; 1680 break;
1601 case NVKM_RAM_TYPE_DDR3: 1681 case NVKM_RAM_TYPE_DDR3:
1602 ram->fuc.r_mr[0] = ramfuc_reg(0x10f300); 1682 ram->fuc.r_mr[0] = ramfuc_reg(0x10f300);
1683 ram->fuc.r_mr[1] = ramfuc_reg(0x10f304);
1603 ram->fuc.r_mr[2] = ramfuc_reg(0x10f320); 1684 ram->fuc.r_mr[2] = ramfuc_reg(0x10f320);
1604 break; 1685 break;
1605 default: 1686 default:
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
index 5c08ae8023fa..d15ea886df27 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
@@ -34,9 +34,6 @@
34#include <subdev/clk/gt215.h> 34#include <subdev/clk/gt215.h>
35#include <subdev/gpio.h> 35#include <subdev/gpio.h>
36 36
37/* XXX: Remove when memx gains GPIO support */
38extern int nv50_gpio_location(int line, u32 *reg, u32 *shift);
39
40struct gt215_ramfuc { 37struct gt215_ramfuc {
41 struct ramfuc base; 38 struct ramfuc base;
42 struct ramfuc_reg r_0x001610; 39 struct ramfuc_reg r_0x001610;
@@ -75,7 +72,7 @@ struct gt215_ramfuc {
75 struct ramfuc_reg r_0x111400; 72 struct ramfuc_reg r_0x111400;
76 struct ramfuc_reg r_0x611200; 73 struct ramfuc_reg r_0x611200;
77 struct ramfuc_reg r_mr[4]; 74 struct ramfuc_reg r_mr[4];
78 struct ramfuc_reg r_gpioFBVREF; 75 struct ramfuc_reg r_gpio[4];
79}; 76};
80 77
81struct gt215_ltrain { 78struct gt215_ltrain {
@@ -466,24 +463,27 @@ gt215_ram_lock_pll(struct gt215_ramfuc *fuc, struct gt215_clk_info *mclk)
466} 463}
467 464
468static void 465static void
469gt215_ram_fbvref(struct gt215_ramfuc *fuc, u32 val) 466gt215_ram_gpio(struct gt215_ramfuc *fuc, u8 tag, u32 val)
470{ 467{
471 struct nvkm_gpio *gpio = fuc->base.fb->subdev.device->gpio; 468 struct nvkm_gpio *gpio = fuc->base.fb->subdev.device->gpio;
472 struct dcb_gpio_func func; 469 struct dcb_gpio_func func;
473 u32 reg, sh, gpio_val; 470 u32 reg, sh, gpio_val;
474 int ret; 471 int ret;
475 472
476 if (nvkm_gpio_get(gpio, 0, 0x2e, DCB_GPIO_UNUSED) != val) { 473 if (nvkm_gpio_get(gpio, 0, tag, DCB_GPIO_UNUSED) != val) {
477 ret = nvkm_gpio_find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func); 474 ret = nvkm_gpio_find(gpio, 0, tag, DCB_GPIO_UNUSED, &func);
478 if (ret) 475 if (ret)
479 return; 476 return;
480 477
481 nv50_gpio_location(func.line, &reg, &sh); 478 reg = func.line >> 3;
482 gpio_val = ram_rd32(fuc, gpioFBVREF); 479 sh = (func.line & 0x7) << 2;
480 gpio_val = ram_rd32(fuc, gpio[reg]);
483 if (gpio_val & (8 << sh)) 481 if (gpio_val & (8 << sh))
484 val = !val; 482 val = !val;
483 if (!(func.log[1] & 1))
484 val = !val;
485 485
486 ram_mask(fuc, gpioFBVREF, (0x3 << sh), ((val | 0x2) << sh)); 486 ram_mask(fuc, gpio[reg], (0x3 << sh), ((val | 0x2) << sh));
487 ram_nsec(fuc, 20000); 487 ram_nsec(fuc, 20000);
488 } 488 }
489} 489}
@@ -498,6 +498,7 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
498 struct nvkm_device *device = subdev->device; 498 struct nvkm_device *device = subdev->device;
499 struct nvkm_bios *bios = device->bios; 499 struct nvkm_bios *bios = device->bios;
500 struct gt215_clk_info mclk; 500 struct gt215_clk_info mclk;
501 struct nvkm_gpio *gpio = device->gpio;
501 struct nvkm_ram_data *next; 502 struct nvkm_ram_data *next;
502 u8 ver, hdr, cnt, len, strap; 503 u8 ver, hdr, cnt, len, strap;
503 u32 data; 504 u32 data;
@@ -642,8 +643,8 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
642 break; 643 break;
643 } 644 }
644 645
645 if (fuc->r_gpioFBVREF.addr && next->bios.timing_10_ODT) 646 if (next->bios.timing_10_ODT)
646 gt215_ram_fbvref(fuc, 0); 647 gt215_ram_gpio(fuc, 0x2e, 1);
647 648
648 /* Brace RAM for impact */ 649 /* Brace RAM for impact */
649 ram_wr32(fuc, 0x1002d4, 0x00000001); 650 ram_wr32(fuc, 0x1002d4, 0x00000001);
@@ -656,6 +657,23 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
656 if (device->chipset == 0xa3 && freq <= 500000) 657 if (device->chipset == 0xa3 && freq <= 500000)
657 ram_mask(fuc, 0x100700, 0x00000006, 0x00000006); 658 ram_mask(fuc, 0x100700, 0x00000006, 0x00000006);
658 659
660 /* Alter FBVDD/Q, apparently must be done with PLL disabled, thus
661 * set it to bypass */
662 if (nvkm_gpio_get(gpio, 0, 0x18, DCB_GPIO_UNUSED) ==
663 next->bios.ramcfg_FBVDDQ) {
664 data = ram_rd32(fuc, 0x004000) & 0x9;
665
666 if (data == 0x1)
667 ram_mask(fuc, 0x004000, 0x8, 0x8);
668 if (data & 0x1)
669 ram_mask(fuc, 0x004000, 0x1, 0x0);
670
671 gt215_ram_gpio(fuc, 0x18, !next->bios.ramcfg_FBVDDQ);
672
673 if (data & 0x1)
674 ram_mask(fuc, 0x004000, 0x1, 0x1);
675 }
676
659 /* Fiddle with clocks */ 677 /* Fiddle with clocks */
660 /* There's 4 scenario's 678 /* There's 4 scenario's
661 * pll->pll: first switch to a 324MHz clock, set up new PLL, switch 679 * pll->pll: first switch to a 324MHz clock, set up new PLL, switch
@@ -753,39 +771,43 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
753 unk71c = ram_rd32(fuc, 0x10071c) & ~0x00000100; 771 unk71c = ram_rd32(fuc, 0x10071c) & ~0x00000100;
754 r111100 = ram_rd32(fuc, 0x111100) & ~0x3a800000; 772 r111100 = ram_rd32(fuc, 0x111100) & ~0x3a800000;
755 773
756 if (next->bios.ramcfg_10_02_04) { 774 /* NVA8 seems to skip various bits related to ramcfg_10_02_04 */
757 switch (ram->base.type) { 775 if (device->chipset == 0xa8) {
758 case NVKM_RAM_TYPE_DDR3: 776 r111100 |= 0x08000000;
759 if (device->chipset != 0xa8) 777 if (!next->bios.ramcfg_10_02_04)
760 r111100 |= 0x00000004;
761 /* no break */
762 case NVKM_RAM_TYPE_DDR2:
763 r111100 |= 0x08000000;
764 break;
765 default:
766 break;
767 }
768 } else {
769 switch (ram->base.type) {
770 case NVKM_RAM_TYPE_DDR2:
771 r111100 |= 0x1a800000;
772 unk714 |= 0x00000010; 778 unk714 |= 0x00000010;
773 break; 779 } else {
774 case NVKM_RAM_TYPE_DDR3: 780 if (next->bios.ramcfg_10_02_04) {
775 if (device->chipset == 0xa8) { 781 switch (ram->base.type) {
776 r111100 |= 0x08000000; 782 case NVKM_RAM_TYPE_DDR2:
777 } else { 783 case NVKM_RAM_TYPE_DDR3:
778 r111100 &= ~0x00000004; 784 r111100 &= ~0x00000020;
785 if (next->bios.ramcfg_10_02_10)
786 r111100 |= 0x08000004;
787 else
788 r111100 |= 0x00000024;
789 break;
790 default:
791 break;
792 }
793 } else {
794 switch (ram->base.type) {
795 case NVKM_RAM_TYPE_DDR2:
796 case NVKM_RAM_TYPE_DDR3:
797 r111100 &= ~0x00000024;
779 r111100 |= 0x12800000; 798 r111100 |= 0x12800000;
799
800 if (next->bios.ramcfg_10_02_10)
801 r111100 |= 0x08000000;
802 unk714 |= 0x00000010;
803 break;
804 case NVKM_RAM_TYPE_GDDR3:
805 r111100 |= 0x30000000;
806 unk714 |= 0x00000020;
807 break;
808 default:
809 break;
780 } 810 }
781 unk714 |= 0x00000010;
782 break;
783 case NVKM_RAM_TYPE_GDDR3:
784 r111100 |= 0x30000000;
785 unk714 |= 0x00000020;
786 break;
787 default:
788 break;
789 } 811 }
790 } 812 }
791 813
@@ -809,8 +831,8 @@ gt215_ram_calc(struct nvkm_ram *base, u32 freq)
809 ram_mask(fuc, 0x100718, 0xffffffff, unk718); 831 ram_mask(fuc, 0x100718, 0xffffffff, unk718);
810 ram_mask(fuc, 0x111100, 0xffffffff, r111100); 832 ram_mask(fuc, 0x111100, 0xffffffff, r111100);
811 833
812 if (fuc->r_gpioFBVREF.addr && !next->bios.timing_10_ODT) 834 if (!next->bios.timing_10_ODT)
813 gt215_ram_fbvref(fuc, 1); 835 gt215_ram_gpio(fuc, 0x2e, 0);
814 836
815 /* Reset DLL */ 837 /* Reset DLL */
816 if (!next->bios.ramcfg_DLLoff) 838 if (!next->bios.ramcfg_DLLoff)
@@ -919,10 +941,7 @@ gt215_ram_func = {
919int 941int
920gt215_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) 942gt215_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
921{ 943{
922 struct nvkm_gpio *gpio = fb->subdev.device->gpio;
923 struct dcb_gpio_func func;
924 struct gt215_ram *ram; 944 struct gt215_ram *ram;
925 u32 reg, shift;
926 int ret, i; 945 int ret, i;
927 946
928 if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL))) 947 if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL)))
@@ -981,12 +1000,10 @@ gt215_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
981 ram->fuc.r_mr[2] = ramfuc_reg(0x1002e0); 1000 ram->fuc.r_mr[2] = ramfuc_reg(0x1002e0);
982 ram->fuc.r_mr[3] = ramfuc_reg(0x1002e4); 1001 ram->fuc.r_mr[3] = ramfuc_reg(0x1002e4);
983 } 1002 }
984 1003 ram->fuc.r_gpio[0] = ramfuc_reg(0x00e104);
985 ret = nvkm_gpio_find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func); 1004 ram->fuc.r_gpio[1] = ramfuc_reg(0x00e108);
986 if (ret == 0) { 1005 ram->fuc.r_gpio[2] = ramfuc_reg(0x00e120);
987 nv50_gpio_location(func.line, &reg, &shift); 1006 ram->fuc.r_gpio[3] = ramfuc_reg(0x00e124);
988 ram->fuc.r_gpioFBVREF = ramfuc_reg(reg);
989 }
990 1007
991 return 0; 1008 return 0;
992} 1009}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
index 9197e0ef5cdb..87bde8ff2d6b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c
@@ -33,6 +33,7 @@
33#include <subdev/bios/rammap.h> 33#include <subdev/bios/rammap.h>
34#include <subdev/bios/timing.h> 34#include <subdev/bios/timing.h>
35#include <subdev/clk/pll.h> 35#include <subdev/clk/pll.h>
36#include <subdev/gpio.h>
36 37
37struct nv50_ramseq { 38struct nv50_ramseq {
38 struct hwsq base; 39 struct hwsq base;
@@ -59,6 +60,7 @@ struct nv50_ramseq {
59 struct hwsq_reg r_0x611200; 60 struct hwsq_reg r_0x611200;
60 struct hwsq_reg r_timing[9]; 61 struct hwsq_reg r_timing[9];
61 struct hwsq_reg r_mr[4]; 62 struct hwsq_reg r_mr[4];
63 struct hwsq_reg r_gpio[4];
62}; 64};
63 65
64struct nv50_ram { 66struct nv50_ram {
@@ -144,6 +146,38 @@ nv50_ram_timing_calc(struct nv50_ram *ram, u32 *timing)
144 nvkm_debug(subdev, " 240: %08x\n", timing[8]); 146 nvkm_debug(subdev, " 240: %08x\n", timing[8]);
145 return 0; 147 return 0;
146} 148}
149
150static int
151nv50_ram_timing_read(struct nv50_ram *ram, u32 *timing)
152{
153 unsigned int i;
154 struct nvbios_ramcfg *cfg = &ram->base.target.bios;
155 struct nvkm_subdev *subdev = &ram->base.fb->subdev;
156 struct nvkm_device *device = subdev->device;
157
158 for (i = 0; i <= 8; i++)
159 timing[i] = nvkm_rd32(device, 0x100220 + (i * 4));
160
161 /* Derive the bare minimum for the MR calculation to succeed */
162 cfg->timing_ver = 0x10;
163 T(CL) = (timing[3] & 0xff) + 1;
164
165 switch (ram->base.type) {
166 case NVKM_RAM_TYPE_DDR2:
167 T(CWL) = T(CL) - 1;
168 break;
169 case NVKM_RAM_TYPE_GDDR3:
170 T(CWL) = ((timing[2] & 0xff000000) >> 24) + 1;
171 break;
172 default:
173 return -ENOSYS;
174 break;
175 }
176
177 T(WR) = ((timing[1] >> 24) & 0xff) - 1 - T(CWL);
178
179 return 0;
180}
147#undef T 181#undef T
148 182
149static void 183static void
@@ -154,6 +188,33 @@ nvkm_sddr2_dll_reset(struct nv50_ramseq *hwsq)
154 ram_nsec(hwsq, 24000); 188 ram_nsec(hwsq, 24000);
155} 189}
156 190
191static void
192nv50_ram_gpio(struct nv50_ramseq *hwsq, u8 tag, u32 val)
193{
194 struct nvkm_gpio *gpio = hwsq->base.subdev->device->gpio;
195 struct dcb_gpio_func func;
196 u32 reg, sh, gpio_val;
197 int ret;
198
199 if (nvkm_gpio_get(gpio, 0, tag, DCB_GPIO_UNUSED) != val) {
200 ret = nvkm_gpio_find(gpio, 0, tag, DCB_GPIO_UNUSED, &func);
201 if (ret)
202 return;
203
204 reg = func.line >> 3;
205 sh = (func.line & 0x7) << 2;
206 gpio_val = ram_rd32(hwsq, gpio[reg]);
207
208 if (gpio_val & (8 << sh))
209 val = !val;
210 if (!(func.log[1] & 1))
211 val = !val;
212
213 ram_mask(hwsq, gpio[reg], (0x3 << sh), ((val | 0x2) << sh));
214 ram_nsec(hwsq, 20000);
215 }
216}
217
157static int 218static int
158nv50_ram_calc(struct nvkm_ram *base, u32 freq) 219nv50_ram_calc(struct nvkm_ram *base, u32 freq)
159{ 220{
@@ -213,10 +274,11 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
213 strap, data, ver, hdr); 274 strap, data, ver, hdr);
214 return -EINVAL; 275 return -EINVAL;
215 } 276 }
277 nv50_ram_timing_calc(ram, timing);
278 } else {
279 nv50_ram_timing_read(ram, timing);
216 } 280 }
217 281
218 nv50_ram_timing_calc(ram, timing);
219
220 ret = ram_init(hwsq, subdev); 282 ret = ram_init(hwsq, subdev);
221 if (ret) 283 if (ret)
222 return ret; 284 return ret;
@@ -235,14 +297,18 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
235 break; 297 break;
236 } 298 }
237 299
238 if (ret) 300 if (ret) {
301 nvkm_error(subdev, "Could not calculate MR\n");
239 return ret; 302 return ret;
303 }
304
305 if (subdev->device->chipset <= 0x96 && !next->bios.ramcfg_00_03_02)
306 ram_mask(hwsq, 0x100710, 0x00000200, 0x00000000);
240 307
241 /* Always disable this bit during reclock */ 308 /* Always disable this bit during reclock */
242 ram_mask(hwsq, 0x100200, 0x00000800, 0x00000000); 309 ram_mask(hwsq, 0x100200, 0x00000800, 0x00000000);
243 310
244 ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */ 311 ram_wait_vblank(hwsq);
245 ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */
246 ram_wr32(hwsq, 0x611200, 0x00003300); 312 ram_wr32(hwsq, 0x611200, 0x00003300);
247 ram_wr32(hwsq, 0x002504, 0x00000001); /* block fifo */ 313 ram_wr32(hwsq, 0x002504, 0x00000001); /* block fifo */
248 ram_nsec(hwsq, 8000); 314 ram_nsec(hwsq, 8000);
@@ -250,6 +316,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
250 ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */ 316 ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */
251 ram_nsec(hwsq, 2000); 317 ram_nsec(hwsq, 2000);
252 318
319 if (next->bios.timing_10_ODT)
320 nv50_ram_gpio(hwsq, 0x2e, 1);
321
253 ram_wr32(hwsq, 0x1002d4, 0x00000001); /* precharge */ 322 ram_wr32(hwsq, 0x1002d4, 0x00000001); /* precharge */
254 ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */ 323 ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
255 ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */ 324 ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */
@@ -286,8 +355,12 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
286 next->bios.rammap_00_16_40 << 14); 355 next->bios.rammap_00_16_40 << 14);
287 ram_mask(hwsq, 0x00400c, 0x0000ffff, (N1 << 8) | M1); 356 ram_mask(hwsq, 0x00400c, 0x0000ffff, (N1 << 8) | M1);
288 ram_mask(hwsq, 0x004008, 0x91ff0000, r004008); 357 ram_mask(hwsq, 0x004008, 0x91ff0000, r004008);
289 if (subdev->device->chipset >= 0x96) 358
359 /* XXX: GDDR3 only? */
360 if (subdev->device->chipset >= 0x92)
290 ram_wr32(hwsq, 0x100da0, r100da0); 361 ram_wr32(hwsq, 0x100da0, r100da0);
362
363 nv50_ram_gpio(hwsq, 0x18, !next->bios.ramcfg_FBVDDQ);
291 ram_nsec(hwsq, 64000); /*XXX*/ 364 ram_nsec(hwsq, 64000); /*XXX*/
292 ram_nsec(hwsq, 32000); /*XXX*/ 365 ram_nsec(hwsq, 32000); /*XXX*/
293 366
@@ -329,19 +402,33 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
329 ram_mask(hwsq, 0x100200, 0x00001000, !next->bios.ramcfg_00_04_02 << 12); 402 ram_mask(hwsq, 0x100200, 0x00001000, !next->bios.ramcfg_00_04_02 << 12);
330 403
331 /* XXX: A lot of this could be "chipset"/"ram type" specific stuff */ 404 /* XXX: A lot of this could be "chipset"/"ram type" specific stuff */
332 unk710 = ram_rd32(hwsq, 0x100710) & ~0x00000101; 405 unk710 = ram_rd32(hwsq, 0x100710) & ~0x00000100;
333 unk714 = ram_rd32(hwsq, 0x100714) & ~0xf0000020; 406 unk714 = ram_rd32(hwsq, 0x100714) & ~0xf0000020;
334 unk718 = ram_rd32(hwsq, 0x100718) & ~0x00000100; 407 unk718 = ram_rd32(hwsq, 0x100718) & ~0x00000100;
335 unk71c = ram_rd32(hwsq, 0x10071c) & ~0x00000100; 408 unk71c = ram_rd32(hwsq, 0x10071c) & ~0x00000100;
409 if (subdev->device->chipset <= 0x96) {
410 unk710 &= ~0x0000006e;
411 unk714 &= ~0x00000100;
412
413 if (!next->bios.ramcfg_00_03_08)
414 unk710 |= 0x00000060;
415 if (!next->bios.ramcfg_FBVDDQ)
416 unk714 |= 0x00000100;
417 if ( next->bios.ramcfg_00_04_04)
418 unk710 |= 0x0000000e;
419 } else {
420 unk710 &= ~0x00000001;
421
422 if (!next->bios.ramcfg_00_03_08)
423 unk710 |= 0x00000001;
424 }
336 425
337 if ( next->bios.ramcfg_00_03_01) 426 if ( next->bios.ramcfg_00_03_01)
338 unk71c |= 0x00000100; 427 unk71c |= 0x00000100;
339 if ( next->bios.ramcfg_00_03_02) 428 if ( next->bios.ramcfg_00_03_02)
340 unk710 |= 0x00000100; 429 unk710 |= 0x00000100;
341 if (!next->bios.ramcfg_00_03_08) { 430 if (!next->bios.ramcfg_00_03_08)
342 unk710 |= 0x1; 431 unk714 |= 0x00000020;
343 unk714 |= 0x20;
344 }
345 if ( next->bios.ramcfg_00_04_04) 432 if ( next->bios.ramcfg_00_04_04)
346 unk714 |= 0x70000000; 433 unk714 |= 0x70000000;
347 if ( next->bios.ramcfg_00_04_20) 434 if ( next->bios.ramcfg_00_04_20)
@@ -352,6 +439,8 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
352 ram_mask(hwsq, 0x100718, 0xffffffff, unk718); 439 ram_mask(hwsq, 0x100718, 0xffffffff, unk718);
353 ram_mask(hwsq, 0x100710, 0xffffffff, unk710); 440 ram_mask(hwsq, 0x100710, 0xffffffff, unk710);
354 441
442 /* XXX: G94 does not even test these regs in trace. Harmless we do it,
443 * but why is it omitted? */
355 if (next->bios.rammap_00_16_20) { 444 if (next->bios.rammap_00_16_20) {
356 ram_wr32(hwsq, 0x1005a0, next->bios.ramcfg_00_07 << 16 | 445 ram_wr32(hwsq, 0x1005a0, next->bios.ramcfg_00_07 << 16 |
357 next->bios.ramcfg_00_06 << 8 | 446 next->bios.ramcfg_00_06 << 8 |
@@ -364,6 +453,9 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
364 } 453 }
365 ram_mask(hwsq, mr[1], 0xffffffff, ram->base.mr[1]); 454 ram_mask(hwsq, mr[1], 0xffffffff, ram->base.mr[1]);
366 455
456 if (!next->bios.timing_10_ODT)
457 nv50_ram_gpio(hwsq, 0x2e, 0);
458
367 /* Reset DLL */ 459 /* Reset DLL */
368 if (!next->bios.ramcfg_DLLoff) 460 if (!next->bios.ramcfg_DLLoff)
369 nvkm_sddr2_dll_reset(hwsq); 461 nvkm_sddr2_dll_reset(hwsq);
@@ -379,6 +471,8 @@ nv50_ram_calc(struct nvkm_ram *base, u32 freq)
379 ram_mask(hwsq, 0x004008, 0x00004000, 0x00000000); 471 ram_mask(hwsq, 0x004008, 0x00004000, 0x00000000);
380 if (next->bios.ramcfg_00_03_02) 472 if (next->bios.ramcfg_00_03_02)
381 ram_mask(hwsq, 0x10021c, 0x00010000, 0x00010000); 473 ram_mask(hwsq, 0x10021c, 0x00010000, 0x00010000);
474 if (subdev->device->chipset <= 0x96 && next->bios.ramcfg_00_03_02)
475 ram_mask(hwsq, 0x100710, 0x00000200, 0x00000200);
382 476
383 return 0; 477 return 0;
384} 478}
@@ -634,5 +728,10 @@ nv50_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
634 ram->hwsq.r_mr[3] = hwsq_reg(0x1002e4); 728 ram->hwsq.r_mr[3] = hwsq_reg(0x1002e4);
635 } 729 }
636 730
731 ram->hwsq.r_gpio[0] = hwsq_reg(0x00e104);
732 ram->hwsq.r_gpio[1] = hwsq_reg(0x00e108);
733 ram->hwsq.r_gpio[2] = hwsq_reg(0x00e120);
734 ram->hwsq.r_gpio[3] = hwsq_reg(0x00e124);
735
637 return 0; 736 return 0;
638} 737}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h
index 0f1f97ccd5f6..8df7306d5729 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramseq.h
@@ -11,5 +11,6 @@
11#define ram_mask(s,r,m,d) hwsq_mask(&(s)->base, &(s)->r_##r, (m), (d)) 11#define ram_mask(s,r,m,d) hwsq_mask(&(s)->base, &(s)->r_##r, (m), (d))
12#define ram_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d)) 12#define ram_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d))
13#define ram_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d)) 13#define ram_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d))
14#define ram_wait_vblank(s) hwsq_wait_vblank(&(s)->base)
14#define ram_nsec(s,n) hwsq_nsec(&(s)->base, (n)) 15#define ram_nsec(s,n) hwsq_nsec(&(s)->base, (n))
15#endif 16#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
index 86bf67456b14..b9f1ffdfc602 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
@@ -76,6 +76,12 @@ nvkm_sddr2_calc(struct nvkm_ram *ram)
76 return -ENOSYS; 76 return -ENOSYS;
77 } 77 }
78 78
79 if (ram->next->bios.timing_ver == 0x20 ||
80 ram->next->bios.ramcfg_timing == 0xff) {
81 ODT = (ram->mr[1] & 0x004) >> 2 |
82 (ram->mr[1] & 0x040) >> 5;
83 }
84
79 CL = ramxlat(ramddr2_cl, CL); 85 CL = ramxlat(ramddr2_cl, CL);
80 WR = ramxlat(ramddr2_wr, WR); 86 WR = ramxlat(ramddr2_wr, WR);
81 if (CL < 0 || WR < 0) 87 if (CL < 0 || WR < 0)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c
index b4edc97dc8c5..26900333b1d6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c
@@ -70,6 +70,8 @@ nvkm_sddr3_calc(struct nvkm_ram *ram)
70{ 70{
71 int CWL, CL, WR, DLL = 0, ODT = 0; 71 int CWL, CL, WR, DLL = 0, ODT = 0;
72 72
73 DLL = !ram->next->bios.ramcfg_DLLoff;
74
73 switch (ram->next->bios.timing_ver) { 75 switch (ram->next->bios.timing_ver) {
74 case 0x10: 76 case 0x10:
75 if (ram->next->bios.timing_hdr < 0x17) { 77 if (ram->next->bios.timing_hdr < 0x17) {
@@ -79,7 +81,6 @@ nvkm_sddr3_calc(struct nvkm_ram *ram)
79 CWL = ram->next->bios.timing_10_CWL; 81 CWL = ram->next->bios.timing_10_CWL;
80 CL = ram->next->bios.timing_10_CL; 82 CL = ram->next->bios.timing_10_CL;
81 WR = ram->next->bios.timing_10_WR; 83 WR = ram->next->bios.timing_10_WR;
82 DLL = !ram->next->bios.ramcfg_DLLoff;
83 ODT = ram->next->bios.timing_10_ODT; 84 ODT = ram->next->bios.timing_10_ODT;
84 break; 85 break;
85 case 0x20: 86 case 0x20:
@@ -87,7 +88,6 @@ nvkm_sddr3_calc(struct nvkm_ram *ram)
87 CL = (ram->next->bios.timing[1] & 0x0000001f) >> 0; 88 CL = (ram->next->bios.timing[1] & 0x0000001f) >> 0;
88 WR = (ram->next->bios.timing[2] & 0x007f0000) >> 16; 89 WR = (ram->next->bios.timing[2] & 0x007f0000) >> 16;
89 /* XXX: Get these values from the VBIOS instead */ 90 /* XXX: Get these values from the VBIOS instead */
90 DLL = !(ram->mr[1] & 0x1);
91 ODT = (ram->mr[1] & 0x004) >> 2 | 91 ODT = (ram->mr[1] & 0x004) >> 2 |
92 (ram->mr[1] & 0x040) >> 5 | 92 (ram->mr[1] & 0x040) >> 5 |
93 (ram->mr[1] & 0x200) >> 7; 93 (ram->mr[1] & 0x200) >> 7;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
index 8996649209ab..73923fd5f7f2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/nv50.c
@@ -54,7 +54,7 @@ nv50_gpio_reset(struct nvkm_gpio *gpio, u8 match)
54 } 54 }
55} 55}
56 56
57int 57static int
58nv50_gpio_location(int line, u32 *reg, u32 *shift) 58nv50_gpio_location(int line, u32 *reg, u32 *shift)
59{ 59{
60 const u32 nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; 60 const u32 nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild
index a0b12d27284a..de888fa62b3e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/Kbuild
@@ -1,3 +1,4 @@
1nvkm-y += nvkm/subdev/ibus/gf100.o 1nvkm-y += nvkm/subdev/ibus/gf100.o
2nvkm-y += nvkm/subdev/ibus/gf117.o
2nvkm-y += nvkm/subdev/ibus/gk104.o 3nvkm-y += nvkm/subdev/ibus/gk104.o
3nvkm-y += nvkm/subdev/ibus/gk20a.o 4nvkm-y += nvkm/subdev/ibus/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c
index 37a0496f7ed1..72d6330d243d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c
@@ -21,7 +21,7 @@
21 * 21 *
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24#include <subdev/ibus.h> 24#include "priv.h"
25 25
26static void 26static void
27gf100_ibus_intr_hub(struct nvkm_subdev *ibus, int i) 27gf100_ibus_intr_hub(struct nvkm_subdev *ibus, int i)
@@ -56,7 +56,7 @@ gf100_ibus_intr_gpc(struct nvkm_subdev *ibus, int i)
56 nvkm_mask(device, 0x128128 + (i * 0x0400), 0x00000200, 0x00000000); 56 nvkm_mask(device, 0x128128 + (i * 0x0400), 0x00000200, 0x00000000);
57} 57}
58 58
59static void 59void
60gf100_ibus_intr(struct nvkm_subdev *ibus) 60gf100_ibus_intr(struct nvkm_subdev *ibus)
61{ 61{
62 struct nvkm_device *device = ibus->device; 62 struct nvkm_device *device = ibus->device;
@@ -92,8 +92,21 @@ gf100_ibus_intr(struct nvkm_subdev *ibus)
92 } 92 }
93} 93}
94 94
95static int
96gf100_ibus_init(struct nvkm_subdev *ibus)
97{
98 struct nvkm_device *device = ibus->device;
99 nvkm_mask(device, 0x122310, 0x0003ffff, 0x00000800);
100 nvkm_wr32(device, 0x12232c, 0x00100064);
101 nvkm_wr32(device, 0x122330, 0x00100064);
102 nvkm_wr32(device, 0x122334, 0x00100064);
103 nvkm_mask(device, 0x122348, 0x0003ffff, 0x00000100);
104 return 0;
105}
106
95static const struct nvkm_subdev_func 107static const struct nvkm_subdev_func
96gf100_ibus = { 108gf100_ibus = {
109 .init = gf100_ibus_init,
97 .intr = gf100_ibus_intr, 110 .intr = gf100_ibus_intr,
98}; 111};
99 112
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c
new file mode 100644
index 000000000000..f69f263c5906
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c
@@ -0,0 +1,51 @@
1/*
2 * Copyright 2015 Samuel Pitosiet
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Samuel Pitoiset
23 */
24#include "priv.h"
25
26static int
27gf117_ibus_init(struct nvkm_subdev *ibus)
28{
29 struct nvkm_device *device = ibus->device;
30 nvkm_mask(device, 0x122310, 0x0003ffff, 0x00000800);
31 nvkm_mask(device, 0x122348, 0x0003ffff, 0x00000100);
32 nvkm_mask(device, 0x1223b0, 0x0003ffff, 0x00000fff);
33 return 0;
34}
35
36static const struct nvkm_subdev_func
37gf117_ibus = {
38 .init = gf117_ibus_init,
39 .intr = gf100_ibus_intr,
40};
41
42int
43gf117_ibus_new(struct nvkm_device *device, int index,
44 struct nvkm_subdev **pibus)
45{
46 struct nvkm_subdev *ibus;
47 if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL)))
48 return -ENOMEM;
49 nvkm_subdev_ctor(&gf117_ibus, device, index, 0, ibus);
50 return 0;
51}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/priv.h
new file mode 100644
index 000000000000..48e1b6365ce6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/priv.h
@@ -0,0 +1,7 @@
1#ifndef __NVKM_IBUS_PRIV_H__
2#define __NVKM_IBUS_PRIV_H__
3
4#include <subdev/ibus.h>
5
6void gf100_ibus_intr(struct nvkm_subdev *);
7#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index cd7feb1b25f6..fc419bb8eab7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -23,35 +23,42 @@
23/* 23/*
24 * GK20A does not have dedicated video memory, and to accurately represent this 24 * GK20A does not have dedicated video memory, and to accurately represent this
25 * fact Nouveau will not create a RAM device for it. Therefore its instmem 25 * fact Nouveau will not create a RAM device for it. Therefore its instmem
26 * implementation must be done directly on top of system memory, while providing 26 * implementation must be done directly on top of system memory, while
27 * coherent read and write operations. 27 * preserving coherency for read and write operations.
28 * 28 *
29 * Instmem can be allocated through two means: 29 * Instmem can be allocated through two means:
30 * 1) If an IOMMU mapping has been probed, the IOMMU API is used to make memory 30 * 1) If an IOMMU unit has been probed, the IOMMU API is used to make memory
31 * pages contiguous to the GPU. This is the preferred way. 31 * pages contiguous to the GPU. This is the preferred way.
32 * 2) If no IOMMU mapping is probed, the DMA API is used to allocate physically 32 * 2) If no IOMMU unit is probed, the DMA API is used to allocate physically
33 * contiguous memory. 33 * contiguous memory.
34 * 34 *
35 * In both cases CPU read and writes are performed using PRAMIN (i.e. using the 35 * In both cases CPU read and writes are performed by creating a write-combined
36 * GPU path) to ensure these operations are coherent for the GPU. This allows us 36 * mapping. The GPU L2 cache must thus be flushed/invalidated when required. To
37 * to use more "relaxed" allocation parameters when using the DMA API, since we 37 * be conservative we do this every time we acquire or release an instobj, but
38 * never need a kernel mapping. 38 * ideally L2 management should be handled at a higher level.
39 *
40 * To improve performance, CPU mappings are not removed upon instobj release.
41 * Instead they are placed into a LRU list to be recycled when the mapped space
42 * goes beyond a certain threshold. At the moment this limit is 1MB.
39 */ 43 */
40#define gk20a_instmem(p) container_of((p), struct gk20a_instmem, base)
41#include "priv.h" 44#include "priv.h"
42 45
43#include <core/memory.h> 46#include <core/memory.h>
44#include <core/mm.h> 47#include <core/mm.h>
45#include <core/tegra.h> 48#include <core/tegra.h>
46#include <subdev/fb.h> 49#include <subdev/fb.h>
47 50#include <subdev/ltc.h>
48#define gk20a_instobj(p) container_of((p), struct gk20a_instobj, memory)
49 51
50struct gk20a_instobj { 52struct gk20a_instobj {
51 struct nvkm_memory memory; 53 struct nvkm_memory memory;
52 struct gk20a_instmem *imem;
53 struct nvkm_mem mem; 54 struct nvkm_mem mem;
55 struct gk20a_instmem *imem;
56
57 /* CPU mapping */
58 u32 *vaddr;
59 struct list_head vaddr_node;
54}; 60};
61#define gk20a_instobj(p) container_of((p), struct gk20a_instobj, memory)
55 62
56/* 63/*
57 * Used for objects allocated using the DMA API 64 * Used for objects allocated using the DMA API
@@ -59,10 +66,12 @@ struct gk20a_instobj {
59struct gk20a_instobj_dma { 66struct gk20a_instobj_dma {
60 struct gk20a_instobj base; 67 struct gk20a_instobj base;
61 68
62 void *cpuaddr; 69 u32 *cpuaddr;
63 dma_addr_t handle; 70 dma_addr_t handle;
64 struct nvkm_mm_node r; 71 struct nvkm_mm_node r;
65}; 72};
73#define gk20a_instobj_dma(p) \
74 container_of(gk20a_instobj(p), struct gk20a_instobj_dma, base)
66 75
67/* 76/*
68 * Used for objects flattened using the IOMMU API 77 * Used for objects flattened using the IOMMU API
@@ -70,25 +79,38 @@ struct gk20a_instobj_dma {
70struct gk20a_instobj_iommu { 79struct gk20a_instobj_iommu {
71 struct gk20a_instobj base; 80 struct gk20a_instobj base;
72 81
73 /* array of base.mem->size pages */ 82 /* will point to the higher half of pages */
83 dma_addr_t *dma_addrs;
84 /* array of base.mem->size pages (+ dma_addr_ts) */
74 struct page *pages[]; 85 struct page *pages[];
75}; 86};
87#define gk20a_instobj_iommu(p) \
88 container_of(gk20a_instobj(p), struct gk20a_instobj_iommu, base)
76 89
77struct gk20a_instmem { 90struct gk20a_instmem {
78 struct nvkm_instmem base; 91 struct nvkm_instmem base;
79 unsigned long lock_flags; 92
93 /* protects vaddr_* and gk20a_instobj::vaddr* */
80 spinlock_t lock; 94 spinlock_t lock;
81 u64 addr; 95
96 /* CPU mappings LRU */
97 unsigned int vaddr_use;
98 unsigned int vaddr_max;
99 struct list_head vaddr_lru;
82 100
83 /* Only used if IOMMU if present */ 101 /* Only used if IOMMU if present */
84 struct mutex *mm_mutex; 102 struct mutex *mm_mutex;
85 struct nvkm_mm *mm; 103 struct nvkm_mm *mm;
86 struct iommu_domain *domain; 104 struct iommu_domain *domain;
87 unsigned long iommu_pgshift; 105 unsigned long iommu_pgshift;
106 u16 iommu_bit;
88 107
89 /* Only used by DMA API */ 108 /* Only used by DMA API */
90 struct dma_attrs attrs; 109 struct dma_attrs attrs;
110
111 void __iomem * (*cpu_map)(struct nvkm_memory *);
91}; 112};
113#define gk20a_instmem(p) container_of((p), struct gk20a_instmem, base)
92 114
93static enum nvkm_memory_target 115static enum nvkm_memory_target
94gk20a_instobj_target(struct nvkm_memory *memory) 116gk20a_instobj_target(struct nvkm_memory *memory)
@@ -100,7 +122,6 @@ static u64
100gk20a_instobj_addr(struct nvkm_memory *memory) 122gk20a_instobj_addr(struct nvkm_memory *memory)
101{ 123{
102 return gk20a_instobj(memory)->mem.offset; 124 return gk20a_instobj(memory)->mem.offset;
103
104} 125}
105 126
106static u64 127static u64
@@ -110,107 +131,217 @@ gk20a_instobj_size(struct nvkm_memory *memory)
110} 131}
111 132
112static void __iomem * 133static void __iomem *
134gk20a_instobj_cpu_map_dma(struct nvkm_memory *memory)
135{
136 struct gk20a_instobj_dma *node = gk20a_instobj_dma(memory);
137 struct device *dev = node->base.imem->base.subdev.device->dev;
138 int npages = nvkm_memory_size(memory) >> 12;
139 struct page *pages[npages];
140 int i;
141
142 /* phys_to_page does not exist on all platforms... */
143 pages[0] = pfn_to_page(dma_to_phys(dev, node->handle) >> PAGE_SHIFT);
144 for (i = 1; i < npages; i++)
145 pages[i] = pages[0] + i;
146
147 return vmap(pages, npages, VM_MAP, pgprot_writecombine(PAGE_KERNEL));
148}
149
150static void __iomem *
151gk20a_instobj_cpu_map_iommu(struct nvkm_memory *memory)
152{
153 struct gk20a_instobj_iommu *node = gk20a_instobj_iommu(memory);
154 int npages = nvkm_memory_size(memory) >> 12;
155
156 return vmap(node->pages, npages, VM_MAP,
157 pgprot_writecombine(PAGE_KERNEL));
158}
159
160/*
161 * Must be called while holding gk20a_instmem_lock
162 */
163static void
164gk20a_instmem_vaddr_gc(struct gk20a_instmem *imem, const u64 size)
165{
166 while (imem->vaddr_use + size > imem->vaddr_max) {
167 struct gk20a_instobj *obj;
168
169 /* no candidate that can be unmapped, abort... */
170 if (list_empty(&imem->vaddr_lru))
171 break;
172
173 obj = list_first_entry(&imem->vaddr_lru, struct gk20a_instobj,
174 vaddr_node);
175 list_del(&obj->vaddr_node);
176 vunmap(obj->vaddr);
177 obj->vaddr = NULL;
178 imem->vaddr_use -= nvkm_memory_size(&obj->memory);
179 nvkm_debug(&imem->base.subdev, "(GC) vaddr used: %x/%x\n",
180 imem->vaddr_use, imem->vaddr_max);
181
182 }
183}
184
185static void __iomem *
113gk20a_instobj_acquire(struct nvkm_memory *memory) 186gk20a_instobj_acquire(struct nvkm_memory *memory)
114{ 187{
115 struct gk20a_instmem *imem = gk20a_instobj(memory)->imem; 188 struct gk20a_instobj *node = gk20a_instobj(memory);
189 struct gk20a_instmem *imem = node->imem;
190 struct nvkm_ltc *ltc = imem->base.subdev.device->ltc;
191 const u64 size = nvkm_memory_size(memory);
116 unsigned long flags; 192 unsigned long flags;
193
194 nvkm_ltc_flush(ltc);
195
117 spin_lock_irqsave(&imem->lock, flags); 196 spin_lock_irqsave(&imem->lock, flags);
118 imem->lock_flags = flags; 197
119 return NULL; 198 if (node->vaddr) {
199 /* remove us from the LRU list since we cannot be unmapped */
200 list_del(&node->vaddr_node);
201
202 goto out;
203 }
204
205 /* try to free some address space if we reached the limit */
206 gk20a_instmem_vaddr_gc(imem, size);
207
208 node->vaddr = imem->cpu_map(memory);
209
210 if (!node->vaddr) {
211 nvkm_error(&imem->base.subdev, "cannot map instobj - "
212 "this is not going to end well...\n");
213 goto out;
214 }
215
216 imem->vaddr_use += size;
217 nvkm_debug(&imem->base.subdev, "vaddr used: %x/%x\n",
218 imem->vaddr_use, imem->vaddr_max);
219
220out:
221 spin_unlock_irqrestore(&imem->lock, flags);
222
223 return node->vaddr;
120} 224}
121 225
122static void 226static void
123gk20a_instobj_release(struct nvkm_memory *memory) 227gk20a_instobj_release(struct nvkm_memory *memory)
124{ 228{
125 struct gk20a_instmem *imem = gk20a_instobj(memory)->imem; 229 struct gk20a_instobj *node = gk20a_instobj(memory);
126 spin_unlock_irqrestore(&imem->lock, imem->lock_flags); 230 struct gk20a_instmem *imem = node->imem;
127} 231 struct nvkm_ltc *ltc = imem->base.subdev.device->ltc;
232 unsigned long flags;
128 233
129/* 234 spin_lock_irqsave(&imem->lock, flags);
130 * Use PRAMIN to read/write data and avoid coherency issues. 235
131 * PRAMIN uses the GPU path and ensures data will always be coherent. 236 /* add ourselves to the LRU list so our CPU mapping can be freed */
132 * 237 list_add_tail(&node->vaddr_node, &imem->vaddr_lru);
133 * A dynamic mapping based solution would be desirable in the future, but 238
134 * the issue remains of how to maintain coherency efficiently. On ARM it is 239 spin_unlock_irqrestore(&imem->lock, flags);
135 * not easy (if possible at all?) to create uncached temporary mappings. 240
136 */ 241 wmb();
242 nvkm_ltc_invalidate(ltc);
243}
137 244
138static u32 245static u32
139gk20a_instobj_rd32(struct nvkm_memory *memory, u64 offset) 246gk20a_instobj_rd32(struct nvkm_memory *memory, u64 offset)
140{ 247{
141 struct gk20a_instobj *node = gk20a_instobj(memory); 248 struct gk20a_instobj *node = gk20a_instobj(memory);
142 struct gk20a_instmem *imem = node->imem; 249
143 struct nvkm_device *device = imem->base.subdev.device; 250 return node->vaddr[offset / 4];
144 u64 base = (node->mem.offset + offset) & 0xffffff00000ULL;
145 u64 addr = (node->mem.offset + offset) & 0x000000fffffULL;
146 u32 data;
147
148 if (unlikely(imem->addr != base)) {
149 nvkm_wr32(device, 0x001700, base >> 16);
150 imem->addr = base;
151 }
152 data = nvkm_rd32(device, 0x700000 + addr);
153 return data;
154} 251}
155 252
156static void 253static void
157gk20a_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data) 254gk20a_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
158{ 255{
159 struct gk20a_instobj *node = gk20a_instobj(memory); 256 struct gk20a_instobj *node = gk20a_instobj(memory);
160 struct gk20a_instmem *imem = node->imem;
161 struct nvkm_device *device = imem->base.subdev.device;
162 u64 base = (node->mem.offset + offset) & 0xffffff00000ULL;
163 u64 addr = (node->mem.offset + offset) & 0x000000fffffULL;
164 257
165 if (unlikely(imem->addr != base)) { 258 node->vaddr[offset / 4] = data;
166 nvkm_wr32(device, 0x001700, base >> 16);
167 imem->addr = base;
168 }
169 nvkm_wr32(device, 0x700000 + addr, data);
170} 259}
171 260
172static void 261static void
173gk20a_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset) 262gk20a_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset)
174{ 263{
175 struct gk20a_instobj *node = gk20a_instobj(memory); 264 struct gk20a_instobj *node = gk20a_instobj(memory);
265
176 nvkm_vm_map_at(vma, offset, &node->mem); 266 nvkm_vm_map_at(vma, offset, &node->mem);
177} 267}
178 268
269/*
270 * Clear the CPU mapping of an instobj if it exists
271 */
179static void 272static void
180gk20a_instobj_dtor_dma(struct gk20a_instobj *_node) 273gk20a_instobj_dtor(struct gk20a_instobj *node)
274{
275 struct gk20a_instmem *imem = node->imem;
276 struct gk20a_instobj *obj;
277 unsigned long flags;
278
279 spin_lock_irqsave(&imem->lock, flags);
280
281 if (!node->vaddr)
282 goto out;
283
284 list_for_each_entry(obj, &imem->vaddr_lru, vaddr_node) {
285 if (obj == node) {
286 list_del(&obj->vaddr_node);
287 break;
288 }
289 }
290 vunmap(node->vaddr);
291 node->vaddr = NULL;
292 imem->vaddr_use -= nvkm_memory_size(&node->memory);
293 nvkm_debug(&imem->base.subdev, "vaddr used: %x/%x\n",
294 imem->vaddr_use, imem->vaddr_max);
295
296out:
297 spin_unlock_irqrestore(&imem->lock, flags);
298}
299
300static void *
301gk20a_instobj_dtor_dma(struct nvkm_memory *memory)
181{ 302{
182 struct gk20a_instobj_dma *node = (void *)_node; 303 struct gk20a_instobj_dma *node = gk20a_instobj_dma(memory);
183 struct gk20a_instmem *imem = _node->imem; 304 struct gk20a_instmem *imem = node->base.imem;
184 struct device *dev = imem->base.subdev.device->dev; 305 struct device *dev = imem->base.subdev.device->dev;
185 306
307 gk20a_instobj_dtor(&node->base);
308
186 if (unlikely(!node->cpuaddr)) 309 if (unlikely(!node->cpuaddr))
187 return; 310 goto out;
188 311
189 dma_free_attrs(dev, _node->mem.size << PAGE_SHIFT, node->cpuaddr, 312 dma_free_attrs(dev, node->base.mem.size << PAGE_SHIFT, node->cpuaddr,
190 node->handle, &imem->attrs); 313 node->handle, &imem->attrs);
314
315out:
316 return node;
191} 317}
192 318
193static void 319static void *
194gk20a_instobj_dtor_iommu(struct gk20a_instobj *_node) 320gk20a_instobj_dtor_iommu(struct nvkm_memory *memory)
195{ 321{
196 struct gk20a_instobj_iommu *node = (void *)_node; 322 struct gk20a_instobj_iommu *node = gk20a_instobj_iommu(memory);
197 struct gk20a_instmem *imem = _node->imem; 323 struct gk20a_instmem *imem = node->base.imem;
324 struct device *dev = imem->base.subdev.device->dev;
198 struct nvkm_mm_node *r; 325 struct nvkm_mm_node *r;
199 int i; 326 int i;
200 327
201 if (unlikely(list_empty(&_node->mem.regions))) 328 gk20a_instobj_dtor(&node->base);
202 return;
203 329
204 r = list_first_entry(&_node->mem.regions, struct nvkm_mm_node, 330 if (unlikely(list_empty(&node->base.mem.regions)))
331 goto out;
332
333 r = list_first_entry(&node->base.mem.regions, struct nvkm_mm_node,
205 rl_entry); 334 rl_entry);
206 335
207 /* clear bit 34 to unmap pages */ 336 /* clear IOMMU bit to unmap pages */
208 r->offset &= ~BIT(34 - imem->iommu_pgshift); 337 r->offset &= ~BIT(imem->iommu_bit - imem->iommu_pgshift);
209 338
210 /* Unmap pages from GPU address space and free them */ 339 /* Unmap pages from GPU address space and free them */
211 for (i = 0; i < _node->mem.size; i++) { 340 for (i = 0; i < node->base.mem.size; i++) {
212 iommu_unmap(imem->domain, 341 iommu_unmap(imem->domain,
213 (r->offset + i) << imem->iommu_pgshift, PAGE_SIZE); 342 (r->offset + i) << imem->iommu_pgshift, PAGE_SIZE);
343 dma_unmap_page(dev, node->dma_addrs[i], PAGE_SIZE,
344 DMA_BIDIRECTIONAL);
214 __free_page(node->pages[i]); 345 __free_page(node->pages[i]);
215 } 346 }
216 347
@@ -218,25 +349,27 @@ gk20a_instobj_dtor_iommu(struct gk20a_instobj *_node)
218 mutex_lock(imem->mm_mutex); 349 mutex_lock(imem->mm_mutex);
219 nvkm_mm_free(imem->mm, &r); 350 nvkm_mm_free(imem->mm, &r);
220 mutex_unlock(imem->mm_mutex); 351 mutex_unlock(imem->mm_mutex);
221}
222
223static void *
224gk20a_instobj_dtor(struct nvkm_memory *memory)
225{
226 struct gk20a_instobj *node = gk20a_instobj(memory);
227 struct gk20a_instmem *imem = node->imem;
228
229 if (imem->domain)
230 gk20a_instobj_dtor_iommu(node);
231 else
232 gk20a_instobj_dtor_dma(node);
233 352
353out:
234 return node; 354 return node;
235} 355}
236 356
237static const struct nvkm_memory_func 357static const struct nvkm_memory_func
238gk20a_instobj_func = { 358gk20a_instobj_func_dma = {
239 .dtor = gk20a_instobj_dtor, 359 .dtor = gk20a_instobj_dtor_dma,
360 .target = gk20a_instobj_target,
361 .addr = gk20a_instobj_addr,
362 .size = gk20a_instobj_size,
363 .acquire = gk20a_instobj_acquire,
364 .release = gk20a_instobj_release,
365 .rd32 = gk20a_instobj_rd32,
366 .wr32 = gk20a_instobj_wr32,
367 .map = gk20a_instobj_map,
368};
369
370static const struct nvkm_memory_func
371gk20a_instobj_func_iommu = {
372 .dtor = gk20a_instobj_dtor_iommu,
240 .target = gk20a_instobj_target, 373 .target = gk20a_instobj_target,
241 .addr = gk20a_instobj_addr, 374 .addr = gk20a_instobj_addr,
242 .size = gk20a_instobj_size, 375 .size = gk20a_instobj_size,
@@ -259,6 +392,8 @@ gk20a_instobj_ctor_dma(struct gk20a_instmem *imem, u32 npages, u32 align,
259 return -ENOMEM; 392 return -ENOMEM;
260 *_node = &node->base; 393 *_node = &node->base;
261 394
395 nvkm_memory_ctor(&gk20a_instobj_func_dma, &node->base.memory);
396
262 node->cpuaddr = dma_alloc_attrs(dev, npages << PAGE_SHIFT, 397 node->cpuaddr = dma_alloc_attrs(dev, npages << PAGE_SHIFT,
263 &node->handle, GFP_KERNEL, 398 &node->handle, GFP_KERNEL,
264 &imem->attrs); 399 &imem->attrs);
@@ -292,24 +427,40 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align,
292{ 427{
293 struct gk20a_instobj_iommu *node; 428 struct gk20a_instobj_iommu *node;
294 struct nvkm_subdev *subdev = &imem->base.subdev; 429 struct nvkm_subdev *subdev = &imem->base.subdev;
430 struct device *dev = subdev->device->dev;
295 struct nvkm_mm_node *r; 431 struct nvkm_mm_node *r;
296 int ret; 432 int ret;
297 int i; 433 int i;
298 434
299 if (!(node = kzalloc(sizeof(*node) + 435 /*
300 sizeof( node->pages[0]) * npages, GFP_KERNEL))) 436 * despite their variable size, instmem allocations are small enough
437 * (< 1 page) to be handled by kzalloc
438 */
439 if (!(node = kzalloc(sizeof(*node) + ((sizeof(node->pages[0]) +
440 sizeof(*node->dma_addrs)) * npages), GFP_KERNEL)))
301 return -ENOMEM; 441 return -ENOMEM;
302 *_node = &node->base; 442 *_node = &node->base;
443 node->dma_addrs = (void *)(node->pages + npages);
444
445 nvkm_memory_ctor(&gk20a_instobj_func_iommu, &node->base.memory);
303 446
304 /* Allocate backing memory */ 447 /* Allocate backing memory */
305 for (i = 0; i < npages; i++) { 448 for (i = 0; i < npages; i++) {
306 struct page *p = alloc_page(GFP_KERNEL); 449 struct page *p = alloc_page(GFP_KERNEL);
450 dma_addr_t dma_adr;
307 451
308 if (p == NULL) { 452 if (p == NULL) {
309 ret = -ENOMEM; 453 ret = -ENOMEM;
310 goto free_pages; 454 goto free_pages;
311 } 455 }
312 node->pages[i] = p; 456 node->pages[i] = p;
457 dma_adr = dma_map_page(dev, p, 0, PAGE_SIZE, DMA_BIDIRECTIONAL);
458 if (dma_mapping_error(dev, dma_adr)) {
459 nvkm_error(subdev, "DMA mapping error!\n");
460 ret = -ENOMEM;
461 goto free_pages;
462 }
463 node->dma_addrs[i] = dma_adr;
313 } 464 }
314 465
315 mutex_lock(imem->mm_mutex); 466 mutex_lock(imem->mm_mutex);
@@ -318,16 +469,15 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align,
318 align >> imem->iommu_pgshift, &r); 469 align >> imem->iommu_pgshift, &r);
319 mutex_unlock(imem->mm_mutex); 470 mutex_unlock(imem->mm_mutex);
320 if (ret) { 471 if (ret) {
321 nvkm_error(subdev, "virtual space is full!\n"); 472 nvkm_error(subdev, "IOMMU space is full!\n");
322 goto free_pages; 473 goto free_pages;
323 } 474 }
324 475
325 /* Map into GPU address space */ 476 /* Map into GPU address space */
326 for (i = 0; i < npages; i++) { 477 for (i = 0; i < npages; i++) {
327 struct page *p = node->pages[i];
328 u32 offset = (r->offset + i) << imem->iommu_pgshift; 478 u32 offset = (r->offset + i) << imem->iommu_pgshift;
329 479
330 ret = iommu_map(imem->domain, offset, page_to_phys(p), 480 ret = iommu_map(imem->domain, offset, node->dma_addrs[i],
331 PAGE_SIZE, IOMMU_READ | IOMMU_WRITE); 481 PAGE_SIZE, IOMMU_READ | IOMMU_WRITE);
332 if (ret < 0) { 482 if (ret < 0) {
333 nvkm_error(subdev, "IOMMU mapping failure: %d\n", ret); 483 nvkm_error(subdev, "IOMMU mapping failure: %d\n", ret);
@@ -340,8 +490,8 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align,
340 } 490 }
341 } 491 }
342 492
343 /* Bit 34 tells that an address is to be resolved through the IOMMU */ 493 /* IOMMU bit tells that an address is to be resolved through the IOMMU */
344 r->offset |= BIT(34 - imem->iommu_pgshift); 494 r->offset |= BIT(imem->iommu_bit - imem->iommu_pgshift);
345 495
346 node->base.mem.offset = ((u64)r->offset) << imem->iommu_pgshift; 496 node->base.mem.offset = ((u64)r->offset) << imem->iommu_pgshift;
347 497
@@ -356,8 +506,13 @@ release_area:
356 mutex_unlock(imem->mm_mutex); 506 mutex_unlock(imem->mm_mutex);
357 507
358free_pages: 508free_pages:
359 for (i = 0; i < npages && node->pages[i] != NULL; i++) 509 for (i = 0; i < npages && node->pages[i] != NULL; i++) {
510 dma_addr_t dma_addr = node->dma_addrs[i];
511 if (dma_addr)
512 dma_unmap_page(dev, dma_addr, PAGE_SIZE,
513 DMA_BIDIRECTIONAL);
360 __free_page(node->pages[i]); 514 __free_page(node->pages[i]);
515 }
361 516
362 return ret; 517 return ret;
363} 518}
@@ -367,8 +522,8 @@ gk20a_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
367 struct nvkm_memory **pmemory) 522 struct nvkm_memory **pmemory)
368{ 523{
369 struct gk20a_instmem *imem = gk20a_instmem(base); 524 struct gk20a_instmem *imem = gk20a_instmem(base);
370 struct gk20a_instobj *node = NULL;
371 struct nvkm_subdev *subdev = &imem->base.subdev; 525 struct nvkm_subdev *subdev = &imem->base.subdev;
526 struct gk20a_instobj *node = NULL;
372 int ret; 527 int ret;
373 528
374 nvkm_debug(subdev, "%s (%s): size: %x align: %x\n", __func__, 529 nvkm_debug(subdev, "%s (%s): size: %x align: %x\n", __func__,
@@ -388,7 +543,6 @@ gk20a_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
388 if (ret) 543 if (ret)
389 return ret; 544 return ret;
390 545
391 nvkm_memory_ctor(&gk20a_instobj_func, &node->memory);
392 node->imem = imem; 546 node->imem = imem;
393 547
394 /* present memory for being mapped using small pages */ 548 /* present memory for being mapped using small pages */
@@ -402,15 +556,25 @@ gk20a_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
402 return 0; 556 return 0;
403} 557}
404 558
405static void 559static void *
406gk20a_instmem_fini(struct nvkm_instmem *base) 560gk20a_instmem_dtor(struct nvkm_instmem *base)
407{ 561{
408 gk20a_instmem(base)->addr = ~0ULL; 562 struct gk20a_instmem *imem = gk20a_instmem(base);
563
564 /* perform some sanity checks... */
565 if (!list_empty(&imem->vaddr_lru))
566 nvkm_warn(&base->subdev, "instobj LRU not empty!\n");
567
568 if (imem->vaddr_use != 0)
569 nvkm_warn(&base->subdev, "instobj vmap area not empty! "
570 "0x%x bytes still mapped\n", imem->vaddr_use);
571
572 return imem;
409} 573}
410 574
411static const struct nvkm_instmem_func 575static const struct nvkm_instmem_func
412gk20a_instmem = { 576gk20a_instmem = {
413 .fini = gk20a_instmem_fini, 577 .dtor = gk20a_instmem_dtor,
414 .memory_new = gk20a_instobj_new, 578 .memory_new = gk20a_instobj_new,
415 .persistent = true, 579 .persistent = true,
416 .zero = false, 580 .zero = false,
@@ -429,23 +593,28 @@ gk20a_instmem_new(struct nvkm_device *device, int index,
429 spin_lock_init(&imem->lock); 593 spin_lock_init(&imem->lock);
430 *pimem = &imem->base; 594 *pimem = &imem->base;
431 595
596 /* do not allow more than 1MB of CPU-mapped instmem */
597 imem->vaddr_use = 0;
598 imem->vaddr_max = 0x100000;
599 INIT_LIST_HEAD(&imem->vaddr_lru);
600
432 if (tdev->iommu.domain) { 601 if (tdev->iommu.domain) {
433 imem->domain = tdev->iommu.domain; 602 imem->mm_mutex = &tdev->iommu.mutex;
434 imem->mm = &tdev->iommu.mm; 603 imem->mm = &tdev->iommu.mm;
604 imem->domain = tdev->iommu.domain;
435 imem->iommu_pgshift = tdev->iommu.pgshift; 605 imem->iommu_pgshift = tdev->iommu.pgshift;
436 imem->mm_mutex = &tdev->iommu.mutex; 606 imem->cpu_map = gk20a_instobj_cpu_map_iommu;
607 imem->iommu_bit = tdev->func->iommu_bit;
437 608
438 nvkm_info(&imem->base.subdev, "using IOMMU\n"); 609 nvkm_info(&imem->base.subdev, "using IOMMU\n");
439 } else { 610 } else {
440 init_dma_attrs(&imem->attrs); 611 init_dma_attrs(&imem->attrs);
441 /* 612 /* We will access the memory through our own mapping */
442 * We will access instmem through PRAMIN and thus do not need a
443 * consistent CPU pointer or kernel mapping
444 */
445 dma_set_attr(DMA_ATTR_NON_CONSISTENT, &imem->attrs); 613 dma_set_attr(DMA_ATTR_NON_CONSISTENT, &imem->attrs);
446 dma_set_attr(DMA_ATTR_WEAK_ORDERING, &imem->attrs); 614 dma_set_attr(DMA_ATTR_WEAK_ORDERING, &imem->attrs);
447 dma_set_attr(DMA_ATTR_WRITE_COMBINE, &imem->attrs); 615 dma_set_attr(DMA_ATTR_WRITE_COMBINE, &imem->attrs);
448 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &imem->attrs); 616 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &imem->attrs);
617 imem->cpu_map = gk20a_instobj_cpu_map_dma;
449 618
450 nvkm_info(&imem->base.subdev, "using DMA API\n"); 619 nvkm_info(&imem->base.subdev, "using DMA API\n");
451 } 620 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
index 930d25b6e63c..85b1464c0194 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
@@ -67,6 +67,20 @@ nvkm_ltc_zbc_depth_get(struct nvkm_ltc *ltc, int index, const u32 depth)
67 return index; 67 return index;
68} 68}
69 69
70void
71nvkm_ltc_invalidate(struct nvkm_ltc *ltc)
72{
73 if (ltc->func->invalidate)
74 ltc->func->invalidate(ltc);
75}
76
77void
78nvkm_ltc_flush(struct nvkm_ltc *ltc)
79{
80 if (ltc->func->flush)
81 ltc->func->flush(ltc);
82}
83
70static void 84static void
71nvkm_ltc_intr(struct nvkm_subdev *subdev) 85nvkm_ltc_intr(struct nvkm_subdev *subdev)
72{ 86{
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c
index 45ac765b753e..fb0de83da13c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gf100.c
@@ -122,6 +122,36 @@ gf100_ltc_intr(struct nvkm_ltc *ltc)
122 } 122 }
123} 123}
124 124
125void
126gf100_ltc_invalidate(struct nvkm_ltc *ltc)
127{
128 struct nvkm_device *device = ltc->subdev.device;
129 s64 taken;
130
131 nvkm_wr32(device, 0x70004, 0x00000001);
132 taken = nvkm_wait_msec(device, 2, 0x70004, 0x00000003, 0x00000000);
133 if (taken < 0)
134 nvkm_warn(&ltc->subdev, "LTC invalidate timeout\n");
135
136 if (taken > 0)
137 nvkm_debug(&ltc->subdev, "LTC invalidate took %lld ns\n", taken);
138}
139
140void
141gf100_ltc_flush(struct nvkm_ltc *ltc)
142{
143 struct nvkm_device *device = ltc->subdev.device;
144 s64 taken;
145
146 nvkm_wr32(device, 0x70010, 0x00000001);
147 taken = nvkm_wait_msec(device, 2, 0x70010, 0x00000003, 0x00000000);
148 if (taken < 0)
149 nvkm_warn(&ltc->subdev, "LTC flush timeout\n");
150
151 if (taken > 0)
152 nvkm_debug(&ltc->subdev, "LTC flush took %lld ns\n", taken);
153}
154
125/* TODO: Figure out tag memory details and drop the over-cautious allocation. 155/* TODO: Figure out tag memory details and drop the over-cautious allocation.
126 */ 156 */
127int 157int
@@ -215,6 +245,8 @@ gf100_ltc = {
215 .zbc = 16, 245 .zbc = 16,
216 .zbc_clear_color = gf100_ltc_zbc_clear_color, 246 .zbc_clear_color = gf100_ltc_zbc_clear_color,
217 .zbc_clear_depth = gf100_ltc_zbc_clear_depth, 247 .zbc_clear_depth = gf100_ltc_zbc_clear_depth,
248 .invalidate = gf100_ltc_invalidate,
249 .flush = gf100_ltc_flush,
218}; 250};
219 251
220int 252int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gk104.c
index 839e6b4c597b..b4f6e0034d58 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gk104.c
@@ -45,6 +45,8 @@ gk104_ltc = {
45 .zbc = 16, 45 .zbc = 16,
46 .zbc_clear_color = gf100_ltc_zbc_clear_color, 46 .zbc_clear_color = gf100_ltc_zbc_clear_color,
47 .zbc_clear_depth = gf100_ltc_zbc_clear_depth, 47 .zbc_clear_depth = gf100_ltc_zbc_clear_depth,
48 .invalidate = gf100_ltc_invalidate,
49 .flush = gf100_ltc_flush,
48}; 50};
49 51
50int 52int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c
index 389331bb63ba..3043bbfd7384 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c
@@ -138,6 +138,8 @@ gm107_ltc = {
138 .zbc = 16, 138 .zbc = 16,
139 .zbc_clear_color = gm107_ltc_zbc_clear_color, 139 .zbc_clear_color = gm107_ltc_zbc_clear_color,
140 .zbc_clear_depth = gm107_ltc_zbc_clear_depth, 140 .zbc_clear_depth = gm107_ltc_zbc_clear_depth,
141 .invalidate = gf100_ltc_invalidate,
142 .flush = gf100_ltc_flush,
141}; 143};
142 144
143int 145int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h
index 4e05037cc99f..4e3755b82769 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h
@@ -17,6 +17,9 @@ struct nvkm_ltc_func {
17 int zbc; 17 int zbc;
18 void (*zbc_clear_color)(struct nvkm_ltc *, int, const u32[4]); 18 void (*zbc_clear_color)(struct nvkm_ltc *, int, const u32[4]);
19 void (*zbc_clear_depth)(struct nvkm_ltc *, int, const u32); 19 void (*zbc_clear_depth)(struct nvkm_ltc *, int, const u32);
20
21 void (*invalidate)(struct nvkm_ltc *);
22 void (*flush)(struct nvkm_ltc *);
20}; 23};
21 24
22int gf100_ltc_oneinit(struct nvkm_ltc *); 25int gf100_ltc_oneinit(struct nvkm_ltc *);
@@ -26,4 +29,6 @@ void gf100_ltc_cbc_clear(struct nvkm_ltc *, u32, u32);
26void gf100_ltc_cbc_wait(struct nvkm_ltc *); 29void gf100_ltc_cbc_wait(struct nvkm_ltc *);
27void gf100_ltc_zbc_clear_color(struct nvkm_ltc *, int, const u32[4]); 30void gf100_ltc_zbc_clear_color(struct nvkm_ltc *, int, const u32[4]);
28void gf100_ltc_zbc_clear_depth(struct nvkm_ltc *, int, const u32); 31void gf100_ltc_zbc_clear_depth(struct nvkm_ltc *, int, const u32);
32void gf100_ltc_invalidate(struct nvkm_ltc *);
33void gf100_ltc_flush(struct nvkm_ltc *);
29#endif 34#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild
index 99672c3d0bad..4476ef75acd6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/Kbuild
@@ -2,6 +2,8 @@ nvkm-y += nvkm/subdev/pci/agp.o
2nvkm-y += nvkm/subdev/pci/base.o 2nvkm-y += nvkm/subdev/pci/base.o
3nvkm-y += nvkm/subdev/pci/nv04.o 3nvkm-y += nvkm/subdev/pci/nv04.o
4nvkm-y += nvkm/subdev/pci/nv40.o 4nvkm-y += nvkm/subdev/pci/nv40.o
5nvkm-y += nvkm/subdev/pci/nv46.o
5nvkm-y += nvkm/subdev/pci/nv4c.o 6nvkm-y += nvkm/subdev/pci/nv4c.o
6nvkm-y += nvkm/subdev/pci/nv50.o 7nvkm-y += nvkm/subdev/pci/g84.o
8nvkm-y += nvkm/subdev/pci/g94.o
7nvkm-y += nvkm/subdev/pci/gf100.o 9nvkm-y += nvkm/subdev/pci/gf100.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
index d1c148e51922..d671dcfaff3c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
@@ -46,6 +46,14 @@ nvkm_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data)
46 pci->func->wr32(pci, addr, data); 46 pci->func->wr32(pci, addr, data);
47} 47}
48 48
49u32
50nvkm_pci_mask(struct nvkm_pci *pci, u16 addr, u32 mask, u32 value)
51{
52 u32 data = pci->func->rd32(pci, addr);
53 pci->func->wr32(pci, addr, (data & ~mask) | value);
54 return data;
55}
56
49void 57void
50nvkm_pci_rom_shadow(struct nvkm_pci *pci, bool shadow) 58nvkm_pci_rom_shadow(struct nvkm_pci *pci, bool shadow)
51{ 59{
@@ -111,6 +119,9 @@ nvkm_pci_init(struct nvkm_subdev *subdev)
111 return ret; 119 return ret;
112 } 120 }
113 121
122 if (pci->func->init)
123 pci->func->init(pci);
124
114 ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci); 125 ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci);
115 if (ret) 126 if (ret)
116 return ret; 127 return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c
new file mode 100644
index 000000000000..3faa6bfb895b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g84.c
@@ -0,0 +1,64 @@
1/*
2 * Copyright 2015 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24#include "priv.h"
25
26#include <core/pci.h>
27
28void
29g84_pci_init(struct nvkm_pci *pci)
30{
31 /* The following only concerns PCIe cards. */
32 if (!pci_is_pcie(pci->pdev))
33 return;
34
35 /* Tag field is 8-bit long, regardless of EXT_TAG.
36 * However, if EXT_TAG is disabled, only the lower 5 bits of the tag
37 * field should be used, limiting the number of request to 32.
38 *
39 * Apparently, 0x041c stores some limit on the number of requests
40 * possible, so if EXT_TAG is disabled, limit that requests number to
41 * 32
42 *
43 * Fixes fdo#86537
44 */
45 if (nvkm_pci_rd32(pci, 0x007c) & 0x00000020)
46 nvkm_pci_mask(pci, 0x0080, 0x00000100, 0x00000100);
47 else
48 nvkm_pci_mask(pci, 0x041c, 0x00000060, 0x00000000);
49}
50
51static const struct nvkm_pci_func
52g84_pci_func = {
53 .init = g84_pci_init,
54 .rd32 = nv40_pci_rd32,
55 .wr08 = nv40_pci_wr08,
56 .wr32 = nv40_pci_wr32,
57 .msi_rearm = nv46_pci_msi_rearm,
58};
59
60int
61g84_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci)
62{
63 return nvkm_pci_new_(&g84_pci_func, device, index, ppci);
64}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c
new file mode 100644
index 000000000000..cd311ee311cc
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/g94.c
@@ -0,0 +1,39 @@
1/*
2 * Copyright 2015 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24#include "priv.h"
25
26static const struct nvkm_pci_func
27g94_pci_func = {
28 .init = g84_pci_init,
29 .rd32 = nv40_pci_rd32,
30 .wr08 = nv40_pci_wr08,
31 .wr32 = nv40_pci_wr32,
32 .msi_rearm = nv40_pci_msi_rearm,
33};
34
35int
36g94_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci)
37{
38 return nvkm_pci_new_(&g94_pci_func, device, index, ppci);
39}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c
index 86f8226532d3..25e1ae70867f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/gf100.c
@@ -31,6 +31,7 @@ gf100_pci_msi_rearm(struct nvkm_pci *pci)
31 31
32static const struct nvkm_pci_func 32static const struct nvkm_pci_func
33gf100_pci_func = { 33gf100_pci_func = {
34 .init = g84_pci_init,
34 .rd32 = nv40_pci_rd32, 35 .rd32 = nv40_pci_rd32,
35 .wr08 = nv40_pci_wr08, 36 .wr08 = nv40_pci_wr08,
36 .wr32 = nv40_pci_wr32, 37 .wr32 = nv40_pci_wr32,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c
index 090a187f165f..6eb417765802 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv40.c
@@ -44,7 +44,7 @@ nv40_pci_wr32(struct nvkm_pci *pci, u16 addr, u32 data)
44 nvkm_wr32(device, 0x088000 + addr, data); 44 nvkm_wr32(device, 0x088000 + addr, data);
45} 45}
46 46
47static void 47void
48nv40_pci_msi_rearm(struct nvkm_pci *pci) 48nv40_pci_msi_rearm(struct nvkm_pci *pci)
49{ 49{
50 nvkm_pci_wr08(pci, 0x0068, 0xff); 50 nvkm_pci_wr08(pci, 0x0068, 0xff);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c
index 3e167d4a381f..fc617e4c0ab6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/nv46.c
@@ -25,11 +25,11 @@
25 25
26#include <core/pci.h> 26#include <core/pci.h>
27 27
28/* MSI re-arm through the PRI appears to be broken on the original G80, 28/* MSI re-arm through the PRI appears to be broken on NV46/NV50/G84/G86/G92,
29 * so we access it via alternate PCI config space mechanisms. 29 * so we access it via alternate PCI config space mechanisms.
30 */ 30 */
31static void 31void
32nv50_pci_msi_rearm(struct nvkm_pci *pci) 32nv46_pci_msi_rearm(struct nvkm_pci *pci)
33{ 33{
34 struct nvkm_device *device = pci->subdev.device; 34 struct nvkm_device *device = pci->subdev.device;
35 struct pci_dev *pdev = device->func->pci(device)->pdev; 35 struct pci_dev *pdev = device->func->pci(device)->pdev;
@@ -37,15 +37,15 @@ nv50_pci_msi_rearm(struct nvkm_pci *pci)
37} 37}
38 38
39static const struct nvkm_pci_func 39static const struct nvkm_pci_func
40nv50_pci_func = { 40nv46_pci_func = {
41 .rd32 = nv40_pci_rd32, 41 .rd32 = nv40_pci_rd32,
42 .wr08 = nv40_pci_wr08, 42 .wr08 = nv40_pci_wr08,
43 .wr32 = nv40_pci_wr32, 43 .wr32 = nv40_pci_wr32,
44 .msi_rearm = nv50_pci_msi_rearm, 44 .msi_rearm = nv46_pci_msi_rearm,
45}; 45};
46 46
47int 47int
48nv50_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci) 48nv46_pci_new(struct nvkm_device *device, int index, struct nvkm_pci **ppci)
49{ 49{
50 return nvkm_pci_new_(&nv50_pci_func, device, index, ppci); 50 return nvkm_pci_new_(&nv46_pci_func, device, index, ppci);
51} 51}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h
index d22c2c117106..cf46d38d0b0a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/priv.h
@@ -7,6 +7,7 @@ int nvkm_pci_new_(const struct nvkm_pci_func *, struct nvkm_device *,
7 int index, struct nvkm_pci **); 7 int index, struct nvkm_pci **);
8 8
9struct nvkm_pci_func { 9struct nvkm_pci_func {
10 void (*init)(struct nvkm_pci *);
10 u32 (*rd32)(struct nvkm_pci *, u16 addr); 11 u32 (*rd32)(struct nvkm_pci *, u16 addr);
11 void (*wr08)(struct nvkm_pci *, u16 addr, u8 data); 12 void (*wr08)(struct nvkm_pci *, u16 addr, u8 data);
12 void (*wr32)(struct nvkm_pci *, u16 addr, u32 data); 13 void (*wr32)(struct nvkm_pci *, u16 addr, u32 data);
@@ -16,4 +17,9 @@ struct nvkm_pci_func {
16u32 nv40_pci_rd32(struct nvkm_pci *, u16); 17u32 nv40_pci_rd32(struct nvkm_pci *, u16);
17void nv40_pci_wr08(struct nvkm_pci *, u16, u8); 18void nv40_pci_wr08(struct nvkm_pci *, u16, u8);
18void nv40_pci_wr32(struct nvkm_pci *, u16, u32); 19void nv40_pci_wr32(struct nvkm_pci *, u16, u32);
20void nv40_pci_msi_rearm(struct nvkm_pci *);
21
22void nv46_pci_msi_rearm(struct nvkm_pci *);
23
24void g84_pci_init(struct nvkm_pci *pci);
19#endif 25#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
index 27a79c0c3888..d95eb8659d1b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
@@ -28,7 +28,7 @@
28void 28void
29nvkm_pmu_pgob(struct nvkm_pmu *pmu, bool enable) 29nvkm_pmu_pgob(struct nvkm_pmu *pmu, bool enable)
30{ 30{
31 if (pmu->func->pgob) 31 if (pmu && pmu->func->pgob)
32 pmu->func->pgob(pmu, enable); 32 pmu->func->pgob(pmu, enable);
33} 33}
34 34
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
index e33f5c03b9ac..d942fa7b9f18 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
@@ -27,6 +27,7 @@
27#include "fuc/gf119.fuc4.h" 27#include "fuc/gf119.fuc4.h"
28 28
29#include <core/option.h> 29#include <core/option.h>
30#include <subdev/fuse.h>
30#include <subdev/timer.h> 31#include <subdev/timer.h>
31 32
32static void 33static void
@@ -57,6 +58,9 @@ gk104_pmu_pgob(struct nvkm_pmu *pmu, bool enable)
57{ 58{
58 struct nvkm_device *device = pmu->subdev.device; 59 struct nvkm_device *device = pmu->subdev.device;
59 60
61 if (!(nvkm_fuse_read(device->fuse, 0x31c) & 0x00000001))
62 return;
63
60 nvkm_mask(device, 0x000200, 0x00001000, 0x00000000); 64 nvkm_mask(device, 0x000200, 0x00001000, 0x00000000);
61 nvkm_rd32(device, 0x000200); 65 nvkm_rd32(device, 0x000200);
62 nvkm_mask(device, 0x000200, 0x08000000, 0x08000000); 66 nvkm_mask(device, 0x000200, 0x08000000, 0x08000000);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild
index 6b46ff4213a3..b035c6e28be8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/Kbuild
@@ -1,4 +1,5 @@
1nvkm-y += nvkm/subdev/volt/base.o 1nvkm-y += nvkm/subdev/volt/base.o
2nvkm-y += nvkm/subdev/volt/gpio.o 2nvkm-y += nvkm/subdev/volt/gpio.o
3nvkm-y += nvkm/subdev/volt/nv40.o 3nvkm-y += nvkm/subdev/volt/nv40.o
4nvkm-y += nvkm/subdev/volt/gk104.o
4nvkm-y += nvkm/subdev/volt/gk20a.o 5nvkm-y += nvkm/subdev/volt/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c
index 4752dbd33923..50b5649ad1a4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c
@@ -30,7 +30,12 @@
30int 30int
31nvkm_volt_get(struct nvkm_volt *volt) 31nvkm_volt_get(struct nvkm_volt *volt)
32{ 32{
33 int ret = volt->func->vid_get(volt), i; 33 int ret, i;
34
35 if (volt->func->volt_get)
36 return volt->func->volt_get(volt);
37
38 ret = volt->func->vid_get(volt);
34 if (ret >= 0) { 39 if (ret >= 0) {
35 for (i = 0; i < volt->vid_nr; i++) { 40 for (i = 0; i < volt->vid_nr; i++) {
36 if (volt->vid[i].vid == ret) 41 if (volt->vid[i].vid == ret)
@@ -46,6 +51,10 @@ nvkm_volt_set(struct nvkm_volt *volt, u32 uv)
46{ 51{
47 struct nvkm_subdev *subdev = &volt->subdev; 52 struct nvkm_subdev *subdev = &volt->subdev;
48 int i, ret = -EINVAL; 53 int i, ret = -EINVAL;
54
55 if (volt->func->volt_set)
56 return volt->func->volt_set(volt, uv);
57
49 for (i = 0; i < volt->vid_nr; i++) { 58 for (i = 0; i < volt->vid_nr; i++) {
50 if (volt->vid[i].uv == uv) { 59 if (volt->vid[i].uv == uv) {
51 ret = volt->func->vid_set(volt, volt->vid[i].vid); 60 ret = volt->func->vid_set(volt, volt->vid[i].vid);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c
new file mode 100644
index 000000000000..b61509e26ec9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c
@@ -0,0 +1,119 @@
1/*
2 * Copyright 2015 Martin Peres
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Martin Peres
23 */
24#include "priv.h"
25
26#include <subdev/volt.h>
27#include <subdev/gpio.h>
28#include <subdev/bios.h>
29#include <subdev/bios/volt.h>
30
31#define gk104_volt(p) container_of((p), struct gk104_volt, base)
32struct gk104_volt {
33 struct nvkm_volt base;
34 struct nvbios_volt bios;
35};
36
37int
38gk104_volt_get(struct nvkm_volt *base)
39{
40 struct nvbios_volt *bios = &gk104_volt(base)->bios;
41 struct nvkm_device *device = base->subdev.device;
42 u32 div, duty;
43
44 div = nvkm_rd32(device, 0x20340);
45 duty = nvkm_rd32(device, 0x20344);
46
47 return bios->base + bios->pwm_range * duty / div;
48}
49
50int
51gk104_volt_set(struct nvkm_volt *base, u32 uv)
52{
53 struct nvbios_volt *bios = &gk104_volt(base)->bios;
54 struct nvkm_device *device = base->subdev.device;
55 u32 div, duty;
56
57 /* the blob uses this crystal frequency, let's use it too. */
58 div = 27648000 / bios->pwm_freq;
59 duty = (uv - bios->base) * div / bios->pwm_range;
60
61 nvkm_wr32(device, 0x20340, div);
62 nvkm_wr32(device, 0x20344, 0x8000000 | duty);
63
64 return 0;
65}
66
67static const struct nvkm_volt_func
68gk104_volt_pwm = {
69 .volt_get = gk104_volt_get,
70 .volt_set = gk104_volt_set,
71}, gk104_volt_gpio = {
72 .vid_get = nvkm_voltgpio_get,
73 .vid_set = nvkm_voltgpio_set,
74};
75
76int
77gk104_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt)
78{
79 const struct nvkm_volt_func *volt_func = &gk104_volt_gpio;
80 struct dcb_gpio_func gpio;
81 struct nvbios_volt bios;
82 struct gk104_volt *volt;
83 u8 ver, hdr, cnt, len;
84 const char *mode;
85
86 if (!nvbios_volt_parse(device->bios, &ver, &hdr, &cnt, &len, &bios))
87 return 0;
88
89 if (!nvkm_gpio_find(device->gpio, 0, DCB_GPIO_VID_PWM, 0xff, &gpio) &&
90 bios.type == NVBIOS_VOLT_PWM) {
91 volt_func = &gk104_volt_pwm;
92 }
93
94 if (!(volt = kzalloc(sizeof(*volt), GFP_KERNEL)))
95 return -ENOMEM;
96 nvkm_volt_ctor(volt_func, device, index, &volt->base);
97 *pvolt = &volt->base;
98 volt->bios = bios;
99
100 /* now that we have a subdev, we can show an error if we found through
101 * the voltage table that we were supposed to use the PWN mode but we
102 * did not find the right GPIO for it.
103 */
104 if (bios.type == NVBIOS_VOLT_PWM && volt_func != &gk104_volt_pwm) {
105 nvkm_error(&volt->base.subdev,
106 "Type mismatch between the voltage table type and "
107 "the GPIO table. Fallback to GPIO mode.\n");
108 }
109
110 if (volt_func == &gk104_volt_gpio) {
111 nvkm_voltgpio_init(&volt->base);
112 mode = "GPIO";
113 } else
114 mode = "PWM";
115
116 nvkm_debug(&volt->base.subdev, "Using %s mode\n", mode);
117
118 return 0;
119}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/priv.h
index 394f37c723af..d5140d991161 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/priv.h
@@ -9,6 +9,8 @@ int nvkm_volt_new_(const struct nvkm_volt_func *, struct nvkm_device *,
9 int index, struct nvkm_volt **); 9 int index, struct nvkm_volt **);
10 10
11struct nvkm_volt_func { 11struct nvkm_volt_func {
12 int (*volt_get)(struct nvkm_volt *);
13 int (*volt_set)(struct nvkm_volt *, u32 uv);
12 int (*vid_get)(struct nvkm_volt *); 14 int (*vid_get)(struct nvkm_volt *);
13 int (*vid_set)(struct nvkm_volt *, u8 vid); 15 int (*vid_set)(struct nvkm_volt *, u8 vid);
14 int (*set_id)(struct nvkm_volt *, u8 id, int condition); 16 int (*set_id)(struct nvkm_volt *, u8 id, int condition);
@@ -17,4 +19,8 @@ struct nvkm_volt_func {
17int nvkm_voltgpio_init(struct nvkm_volt *); 19int nvkm_voltgpio_init(struct nvkm_volt *);
18int nvkm_voltgpio_get(struct nvkm_volt *); 20int nvkm_voltgpio_get(struct nvkm_volt *);
19int nvkm_voltgpio_set(struct nvkm_volt *, u8); 21int nvkm_voltgpio_set(struct nvkm_volt *, u8);
22
23int nvkm_voltpwm_init(struct nvkm_volt *volt);
24int nvkm_voltpwm_get(struct nvkm_volt *volt);
25int nvkm_voltpwm_set(struct nvkm_volt *volt, u32 uv);
20#endif 26#endif